Return to structs.h CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / contrib / libpdel / structs |
1.1 misho 1: 2: /* 3: * Copyright (c) 2001-2002 Packet Design, LLC. 4: * All rights reserved. 5: * 6: * Subject to the following obligations and disclaimer of warranty, 7: * use and redistribution of this software, in source or object code 8: * forms, with or without modifications are expressly permitted by 9: * Packet Design; provided, however, that: 10: * 11: * (i) Any and all reproductions of the source or object code 12: * must include the copyright notice above and the following 13: * disclaimer of warranties; and 14: * (ii) No rights are granted, in any manner or form, to use 15: * Packet Design trademarks, including the mark "PACKET DESIGN" 16: * on advertising, endorsements, or otherwise except as such 17: * appears in the above copyright notice or in the software. 18: * 19: * THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND 20: * TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO 21: * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING 22: * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED 23: * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, 24: * OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE, 25: * OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS 26: * OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, 27: * RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE 28: * LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE 29: * OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT, 30: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL 31: * DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF 32: * USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF 33: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 35: * THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF 36: * THE POSSIBILITY OF SUCH DAMAGE. 37: * 38: * Author: Archie Cobbs <archie@freebsd.org> 39: */ 40: 41: #ifndef _PDEL_STRUCTS_STRUCTS_H_ 42: #define _PDEL_STRUCTS_STRUCTS_H_ 43: 44: /********************************************************************* 45: 46: STRUCTS TYPES 47: ------------- 48: 49: A "structs type" is a descriptor for a C data structure that 50: allows access to the data structure in an automated fashion. 51: For example, once a data structure is described by a associated 52: structs type, the following operations can be performed 53: automatically on any instance of the data structure: 54: 55: o Initialization to default value 56: o Comparison of two instances for equality 57: o "Deep" copying (aka. "cloning") 58: o Access to arbitrary sub-fields by name (aka. "introspection") 59: o Conversion to/from ASCII (primitive types) 60: o Import/export from/to XML, with precise input validation, 61: automating conversion between internal and external formats 62: o Conversion into XML-RPC request or reply 63: o Import/export from/to a machine independent binary encoding 64: o Inserting, deleting, and extending elements in arrays 65: 66: In addition, any required dynamic memory allocation and free'ing 67: is handled automatically. 68: 69: Supported data structures include the normal primitive C types, 70: plus arrays, structures, unions, and pointers to supported types, 71: as well as some other useful types such as opaque binary data, 72: IP address, regular expression, etc. User-defined types may be 73: added as well. 74: 75: Put simply, a structs type describes how to interpret a region 76: of memory so that the operations listed above may be peformed 77: in an automated fashion. 78: 79: Arrays must be defined using the "structs_array" structure. 80: Unions must be defined using the "structs_union" structure. 81: 82: Nested items in a data structure can be identified by names, 83: where each name component is either the name of a structure or 84: union field, or an array index. Name components are separated 85: by dots. For example, "foo.list.12" (see below). 86: 87: EXAMPLE 88: ------- 89: 90: Consider the C data structure defined by "struct janfu": 91: 92: struct fubar { 93: struct structs_array list; // array of strings 94: }; 95: 96: struct janfu { 97: u_int16_t value; // 16 bit hex value 98: struct fubar *foo; // fubar structure 99: }; 100: 101: A memory region containing a 'struct janfu' would be described 102: in C code like so: 103: 104: // Descriptor for field 'list' in 'struct fubar': array of strings 105: static const struct structs_type list_array_type = 106: STRUCTS_ARRAY_TYPE(&structs_type_string, "list_elem", "list_elem"); 107: 108: // Descriptor for 'struct fubar' 109: static const struct structs_field fubar_fields[] = { 110: STRUCTS_STRUCT_FIELD(fubar, list, &list_array_type), 111: STRUCTS_STRUCT_FIELD_END 112: }; 113: static const struct structs_type fubar_type = 114: STRUCTS_STRUCT_TYPE(fubar, &fubar_fields); 115: 116: // Descriptor for a variable of type 'struct fubar *' 117: static const struct structs_type foo_ptr_type = 118: STRUCTS_POINTER_TYPE(&fubar_type, "struct fubar"); 119: 120: // Descriptor for 'struct janfu' 121: static const struct structs_field janfu_fields[] = { 122: STRUCTS_STRUCT_FIELD(janfu, value, &structs_type_uint16), 123: STRUCTS_STRUCT_FIELD(janfu, foo, &foo_ptr_type), 124: STRUCTS_STRUCT_FIELD_END 125: }; 126: static const struct structs_type janfu_type = 127: STRUCTS_STRUCT_TYPE(janfu, &janfu_fields); 128: 129: The type "janfu_type" describes a 'struct janfu' data structure. 130: 131: Then "foo.list.12" refers to the 12th item in the "list" array 132: (assuming it actually exists), counting from zero. It's value 133: could be accessed like this: 134: 135: void 136: print_list_12(const struct janfu *j) 137: { 138: char *s; 139: 140: s = structs_get_string(&janfu_type, "foo.list.12", j, NULL); 141: if (s == NULL) { 142: fprintf(stderr, "structs_get_string: %s: %s", 143: "foo.list.12", strerror(errno)); 144: exit(1); 145: } 146: printf("foo.list.12 = %s\n", s); 147: free(s); 148: } 149: 150: An instance of a "struct janfu", if output as XML, might look 151: like this: 152: 153: <?xml version="1.0" standalone="yes"?> 154: <janfu> 155: <value>0x1234</value> 156: <list> 157: <list_elem>first list element</list_elem> 158: <list_elem>second list element</list_elem> 159: <list_elem>third list element</list_elem> 160: </list> 161: </janfu> 162: 163: A function call that would produce the above output is: 164: 165: void 166: dump_janfu(struct janfu *j) 167: { 168: structs_xml_output(&janfu_type, "janfu", NULL, j, stdout, NULL, 0); 169: } 170: 171: *********************************************************************/ 172: 173: /* Name component separator */ 174: #define STRUCTS_SEPARATOR '.' 175: 176: struct structs_type; 177: 178: /* For representing arbitrary binary data */ 179: struct structs_data { 180: u_int length; /* number of bytes */ 181: u_char *data; /* bytes */ 182: }; 183: 184: /********************************************************************* 185: STRUCTS TYPE METHODS 186: *********************************************************************/ 187: 188: /* 189: * The structs type "init" method. 190: * 191: * The region of memory pointed to by "data" must be at least 192: * type->size bytes and should be uninitialized (i.e., it should 193: * not contain a valid instance of the type). 194: * 195: * This method should initialize the memory with a valid instance 196: * of the type, setting this new instance to be equal to the default 197: * value for the type, and allocating any resources required for the 198: * instance in the process. 199: * 200: * Returns 0 if successful, or -1 (and sets errno) if there was an error. 201: */ 202: typedef int structs_init_t(const struct structs_type *type, void *data); 203: 204: /* 205: * The structs type "copy" method. 206: * 207: * The region of memory pointed to by "from" contains a valid instance 208: * of the type described by "type". 209: * 210: * The region of memory pointed to by "to" is uninitialized. 211: * 212: * This method should initialize "to" with a "deep" copy of the 213: * data structure pointed to by "from". The copy must be equal 214: * (according to the "equal" method) to the original. 215: * 216: * Returns 0 if successful, or -1 (and sets errno) if there was an error. 217: */ 218: typedef int structs_copy_t(const struct structs_type *type, 219: const void *from, void *to); 220: 221: /* 222: * The structs type "equal" method. 223: * 224: * The regions of memory pointed to by "data1" and "data2" contain valid 225: * instances of the type described by "type". 226: * 227: * Returns 1 if "data1" and "data2" are equal (by a "deep" comparison), or 228: * 0 if not, or -1 (and sets errno) if there was an error. 229: */ 230: typedef int structs_equal_t(const struct structs_type *type, 231: const void *data1, const void *data2); 232: 233: /* 234: * The structs type "ascify" method. 235: * 236: * The region of memory pointed to by "data" contains a valid instance 237: * of the type described by "type". 238: * 239: * The method should convert this instance into a NUL-terminated 240: * ASCII string stored in a dynamically allocated buffer that is 241: * allocated with the memory type described by "mtype". 242: * 243: * The ASCII string must be unique, in that it can be used as input 244: * to the "binify" method to create an instance equal (according to the 245: * "equal" method) to the original. 246: * 247: * Returns the ASCII string buffer if successful, or NULL 248: * (and sets errno) if error. 249: */ 250: typedef char *structs_ascify_t(const struct structs_type *type, 251: const char *mtype, const void *data); 252: 253: /* 254: * The structs type "binify" method. 255: * 256: * The region of memory pointed to by "data" is uninitialized. 257: * 258: * The variable "ascii" points to a NUL-terminated string. This method 259: * should use the contents of the string to create a new instace of 260: * the type in the memory pointed to by "data". 261: * 262: * Returns 0 if successful, or -1 if there was an error. In the latter 263: * case, either errno should be set, or a more informative error string 264: * may be printed (including NUL) into "ebuf", which has total size "emax" 265: * (see snprintf(3)). 266: * 267: * This method must be robust in the face of bogus data in "ascii"; 268: * it must return an error if "ascii" is invalid. 269: */ 270: typedef int structs_binify_t(const struct structs_type *type, 271: const char *ascii, void *data, char *ebuf, size_t emax); 272: 273: /* 274: * The structs type "encode" method. 275: * 276: * The region of memory pointed to by "data" contains a valid instance 277: * of the type described by "type". 278: * 279: * This method should encode the data structure into a host order 280: * independent, self-delimiting sequence of bytes. The sequence must be 281: * stored in a dynamically allocated buffer allocated with the memory type 282: * described by "mtype", and "code" must be filled in with the buffer's 283: * pointer and length. 284: * 285: * The binary sequence must be unique, in that it can be used as input 286: * to the "decode" method to create an instance equal (according to the 287: * "equal" method) to the original. 288: * 289: * Returns 0 if successful, or -1 (and sets errno) if there was an error. 290: */ 291: typedef int structs_encode_t(const struct structs_type *type, 292: const char *mtype, struct structs_data *code, 293: const void *data); 294: 295: /* 296: * The structs type "decode" method. 297: * 298: * The region of memory pointed to by "data" is uninitialized. 299: * 300: * The "code" parameter points to a sequence of "cmax" binary data bytes. 301: * This method should decode the binary data and use it to reconstruct 302: * an instance of "type" in the memory region pointed to by "data". 303: * 304: * Returns the number of bytes consumed in the decoding process if 305: * successful, or -1 (and sets errno) if there was an error. In the 306: * latter case, either errno should be set, or a more informative error 307: * string may be printed (including NUL) into "ebuf", which has total 308: * size "emax" (see snprintf(3)). 309: */ 310: typedef int structs_decode_t(const struct structs_type *type, 311: const u_char *code, size_t cmax, void *data, 312: char *ebuf, size_t emax); 313: 314: /* 315: * The structs type "uninit" method. 316: * 317: * The region of memory pointed to by "data" contains a valid instance 318: * of the type described by "type". 319: * 320: * This method should free any resources associated with the instance 321: * pointed to by "data". Upon return, the memory pointed to by "data" 322: * may be no longer used or referenced. 323: */ 324: typedef void structs_uninit_t(const struct structs_type *type, void *data); 325: 326: /********************************************************************* 327: STRUCTS TYPE DEFINITION 328: *********************************************************************/ 329: 330: /* 331: * This structure defines a structs type. 332: */ 333: struct structs_type { 334: size_t size; /* size of an instance */ 335: const char *name; /* human informative name */ 336: int tclass; /* see classes listed below */ 337: structs_init_t *init; /* type "init" method */ 338: structs_copy_t *copy; /* type "copy" method */ 339: structs_equal_t *equal; /* type "equal" method */ 340: structs_ascify_t *ascify; /* type "ascify" method */ 341: structs_binify_t *binify; /* type "binify" method */ 342: structs_encode_t *encode; /* type "encode" method */ 343: structs_decode_t *decode; /* type "decode" method */ 344: structs_uninit_t *uninit; /* type "uninit" method */ 345: union { /* type specific arguments */ 346: const void *v; 347: const char *s; 348: int i; 349: } args[3]; 350: }; 351: 352: /* Classes of types */ 353: #define STRUCTS_TYPE_PRIMITIVE 0 354: #define STRUCTS_TYPE_POINTER 1 355: #define STRUCTS_TYPE_ARRAY 2 356: #define STRUCTS_TYPE_FIXEDARRAY 3 357: #define STRUCTS_TYPE_STRUCTURE 4 358: #define STRUCTS_TYPE_UNION 5 359: 360: /********************************************************************* 361: GENERIC TYPE METHODS 362: *********************************************************************/ 363: 364: __BEGIN_DECLS 365: 366: /* These operate on simple block regions of memory */ 367: extern structs_init_t structs_region_init; 368: extern structs_copy_t structs_region_copy; 369: extern structs_equal_t structs_region_equal; 370: 371: extern structs_encode_t structs_region_encode; 372: extern structs_decode_t structs_region_decode; 373: extern structs_encode_t structs_region_encode_netorder; 374: extern structs_decode_t structs_region_decode_netorder; 375: 376: /* These always return an error with errno set to EOPNOTSUPP */ 377: extern structs_init_t structs_notsupp_init; 378: extern structs_copy_t structs_notsupp_copy; 379: extern structs_equal_t structs_notsupp_equal; 380: extern structs_ascify_t structs_notsupp_ascify; 381: extern structs_binify_t structs_notsupp_binify; 382: extern structs_encode_t structs_notsupp_encode; 383: extern structs_decode_t structs_notsupp_decode; 384: 385: /* This copies any type that is ascifyable by converting to ASCII and back */ 386: extern structs_copy_t structs_ascii_copy; 387: 388: /* This does nothing */ 389: extern structs_uninit_t structs_nothing_free; 390: 391: __END_DECLS 392: 393: /********************************************************************* 394: BASIC STRUCTS FUNCTIONS 395: *********************************************************************/ 396: 397: __BEGIN_DECLS 398: 399: /* 400: * Initialize an item in a data structure to its default value. 401: * This assumes the item is not already initialized. 402: * 403: * If "name" is NULL or empty string, the entire structure is initialied. 404: * 405: * Returns 0 if successful, otherwise -1 and sets errno. 406: */ 407: extern int structs_init(const struct structs_type *type, 408: const char *name, void *data); 409: 410: /* 411: * Reset an item in a data structure to its default value. 412: * This assumes the item is already initialized. 413: * 414: * If "name" is NULL or empty string, the entire structure is reset. 415: * 416: * Returns 0 if successful, otherwise -1 and sets errno. 417: */ 418: extern int structs_reset(const struct structs_type *type, 419: const char *name, void *data); 420: 421: /* 422: * Free an item in a data structure, returning it to its uninitialized state. 423: * This function can be thought of as the opposite of structs_init(). 424: * 425: * If "name" is NULL or empty string, the entire structure is free'd. 426: * 427: * Returns 0 if successful, otherwise -1 and sets errno. 428: */ 429: extern int structs_free(const struct structs_type *type, 430: const char *name, void *data); 431: 432: /* 433: * Compare two data structures of the same type for equality. 434: * 435: * If "name" is NULL or empty string, the entire structures are compared. 436: * Otherwise, the "name" sub-elements of both structures are compared. 437: * 438: * Returns zero or one (for not equal or equal, respectively), 439: * or -1 (and sets errno) if there was an error. 440: */ 441: extern int structs_equal(const struct structs_type *type, 442: const char *name, const void *data1, const void *data2); 443: 444: /* 445: * Find an item in a data structure structure. 446: * 447: * If "name" is NULL or empty string, "type" is returned and "datap" 448: * is unmodified. 449: * 450: * If "set_union" is true, then any unions in the path will be reset 451: * so that their fields agree with "name" in the case that "name" contains 452: * a different field name than is currently set for that union. However, 453: * these changes will only occur if "name" is actually found. 454: * 455: * Returns the type of the item and points *datap at it, or NULL 456: * (and sets errno) if there was an error. 457: */ 458: extern const struct structs_type *structs_find( 459: const struct structs_type *type, const char *name, 460: void **datap, int set_union); 461: 462: /* 463: * Get a copy of an item from a data structure. 464: * 465: * If "name" is NULL or empty string, the entire structure is copied. 466: * 467: * It is assumed that "to" points to a region big enough to hold 468: * the copy of the item. "to" will not be free'd first, so it should 469: * not already be initialized. 470: * 471: * Note: "name" is only applied to "from". The structs types of 472: * "from.<name>" and "to" must be the same. 473: * 474: * Returns 0 if successful, otherwise -1 and sets errno. 475: */ 476: extern int structs_get(const struct structs_type *type, 477: const char *name, const void *from, void *to); 478: 479: /* 480: * Set an item in a data structure. 481: * 482: * If "name" is NULL or empty string, the entire structure is copied. 483: * 484: * It is assumed that "to" is already initialized. 485: * 486: * Note: "name" is only applied to "to". The structs types of 487: * "from" and "to.<name>" must be the same. 488: * 489: * Returns 0 if successful, otherwise -1 and sets errno. 490: */ 491: extern int structs_set(const struct structs_type *type, 492: const void *from, const char *name, void *to); 493: 494: /* 495: * Get the ASCII form of an item, in a string allocated with the 496: * memory type described by "mtype". 497: * 498: * The caller is reponsible for freeing the returned string. 499: * 500: * Returns the ASCII string if successful, otherwise NULL and sets errno. 501: */ 502: extern char *structs_get_string(const struct structs_type *type, 503: const char *name, const void *data, const char *mtype); 504: 505: /* 506: * Set the value of an item in a data structure from an ASCII string. 507: * 508: * The referred to item must be of a type that supports ASCII encoding, 509: * and is assumed to be already initialized. 510: * 511: * Returns 0 if successful, otherwise -1 and sets errno. 512: */ 513: extern int structs_set_string(const struct structs_type *type, 514: const char *name, const char *ascii, 515: void *data, char *ebuf, size_t emax); 516: 517: /* 518: * Get the binary encoded form of an item, put into a buffer 519: * allocated with memory type "mtype" and described by "code". 520: * 521: * The caller is reponsible for freeing the allocated bytes. 522: * 523: * Returns 0 if successful, otherwise -1 and sets errno. 524: */ 525: extern int structs_get_binary(const struct structs_type *type, 526: const char *name, const void *data, 527: const char *mtype, struct structs_data *code); 528: 529: /* 530: * Set an item's value from its binary encoded value. 531: * 532: * The referred to item is assumed to be already initialized. 533: * 534: * Returns 0 if successful, otherwise -1 and sets errno. 535: */ 536: extern int structs_set_binary(const struct structs_type *type, 537: const char *name, const struct structs_data *code, 538: void *data, char *ebuf, size_t emax); 539: 540: /* 541: * Traverse a structure, returning the names of all primitive fields 542: * (i.e., the "leaves" of the data structure). 543: * 544: * The number of items is returned, or -1 and errno if there was an error. 545: * The caller must free the list by freeing each string in the array, 546: * and then the array itself; all memory is allocated using memory type 547: * "mtype". 548: * 549: * If "type" is a primitive type, a list of length one is returned 550: * containing an empty string. 551: */ 552: extern int structs_traverse(const struct structs_type *type, 553: const void *data, char ***listp, const char *mtype); 554: 555: __END_DECLS 556: 557: #endif /* _PDEL_STRUCTS_STRUCTS_H_ */ 558: