예제 #1
0
        public override void WritePacketHeader(Stream stream, AmfHeaderDescriptor descriptor)
        {
            var writer = new AmfStreamWriter(stream);

            WriteUtf8(writer, descriptor.Name);
            writer.Write((byte)(descriptor.MustUnderstand ? 1 : 0));
            writer.Write(-1);
        }
예제 #2
0
        public override void WritePacketHeader(Stream stream, AmfHeaderDescriptor descriptor)
        {
            var writer = new AmfStreamWriter(stream);

            WriteUtf8(writer, descriptor.Name);
            writer.Write((byte)(descriptor.MustUnderstand ? 1 : 0));
            writer.Write(-1);
        }
예제 #3
0
        /// <summary>
        /// Write UTF8 data.
        /// </summary>
        private static void WriteUtf8(AmfStreamWriter writer, byte[] data)
        {
            if (data.Length < ShortStringLimit)
            {
                writer.Write((ushort)data.Length);
            }
            else
            {
                writer.Write((uint)data.Length);
            }

            writer.Write(data);
        }
예제 #4
0
        /// <summary>
        /// Write a double.
        /// </summary>
        /// <param name="writer">
        /// The writer.
        /// </param>
        /// <param name="input">
        /// The input.
        /// </param>
        private static void WriteDouble(AmfStreamWriter writer, XmlReader input)
        {
            double value = Convert.ToDouble(input.ReadString());

            WriteTypeMarker(writer, Amf3TypeMarker.Double);
            writer.Write(value);
        }
예제 #5
0
        /// <summary>
        /// Write UTF-8 string.
        /// </summary>
        /// <param name="context">
        /// The context.
        /// </param>
        /// <param name="writer">
        /// The writer.
        /// </param>
        /// <param name="value">
        /// The value.
        /// </param>
        private static void WriteUtf8(AmfContext context, AmfStreamWriter writer, string value)
        {
            if (value == null)
            {
                value = string.Empty;
            }

            // A special case
            if (value == string.Empty)
            {
                writer.Write((byte)0x01);
                return;
            }

            int index = context.StringReferences.IndexOf(value);

            if (index != -1)
            {
                WriteReference(writer, index);
                return;
            }

            context.StringReferences.Add(value);

            byte[] decoded = Encoding.UTF8.GetBytes(value);

            WriteUtf8(writer, decoded);
        }
예제 #6
0
        /// <summary>
        /// Write an array.
        /// </summary>
        private void WriteArray(AmfContext context, AmfStreamWriter writer, XmlReader input)
        {
            context.References.Add(new AmfReference {
                AmfxType = AmfxContent.Array
            });

            var length = Convert.ToUInt32(input.GetAttribute(AmfxContent.ArrayLength));

            writer.Write(length);

            if (length == 0)
            {
                return;
            }

            input.MoveToContent();

            while (input.Read())
            {
                if (input.NodeType != XmlNodeType.Element)
                {
                    continue;
                }

                for (var i = 0; i < length; i++)
                {
                    var itemreader = input.ReadSubtree();
                    itemreader.MoveToContent();
                    WriteAmfValue(context, itemreader, writer);
                }
            }
        }
예제 #7
0
        /// <summary>
        /// Write a number.
        /// </summary>
        private static void WriteNumber(AmfStreamWriter writer, XmlReader input)
        {
            WriteTypeMarker(writer, Amf0TypeMarker.Number);

            var value = Convert.ToDouble(input.ReadString());

            writer.Write(value);
        }
예제 #8
0
        public override void WritePacketBody(Stream stream, AmfMessageDescriptor descriptor)
        {
            var writer = new AmfStreamWriter(stream);

            WriteUtf8(writer, descriptor.Target);
            WriteUtf8(writer, descriptor.Response);
            writer.Write(-1);
        }
예제 #9
0
        /// <summary>
        /// Write a number.
        /// </summary>
        private static void WriteNumber(AmfStreamWriter writer, XmlReader input)
        {
            WriteTypeMarker(writer, Amf0TypeMarker.Number);

            var value = input.ReadContentAsDouble();

            writer.Write(value);
        }
