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"