Check-in [4c5cfcaed9]

Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
SHA1 Hash:4c5cfcaed908f61eb0fb60b56cf1a1ec105f0333
Date: 2008-11-14 17:30:10
User: stephan
Comment:minor API refactorings (some argument orders changed)
Changes
hide diffs unified diffs patch

Changes to include/s11n.net/c11n/c11n.h

Old (b3be28219ec53288) New (7799fac2c567514e)
1 #ifndef S11N_NET_C11N_H_INCLUDED 1 #ifndef S11N_NET_C11N_H_INCLUDED
2 #define S11N_NET_C11N_H_INCLUDED 1 2 #define S11N_NET_C11N_H_INCLUDED 1
3 3
4 /** @page c11n_page_main c11n: generic serialization library for C 4 /** @page c11n_page_main c11n: generic serialization library for C
5 5
116 hidden lines
122 with a compiler-specific switch. 122 with a compiler-specific switch.
123 123
124 - Some patience. It's beta. 124 - Some patience. It's beta.
125 125
126 126
> 127 @section c11n_sec_example_ultrabrief Exceedingly brief example
> 128
> 129 Here's a very sample of what using c11n looks like. Assume we have
> 130 a custom struct type which looks like:
> 131
> 132 @code
> 133 typedef struct MyList
> 134 {
> 135 int x;
> 136 int y;
> 137 struct MyList * left;
> 138 struct MyList * right;
> 139 } MyList;
> 140 @endcode
> 141
> 142 MyList objects represent a singly-linked list. In this case
> 143 each list entry contains two values, though for the general
> 144 case that is irrelevant.
> 145
> 146 With a bit of code in place for converting MyList objects
> 147 to/from c11n (we won't show that here), we can sae
> 148 a MyList list with:
> 149
> 150 @code
> 151 MyList list;
> 152 ... populate list ...
> 153 c11n_stream * str =
> 154 c11n_stream_for_filename( "myfile.c11n", true );//true==write mode
> 155 c11n_save_serializable( str, MyList_c11n, &list, 0 );
> 156 str->api->destroy(str);
> 157 @endcode
> 158
> 159 We can load it using:
> 160
> 161 @code
> 162 c11n_stream * str =
> 163 c11n_stream_for_filename( "myfile.c11n", false );//false==read mode
> 164 MyList * list = c11n_load_serializable( str, MyList_c11n );
> 165 str->api->destroy(str);
> 166 @endcode
> 167
> 168 There is also an approach for loading serialized data into
> 169 an existing object, rather than creating a new one.
> 170
> 171 While the API is actually ignorant of what file format it uses,
> 172 here's an example of what a MyList list looks like in an
> 173 XML dialect:
> 174
> 175 @code
> 176 <!DOCTYPE s11n::io::expat_serializer>
> 177 <c11n_root_node class='MyList'>
> 178 <items class='MyListList'>
> 179 <item class='MyListItem'>
> 180 <xy>1 -1</xy>
> 181 </item>
> 182 <item class='MyListItem'>
> 183 <xy>2 -2</xy>
> 184 </item>
> 185 <item class='MyListItem'>
> 186 <xy>3 -3</xy>
> 187 </item>
> 188 </items>
> 189 </c11n_root_node>
> 190 @endcode
> 191
> 192
127 @section c11n_sec_cerializable Serializable types 193 @section c11n_sec_cerializable Serializable types
128 194
129 In c11n, serialization happens via marshaller objects which copy 195 In c11n, serialization happens via marshaller objects which copy
130 object state to c11n_nodes (essentially a DOM tree) for serialization. 196 object state to c11n_nodes (essentially a DOM tree) for serialization.
131 For deserialization the marshallers restore an object from data 197 For deserialization the marshallers restore an object from data
1251 hidden lines
1383 for use as the deserialization target. The new object is created using 1449 for use as the deserialization target. The new object is created using
1384 marshaller->api->create(). If deserialization fails the new object is 1450 marshaller->api->create(). If deserialization fails the new object is
1385 deallocated using marshaller->api->destroy(), otherwise it is returned to 1451 deallocated using marshaller->api->destroy(), otherwise it is returned to
1386 the caller, who takes over ownership of the object. 1452 the caller, who takes over ownership of the object.
1387 1453
1388 WARNINGS AND BUGS: | 1454 Bit fat hairy warning:
1389 1455
1390 This routine cannot work with c11n_marshaller_pod_string. See that type | 1456 This routine cannot work with marshallers which require passing a pointer
1391 for details. | 1457 to a pointer to an object, as opposed to a pointer to an object. If passed
| 1458 such a marshaller this routine might silently leak memory.
1392 */ 1459 */
1393 void * c11n_deserialize_new( c11n_node const * src, c11n_marshaller const * marshaller ); 1460 void * c11n_deserialize_new( c11n_node const * src, c11n_marshaller const * marshaller );
1394 1461
1395 /** 1462 /**
1396 Uses the given marshaller to clone ct using its serialization 1463 Uses the given marshaller to clone ct using its serialization
1397 API. On success it returns a new instance of ct, populated 1464 API. On success it returns a new instance of ct, populated
1398 with the data serialized by the marshaller. | 1465 with the data (de)serialized by the marshaller. On error it
| 1466 returns 0.
1399 1467
1400 The caller is responsible for freeing the returned object using 1468 The caller is responsible for freeing the returned object using
1401 marhshaller->destroy(marhshaller,thatObject) or equivalent | 1469 marshaller->destroy(marshaller,thatObject), or the equivalent
1402 for the given type. 1470 for the given type.
> 1471
> 1472 Tip:
> 1473
> 1474 Cloning is an easy way to test the de/serialization routines
> 1475 for a given marshaller. If cloning works then one can be sure
> 1476 that de/serialization as a whole works.
1403 */ 1477 */
1404 void * c11n_clone( c11n_marshaller const * marshaller, void * ct ); 1478 void * c11n_clone( c11n_marshaller const * marshaller, void * ct );
1405 1479
1406 /** 1480 /**
1407 Returns true if key is equal to val, in the lexical comparison sense 1481 Returns true if key is equal to val, in the lexical comparison sense
330 hidden lines
1738 void * data; 1812 void * data;
1739 /** See c11n_deserialize_binary(). */ 1813 /** See c11n_deserialize_binary(). */
1740 size_t size; 1814 size_t size;
1741 } c11n_binary_data; 1815 } c11n_binary_data;
1742 /** 1816 /**
1743 UNTESTED! <
1744 <
1745 The converse of c11n_serialize_binary(). The caller must supply a non-null 1817 The converse of c11n_serialize_binary(). The caller must supply a non-null
1746 dest pointer. The serialized data pulled from src is stored in dest. 1818 dest pointer. The serialized data pulled from src is stored in dest.
1747 If dest->data points to an object before this call then the caller 1819 If dest->data points to an object before this call then the caller
1748 should clean it up (if appropriate) before calling this, as this call 1820 should clean it up (if appropriate) before calling this, as this call
1749 will overwrite that pointer. 1821 will overwrite that pointer.
41 hidden lines
1791 #ifdef __cplusplus 1863 #ifdef __cplusplus
1792 } /* extern "C" */ 1864 } /* extern "C" */
1793 #endif 1865 #endif
1794 1866
1795 #endif /* S11N_NET_C11N_H_INCLUDED */ 1867 #endif /* S11N_NET_C11N_H_INCLUDED */

