changeset 28769:903fe321649b

Add Matlab compatible wrappers for base64_encode and base64_decode. * liboctave/util/oct-base64.cc, oct-base64.h (base64_decode_bytes): New function to decode base64 encoded strings into bytes. * libinterp/corefcn/data.cc (F__base64_decode_bytes__): New internal function to decode base64 encoded strings into bytes. * scripts/+matlab/+net/base64decode.m, scripts/+matlab/+net/base64encode.m: Add Matlab compatible wrappers for base64_encode and __base64_decode_bytes__. * scripts/+matlab/+net/module.mk: Add new file. * scripts/module.mk: Include new module.mk file. * doc/interpreter/system.txi: Add documentation for new functions to manual. * NEWS: Announce new functions.
author Markus Mützel <markus.muetzel@gmx.de>
date Tue, 22 Sep 2020 15:59:00 +0200
parents bffd48bb4b8c
children 671fd568b130
files NEWS doc/interpreter/system.txi libinterp/corefcn/data.cc liboctave/util/oct-base64.cc liboctave/util/oct-base64.h scripts/+matlab/+net/base64decode.m scripts/+matlab/+net/base64encode.m scripts/+matlab/+net/module.mk scripts/module.mk
diffstat 9 files changed, 241 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Tue Sep 22 17:19:46 2020 +0200
+++ b/NEWS	Tue Sep 22 15:59:00 2020 +0200
@@ -153,6 +153,8 @@
 * `jsondecode`
 * `jsonencode`
 * `listfonts`
+* `matlab.net.base64decode`
+* `matlab.net.base64encode`
 * `memory`
 * `rng`
 * `startsWith`
--- a/doc/interpreter/system.txi	Tue Sep 22 17:19:46 2020 +0200
+++ b/doc/interpreter/system.txi	Tue Sep 22 15:59:00 2020 +0200
@@ -324,6 +324,10 @@
 
 @DOCSTRING(base64_decode)
 
+@DOCSTRING(matlab.net.base64encode)
+
+@DOCSTRING(matlab.net.base64decode)
+
 @node Controlling Subprocesses
 @section Controlling Subprocesses
 
--- a/libinterp/corefcn/data.cc	Tue Sep 22 17:19:46 2020 +0200
+++ b/libinterp/corefcn/data.cc	Tue Sep 22 15:59:00 2020 +0200
@@ -7978,7 +7978,7 @@
 Encode a double matrix or array @var{x} into the base64 format string
 @var{s}.
 
-@seealso{base64_decode}
+@seealso{base64_decode, matlab.net.base64decode, matlab.net.base64encode}
 @end deftypefn */)
 {
   if (args.length () != 1)
@@ -8086,7 +8086,7 @@
 
 The optional input parameter @var{dims} should be a vector containing the
 dimensions of the decoded array.
-@seealso{base64_encode}
+@seealso{base64_encode, matlab.net.base64decode, matlab.net.base64encode}
 @end deftypefn */)
 {
   int nargin = args.length ();
@@ -8132,3 +8132,57 @@
 %!error <input was not valid base64> base64_decode ("AQ=")
 %!error <incorrect input size> base64_decode ("AQ==")
 */
+
+DEFUN (__base64_decode_bytes__, args, ,
+       doc: /* -*- texinfo -*-
+@deftypefn  {} {@var{x} =} base64_decode_bytes (@var{s})
+@deftypefnx {} {@var{x} =} base64_decode_bytes (@var{s}, @var{dims})
+Decode the uint8 matrix or array @var{x} from the base64 encoded string
+@var{s}.
+
+The optional input parameter @var{dims} should be a vector containing the
+dimensions of the decoded array.
+@seealso{base64_decode}
+@end deftypefn */)
+{
+  int nargin = args.length ();
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+
+  std::string str = args(0).string_value ();
+
+  intNDArray<octave_uint8> retval = octave::base64_decode_bytes (str);
+
+  if (nargin == 2)
+    {
+      dim_vector dims;
+
+      const Array<octave_idx_type> size
+        = args(1).octave_idx_type_vector_value ();
+
+      dims = dim_vector::alloc (size.numel ());
+      for (octave_idx_type i = 0; i < size.numel (); i++)
+        dims(i) = size(i);
+
+      retval = retval.reshape (dims);
+    }
+
+  return ovl (retval);
+}
+
+/*
+%!assert (__base64_decode_bytes__ (base64_encode (uint8 (1))), uint8 (1))
+
+%!test
+%! in   = uint8 (rand (10)*255);
+%! outv = __base64_decode_bytes__ (base64_encode (in));
+%! outm = __base64_decode_bytes__ (base64_encode (in), size (in));
+%! assert (outv, in(:).');
+%! assert (outm, in);
+
+%!error __base64_decode_bytes__ ()
+%!error __base64_decode_bytes__ (1,2,3)
+%!error __base64_decode_bytes__ (1, "this is not a valid set of dimensions")
+%!error <input was not valid base64> __base64_decode_bytes__ (1)
+*/
--- a/liboctave/util/oct-base64.cc	Tue Sep 22 17:19:46 2020 +0200
+++ b/liboctave/util/oct-base64.cc	Tue Sep 22 15:59:00 2020 +0200
@@ -94,4 +94,31 @@
 
     return retval;
   }
