Exemple #1
0
        public void TypelessWriteVectorObject(IList vector)
        {
            if (WriteVectorHeader(vector, (uint)vector.Count, true))
            {
                return;
            }

            // get type of vector element
            Type elementType = vector.GetType().GetGenericArguments()[0];
            // get class info for type
            string alias = Amf3ClassDef.GetAliasFromType(elementType);

            // get alias of vector element from info
            if (alias == null)
            {
                alias = elementType.FullName;
            }
            // write vector element class alias
            TypelessWrite(alias);

            foreach (object i in vector)
            {
                Write(i);
            }
        }
Exemple #2
0
        private IAmf3Serializer GetSerializerForType(System.Type type)
        {
            IAmf3Serializer serializer;

            if (!typeToSerializer.TryGetValue(type, out serializer))
            {
                var alias = Amf3ClassDef.GetAliasFromType(type);
                if (alias != null)
                {
                    serializer = Amf3ClassDef.GetSerializerFromAlias(alias);
                    if (serializer == null)
                    {
                        // create reflection serializer
                        serializer = new ReflectionSerializer(alias, type, true, false);
                        // automatically register it
                        Amf3ClassDef.RegisterSerializer(alias, serializer);
                    }
                }
                else
                {
                    // create anonymous serializer
                    serializer = new ReflectionSerializer("*", type, true, false);
                }
                // store serializer in our local cache
                typeToSerializer.Add(type, serializer);
            }
            return(serializer);
        }
Exemple #3
0
        private Amf3ClassDef ReadAmf3ClassDef(Amf3Object.Flags flags)
        {
            bool   externalizable = ((flags & Amf3Object.Flags.Externalizable) != 0);
            bool   dynamic        = ((flags & Amf3Object.Flags.Dynamic) != 0);
            string name           = ReadString();

            if (externalizable && dynamic)
            {
                throw new InvalidOperationException("Serialized objects cannot be both dynamic and externalizable");
            }

            List <string> properties = new List <string>();

            int members = ((int)flags) >> 4;

            for (int i = 0; i < members; i++)
            {
                properties.Add(ReadString());
            }

            Amf3ClassDef classDef = new Amf3ClassDef(name, properties.ToArray(), dynamic, externalizable);

            // lookup serializer to use for this class definition
            classDef.Serializer = GetSerializerFromAlias(classDef.Name);

            traitTable.Add(classDef);
            return(classDef);
        }
        public object NewInstance(Amf3ClassDef classDef)
        {
            var expando = new ExpandoObject(classDef.Properties.Length);

            // assign class definition to expando object
            expando.ClassDefinition = classDef;
            return(expando);
        }
Exemple #5
0
        public Amf3Object(Amf3ClassDef classDef)
        {
            if (classDef == null)
            {
                throw new ArgumentNullException("classDef");
            }

            ClassDef   = classDef;
            Properties = new Dictionary <string, object>();
        }
		public static void EmitAllSerializerCode(TextWriter tw, Func<System.Type, Mode> modeSelector)
		{
			var list = Amf3ClassDef.GetAllRegisteredTypes();
			foreach (var kvp in list)
			{
				// apply filter
				var mode = modeSelector(kvp.Value);
				if (mode != Mode.Skip) {
					EmitSerializerCode(tw, mode, kvp.Key, kvp.Value);
				}
			}
		}
Exemple #7
0
        public Amf3Object(Amf3ClassDef classDef)
        {
            if (classDef == null)
            {
                throw new ArgumentNullException("classDef");
            }

            // set class definition
            ClassDef = classDef;

            // allocate property values
            Values = new Variant[classDef.Properties.Length];
        }
Exemple #8
0
        public void TypelessWrite(Amf3ClassDef classDef)
        {
            // have we written this class before with this writer?
            if (classDef.mWriter == this)
            {
                // use the cached id in the class definition
                TypelessWrite((classDef.mId << 2) | 1);
                return;
            }

            int index;

            if (classDefTable.TryGetValue(classDef, out index))
            {
                // store class id inside of class def for this writer
                classDef.mWriter = this;
                classDef.mId     = index;

                TypelessWrite((index << 2) | 1);
            }
            else
            {
                // store class id inside of class def for this writer
                classDef.mWriter = this;
                classDef.mId     = classDefTable.Count;

                // store class reference in lookup table
                classDefTable[classDef] = classDef.mId;

                Amf3Object.Flags flags = Amf3Object.Flags.Inline | Amf3Object.Flags.InlineClassDef;

                if (classDef.Externalizable)
                {
                    flags |= Amf3Object.Flags.Externalizable;
                }
                if (classDef.Dynamic)
                {
                    flags |= Amf3Object.Flags.Dynamic;
                }

                TypelessWrite((int)flags | (classDef.Properties.Length << 4));

                TypelessWrite(classDef.Name);

                foreach (string i in classDef.Properties)
                {
                    TypelessWrite(i);
                }
            }
        }