예제 #10
0
        public override void WritePacketBody(Stream stream, AmfMessageDescriptor descriptor)
        {
            var writer = new AmfStreamWriter(stream);

            WriteUtf8(writer, descriptor.Target);
            WriteUtf8(writer, descriptor.Response);
            writer.Write(-1);
        }
예제 #11
0
        /// <summary>
        /// Write UTF-8 data.
        /// </summary>
        /// <param name="writer">
        /// The writer.
        /// </param>
        /// <param name="data">
        /// The data.
        /// </param>
        private static void WriteUtf8(AmfStreamWriter writer, byte[] data)
        {
            // The first bit is a flag with value 1.
            // The remaining 1 to 28 significant bits are used
            // to encode the byte-length of the data
            int flag = (data.Length << 1) | 0x1;

            WriteUInt29(writer, flag);
            writer.Write(data);
        }
예제 #12
0
        /// <summary>
        /// Write a double.
        /// </summary>
        private static void WriteDouble(AmfStreamWriter writer, XmlReader input)
        {
            input.Read();
            var value = Convert.ToDouble(input.Value, CultureInfo.InvariantCulture);

            input.Read();

            WriteTypeMarker(writer, Amf3TypeMarker.Double);
            writer.Write(value);
        }
예제 #13
0
        /// <summary>
        /// Write an 29-bit unsigned integer.
        /// </summary>
        /// <param name="writer">
        /// The writer.
        /// </param>
        /// <param name="value">
        /// The value.
        /// </param>
        private static void WriteUInt29(AmfStreamWriter writer, int value)
        {
            // < 128:
            // 0x00000000 - 0x0000007F
            if (value < 0x80)
            {
                writer.Write((byte)value); // 0xxxxxxx
            }

            // < 16,384:
            // 0x00000080 - 0x00003FFF
            else if (value < 0x4000)
            {
                writer.Write((byte)(value >> 7 & 0x7F | 0x80)); // 1xxxxxxx
                writer.Write((byte)(value & 0x7F));             // xxxxxxxx
            }

            // < 2,097,152:
            // 0x00004000 - 0x001FFFFF
            else if (value < 0x200000)
            {
                writer.Write((byte)(value >> 14 & 0x7F | 0x80)); // 1xxxxxxx
                writer.Write((byte)(value >> 7 & 0x7F | 0x80));  // 1xxxxxxx
                writer.Write((byte)(value & 0x7F));              // xxxxxxxx
            }

            // 0x00200000 - 0x3FFFFFFF
            else if (value < 0x40000000)
            {
                writer.Write((byte)(value >> 22 & 0x7F | 0x80)); // 1xxxxxxx
                writer.Write((byte)(value >> 15 & 0x7F | 0x80)); // 1xxxxxxx
                writer.Write((byte)(value >> 8 & 0x7F | 0x80));  // 1xxxxxxx
                writer.Write((byte)(value & 0xFF));              // xxxxxxxx
            }

            // 0x40000000 - 0xFFFFFFFF, out of range
            else
            {
                throw new IndexOutOfRangeException("Integer is out of range: " + value);
            }
        }
예제 #14
0
        /// <summary>
        /// Write a date.
        /// </summary>
        /// <param name="context">
        /// The context.
        /// </param>
        /// <param name="writer">
        /// The writer.
        /// </param>
        /// <param name="input">
        /// The input.
        /// </param>
        private static void WriteDate(AmfContext context, AmfStreamWriter writer, XmlReader input)
        {
            context.References.Add(new AmfReference {
                AmfxType = AmfxContent.Date
            });
            WriteTypeMarker(writer, Amf3TypeMarker.Date);

            double milliseconds = Convert.ToDouble(input.ReadString());

            // The first bit is a flag with value 1.
            // The remaining bits are not used.
            WriteUInt29(writer, 0 | 0x1);

            writer.Write(milliseconds);
        }
예제 #15
0
        /// <summary>
        /// Write a reference value.
        /// </summary>
        private static void WriteReference(AmfContext context, AmfStreamWriter writer, XmlReader input)
        {
            var index = Convert.ToInt32(input.GetAttribute(AmfxContent.ReferenceId));
            var proxy = context.References[index];

            switch (proxy.AmfxType)
            {
            case AmfxContent.Array:
            case AmfxContent.Object:
                WriteTypeMarker(writer, Amf0TypeMarker.Reference);
                writer.Write((ushort)index);
                break;

            default:
                throw new InvalidOperationException(string.Format("AMFX type '{0}' cannot be send by reference.", proxy.AmfxType));
            }
        }
