dvfs api and toolkits

nf2 nf2 at scheinwelt.at
Wed Apr 6 12:41:04 EEST 2005

nf2 wrote:

> If you want to write a really portable D-VFS, which can be integrated 
> into any toolkit, it might be better to standardize a communication 
> protocol for the client->D-VFS daemon connection rather than an API... 
> I have started to code a very simple "TinyVariant" library, which 
> could be used for such a socket communication (in case D-BUS doesn't 
> fit). I'll show you soon...

Here is the first release of the "tinyvariant" library:



this is free software. Please see the file COPYING for details.
For building and installation instructions please see the INSTALL file.


Data is stored LOOSE (as C structures) or
PACKED (binary byte sequences) for network or ipc communication.
Type signatures are not separated from data like in dbus. There is no 
alignment padding in PACKED data.

Basic types:
(examples of binary data are shown url-encoded)

's' null terminated string:  "sHELLO%20WORLD%00"

'i' 32 bit integer stored as big endian: "i%00%00%01%00"  (val = hex 0x100)

'p' key value pair: "psKEY%00sVALUE%00"

'(' list of variant values, terminated by a ')':
    a list that contains  "VALUE1", 0x100, "VALUE2"

'Y' byte array - length is stored as xint:
    "Y%82%00abcde....fgh" (size = hex 0x100)
    "Y%05abcde" (size = hex 0x05)

'm' container to transport messages. based on byte-array, but containing 
other tinyvariants:
    "M%12(sSTRING%00sSTRING%00)" - containing a list of two strings, 18 
bytes long, for instance.

xint: unsigned int of unlimited size, used for storing array sizes in a 
very compact way.
    (grows with the size of the array)
    byte encoding: first bit = continue bit, rest: 7 bits data of the 
unsigned integer value (big endian)
    "%7f" = hex 0x7f;  "%81%7f" = hex 0xff; "%83%05" = hex 0x185

future types: 'm' message container, 'n' stand-alone xint, 'y' single 
byte, 'l' lowercase L = int64, 'x' xint, 'o' boolean,...

1) types used in libtinyvariant:
  TVariant* : a pointer pointing to the type id of a tinyvariant value
    like 's', 'i', 'p',.. or a '$' for LOOSE (unpacked) types.
  This means that packed data doesn't have to be unpacked for reading. 
Unpacking is only necessary
  to access container types like tva_list. Therefore, if you unpack with 
the option TVA_DSER_GREEDY,
  only container types will be unpacked.

  LOOSE variants are indentified by a '$' followed by the value type. 
("$s" for instance).
    loose variants are type casted to C-structures internally (TString, 
TInt, TPair, TvaByteArr,..).
     "$i__dddd" - TInt struct.
     "$s__mmmmsssspppp" - TString struct: string size (ssss), with a 
pointer (pppp) to the actual string.

2) constructors of TVariants:

  TVariant * tva_string_new();
  TVA_CONST_STRING() ... just prepends a "s" to a const C-string.
  TVariant * tva_pair_new(TVariant * key, TVariant * value);
  ... and so on ...

3) generic methods of a TVariant*:

  TTypeDef * tva_class(TVariant * t);   /* get class definition */
  TvaResponse tva_getNext(
     TVariant * t,
     TvaGetNextData * ops, 
     TVariant ** t_this_unpacked,
     TVariant ** t_next
  );  /* unpack a PACKED TVariant to LOOSE memory structures recursively 
- with boundary checking */
  TvaResponse tva_calcPackedSize(TVariant *t, size_t * size); /* 
calculate byte # this TVariant would take packed */
  TvaResponse tva_packByteWise(TVariant *t, void * userObj,
     TvaResponse (*packByteWiseCallback)(void * userObj, char c));  /* 
recursive serialize byte-wise */
  char * tva_toString(TVariant * t, TVariant * toString); 
      /* generate a string representation of a TVariant recursively */
  TvaIsType tva_is(TVariant * t, char type);  /* check class of a 
TVariant */
  TvaResponse tva_destroy(TVariant * t);
  TvaResponse tva_destroy_deep(TVariant * t);  /* free TVariant(s) */

4) type specific methods of TVariants:

  tva_int32_t   tva_int32_getInt(TVariant * t);
  char * tva_string_getString(TVariant * t);
  TVariant * tva_pair_getKey(TVariant * t);
  TVariant * tva_pair_getValue(TVariant * t);
  TvaResponse tva_list_append(TVariant * t, TVariant * val);
  TVariant * tva_list_getValueC(TVariant *t , char * keystr);  /* find 
Key/Value-pair and return value. */
  ... and so on...

5) Sample code:

         TVariant * pair1 =tva_pair_new(TVA_CONST_STRING("gnome"), 
        TVariant * pair2 =tva_pair_new(TVA_CONST_STRING("kde"), 
        TVariant * pair3 =tva_pair_new(TVA_CONST_STRING("linux"), 
        TVariant * pair4 =tva_pair_new(TVA_CONST_STRING("nobody"), 
        TVariant * list = tva_list_new();
        tva_list_append(list, pair1);
        tva_list_append(list, pair2);
        tva_list_append(list, pair3);
        tva_list_append(list, pair4);
        /* list toString method */
            TVariant * tmpString = tva_string_new();
            printf("list toString: %s \n", tva_toString(list, tmpString));
        /* find a certain key/value pair */       
        TVariant * find1 = tva_list_getValueC(list, "linux");
        if (find1 != NULL_PTR) {
            printf("value of key [linux]: %s\n", 
        } else {
            printf("key not found\n");
        /* serialize to stdout - url encoded */
        printf("packed list - url-encoded: ");
        stdout_pack_urlenc(list, 9999);
        tva_destroy_deep(list); /* free all TVariants */


list toString: { [ gnome => www.gnome.org ]; [ kde => www.kde.org ]; [ 
linux => www.kernel.org ]; [ nobody => me ] }
value of key [linux]: www.kernel.org
packed list - url-encoded: 
(81 bytes)

 see tinyvariant_test.c for more examples...

More information about the xdg mailing list