svn commit: samba r9339 - in branches/SAMBA_4_0/source: build/pidl/Parse/Pidl/Samba scripting/ejs

tridge at samba.org tridge at samba.org
Wed Aug 17 01:29:35 GMT 2005


Author: tridge
Date: 2005-08-17 01:29:35 +0000 (Wed, 17 Aug 2005)
New Revision: 9339

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=9339

Log:

treat arrays of uint8 values as a special DATA_BLOB type in the ejs
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.

Modified:
   branches/SAMBA_4_0/source/build/pidl/Parse/Pidl/Samba/EJS.pm
   branches/SAMBA_4_0/source/scripting/ejs/ejsrpc.c
   branches/SAMBA_4_0/source/scripting/ejs/ejsrpc.h
   branches/SAMBA_4_0/source/scripting/ejs/mprutil.c


Changeset:
Modified: branches/SAMBA_4_0/source/build/pidl/Parse/Pidl/Samba/EJS.pm
===================================================================
--- branches/SAMBA_4_0/source/build/pidl/Parse/Pidl/Samba/EJS.pm	2005-08-17 01:25:58 UTC (rev 9338)
+++ branches/SAMBA_4_0/source/build/pidl/Parse/Pidl/Samba/EJS.pm	2005-08-17 01:29:35 UTC (rev 9339)
@@ -165,22 +165,32 @@
 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 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 @@
 	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);";

Modified: branches/SAMBA_4_0/source/scripting/ejs/ejsrpc.c
===================================================================
--- branches/SAMBA_4_0/source/scripting/ejs/ejsrpc.c	2005-08-17 01:25:58 UTC (rev 9338)
+++ branches/SAMBA_4_0/source/scripting/ejs/ejsrpc.c	2005-08-17 01:29:35 UTC (rev 9339)
@@ -349,3 +349,40 @@
 {
 	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;
+}

Modified: branches/SAMBA_4_0/source/scripting/ejs/ejsrpc.h
===================================================================
--- branches/SAMBA_4_0/source/scripting/ejs/ejsrpc.h	2005-08-17 01:25:58 UTC (rev 9338)
+++ branches/SAMBA_4_0/source/scripting/ejs/ejsrpc.h	2005-08-17 01:29:35 UTC (rev 9339)
@@ -108,6 +108,13 @@
 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"); \

Modified: branches/SAMBA_4_0/source/scripting/ejs/mprutil.c
===================================================================
--- branches/SAMBA_4_0/source/scripting/ejs/mprutil.c	2005-08-17 01:25:58 UTC (rev 9338)
+++ branches/SAMBA_4_0/source/scripting/ejs/mprutil.c	2005-08-17 01:29:35 UTC (rev 9339)
@@ -318,6 +318,31 @@
 }
 
 /*
+  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
 */
 struct MprVar mprWERROR(WERROR status)



More information about the samba-cvs mailing list