예제 #16
0
        /// <summary>
        /// Write a byte array.
        /// </summary>
        private static void WriteByteArray(AmfContext context, AmfStreamWriter writer, XmlReader input)
        {
            context.References.Add(new AmfReference {
                AmfxType = AmfxContent.ByteArray
            });
            WriteTypeMarker(writer, Amf3TypeMarker.ByteArray);

            var encoded = input.ReadString();
            var bytes   = Convert.FromBase64String(encoded);

            //The first bit is a flag with value 1.
            //The remaining 1 to 28 significant bits are used
            //to encode the byte-length of the data
            var flag = (bytes.Length << 1) | 0x1;

            WriteUInt29(writer, flag);

            writer.Write(bytes);
        }
예제 #17
0
        /// <summary>
        /// Write an integer.
        /// </summary>
        private static void WriteInteger(AmfStreamWriter writer, XmlReader input)
        {
            var text  = input.ReadString();
            var value = Convert.ToInt64(text);

            //Check if the value fits the Int29 span
            if (value >= MinInt29Value && value <= MaxInt29Value)
            {
                //It should be safe to cast it there
                var integer = UInt29Mask & (int)value; //Truncate the value

                WriteTypeMarker(writer, Amf3TypeMarker.Integer);
                WriteUInt29(writer, integer);
            }
            //Promote the value to a double
            else
            {
                WriteTypeMarker(writer, Amf3TypeMarker.Double);
                writer.Write(Convert.ToDouble(value));
            }
        }
예제 #18
0
 /// <summary>
 /// Write AMF message headers count.
 /// </summary>
 private static void WriteHeaderCount(AmfStreamWriter writer, int count)
 {
     writer.Write((ushort)count);
 }
예제 #19
0
        /// <summary>
        /// Write a number.
        /// </summary>
        private static void WriteNumber(AmfStreamWriter writer, XmlReader input)
        {
            WriteTypeMarker(writer, Amf0TypeMarker.Number);

            var value = input.ReadContentAsDouble();
            writer.Write(value);
        }
예제 #20
0
        /// <summary>
        /// Write a reference value.
        /// </summary>
        private static void WriteReference(AmfContext context, AmfStreamWriter writer, XmlReader input)
        {
            var index = Convert.ToInt32(input.GetAttribute(AmfxContent.ReferenceId));
            var proxy = context.References[index];

            switch(proxy.AmfxType)
            {
                case AmfxContent.Array:
                case AmfxContent.Object:
                    WriteTypeMarker(writer, Amf0TypeMarker.Reference);
                    writer.Write((ushort)index);
                    break;

                default:
                    throw new InvalidOperationException(string.Format("AMFX type '{0}' cannot be send by reference.", proxy.AmfxType));
            }
        }
예제 #21
0
 /// <summary>
 /// Write a date.
 /// </summary>
 private static void WriteDate(AmfStreamWriter writer, double value)
 {
     WriteTypeMarker(writer, Amf0TypeMarker.Date);
     writer.Write(value);
     writer.Write((short)0); //Timezone (not used)
 }
예제 #22
0
        /// <summary>
        /// Write UTF8 data.
        /// </summary>
        private static void WriteUtf8(AmfStreamWriter writer, byte[] data)
        {
            if (data.Length < ShortStringLimit)
                writer.Write((ushort)data.Length);
            else
                writer.Write((uint)data.Length);

            writer.Write(data);
        }
예제 #23
0
 /// <summary>
 /// Write a boolean value.
 /// </summary>
 private static void WriteBoolean(AmfStreamWriter writer, bool value)
 {
     writer.Write(value);
 }