Exemple #9
0
        // gets serializer for a class alias string
        private IAmf3Serializer GetSerializerFromAlias(string alias)
        {
            IAmf3Serializer serializer = Amf3ClassDef.GetSerializerFromAlias(alias);

            if (serializer == null)
            {
                var type = Amf3ClassDef.GetTypeFromAlias(alias);
                if (type != null)
                {
                    // create reflection serializer
                    serializer = new ReflectionSerializer(alias, type, true, false);
                    // automatically register it
                    Amf3ClassDef.RegisterSerializer(alias, serializer);
                }
            }
            return(serializer);
        }
Exemple #10
0
        public void TypelessWrite(ExpandoObject obj)
        {
            // this allows for the sharing of expando values easily
            var redirect = obj.ClassDefinition as ExpandoObject;

            if (redirect != null)
            {
                TypelessWrite(redirect);
                return;
            }

            if (CheckObjectTable(obj))
            {
                return;
            }

            // get class definition from expando
            Amf3ClassDef classDef = obj.ClassDefinition as Amf3ClassDef;

            if (classDef == null)
            {
                classDef = anonClassDef;
            }

            TypelessWrite(classDef);
            StoreObject(obj);

            foreach (string i in classDef.Properties)
            {
                Write(obj[i]);
            }

            if (classDef.Dynamic)
            {
                foreach (var kvp in obj)
                {
                    TypelessWrite(kvp.Key);
                    Write(kvp.Value);
                }

                TypelessWrite("");
            }
        }
        public object NewInstance(Amf3ClassDef classDef)
        {
            // First, we look the default constrcutor
            ConstructorInfo constructor = mType.GetConstructor(Type.EmptyTypes);

            if (constructor != null)
            {
                return(constructor.Invoke(null));
            }

            // If there was no default constructor, use a constructor that only has default values
            ConstructorInfo[] allConstructors = mType.GetConstructors();
            foreach (ConstructorInfo oneConstructor in allConstructors)
            {
                ParameterInfo[] parameters = oneConstructor.GetParameters();
                if (parameters.Length == 0)
                {
                    // Why did we not get this with the default constructor?
                    // In any case, handle the case gracefully
                }
                else if (parameters[0].IsOptional)
                {
                    // First parameter is optional, so all others are too, this constructor is good enough
                }
                else
                {
                    // We can't use this constructor, try the next one
                    continue;
                }

                object[] arguments = new object[parameters.Length];
                for (int i = 0; i < parameters.Length; ++i)
                {
                    arguments[i] = parameters[i].DefaultValue;
                }

                return(oneConstructor.Invoke(arguments));
            }

            // Did we miss something?
            throw new NotSupportedException();
        }
        public ReflectionSerializer(string alias, System.Type type, bool addFields = true, bool addProperties = true)
        {
            if (alias == null || type == null)
            {
                throw new ArgumentNullException();
            }

            mType       = type;
            mVectorType = typeof(_root.Vector <>).MakeGenericType(new Type[1] {
                mType
            });

            var properties = new List <string>();

            // get all instance fields of type (public or private)
            mFieldList = new List <FieldInfo>();
            if (addFields)
            {
                foreach (var field in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
                {
                    mFieldList.Add(field);
                    properties.Add(field.Name);
                }
            }

            // get all instance properties of type (public or private)
            mPropertyList = new List <PropertyInfo>();
            if (addProperties)
            {
                foreach (var prop in type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
                {
                    mPropertyList.Add(prop);
                    properties.Add(prop.Name);
                }
            }

            // create class definition from member list
            // this defines the property ordering
            mClassDef = new Amf3ClassDef(alias, properties.ToArray());
        }
Exemple #13
0
        // begins the reading of a new object
        // the classdef passed in here will define the ordering of the subsequent property reads
        public void ReadObjectHeader(Amf3ClassDef serializerClassDef)
        {
            // did serializer definition change?
            if (mSerializerClassDef != serializerClassDef)
            {
                // set new serializer definition
                mNames = serializerClassDef.Properties;
                mSerializerClassDef = serializerClassDef;

                // build remap table from the serializer properties to stream properties
                mSerializerRemapTable = new int[mNames.Length];
                if (!mStreamClassDef.Equals(serializerClassDef))
                {
                    // mapping is required, create remap table
                    for (int i = 0; i < mSerializerRemapTable.Length; i++)
                    {
                        // get stream property index
                        int streamIndex = mStreamClassDef.GetPropertyIndex(mNames[i]);
                        // store in remap table
                        mSerializerRemapTable[i] = streamIndex + 1;
                    }
                }
                else
                {
                    // no remapping required, create direct mapped table
                    for (int i = 0; i < mSerializerRemapTable.Length; i++)
                    {
                        mSerializerRemapTable[i] = i + 1;
                    }
                }
            }

            // begin reading using remap table
            mRemapTable = mSerializerRemapTable;
            mReadIndex  = 0;
            mReadCount  = mRemapTable.Length;
        }
Exemple #14
0
        // this function generates AMF class definitions for all dynamic (expando) objects it finds and assigns them to the ClassDefinition property of Expando
        // it does this by generating a class definition for each unique property list
        // having shared class definitions will result in a much more compact serialized form
        public static void GenerateAndApplyClassDefinitions(object root, bool keepExistingAlias = true)
        {
            var expandos  = new List <ExpandoObject>();
            var classDefs = new Dictionary <string, Amf3ClassDef>();

            // visit all expando objects in graph and apply class definitions
            VisitAllExpandoObjects(root,
                                   (expando) => {
                // get properties from expando
                var properties = new List <String>();
                foreach (var kvp in expando)
                {
                    properties.Add(kvp.Key);
                }

                // sort properties
                properties.Sort();

                string alias = "*";
                if (keepExistingAlias && expando.ClassDefinition != null)
                {
                    var existingClassDef = expando.ClassDefinition as Amf3ClassDef;
                    if (existingClassDef != null)
                    {
                        alias = existingClassDef.Name;
                    }
                    else
                    {
                        var existingClassAlias = expando.ClassDefinition as string;
                        if (existingClassAlias != null)
                        {
                            alias = existingClassAlias;
                        }
                    }
                }

                // create class definition from properties
                var expandoDef = new Amf3ClassDef(alias, properties.ToArray());

                // see if a class definition already exists for these properties...
                Amf3ClassDef classDef;
                if (!classDefs.TryGetValue(expandoDef.Hash, out classDef))
                {
                    // register new class definition
                    classDef = expandoDef;
                    classDefs.Add(classDef.Hash, classDef);

                    if (Verbose)
                    {
                        Console.WriteLine("AMF3 generated class: {0}", classDef.Hash);
                    }
                }

                // set class definition for expando object
                expando.ClassDefinition = classDef;
            }
                                   );

            if (Verbose)
            {
                Console.WriteLine("AMF3 expandos: {0} classDefs: {1}", expandos.Count, classDefs.Count);
            }
        }
Exemple #15
0
 public void WriteObjectHeader(Amf3ClassDef classDef, object obj = null)
 {
     Write(Amf3TypeCode.Object);
     TypelessWrite(classDef);
     StoreObject(obj);
 }
Exemple #16
0
 internal Amf3Reader(Amf3ClassDef streamClassDef)
 {
     mStreamClassDef = streamClassDef;
     mValues         = new Variant[streamClassDef.Properties.Length + 1];                  // +1 for undefined property 0
     mNames          = streamClassDef.Properties;
 }
Exemple #17
0
        public Amf3Object ReadAmf3Object()
        {
            Amf3Object.Flags flags = (Amf3Object.Flags)ReadInteger();

            if ((flags & Amf3Object.Flags.Inline) == 0)
            {
                return((Amf3Object)GetTableEntry(objectTable, ((int)flags) >> 1));
            }

            Amf3ClassDef classDef;

            if ((flags & Amf3Object.Flags.InlineClassDef) == 0)
            {
                classDef = GetTableEntry(traitTable, ((int)flags) >> 2);
            }
            else
            {
                bool   externalizable = ((flags & Amf3Object.Flags.Externalizable) != 0);
                bool   dynamic        = ((flags & Amf3Object.Flags.Dynamic) != 0);
                string name           = ReadString();

                if (externalizable && dynamic)
                {
                    throw new InvalidOperationException("Serialized objects cannot be both dynamic and externalizable");
                }

                List <string> properties = new List <string>();

                int members = ((int)flags) >> 4;

                for (int i = 0; i < members; i++)
                {
                    properties.Add(ReadString());
                }

                classDef = new Amf3ClassDef(name, properties, dynamic, externalizable);
                traitTable.Add(classDef);
            }

            Amf3Object obj = new Amf3Object(classDef);

            objectTable.Add(obj);

            if (classDef.Externalizable)
            {
                obj.Properties["inner"] = ReadNextObject();
                return(obj);
            }

            foreach (string i in classDef.Properties)
            {
                obj.Properties[i] = ReadNextObject();
            }

            if (classDef.Dynamic)
            {
                string key = ReadString();
                while (key != "")
                {
                    obj.Properties[key] = ReadNextObject();
                    key = ReadString();
                }
            }

            return(obj);
        }
Exemple #18
0
 public object NewInstance(Amf3ClassDef classDef)
 {
     return(new Amf3Object(classDef));
 }