adbus_Iterator Struct Reference

Iterator over serialised dbus data. More...

#include <adbus-iterator.h>

Data Fields

const char * data
 Current data pointer.
size_t size
 Data left.
const char * sig
 Current signature pointer.

Related Functions

(Note that these are not member functions.)



static int adbus_iter_bool (adbus_Iterator *i, const adbus_Bool **v)
 Pulls out a boolean (dbus sig "b").
static int adbus_iter_u8 (adbus_Iterator *i, const uint8_t **v)
 Pulls out a uint8_t (dbus sig "y").
static int adbus_iter_i16 (adbus_Iterator *i, const int16_t **v)
 Pulls out a int16_t (dbus sig "n").
static int adbus_iter_u16 (adbus_Iterator *i, const uint16_t **v)
 Pulls out a uint16_t (dbus sig "q").
static int adbus_iter_i32 (adbus_Iterator *i, const int32_t **v)
 Pulls out a int32_t (dbus sig "i").
static int adbus_iter_u32 (adbus_Iterator *i, const uint32_t **v)
 Pulls out a uint32_t (dbus sig "u").
static int adbus_iter_i64 (adbus_Iterator *i, const int64_t **v)
 Pulls out a int64_t (dbus sig "x").
static int adbus_iter_u64 (adbus_Iterator *i, const uint64_t **v)
 Pulls out a uint64_t (dbus sig "t").
static int adbus_iter_double (adbus_Iterator *i, const double **v)
 Pulls out a double (dbus sig "d").
static int adbus_iter_string (adbus_Iterator *i, const char **str, size_t *strsz)
 Pulls out a string (dbus sig "s").
static int adbus_iter_objectpath (adbus_Iterator *i, const char **str, size_t *strsz)
 Pulls out a object path (dbus sig "o").
static int adbus_iter_signature (adbus_Iterator *i, const char **str, size_t *strsz)
 Pulls out a signature (dbus sig "g").
static int adbus_iter_beginarray (adbus_Iterator *i, adbus_IterArray *a)
 Begins an array scope (dbus sig "a").
static adbus_Bool adbus_iter_inarray (adbus_Iterator *i, adbus_IterArray *a)
 Checks that the iterator is still inside the array.
static int adbus_iter_endarray (adbus_Iterator *i, adbus_IterArray *a)
 Ends an array scope (dbus sig "a").
static int adbus_iter_begindictentry (adbus_Iterator *i)
 Begins a dict entry scope (dbus sig "{").
static int adbus_iter_enddictentry (adbus_Iterator *i)
 Ends a dict entry scope (dbus sig "}").
static int adbus_iter_beginstruct (adbus_Iterator *i)
 Begins a struct scope (dbus sig "(").
static int adbus_iter_endstruct (adbus_Iterator *i)
 Ends a struct scope (dbus sig ")").
static int adbus_iter_beginvariant (adbus_Iterator *i, adbus_IterVariant *v)
 Begins a variant scope (dbus sig "v").
static int adbus_iter_endvariant (adbus_Iterator *i, adbus_IterVariant *v)
 Ends a variant scope (dbus sig "v").
int adbus_iter_value (adbus_Iterator *i)
 Skip over a single complete type.
void adbus_iter_buffer (adbus_Iterator *i, const adbus_Buffer *buf)
 Setup an iterator for the data in an adbus_Buffer.
void adbus_iter_args (adbus_Iterator *i, const adbus_Message *msg)
 Setup an iterator for the arguments in an adbus_Message.

Detailed Description

Iterator over serialised dbus data.

Warning:
adbus_Iterator will only work on data in the native endianness. For non native data, it should first be endian flipped using adbus_flip_data() or adbus_flip_value().
adbus_Iterator requires that the data is 8 byte aligned. This is easiest to achieve by copying the data into an adbus_Buffer.

All iterate functions return the data via a pointer out param and return an int. The returned int is zero on success and non-zero on a parse failure or invalid data.

The iterate functions will track along the signature in the iterator, but expect that the signature has already been checked (they will assert when there is a signature mismatch). For argument iteration with built in argument checking see the check functions (eg adbus_check_bool()).

The functions are mainly designed for speed, will do minimal data checking, and are all inlined. The only real checking done is to check null terminators for strings.

Arrays

Arrays can be iterated over in two fashions. You can either use adbus_buf_inarray() in a loop to pull out each entry in the array or simply copy the data directly out of the data and size members of adbus_IterArray.

Warning:
When pulling out array data directly or referencing it directly you need to ensure that the target type has the exact same alignment as the marshalled data.