예제 #24
0
        protected override void WriteAmfValue(AmfContext context, XmlReader input, AmfStreamWriter writer)
        {
            if (input == null) throw new ArgumentNullException("input");
            if (context == null) throw new ArgumentNullException("context");
            if (input.NodeType != XmlNodeType.Element) throw new XmlException(string.Format("Element node expected, {0} found.", input.NodeType));

            if (context.AmfVersion != AmfVersion.Amf3)
            {
                context = new AmfContext(AmfVersion.Amf3);
                writer.Write((byte)Amf0TypeMarker.AvmPlusObject);
            }

            #region Primitive values
            switch (input.Name)
            {
                case AmfxContent.Null:
                    WriteTypeMarker(writer, Amf3TypeMarker.Null);
                    return;

                case AmfxContent.True:
                    WriteTypeMarker(writer, Amf3TypeMarker.True);
                    return;

                case AmfxContent.False:
                    WriteTypeMarker(writer, Amf3TypeMarker.False);
                    return;
            }
            #endregion

            #region Complex values
            switch (input.Name)
            {
                case AmfxContent.Integer:
                    WriteInteger(writer, input);
                    break;

                case AmfxContent.Double:
                    WriteDouble(writer, input);
                    break;

                case AmfxContent.String:
                    WriteString(context, writer, input);
                    break;

                case AmfxContent.Reference:
                    WriteReference(context, writer, input);
                    break;

                case AmfxContent.Date:
                    WriteDate(context, writer, input);
                    break;

                case AmfxContent.Xml:
                    WriteXml(context, writer, input);
                    break;

                case AmfxContent.Array:
                    WriteArray(context, writer, input);
                    break;

                case AmfxContent.ByteArray:
                    WriteByteArray(context, writer, input);
                    break;

                case AmfxContent.Object:
                    WriteObject(context, writer, input);
                    break;

                default:
                    throw new NotSupportedException("Unexpected AMFX type: " + input.Name);
            }
            #endregion
        }
예제 #25
0
        /// <summary>
        /// Write UTF-8 string.
        /// </summary>
        private static void WriteUtf8(AmfContext context, AmfStreamWriter writer, string value)
        {
            if (value == null) value = string.Empty;

            //A special case
            if (value == string.Empty)
            {
                writer.Write((byte)0x01);
                return;
            }

            var index = context.StringReferences.IndexOf(value);

            if(index != -1)
            {
                WriteReference(writer, index);
                return;
            }

            context.StringReferences.Add(value);

            var decoded = Encoding.UTF8.GetBytes(value);

            WriteUtf8(writer, decoded);
        }
예제 #26
0
 /// <summary>
 /// Write an AMF0 type marker.
 /// </summary>
 private static void WriteTypeMarker(AmfStreamWriter writer, Amf3TypeMarker marker)
 {
     writer.Write((byte)marker);
 }
예제 #27
0
        /// <summary>
        /// The write amf value.
        /// </summary>
        /// <param name="context">
        /// The context.
        /// </param>
        /// <param name="input">
        /// The input.
        /// </param>
        /// <param name="writer">
        /// The writer.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// </exception>
        /// <exception cref="XmlException">
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// </exception>
        protected override void WriteAmfValue(AmfContext context, XmlReader input, AmfStreamWriter writer)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }

            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            if (input.NodeType != XmlNodeType.Element)
            {
                throw new XmlException(string.Format("Element node expected, {0} found.", input.NodeType));
            }

            if (context.AmfVersion != AmfVersion.Amf3)
            {
                context = new AmfContext(AmfVersion.Amf3);
                writer.Write((byte)Amf0TypeMarker.AvmPlusObject);
            }

            switch (input.Name)
            {
            case AmfxContent.Null:
                WriteTypeMarker(writer, Amf3TypeMarker.Null);
                return;

            case AmfxContent.True:
                WriteTypeMarker(writer, Amf3TypeMarker.True);
                return;

            case AmfxContent.False:
                WriteTypeMarker(writer, Amf3TypeMarker.False);
                return;
            }



            switch (input.Name)
            {
            case AmfxContent.Integer:
                WriteInteger(writer, input);
                break;

            case AmfxContent.Double:
                WriteDouble(writer, input);
                break;

            case AmfxContent.String:
                WriteString(context, writer, input);
                break;

            case AmfxContent.Reference:
                WriteReference(context, writer, input);
                break;

            case AmfxContent.Date:
                WriteDate(context, writer, input);
                break;

            case AmfxContent.Xml:
                WriteXml(context, writer, input);
                break;

            case AmfxContent.Array:
                this.WriteArray(context, writer, input);
                break;

            case AmfxContent.ByteArray:
                WriteByteArray(context, writer, input);
                break;

            case AmfxContent.Object:
                this.WriteObject(context, writer, input);
                break;

            default:
                throw new NotSupportedException("Unexpected AMFX type: " + input.Name);
            }
        }