Changes to include/s11n.net/c11n/io/c11n_io.h

Old (2df8e7de086cd98b) New (434d46e32819ffdc)
1 #ifndef S11N_NET_C11N_IO_H_INCLUDED 1 #ifndef S11N_NET_C11N_IO_H_INCLUDED
2 #define S11N_NET_C11N_IO_H_INCLUDED 1 2 #define S11N_NET_C11N_IO_H_INCLUDED 1
3 /* 3 /*
4 This file contains declarations and documentation for the generic 4 This file contains declarations and documentation for the generic
5 i/o routines for c11n. The core does not know about this API and no 5 i/o routines for c11n. The core does not know about this API and no
227 hidden lines
233 */ 233 */
234 struct c11n_stream_api 234 struct c11n_stream_api
235 { 235 {
236 /** 236 /**
237 isgood() returns whether or not self is in a valid use state. 237 isgood() returns whether or not self is in a valid use state.
238 It should not return true on eof, as eof is not strictly an | 238 It should return true on eof, as eof is not strictly an error.
239 error. To report EOF it should return 0 from the read() | 239 To report EOF it should return 0 from the read()
240 implementation. 240 implementation.
241 */ 241 */
242 bool (*isgood)( struct c11n_stream * self ); 242 bool (*isgood)( struct c11n_stream * self );
243 /** 243 /**
244 read() must read (at most) count bytes from its underlying 244 read() must read (at most) count bytes from its underlying
511 hidden lines
756 756
757 Note that this routine is ONLY for saving root nodes. That is, one 757 Note that this routine is ONLY for saving root nodes. That is, one
758 node per stream. Subnodes will be written out as part of the src 758 node per stream. Subnodes will be written out as part of the src
759 tree. 759 tree.
760 */ 760 */
761 bool c11n_save_node( c11n_node const * src, c11n_stream * dest, c11n_io_handler * h ); | 761 bool c11n_save_node( c11n_stream * dest, c11n_node const * src, c11n_io_handler * h );
762 762
763 /** 763 /**
764 Works similarly to c11n_load_node(), except that it goes one step further and tries to 764 Works similarly to c11n_load_node(), except that it goes one step further and tries to
765 deserialize that node into a new object. If a node can be loaded (as described for 765 deserialize that node into a new object. If a node can be loaded (as described for
766 c11n_load_node()) then a new object is created via m->api->create(m). That object 766 c11n_load_node()) then a new object is created via m->api->create(m). That object
14 hidden lines
781 781
782 Note that this routine is ONLY for saving top-level objects. That 782 Note that this routine is ONLY for saving top-level objects. That
783 is, one object per stream. Children of src will be written out as 783 is, one object per stream. Children of src will be written out as
784 part of the serialization of src. 784 part of the serialization of src.
785 */ 785 */
786 bool c11n_save_serializable( c11n_marshaller const * marshaller, void const * src, c11n_stream * dest, c11n_io_handler * h ); | 786 bool c11n_save_serializable( c11n_stream * dest, c11n_marshaller const * marshaller, void const * src, c11n_io_handler * h );
787 787
788 788
789 /** 789 /**
790 A type for implementing string escape tables. Not a terribly 790 A type for implementing string escape tables. Not a terribly
791 efficient way to do string escaping, but quite flexible. For 791 efficient way to do string escaping, but quite flexible. For
96 hidden lines
888 #ifdef __cplusplus 888 #ifdef __cplusplus
889 } /* extern "C" */ 889 } /* extern "C" */
890 #endif 890 #endif
891 891
892 #endif // S11N_NET_C11N_IO_H_INCLUDED 892 #endif // S11N_NET_C11N_IO_H_INCLUDED

Changes to src/Doxyfile.at

Old (dd9755ed47933e37) New (b3bd50b28e263790)
1 # Doxyfile 1.5.5 1 # Doxyfile 1.5.5
2 2
3 # This file describes the settings to be used by the documentation system 3 # This file describes the settings to be used by the documentation system
4 # doxygen (www.doxygen.org) for a project 4 # doxygen (www.doxygen.org) for a project
5 # 5 #
548 hidden lines
554 # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 554 # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
555 # certain files from those directories. Note that the wildcards are matched 555 # certain files from those directories. Note that the wildcards are matched
556 # against the file with absolute path, so to exclude all test directories 556 # against the file with absolute path, so to exclude all test directories
557 # for example use the pattern */test/* 557 # for example use the pattern */test/*
558 558
559 EXCLUDE_PATTERNS = whgc.* \ | 559 EXCLUDE_PATTERNS = */b64/* \
| 560 whgc.* \
560 My*.* test*.* 561 My*.* test*.*
561 562
562 # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 563 # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
563 # (namespaces, classes, functions, etc.) that should be excluded from the 564 # (namespaces, classes, functions, etc.) that should be excluded from the
564 # output. The symbol name can be a fully qualified name, a word, or if the 565 # output. The symbol name can be a fully qualified name, a word, or if the
790 hidden lines
1355 1356
1356 # The SEARCHENGINE tag specifies whether or not a search engine should be 1357 # The SEARCHENGINE tag specifies whether or not a search engine should be
1357 # used. If set to NO the values of all tags below this one will be ignored. 1358 # used. If set to NO the values of all tags below this one will be ignored.
1358 1359
1359 SEARCHENGINE = NO 1360 SEARCHENGINE = NO

Changes to src/Makefile

Old (7db471d71f7f96e9) New (3796d7feebfde657)
1 #!/usr/bin/make -f 1 #!/usr/bin/make -f
2 # Requires GNU Make 3.80+! 2 # Requires GNU Make 3.80+!
3 default: all 3 default: all
4 4
5 ifeq (1,$(TCC)) 5 ifeq (1,$(TCC))
153 hidden lines
159 libs: $(libc11n.DLL) 159 libs: $(libc11n.DLL)
160 endif 160 endif
161 161
162 test.o: CFLAGS += -Wno-format 162 test.o: CFLAGS += -Wno-format
163 test.BIN.LDFLAGS := $(libc11n.LIB) $(libwhgc.LIB) $(EXPAT_LDFLAGS) 163 test.BIN.LDFLAGS := $(libc11n.LIB) $(libwhgc.LIB) $(EXPAT_LDFLAGS)
164 test.BIN.OBJECTS := test.o MyType.o MyGraph.o | 164 test.BIN.OBJECTS := test.o MyType.o MyList.o
165 ifeq (1,$(USE_SQLITE3)) 165 ifeq (1,$(USE_SQLITE3))
166 test.BIN.LDFLAGS += $(SQLITE3.LDFLAGS) 166 test.BIN.LDFLAGS += $(SQLITE3.LDFLAGS)
167 endif 167 endif
168 168
169 $(call ShakeNMake.CALL.RULES.BINS,test) 169 $(call ShakeNMake.CALL.RULES.BINS,test)
33 hidden lines
203 #$(MEGA.BIN): $(libc11n.LIB) $(libwhgc.LIB) 203 #$(MEGA.BIN): $(libc11n.LIB) $(libwhgc.LIB)
204 # tcc $(INCLUDES) -r -o $(MEGA.OBJ) $(wildcard c11n*.c wh*.c vappendf.c) 204 # tcc $(INCLUDES) -r -o $(MEGA.OBJ) $(wildcard c11n*.c wh*.c vappendf.c)
205 # tcc -o $(MEGA.BIN) $(MEGA.OBJ) $(SQLITE3.LDFLAGS) 205 # tcc -o $(MEGA.BIN) $(MEGA.OBJ) $(SQLITE3.LDFLAGS)
206 206
207 all: libs bins 207 all: libs bins

Added src/MyList.c

Old () New (347096726de2ca7e)
> 1 /**
> 2 Example of one approach to serializing a linked list using c11n. Note that this
> 3 does not support cycles! It can be done in c11n, but requires a bit of effort.
> 4 There is no single plug-in algorithm which works for all graph types, so we
> 5 can't provide a generic solution to that problem.
> 6
> 7 All of the functions shown here are either required by the
> 8 c11n_marshaller_api API or are helper functions for implementing
> 9 those required by c11n_marshaller_api.
> 10 */
> 11 #include "MyList.h"
> 12 #include <stdlib.h>
> 13 #include <stdio.h>
> 14
> 15 #if 1
> 16 #define MARKER if(1) printf("MARKER: %s:%d:%s(): ",__FILE__,__LINE__,__func__); if(1) printf
> 17 #else
> 18 #define if(0) printf
> 19 #endif
> 20
> 21 /**
> 22 A helper routine for MyList_serialize().
> 23 */
> 24 static bool MyList_serialize_one( MyList const * g, c11n_node * dest )
> 25 {
> 26 c11n_node_set_class( dest, "MyListItem" );
> 27 c11n_node_prop_set_fe( dest, "xy", "%d %d", g->x, g->y );
> 28 return true;
> 29 }
> 30
> 31 /**
> 32 Requires that src is-a pointer to a MyList object. This routine
> 33 serializes ALL nodes linked from src as a list of entries. At
> 34 deserialization time the links to those items are re-established.
> 35 */
> 36 static bool MyList_serialize( struct c11n_marshaller const * self, c11n_node * dest, void const * src )
> 37 {
> 38 c11n_node_set_class( dest, self->api->classname );
> 39 MyList const * me = (MyList const *)src;
> 40
> 41 MyList const * h = me;
> 42 while( h->left ) h = h->left;
> 43 MyList const * at = h;
> 44 c11n_node * nlist = c11n_node_create_child( dest, "items" );
> 45 c11n_node_set_class( nlist, "MyListList" );
> 46 while( at )
> 47 {
> 48 MARKER("Serializing MyList item @%p...\n",(void const *)at);
> 49 c11n_node * ch = c11n_node_create_child( nlist, "item" );
> 50 if( ! MyList_serialize_one( at, ch ) ) return false;
> 51 at = at->right;
> 52 }
> 53 return true;
> 54 }
> 55
> 56 /**
> 57 A helper routine for MyList_deserialize().
> 58 */
> 59 static bool MyList_deserialize_one( c11n_node const * src, MyList * dest )
> 60 {
> 61 return (2 == c11n_node_prop_get_fe( src, "xy", "%d %d", &dest->x, &dest->y ));
> 62 }
> 63
> 64 /**
> 65 The invert of MyList_serialize, it requires that src be-a pointer
> 66 to a non-null (but empty!) MyList object. It tries to deserialize a
> 67 list of MyList objects from src. If successful then the head of that list
> 68 is copied over dest, effectively transfering ownership of all list entries
> 69 to dest. On error dest is not modified.
> 70 */
> 71 static bool MyList_deserialize( struct c11n_marshaller const * self, c11n_node const *src, void * dest )
> 72 {
> 73 if( ! self || !src || !dest ) return false;
> 74 c11n_node const * nitems = c11n_node_children_search_c( src, c11n_node_predicate_name_is, "items" );
> 75 if( ! nitems ) return 0;
> 76 c11n_node_iter_c iter = c11n_node_children_iter_c(nitems);
> 77 MyList * current = 0;
> 78 MyList * head = 0;
> 79 bool isokay = true;
> 80 while( c11n_node_iter_isvalid_c( &iter ) )
> 81 {
> 82 MyList * ml = (MyList*) self->api->create(self);
> 83 MARKER("Deserializing MyList item @%p...\n",(void const *)ml);
> 84 isokay = (ml && MyList_deserialize_one( iter.node, ml ));
> 85 if( ! head )
> 86 {
> 87 current = head = ml;
> 88 }
> 89 else if(ml)
> 90 {
> 91 current->right = ml;
> 92 ml->left = current;
> 93 current = ml;
> 94 }
> 95 if( ! isokay )
> 96 {
> 97 if( head )
> 98 {
> 99 self->api->destroy(self,head);
> 100 }
> 101 return false;
> 102 }
> 103 c11n_node_iter_next_c(&iter);
> 104 }
> 105 if( 0 != head )
> 106 {
> 107 MyList * me = (MyList *)dest;
> 108 *me = *head;
> 109 free(head);
> 110 return true;
> 111 }
> 112 else return false;
> 113 }
> 114
> 115 /**
> 116 Creates a single MyList item with all values inited to 0.
> 117 */
> 118 static void * MyList_create( struct c11n_marshaller const * self)
> 119 {
> 120 static MyList MyList_init = {0,0,0,0};
> 121 MyList * x = (MyList*) malloc(sizeof(MyList));
> 122 if( x ) *x = MyList_init;
> 123 return x;
> 124 }
> 125
> 126 /**
> 127 Sets all values of ALL neighboring items to 0. Does not actually
> 128 free any items. This isn't a useful practical implementation, but
> 129 it's useful for demonstration purposes.
> 130 */
> 131 static void MyList_clear( struct c11n_marshaller const * self, void * obj )
> 132 {
> 133 if( !obj ) return;
> 134 MARKER("Clearing MyList values.\n");
> 135 MyList * h = (MyList*) obj;
> 136 while( h->left ) h = h->left;
> 137 while( h )
> 138 {
> 139 h->x = h->y = 0;
> 140 h = h->right;
> 141 }
> 142 }
> 143
> 144 /**
> 145 Deallocates ALL neighboring items.
> 146 */
> 147 static void MyList_destroy( struct c11n_marshaller const * self, void * obj )
> 148 {
> 149 if( !obj ) return;
> 150 MARKER("Destroying MyList list.\n");
> 151 //MyList_clear( self, obj ); /* If MyList_clear() was responsible for freeing any memory we would need to call it here. */
> 152 MyList * h = (MyList*) obj;
> 153 while( h->left ) h = h->left;
> 154 while( h )
> 155 {
> 156 MyList * x = h->right;
> 157 free(h);
> 158 h = x;
> 159 }
> 160 }
> 161
> 162 static const c11n_marshaller_api c11n_markshaller_api_MyList =
> 163 C11N_MARSHALLER_API_INIT("MyList",
> 164 MyList_serialize,
> 165 MyList_deserialize,
> 166 MyList_create,
> 167 MyList_clear,
> 168 MyList_destroy);
> 169
> 170 static const c11n_marshaller MyList_c11nX = { &c11n_markshaller_api_MyList };
> 171 const c11n_marshaller * MyList_c11n = &MyList_c11nX;

Added src/MyList.h

Old () New (98969ba5402a4946)
> 1 /* example class for use with libc11n */
> 2 #include "s11n.net/c11n/c11n.h"
> 3 struct MyList
> 4 {
> 5 int x;
> 6 int y;
> 7 struct MyList * left;
> 8 struct MyList * right;
> 9 };
> 10 typedef struct MyList MyList;
> 11 /**
> 12 c11n marshaller for MyList objects.
> 13 */
> 14 extern const c11n_marshaller * MyList_c11n;

Changes to src/c11n_io.c

Old (0ffdba378af16ac7) New (fd8c564e1eb5cf41)
1 #ifndef _FILE_OFFSET_BITS 1 #ifndef _FILE_OFFSET_BITS
2 /** See 'man feature_test_macros' on a gcc system */ 2 /** See 'man feature_test_macros' on a gcc system */
3 # define _FILE_OFFSET_BITS 64 3 # define _FILE_OFFSET_BITS 64
4 #endif 4 #endif
5 #ifndef _ISOC99_SOURCE 5 #ifndef _ISOC99_SOURCE
330 hidden lines
336 h->api->destroy(h); 336 h->api->destroy(h);
337 } 337 }
338 return n; 338 return n;
339 } 339 }
340 340
341 bool c11n_save_node( c11n_node const * src, c11n_stream * dest, c11n_io_handler * h ) | 341 bool c11n_save_node( c11n_stream * dest, c11n_node const * src, c11n_io_handler * h )
342 { 342 {
343 bool ownHandler = (h==0); 343 bool ownHandler = (h==0);
344 if( ! src || !dest || !dest->api->isgood(dest) ) return false; 344 if( ! src || !dest || !dest->api->isgood(dest) ) return false;
345 if( ! h ) 345 if( ! h )
346 { 346 {
6 hidden lines
353 if( ownHandler ) h->api->destroy(h); 353 if( ownHandler ) h->api->destroy(h);
354 } 354 }
355 return rc; 355 return rc;
356 } 356 }
357 357
358 bool c11n_save_serializable( c11n_marshaller const * marshaller, void const * src, c11n_stream * dest, c11n_io_handler * h ) | 358 bool c11n_save_serializable( c11n_stream * dest, c11n_marshaller const * marshaller, void const * src, c11n_io_handler * h )
359 { 359 {
360 c11n_node * n = c11n_node_create("c11n_root_node"); 360 c11n_node * n = c11n_node_create("c11n_root_node");
361 bool rc = (n!=0); 361 bool rc = (n!=0);
362 if( rc ) 362 if( rc )
363 { 363 {
364 rc = c11n_serialize( n, marshaller, src ) 364 rc = c11n_serialize( n, marshaller, src )
365 && c11n_save_node( n, dest, h ); | 365 && c11n_save_node( dest, n, h );
366 c11n_node_destroy(n); 366 c11n_node_destroy(n);
367 } 367 }
368 return rc; 368 return rc;
369 } 369 }
370 370
94 hidden lines
465 } 465 }
466 466
467 #ifdef __cplusplus 467 #ifdef __cplusplus
468 } /* extern "C" */ 468 } /* extern "C" */
469 #endif 469 #endif

