Skip to content

Perl storable/C struct back-and-forth translator

License

LGPL-3.0, GPL-3.0 licenses found

Licenses found

LGPL-3.0
COPYING.LESSER
GPL-3.0
COPYING
Notifications You must be signed in to change notification settings

kimiby/camelion

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

75 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CameLion

Perl storable/C struct back-and-forth translator

Overview

CameLion can:

  • Read and write perl-storable structures:
{
  field1 => value1,
  field2 => value2
}
[
    aaa,
    bbb,
    ccc,
    {
        ddd => eee,
        fff => {
            ggg => hhh
        }
    },
    [
        iii,
        jjj, kkk,
             lll
    ]
]
  • Provide access to any node, allowing to modificate it, remove or append any other node.
  • Read and write perl-nfreezed binary data (nfreeze/thaw C-analogue)

Basic

The main entity in the CameLion project is the CML_Node. You can:

Create and free nodes:

// Error checking is skipped due to readability. make sure to check every function

CML_Node * node;

CML_NodeCreate(CML_TYPE_STRING, &node);
...
CML_NodeFree(node);

Supported types are:

  • CML_TYPE_UNDEF
  • CML_TYPE_INTEGER
  • CML_TYPE_STRING
  • CML_TYPE_ARRAY
  • CML_TYPE_HASH

Name nodes:

CML_NodeSetName(node, "mynode");

char nodename[] = {"Perfect"};
CML_NodeSetName(somenode, nodename);

Assign values to nodes:

CML_NodeSetInteger(node, 2);
CML_NodeSetString(node2, "String");

Notice, that you can't assign integer value to string-typed node and vice-versa.

Access nodes values:

node->data.integer // for INTEGER typed nodes
node->data.string  // for STRING typed nodes

node->nodes // For access to subnodes for ARRAY and HASH typed nodes
// Notice that perl-nfreezed data does not support named elements in ARRAYS, therefore the names for ARRAY elements will be ignored while saving to nfreezed data.

Copy node:

// Copy node with all subnodes:
CML_NodeCopy(src, &dst, CML_TRUE);

// Copy only name & value, without subnodes:
CML_NodeCopy(src, &dst, CML_FALSE);

Print node as perl-storable:

char * string;
CML_StorableToString(node, &string);

printf("%s\n", string);
free(string);
{
    vladislav => 'oh baby',
    dont => 'hurt me',
    no => [
        'more',
        'less',
        {
            wut => 'lolwut?',
        },
    ],
},

Append/Insert/Remove nodes:

CML_NodeAppend(dst, child);
CML_NodeInsert(dst, child, 2);
CML_NodeRemove(dst, 1);

Find for subnodes:

{
  field1 => value1,
  field2 => {
    carrot => {
      vegetable => 'true',
      }
    }
  }
}
CML_Node * root;
CML_Node * child;
CML_NodeFindString(root, "field2.carrot.vegetable", &child);

// Now you have access to 'vegetable' subnode via child variable.

You may use type-specified functions like CML_NodeFindInteger or generic function CML_NodeFind which takes a type as an argument.

Perl interaction

Storable <-> Node translation

You can load perl-storable into node via these functions:

CML_Error CML_StorableFromFile  (char * filename, CML_Node ** result);
CML_Error CML_StorableFromString(char * storable, CML_Node ** result);
char teststorable[] = {
    "{\n"
    "   branch1 => {\n"
    "       value1 => 1,\n"
    "       value2 => \"Deep into\",\n"
    "   },\n"
    "   branch2 => [\n"
    "       'Darkness peering',"
    "       'Long I \\'stood\\' there',\n"
    "       \"Wondering, fearing\","
    "   ],\n"
    "   branch3 => {\n"
    "       value3 => Dreaming,\n"
    "       value4 => Dreams,\n"
    "       value5 => \"No mortal ever dared to dream before\",\n"
    "   },\n"
    "}"
}

int main (void)
{
  CML_Node * poe;
  CML_StorableFromString(teststorable, &poe);
  <..>

And unload it back with these:

CML_Error CML_StorableToFile  (CML_Node * node, char *  filename);
CML_Error CML_StorableToString(CML_Node * node, char ** storable);
  <..>
  char * string;
  CML_StorableToString(poe, &string);
  printf("%s\n", string);
  free(string);
  CML_NodeFree(&poe);
}

Nfreezed data <-> Node translation

CML_Error CML_ThawBytes(CML_Bytes * bytes,          CML_Node ** result);
CML_Error CML_ThawFile (char * filename,            CML_Node ** result);
CML_Error CML_ThawData (char * data, uint32_t size, CML_Node ** result);

/// Notice that CML_ThawXXX functions allocate result variable

CML_Error CML_NfreezeNode    (CML_Node * node, CML_Bytes ** result);
CML_Error CML_NfreezeStorable(char * storable, CML_Bytes ** result);
// Notice that CML_NfreezeXXX functions allocate result variable on their own

If you want to save CML_Bytes to file you can use CML_DataToFile function:

CML_DataToFile(bytes->data, bytes->size, "./myfilename.bin");

Also you can use this function to write any data including strings:

char mystring[] = {"something"};
CML_DataToFile(mystring, strlen(mystring), "./stringy.txt");

Using as settings manager

You can also use this library for settings management for c-projects. Just put your settings to perl-storable and place that file somewhere. The library will do the rest:

{
  messages => {
    info    => disabled,
    warnings => disabled,
    errors   => enabled
  }

  timing => {
    lowperiod    => 20, # Seconds
    mediumperiod => 10, # Seconds
    highperiod   =>  2  # Seconds
  }
}
// Loading
CML_Node * settings;
CML_StorableFromFile("./settings.perl", &settings);
...

// Using
CML_Node * lowperiod;
CML_NodeFindInteger(settings, "timing.lowperiod", &lowperiod);
TimerSetPeriod(lowperiod->data.integer);

Error checking

CameLion functions may return number of error codes (see CML_X_ERROR_CODES). To provide user-readable error description one may use CML_HelpError function:

if (result != CML_ERROR_SUCCESS)
{
    printf("Error is %d: %s\n", result, CML_HelpError(result));
    exit(1);
}
Memory allocation failed

Header file generation

If you want to use libcamelion.h in non-C project you may need to preprocess it to get rid of macros.

./scripts/generate_h.sh
mv ./libcamelion.h ./_libcamelion.h
gcc -E ./_libcamelion.h -o ./libcamelion.h
indent -gnu -l200 -i4 -nut ./libcamelion.h

NOTE: using indent might need installation of this utility.

About

Perl storable/C struct back-and-forth translator

Resources

License

LGPL-3.0, GPL-3.0 licenses found

Licenses found

LGPL-3.0
COPYING.LESSER
GPL-3.0
COPYING

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published