For example using adbus_buf_inarray() to iterator over "au" (an array of uint32s);

  std::vector<uint32_t> vec;
  adbus_IterArray a;
  if (adbus_iter_beginarray(buf, &a))
      return -1;
  while (adbus_iter_inarray(buf, &a))
  {
      uint32_t v;
      if (adbus_iter_u32(buf, &v))
          return -1;
      vec.push_back(v);
  }
  if (adbus_iter_endarray(buf, &a))
      return -1;

Equivalently by pulling the array data out directly:

  std::vector<uint32_t> vec;
  adbus_IterArray a;
  if (adbus_iter_beginarray(iter, &a))
      return -1;
  vec.insert(vec.end(), (uint32_t*) a.data, (uint32_t*) (a.data + a.size));
  if (adbus_iter_endarray(iter, &a))
      return -1;

adbus_IterArray is an exposed type with the following members:

  struct adbus_IterArray
  {
      const char* sig;    // signature of array entry - not null terminated
      const char* data;   // beginning of array data
      size_t size;        // size of array data
  };

Dict Entries

Dict entries can only be used as a scope directly inside an array. Thus the signature will always look like a{...}. The begin/end dictentry calls should be inside an inarray loop.

For example to iterate over "a{is}" (a map of int to string):

  std::map<int, std::string> map;
  adbus_IterArray a;
  if (adbus_iter_beginarray(iter, &a))
      return -1;
  while (adbus_iter_inarray(iter, &a))
  {
      int32_t i32;
      const char* str;
      if (adbus_iter_begindictentry(iter))
          return -1;
      if (adbus_iter_i32(iter, &i32))
          return -1;
      if (adbus_iter_string(iter, &str, NULL))
          return -1;
      if (adbus_iter_enddictentry(iter))
          return -1;
      map[i32] = str;
  }
  if (adbus_iter_endarray(iter, &a))
      return -1;

Structs

Structs can be iterated over by begin and end functions with no scoped data.

For example to iterate over "(iis)" (a struct of int, int, string):

  int32_t i1, i2;
  const char* str;
  if (adbus_iter_beginstruct(iter))
      return -1;
  if (adbus_iter_i32(iter, &i1))
      return -1;
  if (adbus_iter_i32(iter, &i1))
      return -1;
  if (adbus_iter_string(iter, &str))
      return -1;
  if (adbus_iter_endstruct(iter))
      return -1;

Variants

Variants have begin and functions and scoped data. After the begin variant call, the sig member of the iterator is set to the signature of the variant data. This can be used to check the signature of the variant, which must be checked before iterating over specific value types.

adbus_IterVariant is an exposed type with the following members:

  struct adbus_IterVariant
  {
      const char* origsig;
      const char* sig;
      const char* data;
      size_t      size;
  };

For example to iterate over a variant which we expect to be either "s" (string) or "u" (uint32_t):

  uint32_t u;
  const char* str;
  adbus_IterVariant v;
  if (adbus_iter_beginvariant(iter, &v))
      return -1;
  if (strcmp(iter->sig, "u") == 0)
  {
      // We have a u32 variant
      if (adbus_iter_u32(iter->sig, &u))
          return -1;
  }
  else if (strcmp(iter->sig, "s") == 0)
  {
      // We have a string variant
      if (adbus_iter_string(iter->sig, &str))
          return -1;
  }
  else
  {
      // We have some other variant
      return -1;
  }
  if (adbus_iter_endvariant(iter, &v))
      return -1;

Alternatively if we don't care too much about the type just yet, we can copy around the variant in its marshalled form with the associated signature. We can do this by using adbus_iter_value() to skip to the end of the variant and finishing it. Then the data, size, and sig members of the adbus_IterVariant will have the needed info.

For example:

  adbus_IterVariant v;
  if (adbus_iter_beginvariant(iter, &v))
      return -1;
  if (adbus_iter_value(iter))
      return -1;
  if (adbus_iter_endvariant(iter, &v))
      return -1;

  adbus_Buffer* buf = adbus_buf_new();
  adbus_buf_setsig(buf, v.sig, -1);
  adbus_buf_append(buf, v.data, v.size);

  // some time later
  adbus_Iterator iter;
  adbus_iter_buffer(&iter, buf);
  // iterate over the data ...

  // once we are done with the data
  adbus_buf_free(buf);

To pull out the information later we simply setup a new iterator and iterate over the copy of the data. Note that the data must still by 8 byte aligned and thus it is often easiest to cart around the data in an adbus_Buffer.

This method has the advantage of keeping the data in dbus marshalled form and thus can hold any dbus type.


The documentation for this struct was generated from the following files:
 All Data Structures Files Functions Variables Friends Defines

Generated on Mon Mar 22 00:10:02 2010 for adbus by  doxygen 1.6.1