예제 #28
0
 /// <summary>
 /// Write AMF message bodies count.
 /// </summary>
 static private void WriteMessageCount(AmfStreamWriter writer, int count)
 {
     writer.Write((ushort)count);
 }
예제 #29
0
 /// <summary>
 /// Write AMF message headers count.
 /// </summary>
 static private void WriteHeaderCount(AmfStreamWriter writer, int count)
 {
     writer.Write((ushort)count);
 }
예제 #30
0
 /// <summary>
 /// Write AMF message version.
 /// </summary>
 static private void WriteAmfVersion(AmfStreamWriter writer, AmfVersion version)
 {
     writer.Write((ushort)version);
 }
예제 #31
0
 /// <summary>
 /// Write an 29-bit unsigned integer.
 /// </summary>
 private static void WriteUInt29(AmfStreamWriter writer, int value)
 {
     //< 128:
     //0x00000000 - 0x0000007F
     if (value < 0x80)
     {
         writer.Write((byte)value);                      //0xxxxxxx
     }
     //< 16,384:
     //0x00000080 - 0x00003FFF
     else if (value < 0x4000)
     {
         writer.Write((byte)(value >> 7 & 0x7F | 0x80));   //1xxxxxxx
         writer.Write((byte)(value & 0x7F));               //xxxxxxxx
     }
     //< 2,097,152:
     //0x00004000 - 0x001FFFFF
     else if (value < 0x200000)
     {
         writer.Write((byte)(value >> 14 & 0x7F | 0x80));  //1xxxxxxx
         writer.Write((byte)(value >> 7 & 0x7F | 0x80));   //1xxxxxxx
         writer.Write((byte)(value & 0x7F));               //xxxxxxxx
     }
     //0x00200000 - 0x3FFFFFFF
     else if (value < 0x40000000)
     {
         writer.Write((byte)(value >> 22 & 0x7F | 0x80));  //1xxxxxxx
         writer.Write((byte)(value >> 15 & 0x7F | 0x80));  //1xxxxxxx
         writer.Write((byte)(value >> 8 & 0x7F | 0x80));   //1xxxxxxx
         writer.Write((byte)(value & 0xFF));               //xxxxxxxx
     }
     //0x40000000 - 0xFFFFFFFF, out of range
     else
     {
         throw new IndexOutOfRangeException("Integer is out of range: " + value);
     }
 }
예제 #32
0
 /// <summary>
 /// Write AMF message version.
 /// </summary>
 private static void WriteAmfVersion(AmfStreamWriter writer, AmfVersion version)
 {
     writer.Write((ushort)version);
 }
예제 #33
0
        /// <summary>
        /// Write UTF-8 data.
        /// </summary>
        private static void WriteUtf8(AmfStreamWriter writer, byte[] data)
        {
            //The first bit is a flag with value 1.
            //The remaining 1 to 28 significant bits are used
            //to encode the byte-length of the data
            var flag = (data.Length << 1) | 0x1;

            WriteUInt29(writer, flag);
            writer.Write(data);
        }
예제 #34
0
 /// <summary>
 /// Write a date.
 /// </summary>
 private static void WriteDate(AmfStreamWriter writer, double value)
 {
     WriteTypeMarker(writer, Amf0TypeMarker.Date);
     writer.Write(value);
     writer.Write((short)0); //Timezone (not used)
 }
예제 #35
0
 /// <summary>
 /// Write an AMF0 type marker.
 /// </summary>
 private static void WriteTypeMarker(AmfStreamWriter writer, Amf0TypeMarker marker)
 {
     writer.Write((byte)marker);
 }
