class ref name: rec_dbag
category-group: dbag
layer: 03
header file: z_dbag_recurs.h

synopsis.
The recursive databag object, or rec_dbag_o, is the most widely-used and perhaps the most visible type of databag. Its sole purpose is to serve as a container for other types of data bags. This solitary feature is extremely important, because data bags are used when non-trivial representation of data is called for. By allowing an object to hold instances (of varying types) of itself, it breaks away from the limitation of the data being either a singleton (name-value pair) or a list of sorts (list, array, matrix - which is a list of rows).

A recursive databag object is sub-classed from the list databag ), and thus retains all its functionality. The recursive databag holds a list of other databag objects of any type. Any of those objects can be a recursive databag, which contains a list of other databags, and the cycle repeats (in a recursive fashion). In a string, a simple '(' marks the beginning of a new recursive databag (just as for its base class, the list databag):

const string *my_building =
"building \
(\n\
    name "Burj Dubai"\n\
    foundation ( composition concrete )\n\
    walls\n\
    (\n\
        exterior\n\
        (\n\
            composition aluminum\n\
            vendor "Schmidlin Facade Technology Ltd"\n\
        )\n\
    )\n\
)";

int myfunction() { rec_dbag_o bag(building_data); string_o curtainwall_mfr = bag.get ("walls exterior vendor"); }
In this example, the recursive databag "building" contains:
  • a simple bag whos name is "name" and value is "Burj Dubai"
  • a recursive databag called "foundation"
  • another recursive databag called "walls", which itself contains in it a recursive databag called "exterior".
As should be clearly evident, you can form your data any way you want; you need to know the structure of the data in order to access specific items; and databags are much more readable than XML. This example contains only recursive and simple databags. You can mix and match other types, such as list, array, and matrix databags inside a recursive databag. The parsing of the string containing your data is done automatically when you instantiate a databag object.

member functions (primary)

rec_dbag_o()
SIGNATURE: rec_dbag_o ()
SYNOPSIS:
creates a a new recursive databag object, completely devoid of contents. The object has no internal structure - no string has been given to it to define any data structure.
 

rec_dbag_o(rec_dbag_o)
SIGNATURE: rec_dbag_o (const rec_dbag_o &that)
SYNOPSIS: copy constructor: creates a a new databag object which is an exact image of the copied databag object "that".
 

operator = (rec_dbag_o)
SIGNATURE: const rec_dbag_o &operator = (const rec_dbag_o &rhs)
SYNOPSIS:
copies exactly the RHS object ("rhs") to the existing databag object instance. Any data existing prior to this call gets destroyed.
RETURNS: a reference to the current databag object
 

destructor
SIGNATURE: ~rec_dbag_o ()
SYNOPSIS: virtual destructor. The databag instance is wiped out and all contents are reinitialized to the at-construction state.
 

clone()
SIGNATURE: dbag_o *clone () const
SYNOPSIS:
creates a clone (using new) of the current databag. A pointer is returned to the newly-created object, as the parent class dbag_o. Use delete to destroy the object.
 

bad_reference()
SIGNATURE: static const rec_dbag_o &bad_reference ()
SYNOPSIS: provides a reference to a global singleton instance of this class. Used for failed reference return values.
TRAITS:
this is a static member function. it cannot be called with an object instance. Invoke it like so:

rec_dbag_o &the_bag = rec_dbag_o::bad_reference();

 

