ICCItem *CCodeChain::StreamItem (ICCItem *pItem, IWriteStream *pStream) // StreamItem // // Save the item to an open stream { ALERROR error; DWORD dwClass; ICCItem *pError; // Save out the object class dwClass = pItem->GetClass()->GetObjID(); if (error = pStream->Write((char *)&dwClass, sizeof(dwClass), NULL)) return CreateSystemError(error); // Let the object save itself pError = pItem->Stream(this, pStream); if (pError->IsError()) return pError; pError->Discard(this); // Done return CreateTrue(); }
JSON *true_type_parse(){ next_char(); assert(*s == 'r'); next_char(); assert(*s == 'u'); next_char(); assert(*s == 'e'); next_char(); return CreateTrue(); }
JSON *Duplicate(JSON *obj, int recurse){ switch (obj->type){ case JSON_NULL: return CreateNULL(); case JSON_TRUE: return CreateTrue(); case JSON_FALSE: return CreateFalse(); case JSON_NUMBER: return CreateNumber(obj->valuedouble); case JSON_STRING: return CreateString(obj->valuestring); case JSON_ARRAY:{ JSON *new_obj = CreateArray(); if (recurse == 0) new_obj->son = obj->son; else{ if (obj->son != NULL){ new_obj->son = Duplicate(obj->son, 1); JSON *old_item = obj->son, *new_item = new_obj->son; for ( ; old_item->next != NULL; old_item = old_item->next, new_item = new_item->next){ JSON *temp = Duplicate(old_item->next,1); new_item->next = temp; temp->last = new_item; } } } return new_obj; } case JSON_OBJECT:{ JSON *new_obj = CreateObject(); if (recurse == 0) new_obj->son = obj->son; else{ if (obj->son != NULL){ new_obj->son = Duplicate(obj->son, 1); JSON *old_item = obj->son, *new_item = new_obj->son; for ( ; old_item->next != NULL; old_item = old_item->next, new_item = new_item->next){ JSON *temp = Duplicate(old_item->next,1); new_item->next = temp; temp->last = new_item; } } } return new_obj; } case JSON_ENTRY:{ JSON *new_obj = CreateEntry(obj->key, Duplicate(obj->value,1)); return new_obj; } default: return NULL; } }
JSON *CreateBool(int b) { JSON* rtn = NULL; if (b == 0) { rtn = CreateFalse(); } else { rtn = CreateTrue(); } return rtn; }
ICCItem *CCodeChain::CreateBool (bool bValue) // CreateBool // // Creates either True or Nil { if (bValue) return CreateTrue(); else return CreateNil(); }
JSON *Duplicate(JSON *item, int recurse) { JSON *rtn = NULL; JSON *iter = NULL; unsigned int i = 0; if (item == NULL) { printf("Exception: Cannot duplicate a NULL JSON pointer.\n"); return rtn; } switch (item->type) { case JSON_NULL: rtn = CreateNULL(); return rtn; case JSON_FALSE: rtn = CreateFalse(); return rtn; case JSON_TRUE: rtn = CreateTrue(); return rtn; case JSON_NUMBER: rtn = CreateNumber(item->valuedouble); return rtn; case JSON_STRING: rtn = CreateString(item->valuestring); return rtn; case JSON_ARRAY: rtn = CreateArray(); if (recurse == 1) { iter = item->childstart; for (i = 0; i < item->childlength; ++i) { AddItemToArray(rtn, Duplicate(iter, 1)); iter = iter->next; } } else { rtn->childlength = item->childlength; rtn->childstart = item->childstart; rtn->childend = item->childend; } return rtn; case JSON_OBJECT: rtn = CreateObject(); if (recurse == 1) { iter = item->childstart; for (i = 0; i < item->childlength; ++i) { AddItemToObject(rtn, iter->key, Duplicate(iter, 1)); iter = iter->next; } } else { rtn->childlength = item->childlength; rtn->childstart = item->childstart; rtn->childend = item->childend; } return rtn; } }
JSON *CreateBool(int b){ return b?CreateTrue():CreateFalse(); }
ICCItem *CCodeChain::Link (const CString &sString, int iOffset, int *retiLinked, int *ioiCurLine) // Link // // Parses the given string and converts it into a linked // chain of items { char *pStart; char *pPos; ICCItem *pResult = NULL; int iCurLine = (ioiCurLine ? *ioiCurLine : 1); pStart = sString.GetPointer() + iOffset; pPos = pStart; // Skip any whitespace pPos = SkipWhiteSpace(pPos, &iCurLine); // If we've reached the end, then we have // nothing if (*pPos == '\0') pResult = CreateNil(); // If we've got a literal quote, then remember it else if (*pPos == SYMBOL_QUOTE) { int iLinked; pPos++; pResult = Link(sString, iOffset + (pPos - pStart), &iLinked, &iCurLine); if (pResult->IsError()) return pResult; pPos += iLinked; // Make it a literal pResult->SetQuoted(); } // If we've got an open paren then we start a list else if (*pPos == SYMBOL_OPENPAREN) { ICCItem *pNew = CreateLinkedList(); if (pNew->IsError()) return pNew; CCLinkedList *pList = dynamic_cast<CCLinkedList *>(pNew); // Keep reading until we find the end pPos++; // If the list is empty, then there's nothing to do pPos = SkipWhiteSpace(pPos, &iCurLine); if (*pPos == SYMBOL_CLOSEPAREN) { pList->Discard(this); pResult = CreateNil(); pPos++; } // Get all the items in the list else { while (*pPos != SYMBOL_CLOSEPAREN && *pPos != '\0') { ICCItem *pItem; int iLinked; pItem = Link(sString, iOffset + (pPos - pStart), &iLinked, &iCurLine); if (pItem->IsError()) return pItem; // Add the item to the list pList->Append(this, pItem, NULL); pItem->Discard(this); // Move the position pPos += iLinked; // Skip whitespace pPos = SkipWhiteSpace(pPos, &iCurLine); } // If we have a close paren then we're done; Otherwise we've // got an error of some kind if (*pPos == SYMBOL_CLOSEPAREN) { pPos++; pResult = pList; } else { pList->Discard(this); pResult = CreateParseError(iCurLine, CONSTLIT("Mismatched open parenthesis")); } } } // If this is an open brace then we've got a literal structure else if (*pPos == SYMBOL_OPENBRACE) { ICCItem *pNew = CreateSymbolTable(); if (pNew->IsError()) return pNew; CCSymbolTable *pTable = dynamic_cast<CCSymbolTable *>(pNew); // Always literal pTable->SetQuoted(); // Keep reading until we find the end pPos++; // If the list is empty, then there's nothing to do pPos = SkipWhiteSpace(pPos, &iCurLine); if (*pPos == SYMBOL_CLOSEBRACE) { pResult = pTable; pPos++; } // Get all the items in the list else { while (*pPos != SYMBOL_CLOSEBRACE && *pPos != '\0') { // Get the key ICCItem *pKey; int iLinked; pKey = Link(sString, iOffset + (pPos - pStart), &iLinked, &iCurLine); if (pKey->IsError()) { pTable->Discard(this); return pKey; } // Move the position and read a colon pPos += iLinked; pPos = SkipWhiteSpace(pPos, &iCurLine); if (*pPos != SYMBOL_COLON) { pKey->Discard(this); pTable->Discard(this); return CreateParseError(iCurLine, CONSTLIT("Struct value not found.")); } pPos++; // Get the value ICCItem *pValue; pValue = Link(sString, iOffset + (pPos - pStart), &iLinked, &iCurLine); if (pValue->IsError()) { pKey->Discard(this); pTable->Discard(this); return pValue; } // Move the position pPos += iLinked; // Add the item to the table pResult = pTable->AddEntry(this, pKey, pValue); pKey->Discard(this); pValue->Discard(this); if (pResult->IsError()) { pTable->Discard(this); return pResult; } // Skip whitespace because otherwise we won't know whether we // hit the end brace. pPos = SkipWhiteSpace(pPos, &iCurLine); } // If we have a close paren then we're done; Otherwise we've // got an error of some kind if (*pPos == SYMBOL_CLOSEBRACE) { pPos++; pResult = pTable; } else { pTable->Discard(this); pResult = CreateParseError(iCurLine, CONSTLIT("Mismatched open brace")); } } } // If this is an open quote, then read everything until // the close quote else if (*pPos == SYMBOL_OPENQUOTE) { // Parse the string, until the end quote, parsing escape codes char *pStartFragment = NULL; CString sResultString; bool bDone = false; while (!bDone) { pPos++; switch (*pPos) { case SYMBOL_CLOSEQUOTE: case '\0': { if (pStartFragment) { sResultString.Append(CString(pStartFragment, pPos - pStartFragment)); pStartFragment = NULL; } bDone = true; break; } case SYMBOL_BACKSLASH: { if (pStartFragment) { sResultString.Append(CString(pStartFragment, pPos - pStartFragment)); pStartFragment = NULL; } pPos++; if (*pPos == '\0') bDone = true; else if (*pPos == 'n') sResultString.Append(CString("\n", 1)); else if (*pPos == 'r') sResultString.Append(CString("\r", 1)); else if (*pPos == 't') sResultString.Append(CString("\t", 1)); else if (*pPos == '0') sResultString.Append(CString("\0", 1)); else if (*pPos == 'x' || *pPos == 'X') { pPos++; int iFirstDigit = strGetHexDigit(pPos); pPos++; int iSecondDigit = 0; if (*pPos == '\0') bDone = true; else iSecondDigit = strGetHexDigit(pPos); char chChar = (char)(16 * iFirstDigit + iSecondDigit); sResultString.Append(CString(&chChar, 1)); } else sResultString.Append(CString(pPos, 1)); break; } default: { if (pStartFragment == NULL) pStartFragment = pPos; break; } } } // If we found the close, then create a string; otherwise, // it is an error if (*pPos == SYMBOL_CLOSEQUOTE) { pResult = CreateString(sResultString); // Always a literal pResult->SetQuoted(); // Skip past quote pPos++; } else pResult = CreateParseError(iCurLine, CONSTLIT("Mismatched quote")); } // If this is a close paren, then it is an error else if (*pPos == SYMBOL_CLOSEPAREN) pResult = CreateParseError(iCurLine, CONSTLIT("Mismatched close parenthesis")); // If this is a close brace, then it is an error else if (*pPos == SYMBOL_CLOSEBRACE) pResult = CreateParseError(iCurLine, CONSTLIT("Mismatched close brace")); // Colons cannot appear alone else if (*pPos == SYMBOL_COLON) pResult = CreateParseError(iCurLine, CONSTLIT("':' character must appear inside quotes or in a struct definition.")); // Otherwise this is an string of some sort else { char *pStartString; CString sIdentifier; int iInt; bool bNotInteger; pStartString = pPos; // Look for whitespace while (*pPos != '\0' && *pPos != ' ' && *pPos != '\n' && *pPos != '\r' && *pPos != '\t' && *pPos != SYMBOL_OPENPAREN && *pPos != SYMBOL_CLOSEPAREN && *pPos != SYMBOL_OPENQUOTE && *pPos != SYMBOL_CLOSEQUOTE && *pPos != SYMBOL_OPENBRACE && *pPos != SYMBOL_CLOSEBRACE && *pPos != SYMBOL_COLON && *pPos != SYMBOL_QUOTE && *pPos != ';') pPos++; // If we did not advance, then we clearly hit an error if (pStartString == pPos) pResult = CreateParseError(iCurLine, strPatternSubst(CONSTLIT("Unexpected character: %s"), CString(pPos, 1))); // If we ended in a quote then that's a bug else if (*pPos == SYMBOL_QUOTE) pResult = CreateParseError(iCurLine, strPatternSubst(CONSTLIT("Identifiers must not use single quote characters: %s"), strSubString(sString, iOffset + (pStartString - pStart), (pPos + 1 - pStartString)))); // Otherwise, get the identifier else { // Create a string from the portion sIdentifier = strSubString(sString, iOffset + (pStartString - pStart), (pPos - pStartString)); // Check to see if this is a reserved identifier if (strCompareAbsolute(sIdentifier, CONSTLIT("Nil")) == 0) pResult = CreateNil(); else if (strCompareAbsolute(sIdentifier, CONSTLIT("True")) == 0) pResult = CreateTrue(); else { // If this is an integer, create an integer; otherwise // create a string iInt = strToInt(sIdentifier, 0, &bNotInteger); if (bNotInteger) pResult = CreateString(sIdentifier); else pResult = CreateInteger(iInt); } } } // Return the result and the number of characters // that we read if (retiLinked) *retiLinked = (pPos - pStart); if (ioiCurLine) *ioiCurLine = iCurLine; return pResult; }
JSON *ParseJSON(const char *value) { JSON *rtn = NULL; StrSlice *ss = NULL; StrSlice *iter = NULL; int len = strlen(value); int index = 0; char *value_deletespace = DeleteSpaces(value); switch(value[0]) { case '-': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '0': //To number return CreateNumber(FormatNumber(value_deletespace)); free(value_deletespace); break; case '\"': // To string return CreateString(FormatString(value)); break; case '{': rtn = CreateObject(); ss = GetObjectSlices(value); iter = ss; if (ss->length == 0) { DeleteStrSlice(ss); return rtn; } while (iter != NULL) { AddItemToObject(rtn, FormatString(iter->str), ParseJSON(DeleteSpaces(iter->next->str))); iter = iter->next->next; } DeleteStrSlice(ss); return rtn; break; case '[': rtn = CreateArray(); ss = GetArraySlices(value); iter = ss; if (ss->length == 0) { DeleteStrSlice(ss); return rtn; } while (iter != NULL) { AddItemToArray(rtn, ParseJSON(DeleteSpaces(iter->str))); iter = iter->next; } DeleteStrSlice(ss); return rtn; break; case 'n': if (strcmp(value_deletespace, "null") == 0) { free(value_deletespace); return CreateNULL(); } else { printf("Exception: Invalid Syntax \"%s\"", value); return NULL; } case 't': if (strcmp(value_deletespace, "true") == 0) { free(value_deletespace); return CreateTrue(); } else { printf("Exception: Invalid Syntax \"%s\"", value); return NULL; } break; case 'f': if (strcmp(value_deletespace, "false") == 0) { free(value_deletespace); return CreateFalse(); } else { printf("Exception: Invalid Syntax \"%s\"", value); return NULL; } break; } }