diff --git a/INSTALL b/INSTALL index a0630de65be4b393b4e18c0b1d9473f66afa2e1d..50ced3e78ac35bb29080d5b6a23e587954fc1a18 100644 --- a/INSTALL +++ b/INSTALL @@ -38,3 +38,10 @@ System: After installing, you may need to rebuild the search path for libraries: sudo ldconfig + +It is possible to install the package on Windows through the use of MinGW +and MSYS. MSYS is required for installing PBC, while GMP can be installed +through a package. Based on your MinGW installation, you may need to add +"-I/usr/local/include" to CPPFLAGS and "-L/usr/local/lib" to LDFLAGS when +building PBC. Likewise, you may need to add these options to CGO_CPPFLAGS +and CGO_LDFLAGS when installing this package. \ No newline at end of file diff --git a/README.md b/README.md index 904d5cbbe5facb2720d1953007cf200d9492cac4..9bd9322200c818067bc133a1793bca1aabe58b67 100644 --- a/README.md +++ b/README.md @@ -38,9 +38,7 @@ cryptosystems. This package must be compiled using cgo. It also requires the installation of GMP and PBC. During the build process, this package will attempt to include `gmp.h` and `pbc/pbc.h`, and then dynamically link to GMP and PBC. -It also expects a POSIX-like environment for several C functions. For this -reason, this package cannot be used in Windows without a POSIX compatibility -layer and a gcc compiler. +Installation on Windows requires the use of MinGW. ## Documentation For additional installation instructions and documentation, see diff --git a/doc.go b/doc.go index 93002b6651c9e7388ece9f1a6241d6357585dbba..c61311e0714fcc900f2c839d45f0f2b554972c1d 100644 --- a/doc.go +++ b/doc.go @@ -71,9 +71,6 @@ This package must be compiled using cgo. It also requires the installation of GMP and PBC. During the build process, this package will attempt to include <gmp.h> and <pbc/pbc.h>, and then dynamically link to GMP and PBC. - It also expects a POSIX-like environment for several C functions. For this - reason, this package cannot be used in Windows without a POSIX compatibility - layer and a gcc compiler. Most systems include a package for GMP. To install GMP in Debian / Ubuntu: @@ -109,6 +106,13 @@ sudo ldconfig + It is possible to install the package on Windows through the use of MinGW + and MSYS. MSYS is required for installing PBC, while GMP can be installed + through a package. Based on your MinGW installation, you may need to add + "-I/usr/local/include" to CPPFLAGS and "-L/usr/local/lib" to LDFLAGS when + building PBC. Likewise, you may need to add these options to CGO_CPPFLAGS + and CGO_LDFLAGS when installing this package. + License This package is free software: you can redistribute it and/or modify it diff --git a/element_fmt.go b/element_fmt.go index ba88b80c796d5400f3d2a1c93b20b37d79e8b981..689760205f32274cb9ce6c1d541672055aa8843d 100644 --- a/element_fmt.go +++ b/element_fmt.go @@ -23,13 +23,13 @@ package pbc /* #include <pbc/pbc.h> +#include "memstream.h" int element_out_str_wrapper(char** bufp, size_t* sizep, int base, element_t e) { - FILE* handle = open_memstream(bufp, sizep); - if (!handle) return 0; - element_out_str(handle, base, e); - fclose(handle); - return 1; + memstream_t* stream = pbc_open_memstream(); + if (stream == NULL) return 0; + element_out_str(pbc_memstream_to_fd(stream), base, e); + return pbc_close_memstream(stream, bufp, sizep); } */ import "C" diff --git a/memstream.h b/memstream.h new file mode 100644 index 0000000000000000000000000000000000000000..20191a2e0eeee6f1841ae9b459175c70cb4c8f4a --- /dev/null +++ b/memstream.h @@ -0,0 +1,35 @@ +// Copyright © 2015 Nik Unger +// +// This file is part of The PBC Go Wrapper. +// +// The PBC Go Wrapper is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at your +// option) any later version. +// +// The PBC Go Wrapper is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +// License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with The PBC Go Wrapper. If not, see <http://www.gnu.org/licenses/>. +// +// The PBC Go Wrapper makes use of The PBC library. The PBC Library and its use +// are covered under the terms of the GNU Lesser General Public License +// version 3, or (at your option) any later version. + +#include <stdio.h> + +// memstream_s is a structure that provides platform-independent conversion from +// file descriptor writes to strings +typedef struct memstream_s memstream_t; + +// pbc_open_memstream returns a memstream that can be used for writing data +memstream_t* pbc_open_memstream(); + +// pbc_memstream_to_fd retrieves the file descriptor for a memstream +FILE* pbc_memstream_to_fd(memstream_t* m); + +// pbc_close_memstream closes the memstream and returns the written data +int pbc_close_memstream(memstream_t* m, char** bufp, size_t* sizep); diff --git a/memstream_bsdlike.go b/memstream_bsdlike.go new file mode 100644 index 0000000000000000000000000000000000000000..d8f070487d22f36b0fde7c7096fa5cef07104cb3 --- /dev/null +++ b/memstream_bsdlike.go @@ -0,0 +1,150 @@ +// Copyright © 2015 Nik Unger +// +// This file is part of The PBC Go Wrapper. +// +// The PBC Go Wrapper is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at your +// option) any later version. +// +// The PBC Go Wrapper is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +// License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with The PBC Go Wrapper. If not, see <http://www.gnu.org/licenses/>. +// +// The PBC Go Wrapper makes use of The PBC library. The PBC Library and its use +// are covered under the terms of the GNU Lesser General Public License +// version 3, or (at your option) any later version. +// + +// +build darwin freebsd + +package pbc + +/* +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include <unistd.h> +#include <errno.h> +#include "memstream.h" + +struct memstream_s { + char* buffer; + size_t cap; + size_t len; + fpos_t cursor; + FILE* fd; + int closed; +}; + +static void memstream_realloc(memstream_t* m, size_t size) { + m->cap = size; + m->buffer = realloc(m->buffer, size); + if (size < m->len) { + m->len = size; + m->cursor = m->len; + } +} + +static int memstream_read(void* cookie, char* buf, int nbytes) { + memstream_t* m = (memstream_t*)cookie; + if (m->closed) { errno = EBADF; return -1; } + if (m->cursor >= m->len) return 0; + size_t toRead = (m->len - m->cursor); + if (toRead > (size_t)nbytes) toRead = (size_t)nbytes; + memcpy(buf, &m->buffer[m->cursor], toRead); + m->cursor += toRead; + return toRead; +} + +static int memstream_write(void* cookie, const char* buf, int nbytes) { + memstream_t* m = (memstream_t*)cookie; + if (m->closed) { errno = EBADF; return -1; } + size_t zeros = m->cursor - m->len; + size_t dataLen = (size_t)nbytes; + size_t neededSpace = zeros + dataLen; + if (neededSpace < dataLen) { + errno = EFBIG; + return -1; + } + size_t newLen = m->len + neededSpace; + if (newLen < m->len) { + errno = EFBIG; + return -1; + } + if (newLen > m->cap) { + size_t newCap = m->cap; + do { + if (SIZE_MAX - newCap < newCap) { + newCap = SIZE_MAX; + } else { + newCap <<= 1; + } + } while (newLen > newCap); + memstream_realloc(m, newCap); + } + if (zeros > 0) { + memset(&m->buffer[m->len], 0, zeros); + } + memcpy(&m->buffer[m->cursor], buf, dataLen); + m->cursor += dataLen; + m->len = newLen; + return neededSpace; +} + +static fpos_t memstream_seek(void* cookie, fpos_t offset, int whence) { + memstream_t* m = (memstream_t*)cookie; + if (m->closed) { errno = EBADF; return -1; } + fpos_t base = 0; + switch (whence) { + case SEEK_SET: base = 0; break; + case SEEK_CUR: base = m->cursor; break; + case SEEK_END: base = m->len; break; + // SEEK_HOLE and SEEK_DATA are not supported on darwin + default: errno = EINVAL; return -1; + } + fpos_t desired = base + offset; + if (desired < 0) { + errno = EINVAL; + return -1; + } + if (offset > 0 && desired < base) { + errno = EOVERFLOW; + return -1; + } + return (m->cursor = desired); +} + +static int memstream_close(void* cookie) { + memstream_t* m = (memstream_t*)cookie; + m->closed = 1; + return 0; +} + +memstream_t* pbc_open_memstream() { + memstream_t* m = malloc(sizeof(memstream_t)); + m->buffer = NULL; + memstream_realloc(m, 1024); + m->len = 0; + m->cursor = 0; + m->closed = 0; + m->fd = funopen(m, memstream_read, memstream_write, memstream_seek, memstream_close); + return m; +} + +FILE* pbc_memstream_to_fd(memstream_t* m) { return m->fd; } + +int pbc_close_memstream(memstream_t* m, char** bufp, size_t* sizep) { + fclose(m->fd); + *bufp = m->buffer; + *sizep = m->len; + free(m); + return 1; +} +*/ +import "C" diff --git a/memstream_other.go b/memstream_other.go new file mode 100644 index 0000000000000000000000000000000000000000..91093c6984fb1d784e1acba66f4be79950825a59 --- /dev/null +++ b/memstream_other.go @@ -0,0 +1,70 @@ +// Copyright © 2015 Nik Unger +// +// This file is part of The PBC Go Wrapper. +// +// The PBC Go Wrapper is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at your +// option) any later version. +// +// The PBC Go Wrapper is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +// License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with The PBC Go Wrapper. If not, see <http://www.gnu.org/licenses/>. +// +// The PBC Go Wrapper makes use of The PBC library. The PBC Library and its use +// are covered under the terms of the GNU Lesser General Public License +// version 3, or (at your option) any later version. + +// +build !linux,!darwin,!freebsd + +package pbc + +/* +#include <stdlib.h> +#include "memstream.h" + +struct memstream_s { + FILE* fd; +}; + +memstream_t* pbc_open_memstream() { + FILE* fd = tmpfile(); + if (fd == NULL) return NULL; + memstream_t* result = malloc(sizeof(memstream_t)); + result->fd = fd; + return result; +} + +FILE* pbc_memstream_to_fd(memstream_t* m) { return m->fd; } + +int pbc_close_memstream(memstream_t* m, char** bufp, size_t* sizep) { + *bufp = NULL; + *sizep = 0; + + FILE* fd = m->fd; + m->fd = NULL; + free(m); + m = NULL; + + if (!ferror(fd)) { + fseek(fd, 0, SEEK_END); + *sizep = (size_t)ftell(fd); + rewind(fd); + *bufp = malloc(*sizep + 1); + size_t readBytes = fread(*bufp, 1, *sizep, fd); + if (readBytes < *sizep || ferror(fd)) { + free(*bufp); + *bufp = NULL; + *sizep = 0; + } + bufp[*sizep] = '\0'; + } + fclose(fd); + return (*bufp != NULL); +} +*/ +import "C" diff --git a/memstream_posix.go b/memstream_posix.go new file mode 100644 index 0000000000000000000000000000000000000000..19375a476ba790664d9e3e9b97bdd86d203410dc --- /dev/null +++ b/memstream_posix.go @@ -0,0 +1,57 @@ +// Copyright © 2015 Nik Unger +// +// This file is part of The PBC Go Wrapper. +// +// The PBC Go Wrapper is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at your +// option) any later version. +// +// The PBC Go Wrapper is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +// License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with The PBC Go Wrapper. If not, see <http://www.gnu.org/licenses/>. +// +// The PBC Go Wrapper makes use of The PBC library. The PBC Library and its use +// are covered under the terms of the GNU Lesser General Public License +// version 3, or (at your option) any later version. + +// +build linux + +package pbc + +/* +#include <stdlib.h> +#include <stdio.h> +#include "memstream.h" + +struct memstream_s { + char* buf; + size_t size; + FILE* fd; +}; + +memstream_t* pbc_open_memstream() { + memstream_t* result = malloc(sizeof(memstream_t)); + result->fd = open_memstream(&result->buf, &result->size); + if (result->fd == NULL) { + free(result); + result = NULL; + } + return result; +} + +FILE* pbc_memstream_to_fd(memstream_t* m) { return m->fd; } + +int pbc_close_memstream(memstream_t* m, char** bufp, size_t* sizep) { + fclose(m->fd); + *bufp = m->buf; + *sizep = m->size; + free(m); + return 1; +} +*/ +import "C" diff --git a/params.go b/params.go index c729348c005a28bbaaa2175b2f55291cf697b7db..314d31cc49569ef4bd890fc19692865f550c9a2f 100644 --- a/params.go +++ b/params.go @@ -23,13 +23,13 @@ package pbc /* #include <pbc/pbc.h> +#include "memstream.h" int param_out_str_wrapper(char** bufp, size_t* sizep, pbc_param_t p) { - FILE* handle = open_memstream(bufp, sizep); - if (!handle) return 0; - pbc_param_out_str(handle, p); - fclose(handle); - return 1; + memstream_t* stream = pbc_open_memstream(); + if (stream == NULL) return 0; + pbc_param_out_str(pbc_memstream_to_fd(stream), p); + return pbc_close_memstream(stream, bufp, sizep); } */ import "C"