void WriteBody(Element elem) { Writer.Write(elem.Count); foreach (var attr in elem) { StringDict.WriteString(attr.Key); var attr_type = attr.Value == null ? typeof(Element) : attr.Value.GetType(); Writer.Write(TypeToId(attr_type, EncodingVersion)); if (attr.Value == null || !Datamodel.IsDatamodelArrayType(attr.Value.GetType())) { WriteAttribute(attr.Value, false); } else { var array = (System.Collections.IList)attr.Value; Writer.Write(array.Count); attr_type = Datamodel.GetArrayInnerType(array.GetType()); foreach (var item in array) { WriteAttribute(item, true); } } } }
static byte TypeToId(Type type, int version) { bool array = Datamodel.IsDatamodelArrayType(type); var search_type = array ? Datamodel.GetArrayInnerType(type) : type; if (array && search_type == typeof(byte) && !SupportedAttributes[version].Contains(typeof(byte))) { search_type = typeof(byte[]); // Recent version of DMX support both "binary" and "uint8_array" attributes. These are the same thing! array = false; } var type_list = SupportedAttributes[version]; byte i = 0; foreach (var list_type in type_list) { if (list_type == search_type) { break; } else { i++; } } if (i == type_list.Length) { throw new CodecException(String.Format("\"{0}\" is not supported in encoding binary {1}", type.Name, version)); } if (array) { i += (byte)(type_list.Length * (version >= 9 ? 2 : 1)); } return(++i); }
object DecodeAttribute(Datamodel dm, bool prefix) { var type = IdToType(Reader.ReadByte()); if (!Datamodel.IsDatamodelArrayType(type)) { return(ReadValue(dm, type, EncodingVersion < 4 || prefix)); } else { var count = Reader.ReadInt32(); var inner_type = Datamodel.GetArrayInnerType(type); var array = CodecUtilities.MakeList(inner_type, count); foreach (var x in Enumerable.Range(0, count)) { array.Add(ReadValue(dm, inner_type, true)); } return(array); } }
void SkipAttribte() { var type = IdToType(Reader.ReadByte()); int count = 1; bool array = false; if (Datamodel.IsDatamodelArrayType(type)) { array = true; count = Reader.ReadInt32(); type = Datamodel.GetArrayInnerType(type); } if (type == typeof(Element)) { foreach (int i in Enumerable.Range(0, count)) { if (Reader.ReadInt32() == -2) { Reader.BaseStream.Seek(37, SeekOrigin.Current); // skip GUID + null terminator if a stub } } return; } int length; if (type == typeof(TimeSpan)) { length = sizeof(int); } else if (type == typeof(System.Drawing.Color)) { length = 4; } else if (type == typeof(bool)) { length = 1; } else if (type == typeof(byte[])) { foreach (var i in Enumerable.Range(0, count)) { Reader.BaseStream.Seek(Reader.ReadInt32(), SeekOrigin.Current); } return; } else if (type == typeof(string)) { if (!StringDict.Dummy && !array && EncodingVersion >= 4) { length = StringDict.IndiceSize; } else { foreach (var i in Enumerable.Range(0, count)) { byte b; do { b = Reader.ReadByte(); } while (b != 0); } return; } } else if (type == typeof(Vector2)) { length = sizeof(float) * 2; } else if (type == typeof(Vector3)) { length = sizeof(float) * 3; } else if (type == typeof(Vector4) || type == typeof(Quaternion)) { length = sizeof(float) * 4; } else if (type == typeof(Matrix4x4)) { length = sizeof(float) * 4 * 4; } else { length = System.Runtime.InteropServices.Marshal.SizeOf(type); } Reader.BaseStream.Seek(length * count, SeekOrigin.Current); }