123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- using Jint.Collections;
- using Jint.Native.Object;
- using Jint.Runtime;
- using Jint.Runtime.Descriptors;
- using Jint.Runtime.Interop;
- namespace Jint.Native.Json
- {
- public sealed class JsonInstance : ObjectInstance
- {
- private JsValue _reviver;
- private JsonInstance(Engine engine)
- : base(engine, objectClass: "JSON")
- {
- }
- public static JsonInstance CreateJsonObject(Engine engine)
- {
- var json = new JsonInstance(engine)
- {
- _prototype = engine.Object.PrototypeObject
- };
- return json;
- }
- protected override void Initialize()
- {
- _properties = new StringDictionarySlim<PropertyDescriptor>(2)
- {
- ["parse"] = new PropertyDescriptor(new ClrFunctionInstance(Engine, "parse", Parse, 2), true, false, true),
- ["stringify"] = new PropertyDescriptor(new ClrFunctionInstance(Engine, "stringify", Stringify, 3), true, false, true)
- };
- }
- private JsValue AbstractWalkOperation(ObjectInstance thisObject, string prop)
- {
- JsValue value = thisObject.Get(prop, thisObject);
- if (value.IsObject())
- {
- var valueAsObject = value.AsObject();
- if (valueAsObject.Class == "Array")
- {
- var valAsArray = value.AsArray();
- var i = 0;
- var arrLen = valAsArray.GetLength();
- while (i < arrLen)
- {
- var newValue = AbstractWalkOperation(valAsArray, TypeConverter.ToString(i));
- if (newValue.IsUndefined())
- {
- valAsArray.Delete(TypeConverter.ToString(i));
- }
- else
- {
- valAsArray.DefineOwnProperty
- (
- TypeConverter.ToString(i),
- new PropertyDescriptor
- (
- value: newValue,
- PropertyFlag.ConfigurableEnumerableWritable
- ));
- }
- i = i + 1;
- }
- }
- else
- {
- var keys = valueAsObject.GetOwnProperties();
- foreach (var p in keys)
- {
- var newElement = AbstractWalkOperation(valueAsObject, p.Key);
- if (newElement.IsUndefined())
- {
- valueAsObject.Delete(p.Key);
- }
- else
- {
- valueAsObject.DefineOwnProperty(
- p.Key,
- new PropertyDescriptor
- (
- value: newElement,
- PropertyFlag.ConfigurableEnumerableWritable
- ));
- }
- }
- }
- }
- return _reviver.Invoke(thisObject, new JsValue[] { prop, value });
- }
- public JsValue Parse(JsValue thisObject, JsValue[] arguments)
- {
- var parser = new JsonParser(_engine);
- var res = parser.Parse(TypeConverter.ToString(arguments[0]));
- if (arguments.Length > 1)
- {
- this._reviver = arguments[1];
- ObjectInstance revRes = ObjectConstructor.CreateObjectConstructor(_engine).Construct(Arguments.Empty);
- revRes.DefineOwnProperty(
- "",
- new PropertyDescriptor(
- value: res,
- PropertyFlag.ConfigurableEnumerableWritable
- ));
- return AbstractWalkOperation(revRes, "");
- }
- return res;
- }
- public JsValue Stringify(JsValue thisObject, JsValue[] arguments)
- {
- JsValue
- value = Undefined,
- replacer = Undefined,
- space = Undefined;
- if (arguments.Length > 2)
- {
- space = arguments[2];
- }
- if (arguments.Length > 1)
- {
- replacer = arguments[1];
- }
- if (arguments.Length > 0)
- {
- value = arguments[0];
- }
- var serializer = new JsonSerializer(_engine);
- if (value.IsUndefined() && replacer.IsUndefined()) {
- return Undefined;
- }
- return serializer.Serialize(value, replacer, space);
- }
- }
- }
|