예제 #1
0
        public ServiceType GetServiceType(Type type)
        {
            ServiceType serviceType;

            if (_typeCache.TryGetValue(type, out serviceType))
                return serviceType;

            serviceType = new ServiceType(type);

            _typeCache[type] = serviceType;

            serviceType.Build(this);

            return serviceType;
        }
예제 #2
0
        public static void SerializeMessage(JsonTextWriter writer, ServiceType type, object message)
        {
            Require.NotNull(writer, "writer");
            Require.NotNull(type, "type");
            Require.NotNull(message, "message");

            writer.WriteStartObject();

            foreach (var field in type.Fields.Values)
            {
                writer.WritePropertyName(field.Tag.ToString(CultureInfo.InvariantCulture));

                object value = field.Getter(message);

                if (value == null)
                {
                    writer.WriteNull();
                }
                else if (field.CollectionType != null)
                {
                    writer.WriteStartArray();

                    foreach (object item in (IEnumerable)value)
                    {
                        if (field.ServiceType != null)
                            SerializeMessage(writer, field.ServiceType, item);
                        else
                            writer.WriteValue(item);
                    }

                    writer.WriteEndArray();
                }
                else
                {
                    if (field.ServiceType != null)
                        SerializeMessage(writer, field.ServiceType, value);
                    else
                        writer.WriteValue(value);
                }
            }

            writer.WriteEndObject();
        }
예제 #3
0
        public ServiceTypeField(ReflectionOptimizer.Getter getter, ReflectionOptimizer.Setter setter, int tag, bool isRequired, Type type)
        {
            Require.NotNull(getter, "getter");
            Require.NotNull(setter, "setter");
            Require.NotNull(type, "type");

            Getter = getter;
            Setter = setter;
            Tag = tag;
            IsRequired = isRequired;
            Type = type;

            // See whether the field is a collection type.

            var listItemType = TypeUtil.GetCollectionType(type);

            if (listItemType != null)
            {
                // We handle two collection types: List<> and the rest.
                // The rest we handle as an array.

                bool isList = type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>);

                if (isList)
                    CollectionType = type;
                else
                    CollectionType = listItemType.MakeArrayType();

                Type = listItemType;
            }

            // Build the service type if the field type is a protobuf type.

            var typeAttributes = Type.GetCustomAttributes(typeof(ProtoContractAttribute), true);

            if (typeAttributes.Length > 0)
                ServiceType = new ServiceType(Type);
        }
예제 #4
0
        private static object DeserializeMessage(JsonTextReader reader, ServiceType type, bool skipRead)
        {
            Require.NotNull(reader, "reader");
            Require.NotNull(type, "type");

            if (!skipRead && !reader.Read())
                throw new HttpException("Invalid request");

            if (reader.TokenType == JsonToken.Null)
                return null;

            object instance = Activator.CreateInstance(type.Type);

            if (reader.TokenType != JsonToken.StartObject)
                throw new HttpException("Invalid request");

            while (reader.Read())
            {
                if (reader.TokenType == JsonToken.EndObject)
                    break;
                else if (reader.TokenType != JsonToken.PropertyName)
                    throw new HttpException("Invalid request");

                int tag;

                if (!int.TryParse((string)reader.Value, NumberStyles.None, CultureInfo.InvariantCulture, out tag))
                    throw new HttpException("Invalid request");

                ServiceTypeField field;

                if (!type.Fields.TryGetValue(tag, out field))
                    throw new HttpException("Unknown tag");

                if (field.CollectionType != null)
                {
                    var collection = new ArrayList();

                    if (!reader.Read())
                        throw new HttpException("Invalid request");

                    if (reader.TokenType == JsonToken.Null)
                        continue;
                    if (reader.TokenType != JsonToken.StartArray)
                        throw new HttpException("Invalid request");

                    while (reader.Read())
                    {
                        if (reader.TokenType == JsonToken.EndArray)
                            break;

                        if (field.ServiceType != null && !field.ServiceType.Type.IsEnum)
                            collection.Add(DeserializeMessage(reader, field.ServiceType, true));
                        else
                            collection.Add(Convert.ChangeType(reader.Value, field.Type));
                    }

                    if (reader.TokenType != JsonToken.EndArray)
                        throw new HttpException("Invalid request");

                    var targetCollection = (IList)Activator.CreateInstance(field.CollectionType, new object[] { collection.Count });

                    for (int i = 0; i < collection.Count; i++)
                    {
                        if (field.CollectionType.IsArray)
                            targetCollection[i] = collection[i];
                        else
                            targetCollection.Add(collection[i]);
                    }

                    field.Setter(instance, targetCollection);
                }
                else if (field.ServiceType != null && !field.ServiceType.Type.IsEnum)
                {
                    if (!reader.Read())
                        throw new HttpException("Invalid request");

                    field.Setter(instance, DeserializeMessage(reader, field.ServiceType, true));
                }
                else
                {
                    if (!reader.Read())
                        throw new HttpException("Invalid request");

                    field.Setter(instance, reader.Value);
                }
            }

            if (reader.TokenType != JsonToken.EndObject)
                throw new HttpException("Invalid request");

            return instance;
        }
예제 #5
0
 public static object DeserializeMessage(JsonTextReader reader, ServiceType type)
 {
     return DeserializeMessage(reader, type, false);
 }