示例#1
0
        public void ReadValue(JsonAction <object, JsonValueType> value, JsonAction readArray, JsonAction readObject)
        {
            if (value is null)
            {
                throw new ArgumentNullException(nameof(value));
            }
            if (readArray is null)
            {
                throw new ArgumentNullException(nameof(readArray));
            }
            if (readObject is null)
            {
                throw new ArgumentNullException(nameof(readObject));
            }
            switch (Values.Peek().Type)
            {
            case JsonValueType.Array:
                readArray();
                return;

            case JsonValueType.Object:
                readObject();
                return;
            }
            if (JsonApi.HasFlag(Values.Peek().Type, JsonValueType.Value))
            {
                value(Values.Peek().Value, Values.Peek().Type);
                return;
            }
            throw new JsonNotSupportException(Values.Peek().Type);
        }
示例#2
0
 public object Write(object value = null, JsonConfig config = null)
 {
     if (config is null)
     {
         config = JsonConfig.Default;
     }
     WriteParameters[0] = JsonApi.ChangeType(value, AfterType, config);
     return(JsonApi.ChangeType(WriteMethod.Invoke(Instance, WriteParameters), WriteMethod.ReturnType, config));
 }
示例#3
0
 public object Read(object value = null, JsonConfig config = null)
 {
     if (config is null)
     {
         config = JsonConfig.Default;
     }
     ReadParameters[0] = JsonApi.ChangeType(value, BeforeType, config);
     return(JsonApi.ChangeType(ReadMethod.Invoke(Instance, ReadParameters), ReadMethod.ReturnType, config));
 }
示例#4
0
        public object BuildValue(Type type = null, object instance = null)
        {
            object returnValue = null;

            Reader.ReadValue(
                (value, _) => returnValue = JsonApi.ChangeType(value, type, Config),
                () => returnValue         = BuildArray(type, instance),
                () => returnValue         = BuildObject(type, instance)
                );
            return(returnValue);
        }
示例#5
0
        public JsonObject BuildObject(JsonObject jsonObject = null)
        {
            JsonObject returnValue = jsonObject ?? new JsonObject();
            string     key         = null;

            Reader.ReadObject(name => {
                key = name;
                return(true);
            }, () => returnValue.Add(JsonApi.Naming(key, Config.NamingType), BuildValue(returnValue.Get(key))));                //todo 待测试复用是否正常
            return(returnValue);
        }
示例#6
0
 public void BuildObject()
 {
     TextWriter.BeginObject();
     Reader.ReadObject(
         name => {
         TextWriter.Write(JsonApi.Naming(name, Config.NamingType), JsonValueType.String);
         return(true);
     },
         () => BuildValue()
         );
     TextWriter.EndObject();
 }
示例#7
0
 public void ReadValue(JsonAction <object, JsonValueType> value, JsonAction readArray, JsonAction readObject)
 {
     if (value is null)
     {
         throw new ArgumentNullException(nameof(value));
     }
     if (readArray is null)
     {
         throw new ArgumentNullException(nameof(readArray));
     }
     if (readObject is null)
     {
         throw new ArgumentNullException(nameof(readObject));
     }
     if (Stacks.Peek().ArrayType != JsonArrayType.Unknown)
     {
         readArray();
         return;
     }
     if (Stacks.Peek().ObjectType != JsonObjectType.Unknown)
     {
         readObject();
         return;
     }
     Stacks.Peek().IsInitialized = true;
     if (Stacks.Peek().Instance is null)
     {
         value(null, JsonValueType.Null);
         return;
     }
     if (Stacks.Peek().Type is null)
     {
         Stacks.Peek().Type = Stacks.Peek().Instance.GetType();
     }
     if (JsonApi.TryGetValueType(Stacks.Peek().Type, out JsonValueType valueType, Config))
     {
         value(Stacks.Peek().Instance, valueType);
         return;
     }
     if (JsonApi.TryGetArrayType(Stacks.Peek().Type, out Stacks.Peek().ArrayType))
     {
         readArray();
         return;
     }
     if (JsonApi.TryGetObjectType(Stacks.Peek().Type, out Stacks.Peek().ObjectType))
     {
         readObject();
         return;
     }
     throw new JsonNotSupportException(Stacks.Peek().Type);
 }
