3 * @brief MPR Universal Variable Type
6 * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
7 * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
9 * This software is distributed under commercial and open source licenses.
10 * You may use the GPL open source license described below or you may acquire
11 * a commercial license from Mbedthis Software. You agree to be fully bound
12 * by the terms of either license. Consult the LICENSE.TXT distributed with
13 * this software for full details.
15 * This software is open source; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version. See the GNU General Public License for more
19 * details at: http://www.mbedthis.com/downloads/gplLicense.html
21 * This program is distributed WITHOUT ANY WARRANTY; without even the
22 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
24 * This GPL license does NOT permit incorporating this software into
25 * proprietary programs. If you are unable to comply with the GPL, you must
26 * acquire a commercial license to use this software. Commercial licenses
27 * for this software and support services are available from Mbedthis
28 * Software at http://www.mbedthis.com
33 /******************************* Documentation ********************************/
35 * Variables can efficiently store primitive types and can hold references to
36 * objects. Objects can store properties which are themselves variables.
37 * Properties can be primitive data types, other objects or functions.
38 * Properties are indexed by a character name. A variable may store one of
39 * the following types:
41 * string, integer, integer-64bit, C function, C function with string args,
42 * Javascript function, Floating point number, boolean value, Undefined
43 * value and the Null value.
45 * Variables have names while objects may be referenced by multiple variables.
46 * Objects use reference counting for garbage collection.
48 * This module is not thread safe for performance and compactness. It relies
49 * on upper modules to provide thread synchronization as required. The API
50 * provides primitives to get variable/object references or to get copies of
51 * variables which will help minimize required lock times.
57 /********************************* Includes ***********************************/
61 /********************************** Defines ***********************************/
64 * Define VAR_DEBUG if you want to track objects. However, this code is not
65 * thread safe and you need to run the server single threaded.
74 * Forward declare types
80 * Possible variable types. Don't use enum because we need to be able to
81 * do compile time conditional compilation on BLD_FEATURE_NUM_TYPE_ID.
84 #define MPR_TYPE_UNDEFINED 0 /* Undefined. No value has been set. */
85 #define MPR_TYPE_NULL 1 /* Value defined to be null. */
86 #define MPR_TYPE_BOOL 2 /* Boolean type. */
87 #define MPR_TYPE_CFUNCTION 3 /* C function or C++ method */
88 #define MPR_TYPE_FLOAT 4 /* Floating point number */
89 #define MPR_TYPE_INT 5 /* Integer number */
90 #define MPR_TYPE_INT64 6 /* 64-bit Integer number */
91 #define MPR_TYPE_OBJECT 7 /* Object reference */
92 #define MPR_TYPE_FUNCTION 8 /* JavaScript function */
93 #define MPR_TYPE_STRING 9 /* String (immutable) */
94 #define MPR_TYPE_STRING_CFUNCTION 10 /* C/C++ function with string args */
95 #define MPR_TYPE_PTR 11 /* Opaque pointer */
98 * Create a type for the default number type
99 * Config.h will define the default number type. For example:
101 * BLD_FEATURE_NUM_TYPE=int
102 * BLD_FEATURE_NUM_TYPE_ID=MPR_TYPE_INT
106 * Set to the type used for MPR numeric variables. Will equate to int, int64
109 typedef BLD_FEATURE_NUM_TYPE MprNum;
112 * Set to the MPR_TYPE used for MPR numeric variables. Will equate to
113 * MPR_TYPE_INT, MPR_TYPE_INT64 or MPR_TYPE_FLOAT.
115 #define MPR_NUM_VAR BLD_FEATURE_NUM_TYPE_ID
116 #define MPR_TYPE_NUM BLD_FEATURE_NUM_TYPE_ID
119 * Return TRUE if a variable is a function type
121 #define mprVarIsFunction(type) \
122 (type == MPR_TYPE_FUNCTION || type == MPR_TYPE_STRING_CFUNCTION || \
123 type == MPR_TYPE_CFUNCTION)
126 * Return TRUE if a variable is a numeric type
128 #define mprVarIsNumber(type) \
129 (type == MPR_TYPE_INT || type == MPR_TYPE_INT64 || type == MPR_TYPE_FLOAT)
132 * Return TRUE if a variable is a boolean
134 #define mprVarIsBoolean(type) \
135 (type == MPR_TYPE_BOOL)
136 #define mprVarIsString(type) \
137 (type == MPR_TYPE_STRING)
138 #define mprVarIsObject(type) \
139 (type == MPR_TYPE_OBJECT)
140 #define mprVarIsFloating(type) \
141 (type == MPR_TYPE_FLOAT)
142 #define mprVarIsPtr(type) \
143 (type == MPR_TYPE_PTR)
144 #define mprVarIsUndefined(var) \
145 ((var)->type == MPR_TYPE_UNDEFINED)
146 #define mprVarIsNull(var) \
147 ((var)->type == MPR_TYPE_NULL)
148 #define mprVarIsValid(var) \
149 (((var)->type != MPR_TYPE_NULL) && ((var)->type != MPR_TYPE_UNDEFINED))
151 #define MPR_VAR_MAX_RECURSE 5 /* Max object loops */
153 #if BLD_FEATURE_SQUEEZE
154 #define MPR_MAX_VAR 64 /* Max var full name */
156 #define MPR_MAX_VAR 512
161 #endif /* _NO_PACK */
164 * Function signatures
166 typedef int MprVarHandle;
167 typedef int (*MprCFunction)(MprVarHandle userHandle, int argc,
168 struct MprVar **argv);
169 typedef int (*MprStringCFunction)(MprVarHandle userHandle, int argc,
176 MPR_VAR_WRITE, /* This property is being updated */
177 MPR_VAR_READ, /* This property is being read */
178 MPR_VAR_CREATE_PROPERTY, /* A property is being created */
179 MPR_VAR_DELETE_PROPERTY, /* A property is being deleted */
180 MPR_VAR_DELETE /* This object is being deleted */
184 * Trigger function return codes.
187 MPR_TRIGGER_ABORT, /* Abort the current operation */
188 MPR_TRIGGER_USE_NEW_VALUE, /* Proceed and use the newValue */
189 MPR_TRIGGER_PROCEED /* Proceed with the operation */
190 } MprVarTriggerStatus;
193 * The MprVarTrigger arguments have the following meaning:
195 * op The operation being performed. See MprVarTriggerOp.
196 * parentProperties Pointer to the MprProperties structure.
197 * vp Pointer to the property that registered the trigger.
198 * newValue New value (see below for more details).
199 * copyDepth Specify what data items to copy.
201 * For VAR_READ, newVar is set to a temporary variable that the trigger
202 * function may assign a value to be returned instead of the actual
204 * For VAR_WRITE, newValue holds the new value. The old existing value may be
206 * For DELETE_PROPERTY, vp is the property being deleted. newValue is null.
207 * For ADD_PROPERTY, vp is set to the property being added and newValue holds
210 typedef MprVarTriggerStatus (*MprVarTrigger)(MprVarTriggerOp op,
211 struct MprProperties *parentProperties, struct MprVar *vp,
212 struct MprVar *newValue, int copyDepth);
215 * mprCreateFunctionVar flags
217 /** Use the alternate handle on function callbacks */
218 #define MPR_VAR_ALT_HANDLE 0x1
220 /** Use the script handle on function callbacks */
221 #define MPR_VAR_SCRIPT_HANDLE 0x2
224 * Useful define for the copyDepth argument
226 /** Don't copy any data. Copy only the variable name */
227 #define MPR_NO_COPY 0
229 /** Copy strings. Increment object reference counts. */
230 #define MPR_SHALLOW_COPY 1
232 /** Copy strings and do complete object copies. */
233 #define MPR_DEEP_COPY 2
236 * GetFirst / GetNext flags
238 /** Step into data properties. */
239 #define MPR_ENUM_DATA 0x1
241 /** Step into functions properties. */
242 #define MPR_ENUM_FUNCTIONS 0x2
245 * Collection type to hold properties in an object
247 typedef struct MprProperties { /* Collection of properties */
249 struct MprProperties *next; /* Linked list */
250 struct MprProperties *prev; /* Linked list */
251 char name[32]; /* Debug name */
253 struct MprVar **buckets; /* Hash chains */
254 int numItems; /* Total count of items */
255 /* FUTURE - Better way of doing this */
256 int numDataItems; /* Enumerable data items */
257 uint hashSize : 8; /* Size of the hash table */
258 /* FUTURE -- increase size of refCount */
259 uint refCount : 8; /* References to this property*/
260 /* FUTURE - make these flags */
261 uint deleteProtect : 8; /* Don't recursively delete */
262 uint visited : 8; /* Node has been processed */
266 * Universal Variable Type
268 typedef struct MprVar {
269 /* FUTURE - remove name to outside reference */
270 MprStr name; /* Property name */
271 /* FUTURE - remove */
272 MprStr fullName; /* Full object name */
273 /* FUTURE - make part of the union */
274 MprProperties *properties; /* Pointer to properties */
279 MprType type : 8; /* Selector into union */
280 uint bucketIndex : 8; /* Copy of bucket index */
282 uint flags : 5; /* Type specific flags */
283 uint allocatedData : 1; /* Data needs freeing */
284 uint readonly : 1; /* Unmodifiable */
285 uint deleteProtect : 1; /* Don't recursively delete */
287 uint visited : 1; /* Node has been processed */
288 uint allocatedVar : 1; /* Var needs freeing */
289 uint spare : 6; /* Unused */
291 struct MprVar *forw; /* Hash table linkage */
292 MprVarTrigger trigger; /* Trigger function */
295 struct MprVar *baseClass; /* Pointer to class object */
297 MprProperties *parentProperties; /* Pointer to parent object */
300 * Union of primitive types. When debugging on Linux, don't use unions
301 * as the gdb debugger can't display them.
303 #if !BLD_DEBUG && !LINUX && !VXWORKS
306 int boolean; /* Use int for speed */
307 #if BLD_FEATURE_FLOATING_POINT
311 #if BLD_FEATURE_INT64
314 struct { /* Javascript functions */
315 MprArray *args; /* Null terminated */
318 struct { /* Function with MprVar args */
322 struct { /* Function with string args */
323 MprStringCFunction fn;
325 } cFunctionWithStrings;
326 MprStr string; /* Allocated string */
327 void *ptr; /* Opaque pointer */
328 #if !BLD_DEBUG && !LINUX && !VXWORKS
334 * Define a field macro so code an use numbers in a "generic" fashion.
336 #if MPR_NUM_VAR == MPR_TYPE_INT || DOXYGEN
337 /* Default numeric type */
338 #define mprNumber integer
340 #if MPR_NUM_VAR == MPR_TYPE_INT64
341 /* Default numeric type */
342 #define mprNumber integer64
344 #if MPR_NUM_VAR == MPR_TYPE_FLOAT
345 /* Default numeric type */
346 #define mprNumber floating
349 typedef BLD_FEATURE_NUM_TYPE MprNumber;
354 #endif /* __NO_PACK */
356 /********************************* Prototypes *********************************/
358 * Variable constructors and destructors
360 extern MprVar mprCreateObjVar(const char *name, int hashSize);
361 extern MprVar mprCreateBoolVar(bool value);
362 extern MprVar mprCreateCFunctionVar(MprCFunction fn, void *thisPtr,
364 #if BLD_FEATURE_FLOATING_POINT
365 extern MprVar mprCreateFloatVar(double value);
367 extern MprVar mprCreateIntegerVar(int value);
368 #if BLD_FEATURE_INT64
369 extern MprVar mprCreateInteger64Var(int64 value);
371 extern MprVar mprCreateFunctionVar(char *args, char *body, int flags);
372 extern MprVar mprCreateNullVar(void);
373 extern MprVar mprCreateNumberVar(MprNumber value);
374 extern MprVar mprCreateStringCFunctionVar(MprStringCFunction fn,
375 void *thisPtr, int flags);
376 extern MprVar mprCreateStringVar(const char *value, bool allocate);
377 extern MprVar mprCreateUndefinedVar(void);
378 extern MprVar mprCreatePtrVar(void *ptr);
379 extern bool mprDestroyVar(MprVar *vp);
380 extern bool mprDestroyAllVars(MprVar* vp);
381 extern MprType mprGetVarType(MprVar *vp);
386 extern void mprCopyVar(MprVar *dest, MprVar *src, int copyDepth);
387 extern void mprCopyVarValue(MprVar *dest, MprVar src, int copyDepth);
388 extern MprVar *mprDupVar(MprVar *src, int copyDepth);
394 mprAddVarTrigger(MprVar *vp, MprVarTrigger fn);
395 extern int mprGetVarRefCount(MprVar *vp);
396 extern void mprSetVarDeleteProtect(MprVar *vp, int deleteProtect);
397 extern void mprSetVarFullName(MprVar *vp, char *name);
398 extern void mprSetVarReadonly(MprVar *vp, int readonly);
399 extern void mprSetVarName(MprVar *vp, char *name);
402 * Create properties and return a reference to the property.
404 extern MprVar *mprCreateProperty(MprVar *obj, const char *property,
406 extern MprVar *mprCreatePropertyValue(MprVar *obj, const char *property,
408 extern int mprDeleteProperty(MprVar *obj, const char *property);
411 * Get/Set properties. Set will update/create.
413 extern MprVar *mprGetProperty(MprVar *obj, const char *property,
415 extern MprVar *mprSetProperty(MprVar *obj, const char *property,
417 extern MprVar *mprSetPropertyValue(MprVar *obj, const char *property,
421 * Directly read/write property values (the property must already exist)
422 * For mprCopyProperty, mprDestroyVar must always called on the var.
424 extern int mprReadProperty(MprVar *prop, MprVar *value);
425 extern int mprWriteProperty(MprVar *prop, MprVar *newValue);
426 extern int mprWritePropertyValue(MprVar *prop, MprVar newValue);
429 * Copy a property. NOTE: reverse of most other args: (dest, src)
431 extern int mprCopyProperty(MprVar *dest, MprVar *prop, int copyDepth);
434 * Enumerate properties
436 extern MprVar *mprGetFirstProperty(MprVar *obj, int includeFlags);
437 extern MprVar *mprGetNextProperty(MprVar *obj, MprVar *currentProperty,
441 * Query properties characteristics
443 extern int mprGetPropertyCount(MprVar *obj, int includeFlags);
446 * Conversion routines
448 extern MprVar mprParseVar(char *str, MprType prefType);
449 extern MprNum mprVarToNumber(const MprVar *vp);
450 extern int mprVarToInteger(const MprVar *vp);
451 #if BLD_FEATURE_INT64
452 extern int64 mprVarToInteger64(const MprVar *vp);
454 extern bool mprVarToBool(const MprVar *vp);
455 #if BLD_FEATURE_FLOATING_POINT
456 extern double mprVarToFloat(const MprVar *vp);
458 extern void mprVarToString(char** buf, int size, char *fmt, MprVar *vp);
461 * Parsing and utility routines
463 extern MprNum mprParseNumber(char *str);
464 extern int mprParseInteger(char *str);
466 #if BLD_FEATURE_INT64
467 extern int64 mprParseInteger64(char *str);
470 #if BLD_FEATURE_FLOATING_POINT
471 extern double mprParseFloat(char *str);
472 extern bool mprIsInfinite(double f);
473 extern bool mprIsNan(double f);
477 extern void mprPrintObjects(char *msg);
478 extern void mprPrintObjRefCount(MprVar *vp);
485 /*****************************************************************************/
486 #endif /* _h_MPR_VAR */
494 * vim600: sw=4 ts=4 fdm=marker