Mercurial > hg > octave-lojdl
changeset 15050:abc858bc5165
Add functions to encode/decode double arrays to/from base64.
* bootstrap.conf: add base64 to list of imported gnulib modules.
* data.cc (base64_encode): new function.
* data.cc (base64_decode): new function.
author | Carlo de Falco <cdf@users.sourceforge.net> |
---|---|
date | Sun, 29 Jul 2012 19:17:48 +0200 |
parents | e499ebcd3b0f |
children | d43fec5684dd |
files | build-aux/bootstrap.conf src/data.cc |
diffstat | 2 files changed, 128 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/build-aux/bootstrap.conf +++ b/build-aux/bootstrap.conf @@ -18,6 +18,7 @@ # gnulib modules used by this package. gnulib_modules=" + base64 c-strcase copysign copysignf @@ -60,7 +61,6 @@ signal sigprocmask sleep - sleep stat stdint stdio
--- a/src/data.cc +++ b/src/data.cc @@ -3,6 +3,7 @@ Copyright (C) 1994-2012 John W. Eaton Copyright (C) 2009 Jaroslav Hajek Copyright (C) 2009-2010 VZLU Prague +Copyright (C) 2012 Carlo de Falco This file is part of Octave. @@ -37,6 +38,10 @@ #include <ctime> #include <string> +extern "C" +{ +#include <base64.h> +} #include "lo-ieee.h" #include "lo-math.h" @@ -7227,3 +7232,125 @@ return retval; } + +DEFUN (base64_encode, args, nargout, "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{s} =} base64_encode (@var{x})\n\ +Encode a double matrix or array @var{x} into the base64 format string @var{s}.\n\ +Encoding different numeric types is currently not supported, variables of such types \ +will be converted to double before encoding.\n\ +@seealso{base64_decode}\n\ +@end deftypefn") +{ + octave_value_list retval; + + int nargin = args.length (); + if (nargin != 1) + print_usage (); + else + { + const Array<double> in = args(0).array_value (); + if (! error_state) + { + const char* inc = reinterpret_cast<const char*> (in.data ()); + size_t inlen = in.numel () * sizeof (double) / sizeof (char); + char* out; + + size_t outlen = base64_encode_alloc (inc, inlen, &out); + + if (! out && outlen == 0 && inlen != 0) + error ("base64_encode: input array too large"); + else if (! out) + error ("base64_encode: memory allocation error"); + else + retval(0) = octave_value (out); + } + } + return retval; +} + +/* + %!assert (base64_encode (single (pi)), base64_encode (double (single (pi)))); + %!assert (base64_encode (uint8 (pi)), base64_encode (double (uint8 (pi)))); + + %!error (base64_encode ("A string")); +*/ + +DEFUN (base64_decode, args, nargout, "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{x} =} base64_decode (@var{s}, @var{dims})\n\ +Decode the double matrix or array @var{x} from the base64 format string @var{s}.\n\ +The optional input parameter @var{dims} should be a vector containing the dimensions \ +of the decoded array.\n\ +@seealso{base64_encode}\n\ +@end deftypefn") +{ + octave_value_list retval; + dim_vector new_dims; + Array<double> res; + + int nargin = args.length (); + if (nargin < 1 || nargin > 2) + print_usage (); + else + { + if (nargin > 1) + { + const Array<octave_idx_type> new_size = args(1).octave_idx_type_vector_value (); + if (! error_state) + { + new_dims = dim_vector::alloc (new_size.length ()); + for (octave_idx_type i = 0; i < new_size.length (); i++) + new_dims(i) = new_size(i); + } + } + + const std::string in = args(0).string_value (); + + if (! error_state) + { + const char *inc = &(in[0]); + char *out; + size_t inlen = in.length (), + outlen; + + bool ok = base64_decode_alloc (inc, inlen, &out, &outlen); + + if (! ok) + error ("base64_decode: input was not valid base64"); + else if (! out) + error ("base64_decode: memory allocation error"); + else + { + if ((outlen % (sizeof (double) / sizeof (char))) != 0) + error ("base64_decode: incorrect input size"); + else + { + octave_idx_type l = (outlen * sizeof (char)) / sizeof (double); + res.resize1 (l); + double *dout = reinterpret_cast<double*> (out); + std::copy (dout, dout + l, res.fortran_vec ()); + + if (nargin > 1) + retval(0) = octave_value (res).reshape (new_dims); + else + retval(0) = octave_value (res); + } + } + } + } + return retval; +} + +/* + %!assert (base64_decode (base64_encode (pi))); + %!test + %! in = randn (10); + %! outv = base64_decode (base64_encode (in)); + %! outm = base64_decode (base64_encode (in), size (in)); + %! assert (outv, in(:).'); + %! assert (outm, in); + + %!error (base64_decode (1, "this is not a valid set of dimensions")) + %!error <not valid> (base64_decode (1)) + %!error <not valid> (base64_decode ("AQ=")) + %!error <incorrect input size> (base64_decode ("AQ==")) +*/