/// <summary> /// Read object properties map. /// </summary> /// <param name="context"> /// The context. /// </param> /// <param name="reader"> /// The reader. /// </param> /// <param name="output"> /// The output. /// </param> /// <remarks> /// Type declaration: /// <c>object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)</c> /// </remarks> /// <exception cref="SerializationException"> /// </exception> /// <returns> /// The <see cref="IList"/>. /// </returns> private IList <string> ReadPropertiesMap(AmfContext context, AmfStreamReader reader, XmlWriter output = null) { try { var result = new List <string>(); string property = ReadString(reader); // Read first property's name // An empty property name indicates that object's declaration ends here while (property != string.Empty) { result.Add(property); this.ReadAmfValue(context, reader, output); property = ReadString(reader); } // Last byte is always an "ObjectEnd" marker var marker = (Amf0TypeMarker)reader.ReadByte(); // Something goes wrong if (marker != Amf0TypeMarker.ObjectEnd) { throw new FormatException(Errors.Amf0Decoder_ReadPropertiesMap_UnexpectedObjectEnd); } return(result); } catch (Exception e) { throw new SerializationException(Errors.Amf0Decoder_ReadPropertiesMap_UnableToDeserialize, e); } }
/// <summary> /// The read amf value. /// </summary> /// <param name="context"> /// The context. /// </param> /// <param name="reader"> /// The reader. /// </param> /// <param name="output"> /// The output. /// </param> /// <exception cref="FormatException"> /// </exception> protected override void ReadAmfValue(AmfContext context, AmfStreamReader reader, XmlWriter output = null) { // Work in a legacy context if (context.AmfVersion == AmfVersion.Amf0) { base.ReadAmfValue(context, reader, output); return; } Amf3TypeMarker dataType; try { // Read a type marker byte dataType = (Amf3TypeMarker)reader.ReadByte(); } catch (Exception e) { #if DEBUG Debug.WriteLine(Errors.Amf3Decoder_ReadValue_InvalidMarker, reader.BaseStream.Position); #endif throw new FormatException( string.Format(Errors.Amf3Decoder_ReadValue_TypeMarkerNotFound, reader.BaseStream.Position), e); } this.ReadValue(context, reader, dataType, output); #if DEBUG Debug.WriteLine(Errors.Amf3Decoder_ReadValue_End, dataType, reader.BaseStream.Position); #endif }
/// <summary> /// The read amf value. /// </summary> /// <param name="context"> /// The context. /// </param> /// <param name="reader"> /// The reader. /// </param> /// <param name="output"> /// The output. /// </param> /// <exception cref="InvalidOperationException"> /// </exception> /// <exception cref="FormatException"> /// </exception> protected override void ReadAmfValue(AmfContext context, AmfStreamReader reader, XmlWriter output = null) { if (context.AmfVersion != AmfVersion.Amf0) { throw new InvalidOperationException( string.Format(Errors.Amf0Decoder_ReadAmfValue_AmfVersionNotSupported, context.AmfVersion)); } Amf0TypeMarker dataType; try { // Read a type marker byte dataType = (Amf0TypeMarker)reader.ReadByte(); } catch (Exception e) { throw new FormatException(Errors.Amf0Decoder_ReadAmfValue_TypeMarkerMissing, e); } // Special case if (dataType == Amf0TypeMarker.AvmPlusObject) { var newContext = new AmfContext(AmfVersion.Amf3); this.ReadAmfValue(newContext, reader, output); return; } this.ReadValue(context, reader, dataType, output); }
/// <summary> /// Read a 29-bit unsigned integer. /// </summary> /// <param name="reader"> /// The reader. /// </param> /// <remarks> /// Up to 4 bytes are required to hold the value however the high bit /// of the first 3 bytes are used as flags to determine /// whether the next byte is part of the integer. /// <c> /// 0x00000000 - 0x0000007F : 0xxxxxxx /// 0x00000080 - 0x00003FFF : 1xxxxxxx 0xxxxxxx /// 0x00004000 - 0x001FFFFF : 1xxxxxxx 1xxxxxxx 0xxxxxxx /// 0x00200000 - 0x3FFFFFFF : 1xxxxxxx 1xxxxxxx 1xxxxxxx xxxxxxxx /// 0x40000000 - 0xFFFFFFFF : throw range exception /// </c> /// </remarks> /// <returns> /// The <see cref="int"/>. /// </returns> private static int ReadUint29(AmfStreamReader reader) { const byte mask = 0x7F; // 0111 1111 int octet = reader.ReadByte() & 0xFF; // 0xxxxxxx if (octet < 128) { return(octet); } int result = (octet & mask) << 7; octet = reader.ReadByte() & 0xFF; // 1xxxxxxx 0xxxxxxx if (octet < 128) { return(result | octet); } result = (result | (octet & mask)) << 7; octet = reader.ReadByte() & 0xFF; // 1xxxxxxx 1xxxxxxx 0xxxxxxx if (octet < 128) { return(result | octet); } result = (result | (octet & mask)) << 8; octet = reader.ReadByte() & 0xFF; // 1xxxxxxx 1xxxxxxx 1xxxxxxx xxxxxxxx return(result | octet); }