r9339: treat arrays of uint8 values as a special DATA_BLOB type in the ejs
[ira/wip.git] / source / scripting / ejs / mprutil.c
index 95571da245711ae157df30299dc0dd69839056e1..700185f07e6867382f8b51d4c39de50e6b42bd97 100644 (file)
@@ -21,7 +21,7 @@
 */
 
 #include "includes.h"
-#include "lib/ejs/ejs.h"
+#include "lib/appweb/ejs/ejs.h"
 #include "lib/ldb/include/ldb.h"
 
 /*
@@ -29,7 +29,7 @@
 */
 struct MprVar mprObject(const char *name)
 {
-       return ejsCreateObj(name?name:"(NULL)", MPR_DEFAULT_HASH_SIZE);
+       return ejsCreateObj(name && *name?name:"(NULL)", MPR_DEFAULT_HASH_SIZE);
 }
 
 /*
@@ -114,7 +114,7 @@ struct MprVar mprList(const char *name, const char **list)
 
        var = mprObject(name);
        for (i=0;list && list[i];i++) {
-               mprAddArray(&var, i, mprCreateStringVar(list[i], 1));
+               mprAddArray(&var, i, mprString(list[i]));
        }
        if (i==0) {
                mprSetVar(&var, "length", mprCreateIntegerVar(i));
@@ -130,7 +130,7 @@ struct MprVar mprString(const char *s)
        if (s == NULL) {
                return mprCreatePtrVar(NULL);
        }
-       return mprCreateStringVar(s, 1);
+       return mprCreateStringVar(s, True);
 }
 
 /*
@@ -143,7 +143,7 @@ struct MprVar mprData(const uint8_t *p, size_t length)
        if (s == NULL) {
                return mprCreateUndefinedVar();
        }
-       var = mprCreateStringVar(s, 1);
+       var = mprString(s);
        talloc_free(s);
        return var;
 }
@@ -151,7 +151,7 @@ struct MprVar mprData(const uint8_t *p, size_t length)
 /*
   turn a ldb_message into a ejs object variable
 */
