# HG changeset patch # User Carlo de Falco # Date 1343582268 -7200 # Node ID abc858bc51657dd6fed7f0ec5c9f603e9448efb5 # Parent e499ebcd3b0f6764216d965eaec9c2670c91348f 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. diff -r e499ebcd3b0f -r abc858bc5165 build-aux/bootstrap.conf --- a/build-aux/bootstrap.conf Sun Jul 29 18:29:02 2012 +0200 +++ b/build-aux/bootstrap.conf Sun Jul 29 19:17:48 2012 +0200 @@ -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 diff -r e499ebcd3b0f -r abc858bc5165 src/data.cc --- a/src/data.cc Sun Jul 29 18:29:02 2012 +0200 +++ b/src/data.cc Sun Jul 29 19:17:48 2012 +0200 @@ -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 #include +extern "C" +{ +#include +} #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 in = args(0).array_value (); + if (! error_state) + { + const char* inc = reinterpret_cast (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 res; + + int nargin = args.length (); + if (nargin < 1 || nargin > 2) + print_usage (); + else + { + if (nargin > 1) + { + const Array 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 (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 (base64_decode (1)) + %!error (base64_decode ("AQ=")) + %!error (base64_decode ("AQ==")) +*/