+
+  intNDArray<octave_uint8>
+  base64_decode_bytes (const std::string& str)
+  {
+    intNDArray<octave_uint8> retval;
+
+    char *out;
+    size_t outlen;
+
+    bool ok
+      = octave_base64_decode_alloc_wrapper (str.data (), str.length (),
+                                            &out, &outlen);
+
+    if (! ok)
+      (*current_liboctave_error_handler)
+        ("base64_decode: input was not valid base64");
+
+    if (! out)
+      (*current_liboctave_error_handler)
+        ("base64_decode: memory allocation error");
+
+    retval.resize (dim_vector (1, outlen));
+    std::copy (out, out + outlen, retval.fortran_vec ());
+    ::free (out);
+
+    return retval;
+  }
 }
--- a/liboctave/util/oct-base64.h	Tue Sep 22 17:19:46 2020 +0200
+++ b/liboctave/util/oct-base64.h	Tue Sep 22 15:59:00 2020 +0200
@@ -30,6 +30,8 @@
 
 #include <string>
 
+#include "intNDArray.h"
+
 template <typename T> class Array;
 
 namespace octave
@@ -39,6 +41,9 @@
 
   extern OCTAVE_API Array<double>
   base64_decode (const std::string& str);
+
+  extern OCTAVE_API intNDArray<octave_uint8>
+  base64_decode_bytes (const std::string& str);
 }
 
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/+matlab/+net/base64decode.m	Tue Sep 22 15:59:00 2020 +0200
@@ -0,0 +1,64 @@
+########################################################################
+##
+## Copyright (C) 2020 The Octave Project Developers
+##
+## See the file COPYRIGHT.md in the top-level directory of this
+## distribution or <https://octave.org/copyright/>.
+##
+## This file is part of Octave.
+##
+## Octave is free software: you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## Octave 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 General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <https://www.gnu.org/licenses/>.
+##
+########################################################################
+
+## -*- texinfo -*-
+## @deftypefn  {} {@var{out_vec} =} matlab.net.base64decode (@var{b64_str})
+##
+## Convert base64 encoded @var{b64_str} to uint8 vector @var{out_vec}.
+##
+## The input @var{b64_str} must be a string vector.
+## The output @var{out_vec} will be a uint8 vector that is decoded
+## according to RFC 4648.
+##
+## @seealso{matlab.net.base64encode, base64_decode, base64_encode, native2unicode}
+## @end deftypefn
+
+function out_vec = base64decode (b64_str)
+
+  if (nargin != 1 || nargout > 1)
+    print_usage ();
+  endif
+
+  if (! isvector (b64_str) || ! ischar (b64_str))
+    error ("base64decode: B64_STR must be a base64 encoded character vector");
+  endif
+
+  out_vec = uint8 (__base64_decode_bytes__ (b64_str));
+
+endfunction
+
+
+## Test char vector input
+%!assert (matlab.net.base64decode ("AQ=="), uint8 (1));
+%!assert (matlab.net.base64decode ("/w=="), uint8 (255));
+%!assert (matlab.net.base64decode ("AQID"), uint8 (1:3));
+%!assert (matlab.net.base64decode ("YQ=="), uint8 ("a"));
+%!assert (matlab.net.base64decode ("YWJjZGVmZw=="), uint8 ("abcdefg"));
+
+## Test input validation
+%!error matlab.net.base64decode ()
+%!error <character vector> matlab.net.base64decode (pi)
+%!error <character vector> matlab.net.base64decode ({1,2})
+%!error <character vector> matlab.net.base64decode ([1,2;3,4])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/+matlab/+net/base64encode.m	Tue Sep 22 15:59:00 2020 +0200
@@ -0,0 +1,67 @@
+########################################################################
+##
+## Copyright (C) 2020 The Octave Project Developers
+##
+## See the file COPYRIGHT.md in the top-level directory of this
+## distribution or <https://octave.org/copyright/>.
+##
+## This file is part of Octave.
+##
+## Octave is free software: you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## Octave 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 General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <https://www.gnu.org/licenses/>.
+##
+########################################################################
+
+## -*- texinfo -*-
+## @deftypefn  {} {@var{b64_str} =} matlab.net.base64encode (@var{in})
+##
+## Convert @var{in} to a base64 encoded string @var{b64_str}.
+##
+## The input @var{in} can be a string or numeric vector.
+## The output @var{b64_str} will be encoded according to RFC 4648.
+##
+## @seealso{matlab.net.base64decode, base64_decode, base64_encode, unicode2native}
+## @end deftypefn
+
+function b64_str = base64encode (in)
+
+  if (nargin != 1 || nargout > 1)
+    print_usage ();
+  endif
+
+  if (! isvector (in) || ! (isnumeric (in) || ischar (in)))
+    error ("base64encode: IN must be a numeric or character vector");
+  endif
+
+  if (any (in != round (in)))
+    error ("base64encode: IN must consist of integers");
+  endif
+
+  b64_str = base64_encode (uint8 (in));
+
+endfunction
+
+
+## Test char vector input
+%!assert (matlab.net.base64encode (1), "AQ==");
+%!assert (matlab.net.base64encode (255), "/w==");
+%!assert (matlab.net.base64encode (1:3), "AQID");
+%!assert (matlab.net.base64encode ("a"), "YQ==");
+%!assert (matlab.net.base64encode ("abcdefg"), "YWJjZGVmZw==");
+
+## Test input validation
+%!error matlab.net.base64encode ()
+%!error <numeric or character vector> matlab.net.base64encode ({1,2})
+%!error <numeric or character vector> matlab.net.base64encode ([1,2;3,4])
+%!error <consist of integers> matlab.net.base64encode (pi)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/+matlab/+net/module.mk	Tue Sep 22 15:59:00 2020 +0200
@@ -0,0 +1,15 @@
+FCN_FILE_DIRS += %reldir%
+
+%canon_reldir%_FCN_FILES = \
+  %reldir%/base64decode.m \
+  %reldir%/base64encode.m
+
+%canon_reldir%dir = $(fcnfiledir)/+matlab/+net
+
+%canon_reldir%_DATA = $(%canon_reldir%_FCN_FILES)
+
+FCN_FILES += $(%canon_reldir%_FCN_FILES)
+
+PKG_ADD_FILES += %reldir%/PKG_ADD
+
+DIRSTAMP_FILES += %reldir%/$(octave_dirstamp)
--- a/scripts/module.mk	Tue Sep 22 17:19:46 2020 +0200
+++ b/scripts/module.mk	Tue Sep 22 15:59:00 2020 +0200
@@ -6,6 +6,7 @@
 
 include %reldir%/+containers/module.mk
 include %reldir%/+matlab/+lang/module.mk
+include %reldir%/+matlab/+net/module.mk
 include %reldir%/audio/module.mk
 include %reldir%/deprecated/module.mk
 include %reldir%/elfun/module.mk