|
@@ -73,6 +73,7 @@ typedef struct
|
73
|
73
|
char* serialBufPtr; // serial buffer pointer
|
74
|
74
|
unsigned serialByteCnt; // count of bytes in serialBuf[]
|
75
|
75
|
bool reportErrPosnFl;// report the file posn of syntax errors
|
|
76
|
+ bool modifiedFl; // the tree has been modified since it was created.
|
76
|
77
|
} cmJs_t;
|
77
|
78
|
|
78
|
79
|
cmJsToken_t _cmJsTokenArray[] =
|
|
@@ -318,9 +319,15 @@ cmJsRC_t cmJsonFinalize( cmJsonH_t* hp )
|
318
|
319
|
|
319
|
320
|
|
320
|
321
|
|
321
|
|
-bool cmJsonIsValid( cmJsonH_t h )
|
|
322
|
+bool cmJsonIsValid( cmJsonH_t h )
|
322
|
323
|
{ return h.h != NULL; }
|
323
|
324
|
|
|
325
|
+bool cmJsonIsModified( cmJsonH_t h )
|
|
326
|
+{
|
|
327
|
+ cmJs_t* p = _cmJsonHandleToPtr(h);
|
|
328
|
+ return p->modifiedFl;
|
|
329
|
+}
|
|
330
|
+
|
324
|
331
|
cmJsRC_t _cmJsonLinkInChild( cmJs_t* p, cmJsonNode_t* parentPtr, cmJsonNode_t* np )
|
325
|
332
|
{
|
326
|
333
|
cmJsRC_t rc = kOkJsRC;
|
|
@@ -431,6 +438,9 @@ cmJsRC_t _cmJsonCreateNode( cmJs_t* p, cmJsonNode_t* parentPtr, unsigned newNode
|
431
|
438
|
|
432
|
439
|
p->rootPtr = np;
|
433
|
440
|
}
|
|
441
|
+
|
|
442
|
+ p->modifiedFl = true;
|
|
443
|
+
|
434
|
444
|
return rc;
|
435
|
445
|
}
|
436
|
446
|
|
|
@@ -814,6 +824,7 @@ cmJsRC_t _cmJsonParse(cmJsonH_t h, const char* buf, unsigned bufCharCnt, const c
|
814
|
824
|
rc = _cmJsonSyntaxError( p, "The lexer failed: %s.", cmLexRcToMsg(cmLexErrorRC(p->lexH)));
|
815
|
825
|
|
816
|
826
|
p->reportErrPosnFl = false;
|
|
827
|
+ p->modifiedFl = false;
|
817
|
828
|
|
818
|
829
|
return rc;
|
819
|
830
|
}
|
|
@@ -824,75 +835,6 @@ cmJsRC_t cmJsonParse( cmJsonH_t h, const char* buf, unsigned bufCharCn
|
824
|
835
|
cmJsRC_t cmJsonParseFile( cmJsonH_t h, const char* fn, cmJsonNode_t* altRootPtr )
|
825
|
836
|
{ return _cmJsonParse(h,NULL,0,fn,altRootPtr); }
|
826
|
837
|
|
827
|
|
-/*
|
828
|
|
-cmJsRC_t cmJsonParseFile( cmJsonH_t h, const char* fn )
|
829
|
|
-{
|
830
|
|
- cmJsRC_t rc = kOkJsRC;
|
831
|
|
- FILE* fp = NULL;
|
832
|
|
- cmJs_t* p = _cmJsonHandleToPtr(h);
|
833
|
|
- unsigned n = 0;
|
834
|
|
- char* textBuf = NULL;
|
835
|
|
-
|
836
|
|
- assert( fn != NULL && p != NULL );
|
837
|
|
-
|
838
|
|
- // open the file
|
839
|
|
- if((fp = fopen(fn,"rb")) == NULL )
|
840
|
|
- return _cmJsonError(p,kFileOpenErrJsRC,"Unable to open the file:'%s'.",fn);
|
841
|
|
-
|
842
|
|
- // seek to the end
|
843
|
|
- if( fseek(fp,0,SEEK_END) != 0 )
|
844
|
|
- {
|
845
|
|
- rc= _cmJsonError(p,kFileSeekErrJsRC,"Unable to seek to the end of '%s'.",fn);
|
846
|
|
- goto errLabel;
|
847
|
|
- }
|
848
|
|
-
|
849
|
|
- // get the length of the file
|
850
|
|
- if( (n=ftell(fp)) == 0 )
|
851
|
|
- {
|
852
|
|
- rc = _cmJsonError(p,kFileOpenErrJsRC,"The file '%s' appears to be empty.",fn);
|
853
|
|
- goto errLabel;
|
854
|
|
- }
|
855
|
|
-
|
856
|
|
- // rewind the file
|
857
|
|
- if( fseek(fp,0,SEEK_SET) != 0 )
|
858
|
|
- {
|
859
|
|
- rc = _cmJsonError(p,kFileSeekErrJsRC,"Unable to seek to the beginning of '%s'.",fn);
|
860
|
|
- goto errLabel;
|
861
|
|
- }
|
862
|
|
-
|
863
|
|
- // allocate the text buffer
|
864
|
|
- if((textBuf = cmMemAllocZ( char, n+1)) == NULL )
|
865
|
|
- {
|
866
|
|
- rc = _cmJsonError(p,kMemAllocErrJsRC,"Unable to allocate the text file buffer for:'%s'.",fn);
|
867
|
|
- goto errLabel;
|
868
|
|
- }
|
869
|
|
-
|
870
|
|
- // read the file into the text buffer
|
871
|
|
- if( fread(textBuf,n,1,fp) != 1 )
|
872
|
|
- {
|
873
|
|
- rc = _cmJsonError(p,kFileReadErrJsRC,"File read failed on:'%s'.",fn);
|
874
|
|
- goto errLabel;
|
875
|
|
- }
|
876
|
|
-
|
877
|
|
- rc = cmJsonParse(h,textBuf,n,NULL);
|
878
|
|
-
|
879
|
|
- errLabel:
|
880
|
|
-
|
881
|
|
- // close the file
|
882
|
|
- if( fclose(fp) != 0 )
|
883
|
|
- {
|
884
|
|
- rc = _cmJsonError(p,kFileCloseErrJsRC,"File close failed on:'%s'.",fn);
|
885
|
|
- goto errLabel;
|
886
|
|
- }
|
887
|
|
-
|
888
|
|
- // free the buffer
|
889
|
|
- if( textBuf != NULL )
|
890
|
|
- cmMemFree(textBuf);
|
891
|
|
-
|
892
|
|
- return rc;
|
893
|
|
-}
|
894
|
|
-*/
|
895
|
|
-
|
896
|
838
|
cmJsonNode_t* cmJsonRoot( cmJsonH_t h )
|
897
|
839
|
{
|
898
|
840
|
cmJs_t* p = _cmJsonHandleToPtr(h);
|
|
@@ -1938,31 +1880,43 @@ cmJsRC_t cmJsonCreateBoolArray( cmJsonH_t h, cmJsonNode_t* parentPtr, uns
|
1938
|
1880
|
|
1939
|
1881
|
cmJsRC_t cmJsonSetInt( cmJsonH_t h, cmJsonNode_t* np, int ival )
|
1940
|
1882
|
{
|
|
1883
|
+ cmJs_t* p = _cmJsonHandleToPtr(h);
|
|
1884
|
+
|
1941
|
1885
|
if( np->typeId != kIntTId )
|
1942
|
|
- return _cmJsonError(_cmJsonHandleToPtr(h),kInvalidNodeTypeJsRC,"Cannot assign type 'int' to node type '%s'.",_cmJsonNodeTypeIdToLabel(np->typeId));
|
|
1886
|
+ return _cmJsonError(p,kInvalidNodeTypeJsRC,"Cannot assign type 'int' to node type '%s'.",_cmJsonNodeTypeIdToLabel(np->typeId));
|
1943
|
1887
|
|
1944
|
1888
|
np->u.intVal = ival;
|
1945
|
1889
|
|
|
1890
|
+ p->modifiedFl = true;
|
|
1891
|
+
|
1946
|
1892
|
return kOkJsRC;
|
1947
|
1893
|
}
|
1948
|
1894
|
|
1949
|
1895
|
cmJsRC_t cmJsonSetReal( cmJsonH_t h, cmJsonNode_t * np, double rval )
|
1950
|
1896
|
{
|
|
1897
|
+ cmJs_t* p = _cmJsonHandleToPtr(h);
|
|
1898
|
+
|
1951
|
1899
|
if( np->typeId != kRealTId )
|
1952
|
|
- return _cmJsonError(_cmJsonHandleToPtr(h),kInvalidNodeTypeJsRC,"Cannot assign type 'real' to node type '%s'.",_cmJsonNodeTypeIdToLabel(np->typeId));
|
|
1900
|
+ return _cmJsonError(p,kInvalidNodeTypeJsRC,"Cannot assign type 'real' to node type '%s'.",_cmJsonNodeTypeIdToLabel(np->typeId));
|
1953
|
1901
|
|
1954
|
1902
|
np->u.realVal = rval;
|
1955
|
1903
|
|
|
1904
|
+ p->modifiedFl = true;
|
|
1905
|
+
|
1956
|
1906
|
return kOkJsRC;
|
1957
|
1907
|
}
|
1958
|
1908
|
|
1959
|
1909
|
cmJsRC_t cmJsonSetBool( cmJsonH_t h, cmJsonNode_t * np, bool bval )
|
1960
|
1910
|
{
|
|
1911
|
+ cmJs_t* p = _cmJsonHandleToPtr(h);
|
|
1912
|
+
|
1961
|
1913
|
if( np->typeId == kTrueTId || np->typeId==kFalseTId )
|
1962
|
|
- return _cmJsonError(_cmJsonHandleToPtr(h),kInvalidNodeTypeJsRC,"Cannot assign type 'bool' to node type '%s'.",_cmJsonNodeTypeIdToLabel(np->typeId));
|
|
1914
|
+ return _cmJsonError(p,kInvalidNodeTypeJsRC,"Cannot assign type 'bool' to node type '%s'.",_cmJsonNodeTypeIdToLabel(np->typeId));
|
1963
|
1915
|
|
1964
|
1916
|
np->u.boolVal = bval;
|
1965
|
1917
|
|
|
1918
|
+ p->modifiedFl = true;
|
|
1919
|
+
|
1966
|
1920
|
return kOkJsRC;
|
1967
|
1921
|
}
|
1968
|
1922
|
|
|
@@ -1980,6 +1934,8 @@ cmJsRC_t cmJsonSetString( cmJsonH_t h, cmJsonNode_t* np, const char* sval )
|
1980
|
1934
|
else
|
1981
|
1935
|
return _cmJsonSetString(p,np,sval,sn);
|
1982
|
1936
|
|
|
1937
|
+ p->modifiedFl = true;
|
|
1938
|
+
|
1983
|
1939
|
return kOkJsRC;
|
1984
|
1940
|
}
|
1985
|
1941
|
|
|
@@ -2331,9 +2287,13 @@ cmJsRC_t _cmJsonInsertOrReplacePair( cmJsonH_t h, cmJsonNode_t* objectNodePtr,
|
2331
|
2287
|
errLabel:
|
2332
|
2288
|
|
2333
|
2289
|
if( rc == kOkJsRC )
|
|
2290
|
+ {
|
2334
|
2291
|
if( retNodePtrPtr != NULL )
|
2335
|
2292
|
*retNodePtrPtr = pairNodePtr;
|
2336
|
2293
|
|
|
2294
|
+ p->modifiedFl = true;
|
|
2295
|
+
|
|
2296
|
+ }
|
2337
|
2297
|
return rc;
|
2338
|
2298
|
}
|
2339
|
2299
|
|
|
@@ -2632,6 +2592,8 @@ cmJsRC_t _cmJsonRemoveNode( cmJs_t* p, cmJsonNode_t* np, bool freeFl, bool balan
|
2632
|
2592
|
*/
|
2633
|
2593
|
}
|
2634
|
2594
|
|
|
2595
|
+ p->modifiedFl = true;
|
|
2596
|
+
|
2635
|
2597
|
return kOkJsRC;
|
2636
|
2598
|
}
|
2637
|
2599
|
|