rec_dbag_o(<args>)
SIGNATURE: rec_dbag_o (const string_o &s)
SYNOPSIS:
create a new recursive databag object. This constructor calls load() This will set the data to the contents of 's'. Note that both the data structure and contents are defined by 's'.
PARAMETERS

  • s: a string object containing a valid databag. If the contents of 's' is not a valid databag schema, the load will fail, or possibly (worst case) will result in an infinite loop. Care should be exercised defining the contents of this string.
  •  

    rec_dbag_o(<args>)
    SIGNATURE: rec_dbag_o (const string_o &name, count_t n, const dbag_o *first, ...)
    SYNOPSIS:
    variable-arguments version of loading a recursive databag. This function is of dubious value and is planned to be phased out.
    TRAITS: this function is marked for termination. DO NOT USE IT
     

    rec_dbag_o(<args>)
    SIGNATURE: rec_dbag_o (const string_o &, const dbag_o * const [], count_t)
    SYNOPSIS: [WIP]
     

    rec_dbag_o(<args>)
    SIGNATURE: rec_dbag_o (const string_o &s, count_t x)
    SYNOPSIS: [WIP]
    TRAITS: this function is inline
     

    operator ==()
    SIGNATURE: int operator == (const dbag_o &that) const
    SYNOPSIS: [WIP]
     

    operator ==()
    SIGNATURE: int operator == (const rec_dbag_o &that) const
    SYNOPSIS: [WIP]
    TRAITS: this function is inline
     

    operator !=()
    SIGNATURE: int operator != (const rec_dbag_o &that) const
    SYNOPSIS: [WIP]
    TRAITS: this function is inline
     

    mod_setall()
    SIGNATURE: int mod_setall (boolean ison = TRUE)
    SYNOPSIS:
    this function turns on (or off, if 'ison' is FALSE) the "is-modified" flag/property for each databag contained within the current object.
    DESCRIPTION:
    this function calls set_modified() for each databag contained within the curent object. It is a reimplementation of the virtual function in the base class dbag_o. For this class, since it is derived from list_dbag_o, this function simply forwards the operation to list_dbag_o::mod_setall(). Each list databag object (contained within) will have its "is-modified" flag/property set on (or off). The implementation is exactly the same as in the matrix_o class.
    See the discussion in the main databag group page for more information.
     

    operator = (rec_dbag_o)
    SIGNATURE: rec_dbag_o &operator = (const list_dbag_o &)
    SYNOPSIS: [WIP]
     

    reset()
    SIGNATURE: int reset ()
    SYNOPSIS: resets the databag. All internal contents are wiped out.
     

    empty_out()
    SIGNATURE: int empty_out ()
    SYNOPSIS:
    "empties out" the current object. This will delete all sub-databags inside. The object's name is unaffected. This function is nearly the same as reset(), with some small internal differences.
    DESCRIPTION:
    This member function "empties out" all data rows of the recursive databag. The object's structure is intact - the 'items' array is not deleted. Think of a wall coat rack with a line of horizontal hooks holding various coats of different sizes, shapes, and design. empty_out() will remove all the coats from the rack. reset() will remove the rack.
     

    load()
    SIGNATURE: int load (const string_o &s)
    SYNOPSIS: [WIP]
     

    get()
    SIGNATURE: const string_o &get (const string_o &, int * = NULL) const
    SYNOPSIS: [WIP]
     

    get()
    SIGNATURE: const string_o &get (count_t, int * = NULL) const
    SYNOPSIS: [WIP]
    TRAITS: this function is inline
     

    get_dbag()
    SIGNATURE: dbag_o &get_dbag (const string_o &, int * = NULL) const
    SYNOPSIS: [WIP]
     

    get_dbag()
    SIGNATURE: dbag_o &get_dbag (count_t, int * = NULL) const
    SYNOPSIS: [WIP]
    TRAITS: this function is inline
     

    put()
    SIGNATURE: int put (const string_o &, const string_o &, boolean force = FALSE, int * = NULL)
    SYNOPSIS: [WIP]
     

    put()
    SIGNATURE: int put (count_t, const string_o &, boolean force = FALSE, int * = NULL)
    SYNOPSIS: [WIP]
    TRAITS: this function is inline
     

    put_dbag()
    SIGNATURE: int put_dbag (const string_o &, const dbag_o &, int * = NULL)
    SYNOPSIS: [WIP]
     

    put_dbag()
    SIGNATURE: int put_dbag (count_t, const dbag_o &, int * = NULL)
    SYNOPSIS: [WIP]
    TRAITS: this function is inline
     

    put_dbag()
    SIGNATURE: int put_dbag (const dbag_o &, int * = NULL)
    SYNOPSIS: [WIP]
    TRAITS: this function is inline
     

    add_dbag()
    SIGNATURE: int add_dbag (const string_o &, const dbag_o &, int * = NULL)
    SYNOPSIS: [WIP]
     

    add_dbag()
    SIGNATURE: int add_dbag (const dbag_o &bag, int *pi = NULL)
    SYNOPSIS: [WIP]
    TRAITS: this function is inline
     

    addput()
    SIGNATURE: int addput (const string_o &, const string_o &, int * = NULL)
    SYNOPSIS: [WIP]
     

    update_dbag()
    SIGNATURE: int update_dbag (const string_o &, const dbag_o &, int * = NULL)
    SYNOPSIS: [WIP]
     

    update_dbag()
    SIGNATURE: int update_dbag (count_t, const dbag_o &, int * = NULL)
    SYNOPSIS: [WIP]
    TRAITS: this function is inline
     

    delete_dbag()
    SIGNATURE: int delete_dbag (const string_o &, int * = NULL)
    SYNOPSIS: [WIP]
     

    delete_dbag()
    SIGNATURE: int delete_dbag (count_t, int * = NULL)
    SYNOPSIS: [WIP]
    TRAITS: this function is inline
     

    merge_dbag()
    SIGNATURE: int merge_dbag (const dbag_o &, int * = NULL)
    SYNOPSIS: [WIP]
     

    get_idx()
    SIGNATURE: count_t get_idx (const string_o &, int *, count_t = 0) const
    SYNOPSIS: [WIP]
     

    contains()
    SIGNATURE: boolean contains (const string_o &, const dbag_o &) const
    SYNOPSIS: [WIP]
     

    contains()
    SIGNATURE: boolean contains (const dbag_o &) const
    SYNOPSIS: [WIP]
    TRAITS: this function is inline
     

    z_eo_dbag()
    SIGNATURE: size_t z_eo_dbag (const string_o &s, int *pi)
    SYNOPSIS: this subroutine returns the character count to the end of the bag, if there is one; else, 0 is returned and 'pi' is set to non-zero
    PARAMETERS

    • s: a string object containing a valid recursive databag
    • pi: [output] error indicator variable. values: 0: successfully computed
      zErr_Data_BadFormat: not a valid recursive databag
     

    note.
    Alternative nomenclature for recursive databags could have been container, cluster, layeered, or perhaps nested. Recursive is appropo in describing the object's internal processing.