2013-03-12 16:38:58 -04:00
|
|
|
tpl examples
|
|
|
|
============
|
2013-03-12 17:23:06 -04:00
|
|
|
Troy D. Hanson <tdh@tkhanson.net>
|
2013-03-12 16:38:58 -04:00
|
|
|
v1.0, October 2006
|
|
|
|
|
|
|
|
|
|
|
|
Examples
|
|
|
|
--------
|
|
|
|
|
|
|
|
This document is a set of representative examples demonstrating how to use
|
|
|
|
tpl. If you're looking for a more explanatory document, please read the
|
|
|
|
link:userguide.html[User Guide].
|
|
|
|
|
|
|
|
An integer array
|
|
|
|
~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
.Storing an array of integers to file
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
#include "tpl.h"
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
tpl_node *tn;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
tn = tpl_map( "A(i)", &i );
|
|
|
|
for( i=0; i<10; i++ ) {
|
|
|
|
tpl_pack( tn, 1 );
|
|
|
|
}
|
|
|
|
tpl_dump( tn, TPL_FILE, "demo.tpl" );
|
|
|
|
tpl_free( tn );
|
|
|
|
}
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
A program that unpacks this tpl data file is shown below.
|
|
|
|
|
|
|
|
.Re-reading an array of integers from file
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "tpl.h"
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
tpl_node *tn;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
tn = tpl_map( "A(i)", &i );
|
|
|
|
tpl_load( tn, TPL_FILE, "demo.tpl" );
|
|
|
|
while (tpl_unpack( tn, 1 ) > 0) {
|
|
|
|
printf("%d ", i);
|
|
|
|
}
|
|
|
|
tpl_free( tn );
|
|
|
|
}
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
When run, this program prints:
|
|
|
|
|
|
|
|
0 1 2 3 4 5 6 7 8 9
|
|
|
|
|
|
|
|
|
|
|
|
A nested array
|
|
|
|
~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
.Packing nested arrays
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
#include "tpl.h"
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
char c;
|
|
|
|
tpl_node *tn;
|
|
|
|
|
|
|
|
tn = tpl_map("A(A(c))", &c);
|
|
|
|
|
|
|
|
for(c='a'; c<'c'; c++) tpl_pack(tn,2);
|
|
|
|
tpl_pack(tn, 1);
|
|
|
|
|
|
|
|
for(c='1'; c<'4'; c++) tpl_pack(tn,2);
|
|
|
|
tpl_pack(tn, 1);
|
|
|
|
|
|
|
|
tpl_dump(tn, TPL_FILE, "test40.tpl");
|
|
|
|
tpl_free(tn);
|
|
|
|
}
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
This creates a nested array in which the parent has two elements: the first
|
|
|
|
element is the two-element nested array 'a', 'b'; and the second element is
|
|
|
|
the three-element nested array '1', '2', '3'.
|
|
|
|
|
|
|
|
.Unpacking nested arrays
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
#include "tpl.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
char c;
|
|
|
|
tpl_node *tn;
|
|
|
|
|
|
|
|
tn = tpl_map("A(A(c))", &c);
|
|
|
|
|
|
|
|
tpl_load(tn, TPL_FILE, "test40.tpl");
|
|
|
|
while (tpl_unpack(tn,1) > 0) {
|
|
|
|
while (tpl_unpack(tn,2) > 0) printf("%c ",c);
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
tpl_free(tn);
|
|
|
|
}
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
When run, this program prints:
|
|
|
|
|
|
|
|
a b
|
|
|
|
1 2 3
|
|
|
|
|
|
|
|
A string array
|
|
|
|
~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
.Packing a string array
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
#include "tpl.h"
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
tpl_node *tn;
|
|
|
|
char *s;
|
|
|
|
|
|
|
|
tn = tpl_map( "A(s)", &s );
|
|
|
|
|
|
|
|
s = "bob";
|
|
|
|
tpl_pack(tn, 1);
|
|
|
|
|
|
|
|
s = "betty";
|
|
|
|
tpl_pack(tn, 1);
|
|
|
|
|
|
|
|
tpl_dump(tn, TPL_FILE, "strings.tpl");
|
|
|
|
tpl_free(tn);
|
|
|
|
}
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
.Unpacking a string array
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "tpl.h"
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
tpl_node *tn;
|
|
|
|
char *s;
|
|
|
|
|
|
|
|
tn = tpl_map( "A(s)", &s );
|
|
|
|
tpl_load( tn, TPL_FILE, "strings.tpl" );
|
|
|
|
|
|
|
|
while (tpl_unpack( tn, 1 ) > 0) {
|
|
|
|
printf("%s\n", s);
|
|
|
|
free(s); /* important! */
|
|
|
|
}
|
|
|
|
|
|
|
|
tpl_free(tn);
|
|
|
|
}
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
When run, this program prints:
|
|
|
|
|
|
|
|
bob
|
|
|
|
betty
|
|
|
|
|
|
|
|
Integer/string pairs
|
|
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
.Packing integer/string pairs
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
#include "tpl.h"
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) {
|
|
|
|
tpl_node *tn;
|
|
|
|
int id;
|
|
|
|
char *name, *names[] = { "joe", "bob", "mary" };
|
|
|
|
|
|
|
|
tn = tpl_map("A(is)", &id, &name);
|
|
|
|
|
|
|
|
for(id=0,name=names[id]; id < 3; name=names[++id])
|
|
|
|
tpl_pack(tn,1);
|
|
|
|
|
|
|
|
tpl_dump(tn, TPL_FILE, "/tmp/test35.tpl");
|
|
|
|
tpl_free(tn);
|
|
|
|
}
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
.Unpacking integer/string pairs
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "tpl.h"
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) {
|
|
|
|
tpl_node *tn;
|
|
|
|
int id;
|
|
|
|
char *name;
|
|
|
|
|
|
|
|
tn = tpl_map("A(is)", &id, &name);
|
|
|
|
tpl_load(tn, TPL_FILE, "/tmp/test35.tpl");
|
|
|
|
|
|
|
|
while ( tpl_unpack(tn,1) > 0 )
|
|
|
|
printf("id %d, user %s\n", id, name);
|
|
|
|
|
|
|
|
tpl_free(tn);
|
|
|
|
}
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
When run, this program prints:
|
|
|
|
|
|
|
|
id 0, user joe
|
|
|
|
id 1, user bob
|
|
|
|
id 2, user mary
|
|
|
|
|
|
|
|
A binary buffer
|
|
|
|
~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
.Packing a binary buffer
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
#include "tpl.h"
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
tpl_node *tn;
|
|
|
|
tpl_bin tb;
|
|
|
|
struct timeval tv; /* we'll pack this structure as raw binary */
|
|
|
|
gettimeofday(&tv,NULL); /* populate the structure with some data */
|
|
|
|
|
|
|
|
tn = tpl_map( "B", &tb );
|
|
|
|
tb.sz = sizeof(struct timeval);
|
|
|
|
tb.addr = &tv;
|
|
|
|
tpl_pack( tn, 0 );
|
|
|
|
|
|
|
|
tpl_dump(tn, TPL_FILE, "bin.tpl");
|
|
|
|
tpl_free(tn);
|
|
|
|
}
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
.Unpacking a binary buffer
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
#include "tpl.h"
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
tpl_node *tn;
|
|
|
|
tpl_bin tb;
|
|
|
|
|
|
|
|
tn = tpl_map( "B", &tb );
|
|
|
|
tpl_load( tn, TPL_FILE, "bin.tpl" );
|
|
|
|
|
|
|
|
tpl_unpack( tn, 0 );
|
|
|
|
printf("binary buffer of length %d at address %p\n", tb.sz, tb.addr);
|
|
|
|
free(tb.addr); /* important! */
|
|
|
|
|
|
|
|
tpl_free(tn);
|
|
|
|
}
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
Simple pipe IPC
|
|
|
|
~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
This is a simple example of inter-process communication (IPC) over a pipe.
|
|
|
|
|
|
|
|
.IPC over a pipe
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
int main() {
|
|
|
|
tpl_node *tn;
|
|
|
|
unsigned i, sum=0;
|
|
|
|
int fd[2], pid;
|
|
|
|
|
|
|
|
pipe(fd);
|
|
|
|
if ( (pid = fork()) == 0) { /* child */
|
|
|
|
|
|
|
|
tn = tpl_map("A(u)",&i);
|
|
|
|
tpl_load(tn, TPL_FD, fd[0]);
|
|
|
|
while (tpl_unpack(tn,1) > 0) sum += i;
|
|
|
|
tpl_free(tn);
|
|
|
|
printf("sum is %d\n", sum);
|
|
|
|
|
|
|
|
} else if (pid > 0) { /* parent */
|
|
|
|
|
|
|
|
tn = tpl_map("A(u)",&i);
|
|
|
|
for(i=0;i<10000;i++) tpl_pack(tn,1);
|
|
|
|
tpl_dump(tn,TPL_FD, fd[1] );
|
|
|
|
tpl_free(tn);
|
|
|
|
|
|
|
|
waitpid(pid,NULL,0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
The child unpacks the integers in the message, and sums them, printing:
|
|
|
|
|
|
|
|
49995000
|
|
|
|
|
|
|
|
The example above (with `#include` headers omitted here) is included in the
|
|
|
|
file `tests/test28.c`.
|