-struct MprVar mprLdbMessage(struct ldb_message *msg)
+static struct MprVar mprLdbMessage(struct ldb_context *ldb, struct ldb_message *msg)
 {
        struct MprVar var;
        int i;
@@ -166,16 +166,29 @@ struct MprVar mprLdbMessage(struct ldb_message *msg)
        for (i=0;i<msg->num_elements;i++) {
                struct ldb_message_element *el = &msg->elements[i];
                struct MprVar val;
+               const struct ldb_attrib_handler *attr;
+               struct ldb_val v;
+
+               attr = ldb_attrib_handler(ldb, el->name);
+               if (attr == NULL) {
+                       goto failed;
+               }
+
                if (el->num_values == 1 &&
                    !str_list_check_ci(multivalued, el->name)) {
-                       val = mprData(el->values[0].data, el->values[0].length);
+                       if (attr->ldif_write_fn(ldb, msg, &el->values[0], &v) != 0) {
+                               goto failed;
+                       }
+                       val = mprData(v.data, v.length);
                } else {
                        int j;
                        val = mprObject(el->name);
                        for (j=0;j<el->num_values;j++) {
-                               mprAddArray(&val, j, 
-                                           mprData(el->values[j].data, 
-                                                   el->values[j].length));
+                               if (attr->ldif_write_fn(ldb, msg, 
+                                                       &el->values[j], &v) != 0) {
+                                       goto failed;
+                               }
+                               mprAddArray(&val, j, mprData(v.data, v.length));
                        }
                }
                mprSetVar(&var, el->name, val);
@@ -183,24 +196,30 @@ struct MprVar mprLdbMessage(struct ldb_message *msg)
 
        /* add the dn if it is not already specified */
        if (mprGetProperty(&var, "dn", 0) == 0) {
-               mprSetVar(&var, "dn", mprCreateStringVar(msg->dn, 1));
+               mprSetVar(&var, "dn", mprString(msg->dn));
        }
        
        return var;             
+failed:
+       return mprCreateUndefinedVar();
 }
 
 
 /*
   turn an array of ldb_messages into a ejs object variable
 */
-struct MprVar mprLdbArray(struct ldb_message **msg, int count, const char *name)
+struct MprVar mprLdbArray(struct ldb_context *ldb, 
+                         struct ldb_message **msg, int count, const char *name)
 {
        struct MprVar res;
        int i;
 
        res = mprObject(name);
        for (i=0;i<count;i++) {
-               mprAddArray(&res, i, mprLdbMessage(msg[i]));
+               mprAddArray(&res, i, mprLdbMessage(ldb, msg[i]));
+       }
+       if (i==0) {
+               mprSetVar(&res, "length", mprCreateIntegerVar(0));
        }
        return res;
 }
@@ -290,7 +309,7 @@ struct MprVar mprNTSTATUS(NTSTATUS status)
 
        res = mprObject("ntstatus");
 
-       mprSetVar(&res, "errstr", mprCreateStringVar(nt_errstr(status), 1));
+       mprSetVar(&res, "errstr", mprString(nt_errstr(status)));
        mprSetVar(&res, "v", mprCreateIntegerVar(NT_STATUS_V(status)));
        mprSetVar(&res, "is_ok", mprCreateBoolVar(NT_STATUS_IS_OK(status)));
        mprSetVar(&res, "is_err", mprCreateBoolVar(NT_STATUS_IS_ERR(status)));
@@ -298,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
 */
@@ -307,7 +351,7 @@ struct MprVar mprWERROR(WERROR status)
 
        res = mprObject("werror");
 
-       mprSetVar(&res, "errstr", mprCreateStringVar(win_errstr(status), 1));
+       mprSetVar(&res, "errstr", mprString(win_errstr(status)));
        mprSetVar(&res, "v", mprCreateIntegerVar(W_ERROR_V(status)));
        mprSetVar(&res, "is_ok", mprCreateBoolVar(W_ERROR_IS_OK(status)));
        mprSetVar(&res, "is_err", mprCreateBoolVar(!W_ERROR_IS_OK(status)));
@@ -363,7 +407,54 @@ void *mprGetPtr(struct MprVar *v, const char *propname)
 */
 void mpr_ReturnString(int eid, const char *s)
 { 
-       mpr_Return(eid, mprCreateStringVar(s, False));
+       mpr_Return(eid, mprString(s));
+}
+
+
+/*
+  set a C function in a variable
+*/
+ void mprSetCFunction(struct MprVar *obj, const char *name, MprCFunction fn)
+{
+       mprSetVar(obj, name, mprCreateCFunctionVar(fn, obj, MPR_VAR_SCRIPT_HANDLE));
 }
 
+/*
+  set a string C function in a variable
+*/
+ void mprSetStringCFunction(struct MprVar *obj, const char *name, MprStringCFunction fn)
+{
+       mprSetVar(obj, name, mprCreateStringCFunctionVar(fn, obj, MPR_VAR_SCRIPT_HANDLE));
+}
 
+/*
+  get a pointer in the current object
+*/
+void *mprGetThisPtr(int eid, const char *name)
+{
+       struct MprVar *this = mprGetProperty(ejsGetLocalObject(eid), "this", 0);
+       return mprGetPtr(this, name);
+}
+
+/*
+  set a pointer as a child of the local object
+*/
+void mprSetThisPtr(int eid, const char *name, void *ptr)
+{
+       struct MprVar *this = mprGetProperty(ejsGetLocalObject(eid), "this", 0);
+       mprSetPtrChild(this, name, ptr);
+}
+
+/*
+  used by object xxx_init() routines to allow for the caller
+  to supply a pre-existing object to add properties to,
+  or create a new object. This makes inheritance easy
+*/
+struct MprVar *mprInitObject(int eid, const char *name, int argc, struct MprVar **argv)
+{
+       if (argc > 0 && mprVarIsObject(argv[0]->type)) {
+               return argv[0];
+       }
+       mpr_Return(eid, mprObject(name));
+       return ejsGetReturnValue(eid);
+}