void fxSerializeJSONNumber(txMachine* the, txJSONSerializer* theSerializer, txNumber theNumber) { int fpclass = c_fpclassify(theNumber); if ((fpclass != FP_NAN) && (fpclass != FP_INFINITE)) { char aBuffer[256]; fxNumberToString(the, theNumber, aBuffer, sizeof(aBuffer), 0, 0); fxSerializeJSONChars(the, theSerializer, aBuffer); } else fxSerializeJSONChars(the, theSerializer, "null"); }
void fxSerializeJSONIndent(txMachine* the, txJSONSerializer* theSerializer) { txInteger aLevel; if (theSerializer->indent[0]) { fxSerializeJSONChar(the, theSerializer, '\r'); for (aLevel = 0; aLevel < theSerializer->level; aLevel++) fxSerializeJSONChars(the, theSerializer, theSerializer->indent); } }
void fxSerializeJSONName(txMachine* the, txJSONSerializer* theSerializer, txFlag* theFlag) { txSlot* aSlot = the->stack; if (*theFlag & 1) { fxSerializeJSONChars(the, theSerializer, ","); fxSerializeJSONIndent(the, theSerializer); } else *theFlag |= 1; if (*theFlag & 2) { if (aSlot->kind == XS_INTEGER_KIND) { fxSerializeJSONChar(the, theSerializer, '"'); fxSerializeJSONInteger(the, theSerializer, aSlot->value.integer); fxSerializeJSONChar(the, theSerializer, '"'); } else fxSerializeJSONString(the, theSerializer, aSlot->value.string); fxSerializeJSONChars(the, theSerializer, ":"); } the->stack++; // POP KEY }
void fxSerializeJSONString(txMachine* the, txJSONSerializer* theStream, txString theString) { static char gxDigits[] = "0123456789ABCDEF"; txU1* aString = (txU1*)theString; txU4 aResult; txUTF8Sequence *aSequence; txInteger aSize; char aBuffer[8]; fxSerializeJSONChar(the, theStream, '"'); aString = (txU1*)theString; while ((aResult = *aString++)) { for (aSequence = gxUTF8Sequences; aSequence->size; aSequence++) { if ((aResult & aSequence->cmask) == aSequence->cval) break; } aSize = aSequence->size - 1; while (aSize > 0) { aSize--; aResult = (aResult << 6) | (*aString++ & 0x3F); } aResult &= aSequence->lmask; switch (aResult) { case 8: fxSerializeJSONChars(the, theStream, "\\b"); break; case 9: fxSerializeJSONChars(the, theStream, "\\t"); break; case 10: fxSerializeJSONChars(the, theStream, "\\n"); break; case 12: fxSerializeJSONChars(the, theStream, "\\f"); break; case 13: fxSerializeJSONChars(the, theStream, "\\r"); break; case 34: fxSerializeJSONChars(the, theStream, "\\\""); break; case 92: fxSerializeJSONChars(the, theStream, "\\\\"); break; default: if ((32 <= aResult) && (aResult < 127)) fxSerializeJSONChar(the, theStream, (char)aResult); else { aBuffer[0] = '\\'; aBuffer[1] = 'u'; aBuffer[2] = gxDigits[(aResult & 0x0000F000) >> 12]; aBuffer[3] = gxDigits[(aResult & 0x00000F00) >> 8]; aBuffer[4] = gxDigits[(aResult & 0x000000F0) >> 4]; aBuffer[5] = gxDigits[(aResult & 0x0000000F)]; aBuffer[6] = 0; fxSerializeJSONChars(the, theStream, aBuffer); } break; } } fxSerializeJSONChar(the, theStream, '"'); }
void fxSerializeJSONProperty(txMachine* the, txJSONSerializer* theSerializer, txFlag* theFlag) { txSlot* aWrapper = the->stack + 2; txSlot* aValue = the->stack + 1; txSlot* aKey = the->stack; txSlot* anInstance; txSlot* aProperty; txFlag aFlag; txIndex aLength, anIndex; txFlag aMask; if (mxIsReference(aValue)) { anInstance = fxGetInstance(the, aValue); if (anInstance->flag & XS_LEVEL_FLAG) fxSerializeJSONError(the, theSerializer, XS_TYPE_ERROR); aProperty = fxGetProperty(the, anInstance, the->toJSONID); if (aProperty && mxIsReference(aProperty) && mxIsFunction(fxGetInstance(the, aProperty))) { *(--the->stack) = *aKey; mxInitSlot(--the->stack, XS_INTEGER_KIND); the->stack->value.integer = 1; /* THIS */ *(--the->stack) = *aValue; /* FUNCTION */ *(--the->stack) = *aProperty; /* RESULT */ mxZeroSlot(--the->stack); fxRunID(the, the->toJSONID); *aValue = *(the->stack++); } } else anInstance = C_NULL; if (theSerializer->replacer) { *(--the->stack) = *aKey; *(--the->stack) = *aValue; mxInitSlot(--the->stack, XS_INTEGER_KIND); the->stack->value.integer = 2; /* THIS */ *(--the->stack) = *aWrapper; /* FUNCTION */ *(--the->stack) = *theSerializer->replacer; /* RESULT */ mxZeroSlot(--the->stack); fxRunID(the, XS_NO_ID); *aValue = *(the->stack++); } again: switch (aValue->kind) { case XS_NULL_KIND: fxSerializeJSONName(the, theSerializer, theFlag); fxSerializeJSONChars(the, theSerializer, "null"); break; case XS_BOOLEAN_KIND: fxSerializeJSONName(the, theSerializer, theFlag); fxSerializeJSONChars(the, theSerializer, aValue->value.boolean ? "true" : "false"); break; case XS_INTEGER_KIND: fxSerializeJSONName(the, theSerializer, theFlag); fxSerializeJSONInteger(the, theSerializer, aValue->value.integer); break; case XS_NUMBER_KIND: fxSerializeJSONName(the, theSerializer, theFlag); fxSerializeJSONNumber(the, theSerializer, aValue->value.number); break; case XS_STRING_KIND: fxSerializeJSONName(the, theSerializer, theFlag); fxSerializeJSONString(the, theSerializer, aValue->value.string); break; case XS_ARRAY_KIND: fxSerializeJSONName(the, theSerializer, theFlag); anInstance->flag |= XS_LEVEL_FLAG; fxSerializeJSONChar(the, theSerializer, '['); theSerializer->level++; fxSerializeJSONIndent(the, theSerializer); aFlag = 4; aLength = aValue->value.array.length; for (anIndex = 0; anIndex < aLength; anIndex++) { aProperty = aValue->value.array.address + anIndex; mxInitSlot(--the->stack, aProperty->kind); the->stack->value = aProperty->value; mxInitSlot(--the->stack, XS_INTEGER_KIND); the->stack->value.integer = anIndex; fxSerializeJSONProperty(the, theSerializer, &aFlag); } theSerializer->level--; fxSerializeJSONIndent(the, theSerializer); fxSerializeJSONChar(the, theSerializer, ']'); anInstance->flag &= ~XS_LEVEL_FLAG; break; case XS_REFERENCE_KIND: case XS_ALIAS_KIND: anInstance = fxGetInstance(the, aValue); if (anInstance->flag & XS_VALUE_FLAG) { aValue = anInstance->next; goto again; } fxSerializeJSONName(the, theSerializer, theFlag); fxSerializeJSONChar(the, theSerializer, '{'); theSerializer->level++; fxSerializeJSONIndent(the, theSerializer); aFlag = 2; if ((the->frame->flag & XS_SANDBOX_FLAG) || (anInstance->flag & XS_SANDBOX_FLAG)) { if (anInstance->flag & XS_SANDBOX_FLAG) anInstance = anInstance->value.instance.prototype; aMask = XS_DONT_ENUM_FLAG | XS_DONT_SCRIPT_FLAG; } else aMask = XS_DONT_ENUM_FLAG | XS_SANDBOX_FLAG; anInstance->flag |= XS_LEVEL_FLAG; aProperty = anInstance->next; while (aProperty) { if (!(aProperty->flag & aMask)) { txID anID = aProperty->ID; if (anID != XS_NO_ID) { mxInitSlot(--the->stack, aProperty->kind); the->stack->value = aProperty->value; if (anID < 0) { txSlot *aSymbol = fxGetSymbol(the, aProperty->ID); mxInitSlot(--the->stack, XS_STRING_KIND); the->stack->value.string = aSymbol->value.symbol.string; } else { mxInitSlot(--the->stack, XS_INTEGER_KIND); the->stack->value.integer = anID; } fxSerializeJSONProperty(the, theSerializer, &aFlag); } } aProperty = aProperty->next; } theSerializer->level--; fxSerializeJSONIndent(the, theSerializer); fxSerializeJSONChar(the, theSerializer, '}'); anInstance->flag &= ~XS_LEVEL_FLAG; break; default: if (*theFlag & 4) { if (*theFlag & 1) { fxSerializeJSONChars(the, theSerializer, ","); fxSerializeJSONIndent(the, theSerializer); } else *theFlag |= 1; fxSerializeJSONChars(the, theSerializer, "null"); } break; } the->stack++; // POP VALUE }
void fxSerializeJSONInteger(txMachine* the, txJSONSerializer* theSerializer, txInteger theInteger) { char aBuffer[256]; fxIntegerToString(theInteger, aBuffer, sizeof(aBuffer)); fxSerializeJSONChars(the, theSerializer, aBuffer); }
void fxSerializeJSONProperty(txMachine* the, txJSONSerializer* theSerializer, txInteger* theFlag) { txSlot* aWrapper = the->stack + 2; txSlot* aValue = the->stack + 1; txSlot* aKey = the->stack; txSlot* anInstance; txSlot* aProperty; txInteger aFlag; txIndex aLength, anIndex; if (mxIsReference(aValue)) { anInstance = fxGetInstance(the, aValue); if (anInstance->flag & XS_LEVEL_FLAG) mxTypeError("cyclic value"); mxPushSlot(aKey); /* COUNT */ mxPushInteger(1); /* THIS */ mxPushSlot(aValue); /* FUNCTION */ mxPushSlot(aValue); fxGetID(the, mxID(_toJSON)); if (mxIsReference(the->stack) && mxIsFunction(the->stack->value.reference)) { fxCall(the); mxPullSlot(aValue); } else { the->stack = aKey; } } else anInstance = C_NULL; if (theSerializer->replacer) { mxPushSlot(aKey); mxPushSlot(aValue); /* COUNT */ mxPushInteger(2); /* THIS */ mxPushSlot(aWrapper); /* FUNCTION */ mxPushSlot(theSerializer->replacer); fxCall(the); mxPullSlot(aValue); } again: switch (aValue->kind) { case XS_NULL_KIND: fxSerializeJSONName(the, theSerializer, theFlag); fxSerializeJSONChars(the, theSerializer, "null"); break; case XS_BOOLEAN_KIND: fxSerializeJSONName(the, theSerializer, theFlag); fxSerializeJSONChars(the, theSerializer, aValue->value.boolean ? "true" : "false"); break; case XS_INTEGER_KIND: fxSerializeJSONName(the, theSerializer, theFlag); fxSerializeJSONInteger(the, theSerializer, aValue->value.integer); break; case XS_NUMBER_KIND: fxSerializeJSONName(the, theSerializer, theFlag); fxSerializeJSONNumber(the, theSerializer, aValue->value.number); break; case XS_STRING_KIND: case XS_STRING_X_KIND: fxSerializeJSONName(the, theSerializer, theFlag); fxSerializeJSONString(the, theSerializer, aValue->value.string); break; case XS_ARRAY_KIND: fxSerializeJSONName(the, theSerializer, theFlag); anInstance->flag |= XS_LEVEL_FLAG; fxSerializeJSONChar(the, theSerializer, '['); theSerializer->level++; fxSerializeJSONIndent(the, theSerializer); aFlag = 4; aLength = aValue->value.array.length; for (anIndex = 0; anIndex < aLength; anIndex++) { aProperty = aValue->value.array.address + anIndex; mxPushSlot(aProperty); mxPushInteger(anIndex); fxSerializeJSONProperty(the, theSerializer, &aFlag); } theSerializer->level--; fxSerializeJSONIndent(the, theSerializer); fxSerializeJSONChar(the, theSerializer, ']'); anInstance->flag &= ~XS_LEVEL_FLAG; break; case XS_REFERENCE_KIND: anInstance = fxGetInstance(the, aValue); aValue = anInstance->next; if (aValue && (aValue->flag & XS_INTERNAL_FLAG) && (aValue->kind != XS_PROXY_KIND)) { goto again; } fxSerializeJSONName(the, theSerializer, theFlag); anInstance->flag |= XS_LEVEL_FLAG; if (fxIsArray(the, anInstance)) { fxSerializeJSONChar(the, theSerializer, '['); theSerializer->level++; fxSerializeJSONIndent(the, theSerializer); aFlag = 4; mxPushReference(anInstance); fxGetID(the, mxID(_length)); aLength = fxToInteger(the, the->stack); mxPop(); for (anIndex = 0; anIndex < aLength; anIndex++) { mxPushReference(anInstance); fxGetID(the, anIndex); mxPushInteger(anIndex); fxSerializeJSONProperty(the, theSerializer, &aFlag); } theSerializer->level--; fxSerializeJSONIndent(the, theSerializer); fxSerializeJSONChar(the, theSerializer, ']'); } else { fxSerializeJSONChar(the, theSerializer, '{'); theSerializer->level++; fxSerializeJSONIndent(the, theSerializer); aFlag = 2; { txSlot aContext; aContext.value.regexp.code = theSerializer; aContext.value.regexp.offsets = &aFlag; fxEachInstanceProperty(the, anInstance, XS_EACH_ENUMERABLE_FLAG | XS_EACH_STRING_FLAG | XS_STEP_GET_FLAG, fxSerializeJSONOwnProperty, &aContext, anInstance); } theSerializer->level--; fxSerializeJSONIndent(the, theSerializer); fxSerializeJSONChar(the, theSerializer, '}'); } anInstance->flag &= ~XS_LEVEL_FLAG; break; default: if (*theFlag & 4) { if (*theFlag & 1) { fxSerializeJSONChars(the, theSerializer, ","); fxSerializeJSONIndent(the, theSerializer); } else *theFlag |= 1; fxSerializeJSONChars(the, theSerializer, "null"); } break; } the->stack++; // POP VALUE }