r9339: treat arrays of uint8 values as a special DATA_BLOB type in the ejs
authorAndrew Tridgell <tridge@samba.org>
Wed, 17 Aug 2005 01:29:35 +0000 (01:29 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:33:25 +0000 (13:33 -0500)
interfaces to RPC. This makes large blobs of data much saner. Tim, you
will probably want to do the same for the smb_interfaces.h generated
code.

Next we will need ways of extracting different data types from these
blobs, for example asking for the blob to be interpreted as a utf16
string, or as a little-endian integer. That will allow for registry
scripting to be quite sane.
(This used to be commit a8bca2e8e27c953c0413693326ec3b5ecf17ba41)

source4/build/pidl/Parse/Pidl/Samba/EJS.pm
source4/scripting/ejs/ejsrpc.c
source4/scripting/ejs/ejsrpc.h
source4/scripting/ejs/mprutil.c

index 1227e7aeb89357a41bd07c0f8b9607fa62fc2997..743139c8cd3bc6f61aa8cc0976f0164ea7d62de7 100644 (file)
@@ -165,22 +165,32 @@ sub EjsPullString($$$$$)
 sub EjsPullArray($$$$$)
 {
        my ($e, $l, $var, $name, $env) = @_;
+       my $nl = Parse::Pidl::NDR::GetNextLevel($e, $l);
        my $length = Parse::Pidl::Util::ParseExpr($l->{LENGTH_IS}, $env);
+       my $size = Parse::Pidl::Util::ParseExpr($l->{SIZE_IS}, $env);
        my $pl = Parse::Pidl::NDR::GetPrevLevel($e, $l);
        if ($pl && $pl->{TYPE} eq "POINTER") {
                $var = get_pointer_to($var);
        }
+       # uint8 arrays are treated as data blobs
+       if ($nl->{TYPE} eq 'DATA' && $e->{TYPE} eq 'uint8') {
+               if (!$l->{IS_FIXED}) {
+                       pidl "EJS_ALLOC_N(ejs, $var, $size);";
+               }
+               pidl "ejs_pull_array_uint8(ejs, v, $name, $var, $length);";
+               return;
+       }
        my $avar = $var . "[i]";
        pidl "{";
        indent;
        pidl "uint32_t i;";
        if (!$l->{IS_FIXED}) {
-               pidl "EJS_ALLOC_N(ejs, $var, $length);";
+               pidl "EJS_ALLOC_N(ejs, $var, $size);";
        }
        pidl "for (i=0;i<$length;i++) {";
        indent;
        pidl "char *id = talloc_asprintf(ejs, \"%s.%u\", $name, i);";
-       EjsPullElement($e, Parse::Pidl::NDR::GetNextLevel($e, $l), $avar, "id", $env);
+       EjsPullElement($e, $nl, $avar, "id", $env);
        pidl "talloc_free(id);";
        deindent;
        pidl "}";
@@ -451,11 +461,17 @@ sub EjsPushSwitch($$$$$)
 sub EjsPushArray($$$$$)
 {
        my ($e, $l, $var, $name, $env) = @_;
+       my $nl = Parse::Pidl::NDR::GetNextLevel($e, $l);
        my $length = Parse::Pidl::Util::ParseExpr($l->{LENGTH_IS}, $env);
        my $pl = Parse::Pidl::NDR::GetPrevLevel($e, $l);
        if ($pl && $pl->{TYPE} eq "POINTER") {
                $var = get_pointer_to($var);
        }
+       # uint8 arrays are treated as data blobs
+       if ($nl->{TYPE} eq 'DATA' && $e->{TYPE} eq 'uint8') {
+               pidl "ejs_push_array_uint8(ejs, v, $name, $var, $length);";
+               return;
+       }
        my $avar = $var . "[i]";
        pidl "{";
        indent;
@@ -463,7 +479,7 @@ sub EjsPushArray($$$$$)
        pidl "for (i=0;i<$length;i++) {";
        indent;
        pidl "const char *id = talloc_asprintf(ejs, \"%s.%u\", $name, i);";
-       EjsPushElement($e, Parse::Pidl::NDR::GetNextLevel($e, $l), $avar, "id", $env);
+       EjsPushElement($e, $nl, $avar, "id", $env);
        deindent;
        pidl "}";
        pidl "ejs_push_uint32(ejs, v, $name \".length\", &i);";
index f107c84b73a2021ff82b1f7f29a5b9c7c12c3b35..de25d3a0f01ecc45d8ec337793afbde977ce4eb9 100644 (file)
@@ -349,3 +349,40 @@ NTSTATUS ejs_push_BOOL(struct ejs_rpc *ejs,
 {
        return mprSetVar(v, name, mprCreateBoolVar(*r));
 }
+
+
+/*
+  pull a uint8 array from a mpr variable to a C element - treating as a data blob
+*/
+NTSTATUS ejs_pull_array_uint8(struct ejs_rpc *ejs, 
+                             struct MprVar *v, const char *name, 
+                             uint8_t *r, uint32_t length)
+{
+       NTSTATUS status;
+       DATA_BLOB *blob;
+
+       status = mprGetVar(&v, name);
+       NT_STATUS_NOT_OK_RETURN(status);
+
+       blob = mprToDataBlob(v);
+       if (blob == NULL) {
+               return NT_STATUS_OBJECT_NAME_INVALID;
+       }
+       if (blob->length != length) {
+               return NT_STATUS_INFO_LENGTH_MISMATCH;
+       }
+       memcpy(r, blob->data, length);
+       return NT_STATUS_OK;
+       
+}
+
+NTSTATUS ejs_push_array_uint8(struct ejs_rpc *ejs, 
+                             struct MprVar *v, const char *name, 
+                             const uint8_t *r, uint32_t length)
+{
+       DATA_BLOB blob;
+       blob.data = discard_const(r);
+       blob.length = length;
+       mprSetVar(v, name, mprDataBlob(blob));
+       return NT_STATUS_OK;
+}
index 99da0d35ea0029b9df17bbb81b2c0fd1164ffb53..03919c36027ad512f7905cc39ac009fead7d3439 100644 (file)
@@ -108,6 +108,13 @@ NTSTATUS ejs_pull_BOOL(struct ejs_rpc *ejs,
 NTSTATUS ejs_push_BOOL(struct ejs_rpc *ejs, 
                       struct MprVar *v, const char *name, const BOOL *r);
 
+NTSTATUS ejs_pull_array_uint8(struct ejs_rpc *ejs, 
+                             struct MprVar *v, const char *name, 
+                             uint8_t *r, uint32_t length);
+NTSTATUS ejs_push_array_uint8(struct ejs_rpc *ejs, 
+                             struct MprVar *v, const char *name, 
+                             const uint8_t *r, uint32_t length);
+
 #define EJS_ALLOC_SIZE(ejs, s, size) do { \
   (s) = talloc_size(ejs, size); \
   if (!(s)) return ejs_panic(ejs, "out of memory"); \
index 657078e7c79a125d324863991f67fb05a1a765e9..700185f07e6867382f8b51d4c39de50e6b42bd97 100644 (file)
@@ -317,6 +317,31 @@ struct MprVar mprNTSTATUS(NTSTATUS status)
        return res;
 }
 
+/*
+  create a data-blob in a mpr variable
+*/
+struct MprVar mprDataBlob(DATA_BLOB blob)
+{
+       struct MprVar res;
+       struct data_blob *pblob = talloc(mprMemCtx(), struct data_blob);
+       *pblob = data_blob_talloc(pblob, blob.data, blob.length);
+
+       res = mprObject("DATA_BLOB");
+
+       mprSetVar(&res, "size", mprCreateIntegerVar(blob.length));
+       mprSetPtrChild(&res, "blob", pblob);
+
+       return res;
+}
+
+/*
+  return a data blob from a mpr var created using mprDataBlob
+*/
+struct data_blob *mprToDataBlob(struct MprVar *v)
+{
+       return talloc_get_type(mprGetPtr(v, "blob"), struct data_blob);
+}
+
 /*
   turn a WERROR into a MprVar object with lots of funky properties
 */