Annotation of embedaddon/libpdel/structs/structs.3, revision 1.1
1.1 ! misho 1: .\" Copyright (c) 2001-2002 Packet Design, LLC.
! 2: .\" All rights reserved.
! 3: .\"
! 4: .\" Subject to the following obligations and disclaimer of warranty,
! 5: .\" use and redistribution of this software, in source or object code
! 6: .\" forms, with or without modifications are expressly permitted by
! 7: .\" Packet Design; provided, however, that:
! 8: .\"
! 9: .\" (i) Any and all reproductions of the source or object code
! 10: .\" must include the copyright notice above and the following
! 11: .\" disclaimer of warranties; and
! 12: .\" (ii) No rights are granted, in any manner or form, to use
! 13: .\" Packet Design trademarks, including the mark "PACKET DESIGN"
! 14: .\" on advertising, endorsements, or otherwise except as such
! 15: .\" appears in the above copyright notice or in the software.
! 16: .\"
! 17: .\" THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
! 18: .\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
! 19: .\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
! 20: .\" THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
! 21: .\" WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
! 22: .\" OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
! 23: .\" OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
! 24: .\" OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
! 25: .\" RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE
! 26: .\" LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
! 27: .\" OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
! 28: .\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
! 29: .\" DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
! 30: .\" USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
! 31: .\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 32: .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
! 33: .\" THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
! 34: .\" THE POSSIBILITY OF SUCH DAMAGE.
! 35: .\"
! 36: .\" Author: Archie Cobbs <archie@freebsd.org>
! 37: .\"
! 38: .\" $Id: structs.3,v 1.16 2004/06/02 17:24:38 archie Exp $
! 39: .\"
! 40: .Dd April 22, 2002
! 41: .Dt STRUCTS 3
! 42: .Os
! 43: .Sh NAME
! 44: .Nm structs
! 45: .Nd library for data structure introspection
! 46: .Sh LIBRARY
! 47: PDEL Library (libpdel, \-lpdel)
! 48: .Sh SYNOPSIS
! 49: .In sys/types.h
! 50: .In pdel/structs/structs.h
! 51: .Ft int
! 52: .Fn structs_init "const struct structs_type *type" "const char *name" "void *data"
! 53: .Ft int
! 54: .Fn structs_reset "const struct structs_type *type" "const char *name" "void *data"
! 55: .Ft int
! 56: .Fn structs_free "const struct structs_type *type" "const char *name" "void *data"
! 57: .Ft int
! 58: .Fn structs_equal "const struct structs_type *type" "const char *name" "const void *data1" "const void *data2"
! 59: .Ft const struct structs_type *
! 60: .Fn structs_find " const struct structs_type *type" "const char *name" "void **datap" "int set_union"
! 61: .Ft int
! 62: .Fn structs_get "const struct structs_type *type" "const char *name" "const void *from" "void *to"
! 63: .Ft int
! 64: .Fn structs_set "const struct structs_type *type" "const void *from" "const char *name" "void *to"
! 65: .Ft char *
! 66: .Fn structs_get_string "const struct structs_type *type" "const char *name" "const void *data" "const char *mtype"
! 67: .Ft int
! 68: .Fn structs_set_string "const struct structs_type *type" "const char *name" "const char *ascii" "void *data" "char *ebuf" "size_t emax"
! 69: .Ft int
! 70: .Fn structs_get_binary "const struct structs_type *type" "const char *name" "const void *data" "const char *mtype" "struct structs_data *code"
! 71: .Ft int
! 72: .Fn structs_set_binary "const struct structs_type *type" "const char *name" "const struct structs_data *code" "void *data" "char *ebuf" "size_t emax"
! 73: .Ft int
! 74: .Fn structs_traverse "const struct structs_type *type" "const void *data" "char ***listp" "const char *mtype"
! 75: .Sh DESCRIPTION
! 76: .\"
! 77: .Ss Overview
! 78: .\"
! 79: The
! 80: .Nm structs
! 81: library includes macros and functions for defining and using
! 82: .Nm structs
! 83: types.
! 84: A
! 85: .Nm structs
! 86: type is a C structure that contains information describing
! 87: some other C data structure.
! 88: This information can be used to access the contents of
! 89: the described data structure dynamically at run time.
! 90: The library provides several pre-defined types for commonly used
! 91: data structures, as well as macros for creating new types.
! 92: .Pp
! 93: A data structure is supported by the
! 94: .Nm structs
! 95: library if it can be described by a
! 96: .Nm structs
! 97: type (see
! 98: .Xr structs_type 3) .
! 99: There are two classes of types: primitive and complex.
! 100: Primitive types describe things such as integers, strings, etc.
! 101: They are user-definable, and several predefined primitive types are
! 102: supplied with the
! 103: .Nm structs
! 104: library.
! 105: Any data structure can be described by a primitive
! 106: .Nm structs
! 107: type if it has the following properties:
! 108: .Pp
! 109: .Bl -bullet -offset 3n -compact
! 110: .It
! 111: It has a fixed size known at compile time.
! 112: .It
! 113: It can be initialized, uninitialized, copied, and compared for equality.
! 114: .It
! 115: It can be converted into an ASCII string and back without losing information.
! 116: .It
! 117: It can be converted into a byte-order independent, self-delimiting
! 118: binary sequence and back without losing information.
! 119: .El
! 120: .Pp
! 121: The complex types are defined recursively in terms of other types,
! 122: and include the following:
! 123: .Pp
! 124: .Bl -enum -offset 3n -compact
! 125: .It
! 126: Pointers
! 127: .It
! 128: Fixed length arrays
! 129: .It
! 130: Variable length arrays
! 131: .It
! 132: Structures
! 133: .It
! 134: Unions
! 135: .Pp
! 136: .El
! 137: The complex types support accessing sub-elements dircectly by
! 138: name at run-time.
! 139: That is, array, structure, and union elements can be
! 140: accessed by field name or array index expressed as an ASCII string.
! 141: The accessed elements may be arbitrarily deep in the data structure.
! 142: .Pp
! 143: The upshot of all this is that if one takes the time to describe a data
! 144: structures with a
! 145: .Nm structs
! 146: type, then the following operations can be performed dynamically
! 147: and automatically on any instance of that data structure:
! 148: .Pp
! 149: .Bl -bullet -offset 3n -compact
! 150: .It
! 151: Initialization and uninitialization, including allocating
! 152: and freeing heap memory or other resources.
! 153: .It
! 154: Comparison of two instances for equality
! 155: .It
! 156: .Dq Deep
! 157: copying, i.e., creating a completely new instance
! 158: that is a copy of an original with no shared components.
! 159: .It
! 160: Access to arbitrary sub-fields by name (aka.
! 161: .Dq introspection
! 162: ).
! 163: .It
! 164: Conversion to/from ASCII (primitive types only)
! 165: .It
! 166: Conversion to/from XML, with precise input validation
! 167: .It
! 168: Conversion to/from XML-RPC "values"
! 169: .It
! 170: Conversion to/from a byte-order independent, self-delimiting byte sequence
! 171: .El
! 172: .Pp
! 173: .\"
! 174: .Ss Data Structure Initialization
! 175: .\"
! 176: A "data structure" is just a contiguous block of memory.
! 177: It may of course contain other sub-structures within it,
! 178: including pointers to yet other data structures, but for the purposes of the
! 179: .Nm structs
! 180: library a "data structure" just a block of memory that you can point to.
! 181: .Pp
! 182: Such a data structure can be in one of two states: uninitialized
! 183: or initialized.
! 184: For example, a region of heap memory freshly returned by
! 185: .Xr malloc 3
! 186: is unintialized.
! 187: The only valid
! 188: .Nm structs
! 189: operation on an uninitialized data structure is to initialize it;
! 190: this is done by invoking
! 191: .Fn structs_init
! 192: (see below).
! 193: .Pp
! 194: Initializing a data structure puts it in a known, valid, default state.
! 195: This may involve more than just filling the region of memory with zeros.
! 196: For example, it may cause additional heap memory to be allocated
! 197: (and initialized), hidden reference counts to be incremented, or other
! 198: resources to be allocated.
! 199: .Pp
! 200: Note that
! 201: .Fn structs_init
! 202: does not itself allocate the block of memory in which the data structure
! 203: is stored, it only initializes it.
! 204: The user code must handle allocation of the block of memory.
! 205: As a consequence, this memory may live on the stack, or the heap.
! 206: Any data structures that are stored in stack variables and are initialized
! 207: during execution of a function must be uninitialized before the function
! 208: returns to avoid resource leaks.
! 209: .Pp
! 210: .Fn structs_free
! 211: (see below)
! 212: is used to free any resources associated with an initialized data structure
! 213: and return it to the uninitialized state.
! 214: Note that this does not invoke
! 215: .Xr free 3
! 216: on the block of memory containing the data structure, though it may cause
! 217: .Xr free 3
! 218: to be invoked for any additional memory previously allocated by
! 219: .Fn structs_init .
! 220: .\"
! 221: .Ss Structs Functions
! 222: .\"
! 223: Generally speaking, in the functions shown above
! 224: .Fa type
! 225: points to the
! 226: .Nm structs
! 227: type describing a data structure,
! 228: .Fa data
! 229: points to an instance of that data structure, and
! 230: .Fa name
! 231: references by name the target sub-field or sub-element of the data structure
! 232: on which the operation is to take place.
! 233: If
! 234: .Fa name
! 235: is equal to
! 236: .Dv NULL
! 237: or the empty string then the entire data structure is the target.
! 238: In practice,
! 239: .Fa name
! 240: is often
! 241: .Dv NULL .
! 242: .Pp
! 243: .Fn structs_init
! 244: initializes the uninitialized sub-field
! 245: .Fa name
! 246: of the data structure pointed to by
! 247: .Fa data .
! 248: The data structure will be set to its default value, which is defined by
! 249: .Fa type.
! 250: .Pp
! 251: .Fn structs_reset
! 252: resets the already initialized sub-field
! 253: .Fa name
! 254: of the data structure pointed to by
! 255: .Fa data
! 256: to its default value, i.e., the same value that it would have after
! 257: a call to
! 258: .Fn structs_init .
! 259: .Pp
! 260: .Fn structs_free
! 261: uninitializes the sub-field
! 262: .Fa name
! 263: of the data structure pointed to by
! 264: .Fa data ,
! 265: freeing any resources previously allocated by
! 266: .Fn structs_init .
! 267: .Pp
! 268: .Fn structs_equal
! 269: compares the sub-fields
! 270: .Fa name
! 271: of the two data structures pointed to by
! 272: .Fa data1
! 273: and
! 274: .Fa data2
! 275: for equality.
! 276: It returns 1 if they are equal or 0 if not.
! 277: .Pp
! 278: .Fn structs_find
! 279: locates a sub-field of a data structure by name and returns its
! 280: .Nm structs
! 281: type.
! 282: When invoked,
! 283: .Fa "*datap"
! 284: should point to the data structure being searched.
! 285: Upon successful return, it will point to the sub-field named by
! 286: .Fa name .
! 287: If
! 288: .Fa set_union
! 289: is non-zero, then if during the search any unions are encountered
! 290: and the union's current field is different from the named field,
! 291: then the union's field is changed to the named field and its value
! 292: reset to the default value before continuing with the search.
! 293: .Pp
! 294: .Fn structs_get
! 295: generates a copy of the sub-field
! 296: .Fa name
! 297: in the data structure pointed to by
! 298: .Fa from
! 299: and places it in the uninitialized region of memory pointed to by
! 300: .Fa to ;
! 301: .Fa type
! 302: is the
! 303: .Nm structs
! 304: type of
! 305: .Fa from .
! 306: This is a recursive, or "deep" copy containing no shared elements with
! 307: .Fa from .
! 308: Note that the
! 309: .Nm structs
! 310: type of
! 311: .Fa "from.<name>"
! 312: and
! 313: .Fa to
! 314: must be the same.
! 315: Upon successful return,
! 316: .Fa to
! 317: will be initialized and therefore it is the caller's responsibility
! 318: to eventually uninitialize it.
! 319: .Pp
! 320: .Fn structs_set
! 321: changes the contents of the already initialized sub-field
! 322: .Fa name
! 323: in the data structure pointed to by
! 324: .Fa to
! 325: to be a copy of the data structure pointed to by
! 326: .Fa from ;
! 327: .Fa type
! 328: is the
! 329: .Nm structs
! 330: type of
! 331: .Fa to .
! 332: This is a recursive, or "deep" copy containing no shared elements with
! 333: .Fa from .
! 334: Note that the
! 335: .Nm structs
! 336: type of
! 337: .Fa "from"
! 338: and
! 339: .Fa "to.<name>"
! 340: must be the same.
! 341: .Fn structs_set
! 342: does not modify
! 343: .Fa from
! 344: in any way.
! 345: .Pp
! 346: .Fn structs_get_string
! 347: returns the ASCII form of the sub-field
! 348: .Fa name
! 349: in the data structure pointed to by
! 350: .Fa data .
! 351: This operation is only required to be implemented for primitive types.
! 352: The returned string is allocated with
! 353: .Xr typed_mem 3
! 354: type
! 355: .Fa mtype ,
! 356: and the caller is responsible for eventually freeing it.
! 357: .Pp
! 358: .Fn structs_set_string
! 359: changes the contents of the already initialized sub-field
! 360: .Fa name
! 361: in the data structure pointed to by
! 362: .Fa data
! 363: to the value represented by the ASCII string
! 364: .Fa ascii .
! 365: This operation is only required to be implemented for primitive types.
! 366: If there is an error, e.g.,
! 367: .Fa ascii
! 368: is not a valid representation of the type, then
! 369: .Fn structs_set_string
! 370: will return -1 and if
! 371: .Fa ebuf
! 372: is not
! 373: .Dv NULL
! 374: an error message (including terminating '\\0') will be printed into the buffer
! 375: .Fa ebuf ,
! 376: which is assumed to have length
! 377: .Fa emax .
! 378: .Pp
! 379: .Fn structs_get_binary
! 380: and
! 381: .Fn structs_set_binary
! 382: are similar, except that they work with byte-order independent,
! 383: self-delimiting binary data instead of ASCII strings.
! 384: .Pp
! 385: .Fn structs_get_binary
! 386: returns the binary encoding of the sub-field
! 387: .Fa name
! 388: in the data structure pointed to by
! 389: .Fa data .
! 390: The
! 391: .Fa code
! 392: argument is a pointer to a
! 393: .Li "struct structs_data" :
! 394: .Pp
! 395: .Bd -literal -compact -offset 3n
! 396: struct structs_data {
! 397: u_int length; /* number of bytes */
! 398: u_char *data; /* pointer to the bytes */
! 399: };
! 400: .Ed
! 401: .Pp
! 402: Upon successful return,
! 403: .Fa "code->data"
! 404: points to the binary encoding, which has length
! 405: .Fa "code->length"
! 406: and is allocated with
! 407: .Xr typed_mem 3
! 408: type
! 409: .Fa mtype .
! 410: The caller is eventually responsible for freeing
! 411: .Fa "code->data" .
! 412: .Pp
! 413: .Fn structs_set_binary
! 414: changes the contents of the already initialized sub-field
! 415: .Fa name
! 416: in the data structure pointed to by
! 417: .Fa data
! 418: to the value represented by the byte-order independent, self-delimiting
! 419: binary encoding described by
! 420: .Fa code .
! 421: On success, the actual number of bytes consumed is returned; this will
! 422: be less than or equal to
! 423: .Fa "code->length" .
! 424: If there is an error, e.g.,
! 425: the encoding was invalid, then
! 426: .Fn structs_set_binary
! 427: will return -1 and if
! 428: .Fa ebuf
! 429: is not
! 430: .Dv NULL
! 431: an error message (including terminating '\\0') will be printed into the buffer
! 432: .Fa ebuf ,
! 433: which is assumed to have length
! 434: .Fa emax .
! 435: .Pp
! 436: .Fn structs_traverse
! 437: generates a list of the names of all of the "leaf" sub-structures in
! 438: the data structure pointed to by
! 439: .Fa data ;
! 440: these will all have primitive
! 441: .Nm structs
! 442: type.
! 443: It returns the number of elements in the array.
! 444: A pointer to the array is stored in the location referenced by
! 445: .Fa listp.
! 446: Each name in the array, as well as the array itself, is allocated with
! 447: .Xr typed_mem 3
! 448: type
! 449: .Fa mtype .
! 450: The caller is responsible for freeing all array elements as well as
! 451: the array itself.
! 452: .Sh RETURN VALUES
! 453: All of the above functions indicate an error condition by returning
! 454: either -1 or
! 455: .Dv NULL
! 456: and setting
! 457: .Va errno
! 458: to an appropriate value.
! 459: .Pp
! 460: Whenever there is an error, no partial work is done: the state of
! 461: the parameters has not changed, and nothing has been allocated or freed.
! 462: .Sh SEE ALSO
! 463: .Xr libpdel 3 ,
! 464: .Xr structs_type 3 ,
! 465: .Xr structs_type_array 3 ,
! 466: .Xr structs_type_boolean 3 ,
! 467: .Xr structs_type_bpf 3 ,
! 468: .Xr structs_type_data 3 ,
! 469: .Xr structs_type_dnsname 3 ,
! 470: .Xr structs_type_ether 3 ,
! 471: .Xr structs_type_float 3 ,
! 472: .Xr structs_type_id 3 ,
! 473: .Xr structs_type_int 3 ,
! 474: .Xr structs_type_ip4 3 ,
! 475: .Xr structs_type_null 3 ,
! 476: .Xr structs_type_pointer 3 ,
! 477: .Xr structs_type_regex 3 ,
! 478: .Xr structs_type_string 3 ,
! 479: .Xr structs_type_struct 3 ,
! 480: .Xr structs_type_time 3 ,
! 481: .Xr structs_type_union 3 ,
! 482: .Xr structs_xml_input 3 ,
! 483: .Xr structs_xmlrpc 3 ,
! 484: .Xr typed_mem 3
! 485: .Sh HISTORY
! 486: The PDEL library was developed at Packet Design, LLC.
! 487: .Dv "http://www.packetdesign.com/"
! 488: .Sh AUTHORS
! 489: .An Archie Cobbs Aq archie@freebsd.org
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>