예제 #36
0
        /// <summary>
        /// Write an object.
        /// </summary>
        private void WriteObject(AmfContext context, AmfStreamWriter writer, XmlReader input)
        {
            context.References.Add(new AmfReference { AmfxType = AmfxContent.Object });

            WriteTypeMarker(writer, Amf0TypeMarker.Object);

            var typeName = string.Empty;

            if (input.HasAttributes)
                typeName = input.GetAttribute(AmfxContent.ObjectType);

            #region Read traits
            var traits = new AmfTypeTraits { TypeName = typeName };

            while (input.Read())
            {
                if (input.NodeType != XmlNodeType.Element && input.Name != AmfxContent.Traits) continue;

                if (!input.IsEmptyElement)
                {
                    var traitsReader = input.ReadSubtree();
                    traitsReader.MoveToContent();
                    traitsReader.ReadStartElement();

                    var members = new List<string>();

                    while (input.NodeType != XmlNodeType.EndElement)
                        members.Add(traitsReader.ReadElementContentAsString());

                    traits.ClassMembers = members.ToArray();
                }

                break;
            }
            #endregion

            #region Type name
            //Untyped object
            if(string.IsNullOrEmpty(traits.TypeName))
            {
                WriteTypeMarker(writer, Amf0TypeMarker.Object);
            }
            //Strongly-typed object
            else
            {
                WriteTypeMarker(writer, Amf0TypeMarker.TypedObject);
                var typeNameData = Encoding.UTF8.GetBytes(traits.TypeName);
                writer.Write((ushort)typeNameData.Length);
                writer.Write(typeNameData);
            }
            #endregion

            #region Write members
            var i = 0;

            while (input.Read())
            {
                if (input.NodeType != XmlNodeType.Element) continue;

                var memberName = traits.ClassMembers[i];
                var memberReader = input.ReadSubtree();
                memberReader.MoveToContent();

                WriteUtf8(writer, memberName);
                WriteAmfValue(context, memberReader, writer);

                i++;
            }
            #endregion

            WriteUtf8(writer, string.Empty);
            WriteTypeMarker(writer, Amf0TypeMarker.ObjectEnd);
        }
예제 #37
0
 /// <summary>
 /// Write an XML.
 /// </summary>
 private static void WriteXml(AmfStreamWriter writer, byte[] value)
 {
     WriteTypeMarker(writer, Amf0TypeMarker.XmlDocument);
     writer.Write((uint)value.Length);
     writer.Write(value);
 }
예제 #38
0
        /// <summary>
        /// Write an array.
        /// </summary>
        private void WriteArray(AmfContext context, AmfStreamWriter writer, XmlReader input)
        {
            context.References.Add(new AmfReference {AmfxType = AmfxContent.Array});

            var length = Convert.ToUInt32(input.GetAttribute(AmfxContent.ArrayLength));
            writer.Write(length);

            if (length == 0) return;

            input.MoveToContent();

            while (input.Read())
            {
                if (input.NodeType != XmlNodeType.Element)
                    continue;

                for (var i = 0; i < length; i++)
                {
                    var itemreader = input.ReadSubtree();
                    itemreader.MoveToContent();
                    WriteAmfValue(context, itemreader, writer);
                }
            }
        }
예제 #39
0
        /// <summary>
        /// Write a byte array.
        /// </summary>
        private static void WriteByteArray(AmfContext context, AmfStreamWriter writer, XmlReader input)
        {
            context.References.Add(new AmfReference { AmfxType = AmfxContent.ByteArray });
            WriteTypeMarker(writer, Amf3TypeMarker.ByteArray);

            input.Read();
            var encoded = input.Value;
            input.Read();

            var bytes = Convert.FromBase64String(encoded);

            //The first bit is a flag with value 1.
            //The remaining 1 to 28 significant bits are used
            //to encode the byte-length of the data
            var flag = (bytes.Length << 1) | 0x1;
            WriteUInt29(writer, flag);

            writer.Write(bytes);
        }
예제 #40
0
        /// <summary>
        /// Write a date.
        /// </summary>
        private static void WriteDate(AmfContext context, AmfStreamWriter writer, XmlReader input)
        {
            context.References.Add(new AmfReference { AmfxType = AmfxContent.Date });
            WriteTypeMarker(writer, Amf3TypeMarker.Date);

            var milliseconds = input.ReadElementContentAsDouble();

            //The first bit is a flag with value 1.
            //The remaining bits are not used.
            WriteUInt29(writer, 0 | 0x1);

            writer.Write(milliseconds);
        }