Changes to src/test.c

Old (caa3355a092dd802) New (4730a67623abf384)
1 #include <stdio.h> 1 #include <stdio.h>
2 #include <stdlib.h> 2 #include <stdlib.h>
3 #include <string.h> 3 #include <string.h>
4 #include <ctype.h> 4 #include <ctype.h>
5 #include <assert.h> 5 #include <assert.h>
193 hidden lines
199 else 199 else
200 { 200 {
201 c11n_node * de = c11n_node_create( "deserialized" ); 201 c11n_node * de = c11n_node_create( "deserialized" );
202 c11n_serialize( de, TR, my2 ); 202 c11n_serialize( de, TR, my2 );
203 MARKER("c11n_deserialize_new() got:\n"); 203 MARKER("c11n_deserialize_new() got:\n");
204 c11n_save_node( de, ThisApp.cout, 0 ); | 204 c11n_save_node( ThisApp.cout, de, 0 );
205 c11n_node_destroy(de); 205 c11n_node_destroy(de);
206 TR->api->destroy(TR,my2); 206 TR->api->destroy(TR,my2);
207 } 207 }
208 my2 = c11n_clone( TR, &yourMyVal ); 208 my2 = c11n_clone( TR, &yourMyVal );
209 if( ! my2 ) 209 if( ! my2 )
5 hidden lines
215 else 215 else
216 { 216 {
217 c11n_node * de = c11n_node_create( "cloned" ); 217 c11n_node * de = c11n_node_create( "cloned" );
218 c11n_serialize( de, TR, my2 ); 218 c11n_serialize( de, TR, my2 );
219 MARKER("c11n_clone_new() got:\n"); 219 MARKER("c11n_clone_new() got:\n");
220 c11n_save_node( de, ThisApp.cout, 0 ); | 220 c11n_save_node( ThisApp.cout, de, 0 );
221 c11n_node_destroy(de); 221 c11n_node_destroy(de);
222 TR->api->destroy(TR,my2); 222 TR->api->destroy(TR,my2);
223 } 223 }
224 224
225 TR->api->clear( TR, &yourMyVal ); 225 TR->api->clear( TR, &yourMyVal );
227 #endif 227 #endif
228 228
229 //c11n_dump_node( N, true ); 229 //c11n_dump_node( N, true );
230 230
231 c11n_stream * o1t = c11n_stream_for_FILE( stdout ); 231 c11n_stream * o1t = c11n_stream_for_FILE( stdout );
232 if( ! c11n_save_node( N, o1t, 0 ) || !c11n_save_node( MY, o1t, 0 )) | 232 if( ! c11n_save_node( o1t, N, 0 ) || !c11n_save_node( o1t, MY, 0 ))
233 { 233 {
234 MARKER("test save failed\n"); 234 MARKER("test save failed\n");
235 o1t->api->destroy(o1t); 235 o1t->api->destroy(o1t);
236 c11n_node_destroy(N); 236 c11n_node_destroy(N);
237 return 22; 237 return 22;
132 hidden lines
370 bob.close_node( &bob ); 370 bob.close_node( &bob );
371 SHOW; 371 SHOW;
372 char const * ofile = "saveload.out"; 372 char const * ofile = "saveload.out";
373 c11n_stream * ostr = c11n_stream_for_filename( ofile, true ); 373 c11n_stream * ostr = c11n_stream_for_filename( ofile, true );
374 MARKER("ostr @%p, implData @%p\n",ostr,ostr->implData); 374 MARKER("ostr @%p, implData @%p\n",ostr,ostr->implData);
375 bool rv = c11n_save_node( bob.root_node, ostr, 0 ); | 375 bool rv = c11n_save_node( ostr, bob.root_node, 0 );
376 ostr->api->destroy(ostr); 376 ostr->api->destroy(ostr);
377 #if 1 377 #if 1
378 if( ! rv ) 378 if( ! rv )
379 { 379 {
380 MARKER("Save of %s failed :(\n",ofile); 380 MARKER("Save of %s failed :(\n",ofile);
381 bob.clear(&bob); 381 bob.clear(&bob);
382 return -1; 382 return -1;
383 } 383 }
384 c11n_save_node( bob.root_node, ThisApp.cout, 0 ); | 384 c11n_save_node( ThisApp.cout, bob.root_node, 0 );
385 bob.clear(&bob); 385 bob.clear(&bob);
386 ostr = c11n_stream_for_filename( ofile, false ); 386 ostr = c11n_stream_for_filename( ofile, false );
387 c11n_node * x = c11n_load_node( ostr ); // 387 c11n_node * x = c11n_load_node( ostr ); //
388 ostr->api->destroy(ostr); 388 ostr->api->destroy(ostr);
389 MARKER("x=%p\n",x); 389 MARKER("x=%p\n",x);
390 if( x ) 390 if( x )
391 { 391 {
392 MARKER("Loaded x @%p from file %s.\n",x,ofile); 392 MARKER("Loaded x @%p from file %s.\n",x,ofile);
393 c11n_save_node( x, ThisApp.cout, 0 ); | 393 c11n_save_node( ThisApp.cout, x, 0 );
394 c11n_node_destroy(x); 394 c11n_node_destroy(x);
395 MARKER("(end of loaded data)\n"); 395 MARKER("(end of loaded data)\n");
396 } 396 }
397 else 397 else
398 { 398 {
68 hidden lines
467 { 467 {
468 MARKER("serialize binary failed!\n"); 468 MARKER("serialize binary failed!\n");
469 c11n_node_destroy( n ); 469 c11n_node_destroy( n );
470 return 1; 470 return 1;
471 } 471 }
472 c11n_save_node( n, ThisApp.cout, 0 ); | 472 c11n_save_node( ThisApp.cout, n, 0 );
473 473
474 MyType my2; 474 MyType my2;
475 c11n_binary_data bin; 475 c11n_binary_data bin;
476 if( ! c11n_deserialize_binary( n, &bin ) ) 476 if( ! c11n_deserialize_binary( n, &bin ) )
477 { 477 {
67 hidden lines
545 c11n_node_destroy(de); 545 c11n_node_destroy(de);
546 return rc; 546 return rc;
547 } 547 }
548 #endif // C11N_IO_USE_SQL 548 #endif // C11N_IO_USE_SQL
549 549
> 550 #include "MyList.h"
> 551 int test_list()
> 552 {
> 553 MARKER("Testing MyList...\n");
> 554 #define NEW MyList_c11n->api->create(MyList_c11n)
> 555 MyList * head = NEW;
> 556 head->right = NEW;
> 557 head->right->left = head;
> 558 head->right->right = NEW;
> 559 head->right->right->left = head->right;
> 560 #undef NEW
> 561
> 562 head->x = 1;
> 563 head->y = -1;
> 564 head->right->x = 2;
> 565 head->right->y = -2;
> 566 head->right->right->x = 3;
> 567 head->right->right->y = -3;
> 568
> 569
> 570 char const * filename = "MyList.c11n";
> 571 c11n_stream * str = c11n_stream_for_filename( filename, true );
> 572 c11n_io_handler * h = c11n_io_handler_by_name( "expat" );
> 573 c11n_save_serializable( str, MyList_c11n, head, h );
> 574 str->api->destroy(str);
> 575 str = c11n_stream_for_filename( filename, false );
> 576 c11n_node * n = c11n_load_node( str );
> 577 str->api->destroy(str);
> 578 assert( n && "Load node failed :(");
> 579 MARKER("Loaded MyList node tree:\n");
> 580 c11n_save_node( ThisApp.cout, n, 0 );
> 581
> 582 MyList_c11n->api->destroy(MyList_c11n,head);
> 583 head = 0;
> 584 head = c11n_deserialize_new( n, MyList_c11n );
> 585 c11n_node_destroy(n);
> 586 assert(head && "deserialize failed :(");
> 587 MARKER("Deserialized MyList list:\n");
> 588 c11n_save_serializable( ThisApp.cout, MyList_c11n, head, h );
> 589 MyList * clone = c11n_clone( MyList_c11n, head );
> 590 MyList_c11n->api->destroy(MyList_c11n,head);
> 591 assert( clone && "Cloning failed :(" );
> 592 MARKER("Cloned MyList:\n");
> 593 c11n_save_serializable( ThisApp.cout, MyList_c11n, clone, h );
> 594 MyList_c11n->api->destroy( MyList_c11n, clone );
> 595 if( h ) h->api->destroy(h);
> 596 MARKER("Done testing MyList.\n");
> 597 return 0;
> 598 }
550 599
551 int main( int argc, char ** argv ) 600 int main( int argc, char ** argv )
552 { 601 {
553 //memblob_set_default_alloc_policy( my_memblob_alloc_policy ); 602 //memblob_set_default_alloc_policy( my_memblob_alloc_policy );
554 ThisApp.gc = whgc_create_context(&ThisApp); 603 ThisApp.gc = whgc_create_context(&ThisApp);
12 hidden lines
567 DO(test_otherstuff()); 616 DO(test_otherstuff());
568 #if C11N_IO_USE_SQL 617 #if C11N_IO_USE_SQL
569 DO(test_sql()); 618 DO(test_sql());
570 #endif 619 #endif
571 DO(test_binary()); 620 DO(test_binary());
> 621 DO(test_list());
572 #undef DO 622 #undef DO
573 printf("Done - cleaning up. rc=%d=[%s].\n",rc, 623 printf("Done - cleaning up. rc=%d=[%s].\n",rc,
574 (0==rc) 624 (0==rc)
575 ? "You win :)" 625 ? "You win :)"
576 : "You lose :("); 626 : "You lose :(");
577 ThisApp.cout->api->destroy(ThisApp.cout); 627 ThisApp.cout->api->destroy(ThisApp.cout);
578 whgc_destroy_context(ThisApp.gc); 628 whgc_destroy_context(ThisApp.gc);
579 return rc; 629 return rc;
580 } 630 }