예제 #1
0
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");
}
예제 #2
0
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);
	}
}
예제 #3
0
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
}
예제 #4
0
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, '"');
}
예제 #5
0
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
}
예제 #6
0
void fxSerializeJSONInteger(txMachine* the, txJSONSerializer* theSerializer, txInteger theInteger)
{
	char aBuffer[256];
	fxIntegerToString(theInteger, aBuffer, sizeof(aBuffer));
	fxSerializeJSONChars(the, theSerializer, aBuffer);
}
예제 #7
0
파일: xs6JSON.c 프로젝트: basuke/kinomajs
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
}