1414 along with WJElement. If not, see <http://www.gnu.org/licenses/>.
1515*/
1616
17-
1817#include "element.h"
1918#include <time.h>
2019
@@ -63,13 +62,12 @@ _WJElement * _WJENew(_WJElement *parent, char *name, size_t len, const char *fil
6362 if (!parent -> pub .child ) {
6463 parent -> pub .child = (WJElement ) result ;
6564 } else {
66- /* Find the last child so it can be added at the end */
67- for (prev = parent -> pub .child ; prev && prev -> next ; prev = prev -> next );
68-
65+ prev = parent -> pub .last ;
6966 prev -> next = (WJElement ) result ;
7067 result -> pub .prev = prev ;
7168 }
7269
70+ parent -> pub .last = (WJElement ) result ;
7371 parent -> pub .count ++ ;
7472 }
7573
@@ -115,6 +113,9 @@ EXPORT XplBool _WJEDetach(WJElement document, const char *file, const int line)
115113 if (document -> parent -> child == document ) {
116114 document -> parent -> child = document -> next ;
117115 }
116+ if (document -> parent -> last == document ) {
117+ document -> parent -> last = document -> prev ;
118+ }
118119 document -> parent -> count -- ;
119120 document -> parent = NULL ;
120121 }
@@ -141,6 +142,10 @@ EXPORT XplBool WJEAttach(WJElement container, WJElement document)
141142 return (FALSE);
142143 }
143144
145+ if (document -> parent == container ) {
146+ return (TRUE);
147+ }
148+
144149 if (document -> name ) {
145150 while ((prev = WJEChild (container , document -> name , WJE_GET ))) {
146151 WJEDetach (prev );
@@ -155,12 +160,11 @@ EXPORT XplBool WJEAttach(WJElement container, WJElement document)
155160 if (!container -> child ) {
156161 container -> child = document ;
157162 } else {
158- /* Find the last child so it can be added at the end */
159- for (prev = container -> child ; prev && prev -> next ; prev = prev -> next );
160-
163+ prev = container -> last ;
161164 prev -> next = document ;
162165 document -> prev = prev ;
163166 }
167+ container -> last = document ;
164168 container -> count ++ ;
165169 WJEChanged (container );
166170
@@ -307,6 +311,17 @@ static WJElement _WJELoad(_WJElement *parent, WJReader reader, char *where, WJEL
307311 return ((WJElement ) l );
308312}
309313
314+ EXPORT WJElement _WJEOpenDocument (WJReader reader , char * where , WJELoadCB loadcb , void * data , const char * file , const int line )
315+ {
316+ WJElement element ;
317+
318+ if ((element = _WJELoad (NULL , reader , where , loadcb , data , file , line ))) {
319+ MemUpdateOwner (element , file , line );
320+ }
321+
322+ return (element );
323+ }
324+
310325typedef struct WJEMemArgs
311326{
312327 char * json ;
@@ -315,7 +330,7 @@ typedef struct WJEMemArgs
315330 size_t len ;
316331} WJEMemArgs ;
317332
318- EXPORT size_t WJEMemCallback (char * buffer , size_t length , size_t seen , void * userdata )
333+ static size_t WJEMemCallback (char * buffer , size_t length , size_t seen , void * userdata )
319334{
320335 WJEMemArgs * args = (WJEMemArgs * ) userdata ;
321336 char * json ;
@@ -371,7 +386,7 @@ EXPORT size_t WJEMemCallback(char *buffer, size_t length, size_t seen, void *use
371386 and allows parsing documents with a non standard quote char for the sake of
372387 embedding documents directly in C code.
373388*/
374- EXPORT WJElement _WJEParse (const char * json , char quote )
389+ EXPORT WJElement __WJEFromString (const char * json , char quote , const char * file , const int line )
375390{
376391 WJElement doc ;
377392 WJEMemArgs args ;
@@ -385,24 +400,13 @@ EXPORT WJElement _WJEParse(const char *json, char quote)
385400 }
386401
387402 if (json && (reader = WJROpenDocument (WJEMemCallback , & args , NULL , 0 ))) {
388- doc = WJEOpenDocument (reader , NULL , NULL , NULL );
403+ doc = _WJEOpenDocument (reader , NULL , NULL , NULL , file , line );
389404 WJRCloseDocument (reader );
390405 }
391406
392407 return (doc );
393408}
394409
395- EXPORT WJElement _WJEOpenDocument (WJReader reader , char * where , WJELoadCB loadcb , void * data , const char * file , const int line )
396- {
397- WJElement element ;
398-
399- if ((element = _WJELoad (NULL , reader , where , loadcb , data , file , line ))) {
400- MemUpdateOwner (element , file , line );
401- }
402-
403- return (element );
404- }
405-
406410EXPORT char * _WJEToString (WJElement document , XplBool pretty , const char * file , const int line )
407411{
408412 WJWriter writer ;
@@ -656,7 +660,7 @@ EXPORT XplBool _WJEWriteDocument(WJElement document, WJWriter writer, char *name
656660 return (TRUE);
657661}
658662
659- EXPORT XplBool WJECloseDocument (WJElement document )
663+ EXPORT XplBool _WJECloseDocument (WJElement document , const char * file , const int line )
660664{
661665 _WJElement * current = (_WJElement * ) document ;
662666 WJElement child ;
@@ -697,26 +701,26 @@ EXPORT XplBool WJECloseDocument(WJElement document)
697701 /* Destroy all children */
698702 while ((child = document -> child )) {
699703 WJEDetach (child );
700- WJECloseDocument (child );
704+ _WJECloseDocument (child , file , line );
701705 }
702706
703707 if (current -> pub .type == WJR_TYPE_STRING ) {
704- MemFree (current -> value .string );
708+ MemFreeEx (current -> value .string , file , line );
705709 current -> pub .length = 0 ;
706710 }
707711
708712 if (document -> name && current -> _name != document -> name ) {
709- MemRelease (& document -> name );
713+ MemReleaseEx (& document -> name , file , line );
710714 }
711715
712- MemFree (current );
716+ MemFreeEx (current , file , line );
713717
714718 return (TRUE);
715719}
716720
717721EXPORT void WJEDump (WJElement document )
718722{
719- WJEWriteFILE (document , stdout );
723+ WJEWriteFILE (document , stdout );
720724}
721725
722726EXPORT void WJEWriteFILE (WJElement document , FILE * fd )
@@ -728,6 +732,7 @@ EXPORT void WJEWriteFILE(WJElement document, FILE* fd)
728732 WJWCloseDocument (dumpWriter );
729733 }
730734 fprintf (fd , "\n" );
735+ fflush (fd );
731736}
732737
733738EXPORT void WJEDumpFile (WJElement document )
@@ -750,47 +755,26 @@ EXPORT void WJEDumpFile(WJElement document)
750755 }
751756}
752757
753- typedef struct _MemWriterData {
754- size_t maxlength ;
755- size_t length ;
756- char * buffer ;
757- } _MemWriterData ;
758- static size_t MemWriteCB (char * data , size_t size , void * writedata ) {
759- size_t write ;
760- _MemWriterData * w = (_MemWriterData * )writedata ;
761- if (w -> maxlength ) {
762- write = w -> maxlength - strlen (w -> buffer ) - 1 ;
763- } else {
764- if (size > w -> length - strlen (w -> buffer )) {
765- w -> length += 4096 ;
766- w -> buffer = MemReallocWait (w -> buffer , w -> length );
767- }
768- write = size ;
769- }
770- if (size < write ) {
771- write = size ;
772- }
773- if (w -> buffer ) {
774- strncat (w -> buffer , data , write );
758+ static size_t fileReaderCB ( char * data , size_t length , size_t seen , void * client )
759+ {
760+ DebugAssert (length );
761+ DebugAssert (data );
762+ if (!data ) {
763+ return 0 ;
775764 }
776- return size ;
765+ return fread ( data , 1 , length , client ) ;
777766}
778767
779- EXPORT char * WJEWriteMEM ( WJElement document , XplBool pretty , size_t maxlength )
768+ EXPORT WJElement WJEReadFILE ( FILE * fd )
780769{
781- WJWriter memWriter ;
782- _MemWriterData data ;
783-
784- data .length = 0 ;
785- data .maxlength = maxlength ;
786- data .buffer = MemMalloc (maxlength );
787- if (data .buffer ) {
788- * data .buffer = '\0' ;
789- }
770+ WJReader reader ;
771+ WJElement obj = NULL ;
790772
791- if ((memWriter = _WJWOpenDocument ( pretty , MemWriteCB , & data , maxlength ))) {
792- WJEWriteDocument ( document , memWriter , NULL );
793- WJWCloseDocument ( memWriter );
773+ if ((reader = WJROpenDocument ( fileReaderCB , fd , NULL , 0 ))) {
774+ obj = WJEOpenDocument ( reader , NULL , NULL , NULL );
775+ WJRCloseDocument ( reader );
794776 }
795- return MemRealloc ( data . buffer , strlen ( data . buffer ) + 1 ) ;
777+ return obj ;
796778}
779+
780+
0 commit comments