Major Update:
- Update printing: Do not use '\n' if indent = 0
- Implement refilling of buffer (from fd) while parsing
- No longer use LineMark, but keep track of char position with CharNo
- Use Mark to reference point for shifting buffer on refill
- SkipWhiteSpace no longer inline method
- Refill buffer if required, change Mark & CharNo on line break
- CreateBuffer(), RefillBuffer() & FreeBuffer() now public methods
- Make Loading and Saving more flexible:
- Refactor from LoadFromFile():
ReadFromFile(), ReadFromHandle(), ReadFromBuffer()
- Refactor from SaveToFile() & PrintToScreen:
WriteToFile(), WriteToScreen, WriteToHandle()
This commit is contained in:
@@ -688,16 +688,16 @@ int CShiftBuffer::Clear( int ClearLen )
|
||||
if ((ClearLen == -1) || (ClearLen >= BufLen))
|
||||
{
|
||||
// Clear all data
|
||||
BytesCleared = BufLen;
|
||||
BufLen = 0;
|
||||
Buffer[0] = 0;
|
||||
BytesCleared = BufLen;
|
||||
}
|
||||
else {
|
||||
// Shift remaining data
|
||||
BytesCleared = ClearLen;
|
||||
memmove( Buffer, &Buffer[ClearLen], BufLen-ClearLen ); // Shift remaining old data left
|
||||
BufLen -= ClearLen;
|
||||
Buffer[BufLen] = 0;
|
||||
BytesCleared = ClearLen;
|
||||
}
|
||||
|
||||
return BytesCleared;
|
||||
|
||||
@@ -27,12 +27,13 @@ CJSONparse::CJSONparse( CDataTree * pDataTree )
|
||||
OutputHandle = -1;
|
||||
|
||||
Buffer = NULL;
|
||||
BufEnd = NULL;
|
||||
|
||||
// Parsing operation
|
||||
BufPos = NULL;
|
||||
LineMark = NULL;
|
||||
Mark = NULL;
|
||||
LineNo = 0;
|
||||
CharNo = 0;
|
||||
RefillBuffer = false;
|
||||
|
||||
// Printing operation
|
||||
Spacer[0] = 0;
|
||||
@@ -53,53 +54,31 @@ CJSONparse::~CJSONparse()
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CJSONparse::PrintToScreen( const char * RootPath, const int Indent )
|
||||
bool CJSONparse::WriteToScreen( const char * RootPath, const int Indent )
|
||||
{
|
||||
TDataMember * RootObject;
|
||||
|
||||
// Validate
|
||||
if (!DataTree) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set to StdOut
|
||||
OutputHandle = 1;
|
||||
|
||||
// Get Root object
|
||||
if (!RootPath || !*RootPath) {
|
||||
RootObject = DataTree->GetRootMember();
|
||||
}
|
||||
else if (!(RootObject = DataTree->GetMember( NULL, RootPath ))) {
|
||||
Error = true;
|
||||
sprintf( ErrorText, "Invalid root object path" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Print key name
|
||||
if (RootObject->Name) {
|
||||
write( OutputHandle, "\"", 1 );
|
||||
write( OutputHandle, RootObject->Name, strlen(RootObject->Name) );
|
||||
write( OutputHandle, "\" : ", 4 );
|
||||
}
|
||||
|
||||
// Print to screen
|
||||
PrintObject( RootObject, Indent );
|
||||
WriteToHandle( RootPath, 1, Indent );
|
||||
|
||||
// Close file
|
||||
close( OutputHandle );
|
||||
OutputHandle = -1;
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CJSONparse::SaveToFile( const char * RootPath, const char * FilePath, const int Indent )
|
||||
bool CJSONparse::WriteToFile( const char * RootPath, const char * Path, const char * FileName, const int Indent )
|
||||
{
|
||||
TDataMember * RootObject;
|
||||
char FilePath[250] = "";
|
||||
|
||||
// Validate
|
||||
if (!DataTree) {
|
||||
return false;
|
||||
// Build file name
|
||||
strcpy( FilePath, Path );
|
||||
strcat( FilePath, FileName );
|
||||
|
||||
// Read file
|
||||
return WriteToFile( RootPath, FilePath, Indent );
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CJSONparse::WriteToFile( const char * RootPath, const char * FilePath, const int Indent )
|
||||
{
|
||||
int Handle = -1;
|
||||
|
||||
// Clear Error
|
||||
Error = false;
|
||||
@@ -112,12 +91,38 @@ bool CJSONparse::SaveToFile( const char * RootPath, const char * FilePath, const
|
||||
}
|
||||
|
||||
// Open file
|
||||
if (!(OutputHandle = open( FilePath, O_CREAT|O_WRONLY|O_TRUNC ))) {
|
||||
if ((Handle = open( FilePath, O_CREAT|O_WRONLY|O_TRUNC )) < 0) {
|
||||
Error = true;
|
||||
sprintf( ErrorText, "Could not open file" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Save to file
|
||||
WriteToHandle( RootPath, Handle, Indent );
|
||||
|
||||
// Close file
|
||||
close( Handle );
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CJSONparse::WriteToHandle( const char * RootPath, const int Handle, const int Indent )
|
||||
{
|
||||
TDataMember * RootObject;
|
||||
|
||||
// Validate
|
||||
if (!DataTree) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Open file
|
||||
if (Handle < 0) {
|
||||
Error = true;
|
||||
sprintf( ErrorText, "Could not write to invalid handle" );
|
||||
return false;
|
||||
}
|
||||
OutputHandle = Handle;
|
||||
|
||||
// Get Root object
|
||||
if (!RootPath || !*RootPath) {
|
||||
RootObject = DataTree->GetRootMember();
|
||||
@@ -130,17 +135,29 @@ bool CJSONparse::SaveToFile( const char * RootPath, const char * FilePath, const
|
||||
|
||||
// Print to file
|
||||
PrintObject( RootObject, Indent );
|
||||
write( OutputHandle, "\n", 1 );
|
||||
|
||||
// Close file
|
||||
close( OutputHandle );
|
||||
OutputHandle = -1;
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CJSONparse::LoadFromFile( const char * RootPath, const char * FilePath, int pBufLen )
|
||||
bool CJSONparse::ReadFromFile( const char * RootPath, const char * Path, const char * FileName )
|
||||
{
|
||||
TDataMember * RootObject = NULL;
|
||||
char FilePath[250] = "";
|
||||
|
||||
// Build file name
|
||||
strcpy( FilePath, Path );
|
||||
strcat( FilePath, FileName );
|
||||
|
||||
// Read file
|
||||
return ReadFromFile( RootPath, FilePath );
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CJSONparse::ReadFromFile( const char * RootPath, const char * FilePath )
|
||||
{
|
||||
int Handle = -1;
|
||||
|
||||
// Validate
|
||||
if (!DataTree) {
|
||||
@@ -158,14 +175,36 @@ bool CJSONparse::LoadFromFile( const char * RootPath, const char * FilePath, int
|
||||
}
|
||||
|
||||
// Open file
|
||||
if (!(InputHandle = open( FilePath, O_RDONLY ))) {
|
||||
if ((Handle = open( FilePath, O_RDONLY )) < 0) {
|
||||
Error = true;
|
||||
sprintf( ErrorText, "Could not open file" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Continuously refill buffer while loading
|
||||
ReadFromHandle( RootPath, Handle, true );
|
||||
|
||||
// Close File
|
||||
close( Handle );
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CJSONparse::ReadFromHandle( const char * RootPath, int Handle, bool pRefillBuffer )
|
||||
{
|
||||
// Clear Error
|
||||
Error = false;
|
||||
|
||||
// Validate
|
||||
if (Handle < 0) {
|
||||
Error = true;
|
||||
sprintf( ErrorText, "Cannot read from invalid handle" );
|
||||
return false;
|
||||
}
|
||||
InputHandle = Handle;
|
||||
|
||||
// Load Buffer
|
||||
CreateBuffer( pBufLen );
|
||||
CreateBuffer( 50 );
|
||||
if (!FillBuffer()) {
|
||||
Error = true;
|
||||
sprintf( ErrorText, "Could not read from file" );
|
||||
@@ -173,6 +212,31 @@ bool CJSONparse::LoadFromFile( const char * RootPath, const char * FilePath, int
|
||||
return false;
|
||||
}
|
||||
|
||||
// Continuously refill buffer while loading
|
||||
RefillBuffer = pRefillBuffer;
|
||||
ReadFromBuffer( RootPath );
|
||||
RefillBuffer = false;
|
||||
|
||||
// Destroy buffer
|
||||
FreeBuffer();
|
||||
|
||||
InputHandle = -1;
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CJSONparse::ReadFromBuffer( const char * RootPath )
|
||||
{
|
||||
TDataMember * RootObject = NULL;
|
||||
|
||||
// Validate
|
||||
if (!DataTree || !Buffer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Clear Error
|
||||
Error = false;
|
||||
|
||||
// Get/Create Root object
|
||||
if (!RootPath || !*RootPath) {
|
||||
RootObject = DataTree->GetRootMember();
|
||||
@@ -183,16 +247,20 @@ bool CJSONparse::LoadFromFile( const char * RootPath, const char * FilePath, int
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reset values
|
||||
LineNo = 1;
|
||||
// Delete existing object contents
|
||||
DataTree->Delete( RootObject, NULL );
|
||||
|
||||
// Position Counters
|
||||
LineNo = 1;
|
||||
CharNo = 0;
|
||||
|
||||
// Parse Root Object
|
||||
SkipWhiteSpace();
|
||||
if (!ParseObject( RootObject )) {
|
||||
if (!Error) {
|
||||
Error = true;
|
||||
sprintf( ErrorText, "First entry in file must be an Object on line %d:%ld", LineNo, BufPos-LineMark );
|
||||
CharNo += BufPos-Mark;
|
||||
sprintf( ErrorText, "First entry in file must be an Object on line %d:%d", LineNo, CharNo );
|
||||
}
|
||||
FreeBuffer();
|
||||
return false;
|
||||
@@ -202,15 +270,13 @@ bool CJSONparse::LoadFromFile( const char * RootPath, const char * FilePath, int
|
||||
SkipWhiteSpace();
|
||||
if (*BufPos != 0) {
|
||||
Error = true;
|
||||
sprintf( ErrorText, "No content expected after Root object on line %d:%ld", LineNo, BufPos-LineMark );
|
||||
CharNo += BufPos-Mark;
|
||||
sprintf( ErrorText, "No content expected after Root object on line %d:%d", LineNo, CharNo );
|
||||
FreeBuffer();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Success
|
||||
close( InputHandle );
|
||||
InputHandle = -1;
|
||||
FreeBuffer();
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -226,8 +292,7 @@ bool CJSONparse::CreateBuffer( int pBufLen )
|
||||
|
||||
// Reset markers
|
||||
Buffer->PeekDirect( &BufPos, 0 );
|
||||
BufEnd = BufPos;
|
||||
LineMark = BufPos;
|
||||
Mark = BufPos;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -235,13 +300,19 @@ bool CJSONparse::CreateBuffer( int pBufLen )
|
||||
|
||||
bool CJSONparse::FillBuffer()
|
||||
{
|
||||
char * BufStart;
|
||||
int PosShift = BufPos - Mark;
|
||||
|
||||
// Remove all bytes up to Mark
|
||||
Buffer->PeekDirect( &BufStart, 0 );
|
||||
Buffer->Clear( Mark-BufStart );
|
||||
|
||||
// Read from file
|
||||
Buffer->ReadFromFD( InputHandle );
|
||||
|
||||
// Update Markers
|
||||
Buffer->PeekDirect( &BufEnd, Buffer->Len() );
|
||||
Buffer->PeekDirect( &BufPos, 0 );
|
||||
LineMark = BufPos;
|
||||
// Reset Mark to start of buffer
|
||||
Mark = BufStart;
|
||||
BufPos = Mark + PosShift;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -255,18 +326,40 @@ void CJSONparse::FreeBuffer()
|
||||
Buffer = NULL;
|
||||
|
||||
// Update Markers
|
||||
BufEnd = NULL;
|
||||
BufPos = NULL;
|
||||
LineMark = NULL;
|
||||
Mark = NULL;
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CJSONparse::ParseString( char ** Value, int &pLen )
|
||||
void CJSONparse::SkipWhiteSpace()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
// Append buffer if required
|
||||
if (!*BufPos && RefillBuffer)
|
||||
FillBuffer();
|
||||
|
||||
// Skip whitespace
|
||||
if (!isspace(*BufPos)) {
|
||||
CharNo += BufPos-Mark;
|
||||
Mark = BufPos;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*BufPos == '\n') {
|
||||
Mark = BufPos;
|
||||
LineNo++;
|
||||
CharNo = 0;
|
||||
}
|
||||
BufPos++;
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CJSONparse::ParseString( char ** Value, int &Len )
|
||||
{
|
||||
char * Mark;
|
||||
char * EndMark;
|
||||
int Len;
|
||||
|
||||
// Check for opening quote
|
||||
if (*BufPos != '"') {
|
||||
@@ -278,12 +371,19 @@ bool CJSONparse::ParseString( char ** Value, int &pLen )
|
||||
Len = 0;
|
||||
|
||||
// Mark start of quote
|
||||
Mark = BufPos;
|
||||
BufPos++;
|
||||
|
||||
// Check for closing quote
|
||||
while ((BufPos = strpbrk( BufPos, "\"/\\\n\t\b\f\n\r" )))
|
||||
while (true)
|
||||
{
|
||||
// Check for special characters
|
||||
if ((EndMark = strpbrk( BufPos, "\"/\\\n\t\b\f\n\r" ))) {
|
||||
BufPos = EndMark;
|
||||
} else if (RefillBuffer) {
|
||||
FillBuffer();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*BufPos == '"') {
|
||||
// End of string found
|
||||
BufPos++;
|
||||
@@ -291,15 +391,25 @@ bool CJSONparse::ParseString( char ** Value, int &pLen )
|
||||
}
|
||||
else if (!*BufPos) {
|
||||
Error = true;
|
||||
sprintf( ErrorText, "Expect closing '\"' for string on line %d:%ld", LineNo, Mark-LineMark );
|
||||
sprintf( ErrorText, "Expect closing '\"' for string on line %d:%d", LineNo, CharNo+1 );
|
||||
return false;
|
||||
}
|
||||
else if (*BufPos == '\\') {
|
||||
if (!*(BufPos+1) && RefillBuffer) {
|
||||
if (FillBuffer()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (*(BufPos+1) == 'u') {
|
||||
for (EndMark = BufPos+2; EndMark < BufPos+6; EndMark++) {
|
||||
if (!*BufPos && RefillBuffer) {
|
||||
FillBuffer();
|
||||
continue;
|
||||
}
|
||||
if (!isxdigit( *EndMark )) {
|
||||
Error = true;
|
||||
sprintf( ErrorText, "Expect 4-digit hex value for escape value on line %d:%ld", LineNo, Mark-LineMark );
|
||||
CharNo += BufPos-EndMark;
|
||||
sprintf( ErrorText, "Expect 4-digit hex value for escape value on line %d:%d", LineNo, CharNo );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -310,18 +420,20 @@ bool CJSONparse::ParseString( char ** Value, int &pLen )
|
||||
}
|
||||
else {
|
||||
Error = true;
|
||||
sprintf( ErrorText, "Invalid escape sequence on line %d:%ld", LineNo, Mark-LineMark );
|
||||
CharNo += BufPos-Mark+1;
|
||||
sprintf( ErrorText, "Invalid escape sequence on line %d:%d", LineNo, CharNo );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Error = true;
|
||||
sprintf( ErrorText, "Un-escaped special character in string on line %d:%ld", LineNo, BufPos-LineMark );
|
||||
CharNo += BufPos-Mark+1;
|
||||
sprintf( ErrorText, "Un-escaped special character in string on line %d:%d", LineNo, CharNo );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate size of name
|
||||
// Get size of name
|
||||
Len = BufPos-Mark-2;
|
||||
|
||||
// Create Return value pointer
|
||||
@@ -329,9 +441,6 @@ bool CJSONparse::ParseString( char ** Value, int &pLen )
|
||||
memcpy( *Value, Mark+1, Len );
|
||||
(*Value)[Len] = 0;
|
||||
|
||||
// Set other parameters
|
||||
pLen = Len;
|
||||
|
||||
// Success
|
||||
return true;
|
||||
}
|
||||
@@ -354,21 +463,22 @@ bool CJSONparse::ParseObject( TDataMember * Object )
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Look for Member Name
|
||||
// Evaluate key name
|
||||
SkipWhiteSpace();
|
||||
if (*BufPos == '}') {
|
||||
// End of Object
|
||||
break;
|
||||
}
|
||||
else if (!ParseString( &MemberName, Len )) {
|
||||
if (!Error) {
|
||||
Error = true;
|
||||
sprintf( ErrorText, "Expect quoted key name on line %d:%ld", LineNo, BufPos-LineMark );
|
||||
sprintf( ErrorText, "Expect quoted key name on line %d:%d", LineNo, CharNo );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (!Len) {
|
||||
Error = true;
|
||||
sprintf( ErrorText, "Empty parameter name on line %d:%ld", LineNo, BufPos-LineMark );
|
||||
sprintf( ErrorText, "Empty parameter name on line %d:%d", LineNo, CharNo );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -379,7 +489,7 @@ bool CJSONparse::ParseObject( TDataMember * Object )
|
||||
SkipWhiteSpace();
|
||||
if (*BufPos != ':') {
|
||||
Error = true;
|
||||
sprintf( ErrorText, "Expected ':' delimiter on line %d:%ld", LineNo, BufPos-LineMark );
|
||||
sprintf( ErrorText, "Expected ':' delimiter on line %d:%d", LineNo, CharNo );
|
||||
return false;
|
||||
}
|
||||
BufPos++;
|
||||
@@ -394,6 +504,7 @@ bool CJSONparse::ParseObject( TDataMember * Object )
|
||||
!Error &&
|
||||
!ParsePrimitive( Member ))
|
||||
{
|
||||
// Destroy member
|
||||
DataTree->Delete( Object, MemberName );
|
||||
return false;
|
||||
}
|
||||
@@ -413,7 +524,7 @@ bool CJSONparse::ParseObject( TDataMember * Object )
|
||||
// Expect end of object
|
||||
if (*BufPos != '}') {
|
||||
Error = true;
|
||||
sprintf( ErrorText, "Closing brace for object '}' expected on line %d:%ld", LineNo, BufPos-LineMark );
|
||||
sprintf( ErrorText, "Closing brace for object '}' expected on line %d:%d", LineNo, CharNo );
|
||||
return false;
|
||||
}
|
||||
BufPos++;
|
||||
@@ -476,7 +587,7 @@ bool CJSONparse::ParseArray( TDataMember * Array )
|
||||
// Expect end of object
|
||||
if (*BufPos != ']') {
|
||||
Error = true;
|
||||
sprintf( ErrorText, "Closing brace for array ']' expected on line %d:%ld", LineNo, BufPos-LineMark );
|
||||
sprintf( ErrorText, "Closing brace for array ']' expected on line %d:%d", LineNo, CharNo );
|
||||
return false;
|
||||
}
|
||||
BufPos++;
|
||||
@@ -507,14 +618,14 @@ bool CJSONparse::ParsePrimitive( TDataMember * Member )
|
||||
{
|
||||
char * Value = NULL;
|
||||
int Len = 0;
|
||||
char * Mark;
|
||||
char * EndMark;
|
||||
|
||||
// Mark start of value
|
||||
Mark = BufPos;
|
||||
|
||||
// Get end of value
|
||||
while ((*BufPos != 0) && !isspace(*BufPos) && (*BufPos != ',')) {
|
||||
while (true) {
|
||||
if (!*BufPos && RefillBuffer)
|
||||
FillBuffer();
|
||||
if (!*BufPos || isspace(*BufPos) || (*BufPos == ',') || (*BufPos == '}') || (*BufPos == ']'))
|
||||
break;
|
||||
BufPos++;
|
||||
}
|
||||
|
||||
@@ -522,7 +633,7 @@ bool CJSONparse::ParsePrimitive( TDataMember * Member )
|
||||
Len = BufPos - Mark;
|
||||
if (!Len) {
|
||||
Error = true;
|
||||
sprintf( ErrorText, "Missing param value on line %d:%ld", LineNo, Mark-LineMark );
|
||||
sprintf( ErrorText, "Missing param value on line %d:%d", LineNo, CharNo );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -556,7 +667,7 @@ bool CJSONparse::ParsePrimitive( TDataMember * Member )
|
||||
}
|
||||
else {
|
||||
Error = true;
|
||||
sprintf( ErrorText, "Invalid primitive param value on line %d:%ld", LineNo, Mark-LineMark );
|
||||
sprintf( ErrorText, "Invalid primitive param value on line %d:%d", LineNo, CharNo );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -578,14 +689,17 @@ bool CJSONparse::PrintObject( TDataMember * Object, const int Indent )
|
||||
write( OutputHandle, "{", 1 );
|
||||
|
||||
// Extend spacer
|
||||
if (Indent) {
|
||||
memset( &Spacer[SpacerLen], ' ', 2 );
|
||||
SpacerLen += 2;
|
||||
Spacer[SpacerLen] = 0;
|
||||
}
|
||||
|
||||
// Save parameters
|
||||
for (Member = Object->FirstChild; Member != NULL; (Member = Member->Next))
|
||||
{
|
||||
// Write parameter name
|
||||
// Whitespace around first bracket
|
||||
if (Indent) {
|
||||
if (First) {
|
||||
First = false;
|
||||
if (Object->Name) {
|
||||
@@ -599,11 +713,16 @@ bool CJSONparse::PrintObject( TDataMember * Object, const int Indent )
|
||||
else {
|
||||
write( OutputHandle, Spacer, SpacerLen );
|
||||
}
|
||||
}
|
||||
|
||||
// Print key name
|
||||
write( OutputHandle, "\"", 1 );
|
||||
write( OutputHandle, Member->Name, strlen(Member->Name) );
|
||||
if (Indent) {
|
||||
write( OutputHandle,"\" : ", 4 );
|
||||
} else {
|
||||
write( OutputHandle, "\":", 2 );
|
||||
}
|
||||
|
||||
// Print value
|
||||
Last = (++Count >= Object->Len);
|
||||
@@ -633,15 +752,17 @@ bool CJSONparse::PrintObject( TDataMember * Object, const int Indent )
|
||||
PrintObject( Member, Indent );
|
||||
break;
|
||||
}
|
||||
if (!Last) {
|
||||
if (!Last)
|
||||
write( OutputHandle, ",", 1 );
|
||||
}
|
||||
if (Indent)
|
||||
write( OutputHandle, "\n", 1 );
|
||||
}
|
||||
|
||||
// Shorten spacer
|
||||
if (Indent) {
|
||||
SpacerLen -= 2;
|
||||
Spacer[SpacerLen] = 0;
|
||||
}
|
||||
|
||||
// Closing brace
|
||||
if (Object->Len) {
|
||||
@@ -663,19 +784,23 @@ bool CJSONparse::PrintArray( TDataMember * Array, const int Indent )
|
||||
write( OutputHandle, "[", 1 );
|
||||
|
||||
// Extend spacer
|
||||
if (Indent) {
|
||||
memset( &Spacer[SpacerLen], ' ', 2 );
|
||||
SpacerLen += 2;
|
||||
Spacer[SpacerLen] = 0;
|
||||
}
|
||||
|
||||
// Save parameters
|
||||
for (Member = Array->FirstChild; Member != NULL; (Member = Member->Next))
|
||||
{
|
||||
// Write parameter name
|
||||
// Whitespace around brace
|
||||
if (Indent) {
|
||||
if (First) {
|
||||
First = false;
|
||||
write( OutputHandle, "\n", 1 );
|
||||
}
|
||||
write( OutputHandle, Spacer, SpacerLen );
|
||||
}
|
||||
|
||||
Last = (++Count >= Array->Len);
|
||||
switch (Member->Type)
|
||||
@@ -704,15 +829,17 @@ bool CJSONparse::PrintArray( TDataMember * Array, const int Indent )
|
||||
PrintObject( Member, Indent );
|
||||
break;
|
||||
}
|
||||
if (!Last) {
|
||||
if (!Last)
|
||||
write( OutputHandle, ",", 1 );
|
||||
}
|
||||
if (Indent)
|
||||
write( OutputHandle, "\n", 1 );
|
||||
}
|
||||
|
||||
// Shorten spacer
|
||||
if (Indent) {
|
||||
SpacerLen -= 2;
|
||||
Spacer[SpacerLen] = 0;
|
||||
}
|
||||
|
||||
// Closing brace
|
||||
if (Array->Len) {
|
||||
|
||||
@@ -32,10 +32,11 @@ private:
|
||||
CShiftBuffer * Buffer;
|
||||
|
||||
// Parsing operation
|
||||
char * BufEnd;
|
||||
char * BufPos;
|
||||
char * LineMark;
|
||||
char * Mark;
|
||||
int LineNo;
|
||||
int CharNo;
|
||||
bool RefillBuffer;
|
||||
|
||||
// Printing Operation
|
||||
char Spacer[100];
|
||||
@@ -45,21 +46,8 @@ private:
|
||||
bool Error;
|
||||
char ErrorText[100];
|
||||
|
||||
// File Buffer operation
|
||||
bool CreateBuffer( int pBufLen );
|
||||
bool FillBuffer();
|
||||
void FreeBuffer();
|
||||
|
||||
// Parsing functions
|
||||
inline void SkipWhiteSpace() {
|
||||
while (isspace(*BufPos)) {
|
||||
if (*BufPos == '\n') {
|
||||
LineMark = BufPos;
|
||||
LineNo++;
|
||||
}
|
||||
BufPos++;
|
||||
}
|
||||
}
|
||||
void SkipWhiteSpace();
|
||||
bool ParseString( char ** Value, int &pLen );
|
||||
bool ParseObject( TDataMember * Object );
|
||||
bool ParseArray( TDataMember * Array );
|
||||
@@ -73,10 +61,22 @@ public:
|
||||
CJSONparse( CDataTree * pDataTree );
|
||||
~CJSONparse();
|
||||
|
||||
bool PrintToScreen( const char * Path, const int Indent );
|
||||
// Buffer operation
|
||||
bool CreateBuffer( int pBufLen );
|
||||
bool FillBuffer();
|
||||
void FreeBuffer();
|
||||
bool ReadFromBuffer( const char * RootPath );
|
||||
|
||||
bool LoadFromFile( const char * Path, const char * FilePath, int pBufLen = 500 );
|
||||
bool SaveToFile( const char * Path, const char * FilePath, const int Indent = 2 );
|
||||
// Input
|
||||
bool ReadFromHandle( const char * RootPath, const int Handle, bool pRefillBuffer );
|
||||
bool ReadFromFile( const char * RootPath, const char * Path, const char * FileName );
|
||||
bool ReadFromFile( const char * RootPath, const char * FilePath );
|
||||
|
||||
// Output
|
||||
bool WriteToHandle( const char * RootPath, const int Handle, const int Indent = 2 );
|
||||
bool WriteToScreen( const char * RootPath, const int Indent = 2 );
|
||||
bool WriteToFile( const char * RootPath, const char * Path, const char * FileName, const int Indent = 2 );
|
||||
bool WriteToFile( const char * RootPath, const char * FilePath, const int Indent = 2 );
|
||||
|
||||
const char * GetError() { return ((Error)? ErrorText : "Success"); };
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user