public virtual void TestObjectLabeling()
        {
            //Do a few tricky experiments to make sure things are being written
            //the way we expect
            //Write the data array with ObjectWritable
            //which will indirectly write it using APW.Internal
            ObjectWritable.WriteObject(@out, i, i.GetType(), null, true);
            //Write the corresponding APW directly with ObjectWritable
            ArrayPrimitiveWritable apw = new ArrayPrimitiveWritable(i);

            ObjectWritable.WriteObject(@out, apw, apw.GetType(), null, true);
            //Get ready to read it back
            @in.Reset(@out.GetData(), @out.GetLength());
            //Read the int[] object as written by ObjectWritable, but
            //"going around" ObjectWritable
            string className = UTF8.ReadString(@in);

            Assert.Equal("The int[] written by ObjectWritable was not labelled as "
                         + "an ArrayPrimitiveWritable.Internal", typeof(ArrayPrimitiveWritable.Internal)
                         .FullName, className);
            ArrayPrimitiveWritable.Internal apwi = new ArrayPrimitiveWritable.Internal();
            apwi.ReadFields(@in);
            Assert.Equal("The ArrayPrimitiveWritable.Internal component type was corrupted"
                         , typeof(int), apw.GetComponentType());
            Assert.True("The int[] written by ObjectWritable as " + "ArrayPrimitiveWritable.Internal was corrupted"
                        , Arrays.Equals(i, (int[])(apwi.Get())));
            //Read the APW object as written by ObjectWritable, but
            //"going around" ObjectWritable
            string declaredClassName = UTF8.ReadString(@in);

            Assert.Equal("The APW written by ObjectWritable was not labelled as "
                         + "declaredClass ArrayPrimitiveWritable", typeof(ArrayPrimitiveWritable).FullName
                         , declaredClassName);
            className = UTF8.ReadString(@in);
            Assert.Equal("The APW written by ObjectWritable was not labelled as "
                         + "class ArrayPrimitiveWritable", typeof(ArrayPrimitiveWritable).FullName, className
                         );
            ArrayPrimitiveWritable apw2 = new ArrayPrimitiveWritable();

            apw2.ReadFields(@in);
            Assert.Equal("The ArrayPrimitiveWritable component type was corrupted"
                         , typeof(int), apw2.GetComponentType());
            Assert.True("The int[] written by ObjectWritable as " + "ArrayPrimitiveWritable was corrupted"
                        , Arrays.Equals(i, (int[])(apw2.Get())));
        }
Example #2
0
        /// <summary>
        /// Read a
        /// <see cref="IWritable"/>
        /// ,
        /// <see cref="string"/>
        /// , primitive type, or an array of
        /// the preceding.
        /// </summary>
        /// <exception cref="System.IO.IOException"/>
        public static object ReadObject(BinaryReader reader, ObjectWritable objectWritable, Configuration
                                        conf)
        {
            string className     = UTF8.ReadString(@in);
            Type   declaredClass = PrimitiveNames[className];

            if (declaredClass == null)
            {
                declaredClass = LoadClass(conf, className);
            }
            object instance;

            if (declaredClass.IsPrimitive)
            {
                // primitive types
                if (declaredClass == typeof(bool))
                {
                    // boolean
                    instance = Extensions.ValueOf(@in.ReadBoolean());
                }
                else
                {
                    if (declaredClass == typeof(char))
                    {
                        // char
                        instance = char.ValueOf(@in.ReadChar());
                    }
                    else
                    {
                        if (declaredClass == typeof(byte))
                        {
                            // byte
                            instance = byte.ValueOf(@in.ReadByte());
                        }
                        else
                        {
                            if (declaredClass == typeof(short))
                            {
                                // short
                                instance = short.ValueOf(@in.ReadShort());
                            }
                            else
                            {
                                if (declaredClass == typeof(int))
                                {
                                    // int
                                    instance = Extensions.ValueOf(@in.ReadInt());
                                }
                                else
                                {
                                    if (declaredClass == typeof(long))
                                    {
                                        // long
                                        instance = Extensions.ValueOf(@in.ReadLong());
                                    }
                                    else
                                    {
                                        if (declaredClass == typeof(float))
                                        {
                                            // float
                                            instance = float.ValueOf(@in.ReadFloat());
                                        }
                                        else
                                        {
                                            if (declaredClass == typeof(double))
                                            {
                                                // double
                                                instance = double.ValueOf(@in.ReadDouble());
                                            }
                                            else
                                            {
                                                if (declaredClass == typeof(void))
                                                {
                                                    // void
                                                    instance = null;
                                                }
                                                else
                                                {
                                                    throw new ArgumentException("Not a primitive: " + declaredClass);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                if (declaredClass.IsArray)
                {
                    // array
                    int length = @in.ReadInt();
                    instance = System.Array.CreateInstance(declaredClass.GetElementType(), length);
                    for (int i = 0; i < length; i++)
                    {
                        Runtime.SetArrayValue(instance, i, ReadObject(@in, conf));
                    }
                }
                else
                {
                    if (declaredClass == typeof(ArrayPrimitiveWritable.Internal))
                    {
                        // Read and unwrap ArrayPrimitiveWritable$Internal array.
                        // Always allow the read, even if write is disabled by allowCompactArrays.
                        ArrayPrimitiveWritable.Internal temp = new ArrayPrimitiveWritable.Internal();
                        temp.ReadFields(@in);
                        instance      = temp.Get();
                        declaredClass = instance.GetType();
                    }
                    else
                    {
                        if (declaredClass == typeof(string))
                        {
                            // String
                            instance = UTF8.ReadString(@in);
                        }
                        else
                        {
                            if (declaredClass.IsEnum())
                            {
                                // enum
                                instance = Enum.ValueOf((Type)declaredClass, UTF8.ReadString(@in));
                            }
                            else
                            {
                                if (typeof(Message).IsAssignableFrom(declaredClass))
                                {
                                    instance = TryInstantiateProtobuf(declaredClass, @in);
                                }
                                else
                                {
                                    // Writable
                                    Type   instanceClass = null;
                                    string str           = UTF8.ReadString(@in);
                                    instanceClass = LoadClass(conf, str);
                                    IWritable writable = WritableFactories.NewInstance(instanceClass, conf);
                                    writable.ReadFields(@in);
                                    instance = writable;
                                    if (instanceClass == typeof(ObjectWritable.NullInstance))
                                    {
                                        // null
                                        declaredClass = ((ObjectWritable.NullInstance)instance).declaredClass;
                                        instance      = null;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (objectWritable != null)
            {
                // store values
                objectWritable.declaredClass = declaredClass;
                objectWritable.instance      = instance;
            }
            return(instance);
        }