Beispiel #1
0
        private object DeserializeArrayItem(string json, ref int currentReadIndex, int arrayItemIndex, SerializationContext context)
        {
            if (json[currentReadIndex] == 'n' &&
                json[currentReadIndex + 1] == 'u' &&
                json[currentReadIndex + 2] == 'l' &&
                json[currentReadIndex + 3] == 'l')
            {
                currentReadIndex = currentReadIndex + 4;
                return(null);
            }

            //Type objectTargetType = null;
            if (json[currentReadIndex + 2] == '#' &&
                json[currentReadIndex + 3] == 't' &&
                json[currentReadIndex + 4] == 'y' &&
                json[currentReadIndex + 5] == 'p' &&
                json[currentReadIndex + 6] == 'e'
                )
            {
                return(DeserializeSpecialType(json, ref currentReadIndex, context, currentReadIndex));
            }

            object itemValue;

            if (this.isObject)
            {
                // determine target type during deserialization
                Type type = null;
                if (unknownTypeResolver != null)
                {
                    context.Key             = this.key;
                    context.ValueStartIndex = currentReadIndex;
                    context.ArrayIndex      = arrayItemIndex;
                    context.JsonString      = json;

                    type = unknownTypeResolver(context);

                    context.ArrayIndex = null;
                }

                if (type == null || type.Equals(typeof(object)))
                {
                    type = Structure.GetDefaultType(json, currentReadIndex);

                    if (type == null)
                    {
                        int    readCount = Math.Min(json.Length - currentReadIndex, 25);
                        string jsonPart  = json.Substring(currentReadIndex, readCount);

                        throw new InvalidOperationException(string.Format("Unable to get the target type for array object index {0}; Key: {1}; JSON part: \"{2}\"", arrayItemIndex, this.key, jsonPart));
                    }
                }

                IJsonTypeStructure currentObjectStructure;
                if (!typeSerializerCache.TryGetValue(type, out currentObjectStructure))
                {
                    currentObjectStructure    = Structure.DetermineStructure(type, GetNestedArrayKey(this.key, arrayItemIndex), context, true);
                    typeSerializerCache[type] = currentObjectStructure;
                }

                itemValue = currentObjectStructure.Deserialize(json, ref currentReadIndex, context);
            }
            else
            {
                if (itemDeSerializer == null)
                {
                    itemDeSerializer = Structure.DetermineStructure(itemType, key, context, true);
                }

                // fixed array target type
                itemValue = itemDeSerializer.Deserialize(json, ref currentReadIndex, context);
            }

            return(itemValue);
        }
Beispiel #2
0
        // ----------------------------------------------------------------------------------------
        #endregion

        #region StructureArray properties
        // ----------------------------------------------------------------------------------------
        // StructureArray properties
        // ----------------------------------------------------------------------------------------

        // ----------------------------------------------------------------------------------------
        #endregion

        #region StructureArray methods
        // ----------------------------------------------------------------------------------------
        // StructureArray methods
        // ----------------------------------------------------------------------------------------

        /// <summary>
        /// Serializes the specified object.
        /// </summary>
        /// <param name="sb">The string builder.</param>
        /// <param name="obj">The object to serialize.</param>
        /// <param name="context">The context.</param>
        public override void Serialize(StringBuilder sb, object obj, SerializationContext context)
        {
            if (keyExpected)
            {
                sb.Append(Structure.QuotationMark);
                sb.Append(key);
                if (obj == null)
                {
                    sb.Append(Structure.QuotationColonNullValue);
                    return;
                }
                else
                {
                    sb.Append(Structure.QuotationColonSeparator);
                }
            }

            if (isByteArray)
            {
                // Optimization: add byte array as base64 encoded string
                sb.Append(Structure.CharQuotationMark);
                byte[] data = (byte[])obj;
                sb.Append(Convert.ToBase64String(data));
                sb.Append(Structure.CharQuotationMark);
            }
            else
            {
                sb.Append(Structure.CharLeftSquareBrace);


                //Type collType = obj.GetType();

                // check if own collection implementation exposes special target type // todo: check if possible and required
                //bool specialTypeAdded = false;
                //if (!collType.IsArray
                //    && !IsSystemCollection(collType))
                //    //&& !checkedSubInterfaceTypes.Contains(collType))
                //{
                //    var exposureAttributes = collType.GetCustomAttributes(typeof(ExposeSubTypeAttribute), false);
                //    if (exposureAttributes.Length > 0)
                //    {
                //        // expose specialized sub interface type
                //        if (this.typeSerializerCache == null)
                //            this.typeSerializerCache = new Dictionary<Type, IJsonTypeStructure>();

                //        // add typed collection attribute
                //        sb.Append(Structure.TypeMetaTagJson);
                //        sb.Append(this.type.FullName);
                //        sb.Append(Structure.CharQuotationMark);

                //        specialTypeAdded = true;
                //    }
                //    //checkedSubInterfaceTypes.Add(collType);
                //}

                IEnumerable collection = (IEnumerable)obj;

                int count = 0;
                foreach (var item in collection)
                {
                    //if (specialTypeAdded
                    //    && count == 0)
                    //{
                    //    sb.Append(Structure.CharComma);
                    //}

                    if (item != null)
                    {
                        if (isObject)
                        {
                            // determine serialize type
                            Type itemType = item.GetType();
                            IJsonTypeStructure currentObjectStructure;
                            if (!typeSerializerCache.TryGetValue(itemType, out currentObjectStructure))
                            {
                                Type targetType = null;
                                if (unknownTypeResolver != null)
                                {
                                    context.Key        = this.key;
                                    context.ArrayIndex = count;

                                    targetType = unknownTypeResolver(context);

                                    context.ArrayIndex = null;
                                }
                                if (targetType == null)
                                {
                                    targetType = itemType;
                                }
                                currentObjectStructure = Structure.DetermineStructure(targetType, GetNestedArrayKey(this.key, count), context, true);

                                typeSerializerCache[itemType] = currentObjectStructure;
                            }

                            currentObjectStructure.Serialize(sb, item, context);
                        }
                        else
                        {
                            if (itemSerializer == null)
                            {
                                this.itemSerializer = Structure.DetermineStructure(itemType, key, context, true);
                            }

                            // use static serialize type
                            itemSerializer.Serialize(sb, item, context);
                        }
                    }
                    else
                    {
                        sb.Append(Structure.NullValue);
                    }
                    sb.Append(Structure.CharComma);
                    count++;
                }
                if (count > 0)
                {
                    sb.Length -= 1; // remove last comma
                }

                sb.Append(Structure.CharRightSquareBracet);
            }
        }