예제 #41
0
 /// <summary>
 /// Write an XML.
 /// </summary>
 private static void WriteXml(AmfStreamWriter writer, byte[] value)
 {
     WriteTypeMarker(writer, Amf0TypeMarker.XmlDocument);
     writer.Write((uint)value.Length);
     writer.Write(value);
 }
예제 #42
0
        /// <summary>
        /// Write a double.
        /// </summary>
        private static void WriteDouble(AmfStreamWriter writer, XmlReader input)
        {
            input.Read();
            var value = Convert.ToDouble(input.Value, CultureInfo.InvariantCulture);
            input.Read();

            WriteTypeMarker(writer, Amf3TypeMarker.Double);
            writer.Write(value);
        }
예제 #43
0
        /// <summary>
        /// Write an object.
        /// </summary>
        private void WriteObject(AmfContext context, AmfStreamWriter writer, XmlReader input)
        {
            context.References.Add(new AmfReference {
                AmfxType = AmfxContent.Object
            });

            WriteTypeMarker(writer, Amf0TypeMarker.Object);

            var typeName = string.Empty;

            if (input.HasAttributes)
            {
                typeName = input.GetAttribute(AmfxContent.ObjectType);
            }

            #region Read traits
            var traits = new AmfTypeTraits {
                TypeName = typeName
            };

            while (input.Read())
            {
                if (input.NodeType != XmlNodeType.Element && input.Name != AmfxContent.Traits)
                {
                    continue;
                }

                if (!input.IsEmptyElement)
                {
                    var traitsReader = input.ReadSubtree();
                    traitsReader.MoveToContent();
                    traitsReader.ReadStartElement();

                    var members = new List <string>();

                    while (input.NodeType != XmlNodeType.EndElement)
                    {
                        members.Add(traitsReader.ReadElementContentAsString());
                    }

                    traits.ClassMembers = members.ToArray();
                }

                break;
            }
            #endregion

            #region Type name
            //Untyped object
            if (string.IsNullOrEmpty(traits.TypeName))
            {
                WriteTypeMarker(writer, Amf0TypeMarker.Object);
            }
            //Strongly-typed object
            else
            {
                WriteTypeMarker(writer, Amf0TypeMarker.TypedObject);
                var typeNameData = Encoding.UTF8.GetBytes(traits.TypeName);
                writer.Write((ushort)typeNameData.Length);
                writer.Write(typeNameData);
            }
            #endregion

            #region Write members
            var i = 0;

            while (input.Read())
            {
                if (input.NodeType != XmlNodeType.Element)
                {
                    continue;
                }

                var memberName   = traits.ClassMembers[i];
                var memberReader = input.ReadSubtree();
                memberReader.MoveToContent();

                WriteUtf8(writer, memberName);
                WriteAmfValue(context, memberReader, writer);

                i++;
            }
            #endregion

            WriteUtf8(writer, string.Empty);
            WriteTypeMarker(writer, Amf0TypeMarker.ObjectEnd);
        }
예제 #44
0
        /// <summary>
        /// Write an integer.
        /// </summary>
        private static void WriteInteger(AmfStreamWriter writer, XmlReader input)
        {
            input.Read();
            var value = Convert.ToInt32(input.Value, CultureInfo.InvariantCulture);
            input.Read();

            //Check if the value fits the Int29 span
            if (value >= MinInt29Value && value <= MaxInt29Value)
            {
                //It should be safe to cast it there
                var integer = UInt29Mask & (int)value; //Truncate the value

                WriteTypeMarker(writer, Amf3TypeMarker.Integer);
                WriteUInt29(writer, integer);
            }
            //Promote the value to a double
            else
            {
                WriteTypeMarker(writer, Amf3TypeMarker.Double);
                writer.Write(Convert.ToDouble(value, CultureInfo.InvariantCulture));
            }
        }
예제 #45
0
 /// <summary>
 /// Write a boolean value.
 /// </summary>
 private static void WriteBoolean(AmfStreamWriter writer, bool value)
 {
     writer.Write(value);
 }
예제 #46
0
 /// <summary>
 /// Write AMF message bodies count.
 /// </summary>
 private static void WriteMessageCount(AmfStreamWriter writer, int count)
 {
     writer.Write((ushort)count);
 }