示例#8
0
        public JsonConverter(Type type)
        {
            Type = type ?? throw new ArgumentNullException(nameof(type));
            Type interfaceType = Type.GetInterface(typeof(IJsonConverter <object, object>).Name);

            if (interfaceType is null)
            {
                throw new JsonException($"{type}需要实现{typeof (IJsonConverter<object, object>)}接口");
            }
            Type[] types = interfaceType.GetGenericArguments();
            BeforeType  = types[0];
            AfterType   = types[1];
            ReadMethod  = interfaceType.GetMethod(nameof(IJsonConverter <object, object> .Read), new Type[] { BeforeType });
            WriteMethod = interfaceType.GetMethod(nameof(IJsonConverter <object, object> .Write), new Type[] { AfterType });
            Instance    = JsonApi.CreateInstance(Type);
        }
示例#9
0
        internal void Write(object value, JsonValueType valueType)
        {
            CheckEnd();
            Head();
            if (JsonApi.HasFlag(Stacks.Peek().Stage, JsonTextWriterStage.Key))
            {
                valueType = JsonValueType.String;
            }
            switch (valueType)
            {
            case JsonValueType.Null:
                TextWriter.Write(JsonKeyword.Null);
                break;

            case JsonValueType.Integer:
                TextWriter.Write(value);
                break;

            case JsonValueType.Decimal:
                TextWriter.Write(value);
                if (value.ToString().IndexOf('.') < 0)
                {
                    TextWriter.Write(".0");
                }
                break;

            case JsonValueType.Bool:
                TextWriter.Write(Convert.ToBoolean(value) ? JsonKeyword.True : JsonKeyword.False);
                break;

            case JsonValueType.String:
                WriteString(JsonApi.CancelUnescape(Convert.ToString(value)));
                break;

            case JsonValueType.DateTime:
                DateTime dateTime = Convert.ToDateTime(value);
                WriteString(Config.UTCTime ? dateTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") : dateTime.ToString());
                break;

            default:
                throw new JsonNotSupportException(valueType);
            }
            Tail();
        }
示例#10
0
 object ConverterRead(Type type, object instance, JsonField field)
 {
     if (type is null)
     {
         throw new ArgumentNullException(nameof(type));
     }
     if (field?.HasConverter ?? false)
     {
         Type readType;
         if (field.ConverterReadType == type.BaseType || JsonApi.GetElementType(field.ConverterReadType) == JsonApi.GetElementType(type).BaseType)                    //todo 让多个转换器之间也支持
         {
             readType = type;
         }
         else
         {
             readType = field.ConverterReadType;
         }
         return(JsonApi.ChangeType(field.ConverterRead(BuildValue(readType, instance), Config), type, Config));
     }
     return(BuildValue(type, instance));
 }
示例#11
0
 void Initialize(bool isArray)
 {
     if (Stacks.Peek().IsInitialized)
     {
         return;
     }
     Stacks.Peek().IsInitialized = true;
     if (Stacks.Peek().Instance is null)
     {
         return;
     }
     if (Stacks.Peek().Type is null)
     {
         Stacks.Peek().Type = Stacks.Peek().Instance.GetType();
     }
     if (isArray)
     {
         JsonApi.TryGetArrayType(Stacks.Peek().Type, out Stacks.Peek().ArrayType);
         return;
     }
     JsonApi.TryGetObjectType(Stacks.Peek().Type, out Stacks.Peek().ObjectType);
 }
示例#12
0
 public void Write(object value)
 {
     if (value is JsonValue jsonValue)
     {
         new JsonTextBuilder(new JsonValueReader(jsonValue, Config), this, Config).BuildValue();
         return;
     }
     if (value is JsonArray array)
     {
         new JsonTextBuilder(new JsonValueReader(array, Config), this, Config).BuildArray();
         return;
     }
     if (value is JsonObject jsonObject)
     {
         new JsonTextBuilder(new JsonValueReader(jsonObject, Config), this, Config).BuildObject();
         return;
     }
     if (JsonApi.TryGetValueType(value, out JsonValueType valueType, Config))
     {
         Write(value, valueType);
         return;
     }
     new JsonTextBuilder(new JsonSerializer(value, Config), this, Config).BuildValue();
 }
示例#13
0
        public void ReadObject(JsonFunc <string, bool> key, JsonAction readValue)
        {
            if (key is null)
            {
                throw new ArgumentNullException(nameof(key));
            }
            if (readValue is null)
            {
                throw new ArgumentNullException(nameof(readValue));
            }
            Initialize(false);
            switch (Stacks.Peek().ObjectType)
            {
            default:
                throw new JsonNotSupportException(Stacks.Peek().ObjectType);

            case JsonObjectType.Class:
                JsonApi.ForEachSerializableMembers(Stacks.Peek().Type, (memberInfo, fieldInfo, propertyInfo, field) => {
                    bool isReaded   = false;
                    object instance = null;
                    Type fieldType  = null;
                    object Read()
                    {
                        if (isReaded)
                        {
                            return(instance);
                        }
                        isReaded = true;
                        switch (memberInfo.MemberType)
                        {
                        default:
                            throw new JsonNotSupportException(memberInfo.MemberType);

                        case MemberTypes.Field:
                            fieldType = fieldInfo.FieldType;
                            return(instance = fieldInfo.GetValue(Stacks.Peek().Instance));

                        case MemberTypes.Property:
                            fieldType = propertyInfo.PropertyType;
                            return(instance = propertyInfo.GetValue(Stacks.Peek().Instance, null));
                        }
                    }
                    object ConverterWrite(object value)
                    {
                        if (field?.HasConverter ?? false)
                        {
                            if (field.ConverterWriteType != fieldType.BaseType &&
                                JsonApi.GetElementType(field.ConverterWriteType) != JsonApi.GetElementType(fieldType).BaseType
                                )
                            {
                                fieldType = field.ConverterWriteType;
                            }
                            return(field.ConverterWrite(value, Config));
                        }
                        return(value);
                    }
                    if (!JsonApi.CanSerializeValue(Read(), Config))
                    {
                        return;
                    }
                    if (key(field?.Name ?? memberInfo.Name))
                    {
                        Stacks.Push(new JsonSerializerStack(ConverterWrite(Read()), field));
                        Stacks.Peek().Type = fieldType;
                        readValue();
                        Stacks.Pop();
                    }
                });
                break;

            case JsonObjectType.DataRow: {
                DataRow dataRow = (DataRow)Stacks.Peek().Instance;
                for (int i = 0; i < dataRow.Table.Columns.Count; i++)
                {
                    if (key(dataRow.Table.Columns[i].ColumnName))
                    {
                        Stacks.Push(new JsonSerializerStack(dataRow[i]));
                        readValue();
                        Stacks.Pop();
                    }
                }
                break;
            }

            case JsonObjectType.DataSet: {
                DataSet dataSet = (DataSet)Stacks.Peek().Instance;
                foreach (DataTable dataTable in dataSet.Tables)
                {
                    if (key(dataTable.TableName))
                    {
                        Stacks.Push(new JsonSerializerStack(dataTable));
                        readValue();
                        Stacks.Pop();
                    }
                }
                break;
            }

            case JsonObjectType.GenericDictionary:
            case JsonObjectType.GenericSortedDictionary:
            case JsonObjectType.GenericSortedList: {
                IDictionary dictionary = (IDictionary)Stacks.Peek().Instance;
                foreach (DictionaryEntry entry in dictionary)
                {
                    if (key(Convert.ToString(entry.Key)))
                    {
                        Stacks.Push(new JsonSerializerStack(entry.Value));
                        readValue();
                        Stacks.Pop();
                    }
                }
                break;
            }

            case JsonObjectType.GenericKeyValuePair: {
                if (key(Convert.ToString(Stacks.Peek().Type.GetProperty("Key").GetValue(Stacks.Peek().Instance, null))))
                {
                    Stacks.Push(new JsonSerializerStack(Stacks.Peek().Type.GetProperty("Value").GetValue(Stacks.Peek().Instance, null)));
                    readValue();
                    Stacks.Pop();
                }
                break;
            }
            }
        }
示例#14
0
        public object BuildArray(Type type, object instance = null)
        {
            if (type is null)
            {
                throw new ArgumentNullException(nameof(type));
            }
            if (!JsonApi.TryGetArrayType(type, out JsonArrayType arrayType))
            {
                throw new JsonNotSupportException(type);
            }
            switch (arrayType)
            {
            default:
                throw new JsonNotSupportException(arrayType);

            case JsonArrayType.Array: {
                JsonArray  jsonArray = new JsonValueBuilder(Reader, Config).BuildArray();
                List <int> bounds    = new List <int> ();
                MeasureArray(jsonArray, ref bounds);
                if (bounds.Count != type.GetArrayRank())
                {
                    throw new JsonException("数组维数不匹配");
                }
                Type  elementType = type.GetElementType();
                Array array       = null;
                bool  create      = false;
                if (instance?.GetType() != type)
                {
                    create = true;
                }
                else
                {
                    array = (Array)instance;
                    for (int i = 0; i < array.Rank; i++)
                    {
                        if (array.GetLength(i) != bounds[i])
                        {
                            create = true;
                            break;
                        }
                    }
                }
                if (create)
                {
                    if (bounds.Count == 1)
                    {
                        array = Array.CreateInstance(elementType, bounds[0]);
                    }
                    else
                    {
                        array = Array.CreateInstance(elementType, bounds.ToArray());
                    }
                }
                if (array.Rank == 1)
                {
                    for (int i = 0; i < jsonArray.Count; i++)
                    {
                        JsonDeserializer deserializer = new JsonDeserializer(new JsonValueReader(jsonArray[i], Config), Config);
                        array.SetValue(deserializer.BuildValue(elementType, array.GetValue(i)), i);
                    }
                    return(array);
                }
                int[] indices   = new int[bounds.Count];
                int   dimension = 0;
                void ForEachArray(JsonArray currentArray)
                {
                    int length = bounds[dimension];

                    for (int i = 0; i < length; i++)
                    {
                        indices[dimension] = i;
                        if (dimension == indices.Length - 1)
                        {
                            JsonDeserializer deserializer = new JsonDeserializer(new JsonValueReader(currentArray[i], Config), Config);
                            array.SetValue(deserializer.BuildValue(elementType, array.GetValue(indices)), indices);
                            continue;
                        }
                        dimension++;
                        ForEachArray(currentArray[i]);
                    }
                    dimension--;
                }

                ForEachArray(jsonArray);
                return(array);
            }

            case JsonArrayType.GenericList:
            case JsonArrayType.GenericIList:
            case JsonArrayType.GenericObservableCollection: {
                Type elementType = type.GetGenericArguments()[0];
                if (instance?.GetType() != type)
                {
                    if (type.IsInterface)
                    {
                        switch (arrayType)
                        {
                        default:
                            throw new JsonNotSupportException(arrayType);

                        case JsonArrayType.GenericIList:
                            instance = JsonApi.CreateInstance(typeof(List <>).MakeGenericType(elementType));
                            break;
                        }
                    }
                    else
                    {
                        instance = JsonApi.CreateInstance(type);
                    }
                }
                IList list     = (IList)instance;
                int   oldCount = list.Count;
                int   newCount = 0;
                Reader.ReadArray(i => {
                        newCount = i + 1;
                        if (i < oldCount)
                        {
                            list[i] = BuildValue(elementType, list[i]);
                            return;
                        }
                        list.Add(BuildValue(elementType));
                    });
                while (list.Count > newCount)
                {
                    list.RemoveAt(list.Count - 1);
                }
                return(list);
            }

            case JsonArrayType.DataTable: {
                if (instance?.GetType() != type)
                {
                    instance = JsonApi.CreateInstance(type);
                }
                DataTable dataTable    = (DataTable)instance;
                int       columnNumber = dataTable.Columns.Count;
                int       columnIndex;
                ArrayList arrayList = null;
                object[]  values    = null;
                Reader.ReadArray(i => {
                        bool hasRow = dataTable.Rows.Count > i;
                        if (!hasRow)
                        {
                            if (i == 0)
                            {
                                arrayList = new ArrayList();
                            }
                            else if (values is null)
                            {
                                values = new object[columnNumber];
                            }
                        }
                        columnIndex = 0;
                        Reader.ReadObject(columnName => {
                            if (!hasRow && i == 0)
                            {
                                columnNumber++;
                                dataTable.Columns.Add(columnName);
                            }
                            return(true);
                        }, () => {
                            object value = BuildValue();
                            if (hasRow)
                            {
                                dataTable.Rows[i].ItemArray[columnIndex] = value;
                                return;
                            }
                            if (i == 0)
                            {
                                arrayList.Add(value);
                                return;
                            }
                            values[columnIndex] = value;
                            columnIndex++;
                        });
                        if (!hasRow)
                        {
                            dataTable.Rows.Add(i == 0 ? arrayList.ToArray() : values);
                        }
                    });
                return(dataTable);
            }
            }
        }
示例#15
0
        public object BuildObject(Type type, object instance = null)
        {
            if (type is null)
            {
                throw new ArgumentNullException(nameof(type));
            }
            if (!JsonApi.TryGetObjectType(type, out JsonObjectType objectType))
            {
                throw new JsonNotSupportException(type);
            }
            if (instance?.GetType() != type)
            {
                instance = JsonApi.CreateInstance(type);
            }
            switch (objectType)
            {
            default:
                throw new JsonNotSupportException(objectType);

            case JsonObjectType.Class: {
                MemberInfo   memberInfo   = null;
                FieldInfo    fieldInfo    = null;
                PropertyInfo propertyInfo = null;
                JsonField    field        = null;
                Reader.ReadObject(name => {
                        foreach (MemberInfo current in JsonApi.GetMembers(type))
                        {
                            if (JsonApi.CanSerializeMember(current, out fieldInfo, out propertyInfo, out field))
                            {
                                if (JsonApi.Equals(name, field?.Name ?? current.Name, Config))
                                {
                                    memberInfo = current;
                                    return(true);
                                }
                            }
                        }
                        return(false);
                    }, () => {
                        object value;
                        switch (memberInfo.MemberType)
                        {
                        default:
                            throw new JsonNotSupportException(memberInfo.MemberType);

                        case MemberTypes.Field:
                            value = ConverterRead(fieldInfo.FieldType, fieldInfo.GetValue(instance), field);
                            break;

                        case MemberTypes.Property:
                            value = ConverterRead(propertyInfo.PropertyType, propertyInfo.GetValue(instance, null), field);
                            break;
                        }
                        if (!JsonApi.CanSerializeValue(value, Config))
                        {
                            return;
                        }
                        switch (memberInfo.MemberType)
                        {
                        default:
                            throw new JsonNotSupportException(memberInfo.MemberType);

                        case MemberTypes.Field:
                            fieldInfo.SetValue(instance, value);
                            break;

                        case MemberTypes.Property:
                            propertyInfo.SetValue(instance, value, null);
                            break;
                        }
                    });
                return(instance);
            }

            case JsonObjectType.DataSet: {
                DataSet dataSet   = (DataSet)instance;
                string  tableName = null;
                Reader.ReadObject(name => {
                        tableName = name;
                        return(true);
                    }, () => {
                        DataTable dataTable = dataSet.Tables[tableName];
                        bool hasTable       = dataTable != null;
                        dataTable           = BuildArray <DataTable> (dataTable);
                        if (!hasTable)
                        {
                            dataSet.Tables.Add(dataTable);
                        }
                        dataTable.TableName = JsonApi.Naming(tableName, Config.NamingType);
                    });
                return(instance);
            }

            case JsonObjectType.GenericDictionary:
            case JsonObjectType.GenericSortedDictionary:
            case JsonObjectType.GenericSortedList: {
                Type        keyType    = type.GetGenericArguments()[0];
                Type        valueType  = type.GetGenericArguments()[1];
                IDictionary dictionary = (IDictionary)instance;
                dictionary.Clear();
                object key = null;
                Reader.ReadObject(name => {
                        key = JsonApi.ChangeType(JsonApi.Naming(name, Config.NamingType), keyType, Config);
                        return(true);
                    }, () => {
                        dictionary[key] = BuildValue(valueType);
                    });
                return(instance);
            }

            case JsonObjectType.GenericKeyValuePair: {
                Type keyType   = type.GetGenericArguments()[0];
                Type valueType = type.GetGenericArguments()[1];
                Reader.ReadObject(name => {
                        type.GetRuntimeField("key").SetValue(instance, JsonApi.ChangeType(JsonApi.Naming(name, Config.NamingType), keyType, Config));
                        return(true);
                    }, () => {
                        FieldInfo fieldInfo = type.GetRuntimeField("value");
                        fieldInfo.SetValue(instance, BuildValue(valueType, fieldInfo.GetValue(instance)));
                    });
                return(instance);
            }
            }
        }