public static SEQ Load(byte[] data) { if (data == null) { throw new ArgumentNullException("data"); } // All SEP/SEQ stuff is big-endian, like MIDI if (data.Length < 15) { ErrorManager.SignalError("SEQ: Data is too short"); } int magic = BEBitConv.FromInt32(data, 0); int version = BEBitConv.FromInt32(data, 4); if (magic != Magic) { ErrorManager.SignalIgnorableError("SEQ: Magic number is wrong"); } if (version != Version) { ErrorManager.SignalIgnorableError("SEQ: Version number is wrong"); } short resolution = BEBitConv.FromInt16(data, 8); int tempo = MIDIConv.From3BE(data, 10); short rhythm = BEBitConv.FromInt16(data, 13); byte[] scoredata = new byte [data.Length - 15]; Array.Copy(data, 15, scoredata, 0, scoredata.Length); return(new SEQ(resolution, tempo, rhythm, scoredata)); }
public static VAB Join(VH vh, SampleLine[] vb) { if (vh == null) { throw new ArgumentNullException("vh"); } if (vb == null) { throw new ArgumentNullException("vb"); } if (vh.VBSize != vb.Length) { ErrorManager.SignalIgnorableError("VAB: VB size field mismatch"); } SampleSet[] waves = new SampleSet [vh.Waves.Count]; int offset = 0; for (int i = 0; i < vh.Waves.Count; i++) { int wavelength = vh.Waves[i]; if (offset + wavelength > vb.Length) { ErrorManager.SignalError("VAB: Wave ends out of bounds"); } SampleLine[] wavelines = new SampleLine[wavelength]; for (int j = 0; j < wavelength; j++) { wavelines[j] = vb[offset + j]; } offset += wavelength; waves[i] = new SampleSet(wavelines); } return(new VAB(vh.IsOldVersion, vh.Volume, vh.Panning, vh.Attribute1, vh.Attribute2, vh.Programs, waves)); }
public override Entry Load(byte[][] items, int eid) { if (items == null) { throw new ArgumentNullException("items"); } if (items.Length != 2) { ErrorManager.SignalError("WavebankEntry: Wrong number of items"); } if (items[0].Length != 8) { ErrorManager.SignalError("WavebankEntry: First item length is wrong"); } int id = BitConv.FromInt32(items[0], 0); int length = BitConv.FromInt32(items[0], 4); if (id < 0 || id > 6) { ErrorManager.SignalIgnorableError("WavebankEntry: ID is invalid"); } if (length != items[1].Length) { ErrorManager.SignalIgnorableError("WavebankEntry: Length field mismatch"); } return(new WavebankEntry(id, SampleSet.Load(items[1]), eid)); }
public static VHTone Load(byte[] data) { if (data.Length != 32) { throw new ArgumentException("Value must be 32 bytes long.", "data"); } byte priority = data[0]; byte mode = data[1]; byte volume = data[2]; byte panning = data[3]; byte centernote = data[4]; byte pitchshift = data[5]; byte minimumnote = data[6]; byte maximumnote = data[7]; byte vibratowidth = data[8]; byte vibratotime = data[9]; byte portamentowidth = data[10]; byte portamentotime = data[11]; byte pitchbendminimum = data[12]; byte pitchbendmaximum = data[13]; byte reserved1 = data[14]; byte reserved2 = data[15]; short adsr1 = BitConv.FromInt16(data, 16); short adsr2 = BitConv.FromInt16(data, 18); // Unused 2 bytes here short wave = BitConv.FromInt16(data, 22); short reserved3 = BitConv.FromInt16(data, 24); short reserved4 = BitConv.FromInt16(data, 26); short reserved5 = BitConv.FromInt16(data, 28); short reserved6 = BitConv.FromInt16(data, 30); if (reserved1 != 0xB1) { ErrorManager.SignalIgnorableError("VHTone: Reserved value 1 is wrong"); } if (reserved2 != 0xB2) { ErrorManager.SignalIgnorableError("VHTone: Reserved value 2 is wrong"); } if (reserved3 != 0xC0) { ErrorManager.SignalIgnorableError("VHTone: Reserved value 3 is wrong"); } if (reserved4 != 0xC1) { ErrorManager.SignalIgnorableError("VHTone: Reserved value 4 is wrong"); } if (reserved5 != 0xC2) { ErrorManager.SignalIgnorableError("VHTone: Reserved value 5 is wrong"); } if (reserved6 != 0xC3) { ErrorManager.SignalIgnorableError("VHTone: Reserved value 6 is wrong"); } return(new VHTone(priority, mode, volume, panning, centernote, pitchshift, minimumnote, maximumnote, vibratowidth, vibratotime, portamentowidth, portamentotime, pitchbendminimum, pitchbendmaximum, adsr1, adsr2, wave)); }
public sealed override Chunk Load(int chunkid, byte[] data) { if (data == null) { throw new ArgumentNullException("data"); } if (data.Length != Chunk.Length) { throw new ArgumentException("Data must be 65536 bytes long."); } int id = BitConv.FromInt32(data, 4); int entrycount = BitConv.FromInt32(data, 8); int checksum = BitConv.FromInt32(data, 12); int headersize = 20 + entrycount * 4; if (id != chunkid) { ErrorManager.SignalIgnorableError("EntryChunk: Chunk id is incorrect"); } if (entrycount < 0) { ErrorManager.SignalError("EntryChunk: Entry count is negative"); } if (checksum != Chunk.CalculateChecksum(data)) { ErrorManager.SignalIgnorableError("Chunk: Checksum is wrong"); } if (headersize > data.Length) { ErrorManager.SignalError("EntryChunk: Data is too short"); } Entry[] entries = new Entry [entrycount]; byte[] entrydata; for (int i = 0; i < entrycount; i++) { int entrystart = BitConv.FromInt32(data, 16 + i * 4); int entryend = BitConv.FromInt32(data, 20 + i * 4); if (entrystart < 0) { ErrorManager.SignalError("EntryChunk: Entry begins out of bounds"); } if (entryend < entrystart) { ErrorManager.SignalError("EntryChunk: Entry ends before it begins"); } if (entryend > data.Length) { ErrorManager.SignalError("EntryChunk: Entry ends out of bounds"); } int entrysize = entryend - entrystart; entrydata = new byte [entrysize]; Array.Copy(data, entrystart, entrydata, 0, entrysize); entries[i] = Entry.Load(entrydata); } return(Load(entries)); }
public static UnprocessedEntry Load(byte[] data) { if (data == null) { throw new ArgumentNullException("data"); } if (data.Length < 16) { ErrorManager.SignalError("Entry: Data is too short"); } int magic = BitConv.FromInt32(data, 0); int eid = BitConv.FromInt32(data, 4); int type = BitConv.FromInt32(data, 8); int itemcount = BitConv.FromInt32(data, 12); if (magic != Magic) { ErrorManager.SignalIgnorableError("Entry: Magic number is wrong"); } if (itemcount < 0) { ErrorManager.SignalError("Entry: Item count is negative"); } if (data.Length < 20 + itemcount * 4) { ErrorManager.SignalError("Entry: Data is too short"); } byte[][] items = new byte [itemcount][]; byte[] itemdata; for (int i = 0; i < itemcount; i++) { int itemstart = BitConv.FromInt32(data, 16 + i * 4); int itemend = BitConv.FromInt32(data, 20 + i * 4); if (itemstart < 0) { ErrorManager.SignalError("Entry: Item begins out of bounds"); } if (itemend < itemstart) { ErrorManager.SignalError("Entry: Item ends before it begins"); } if (itemend > data.Length) { ErrorManager.SignalError("Entry: Item ends out of bounds"); } int itemsize = itemend - itemstart; itemdata = new byte [itemsize]; Array.Copy(data, itemstart, itemdata, 0, itemsize); items[i] = itemdata; } return(new UnprocessedEntry(items, eid, type)); }
public override Entry Load(byte[][] items, int eid) { if (items == null) { throw new ArgumentNullException("items"); } T4Item[] t4items = new T4Item [items.Length]; for (int i = 0; i < items.Length; i++) { t4items[i] = T4Item.Load(items[i]); if (t4items[i].Unknown1 != ((i == 0 || i == items.Length - 1) ? 0 : 1)) { ErrorManager.SignalIgnorableError("T4Entry: Item unknown field is wrong"); } } return(new T4Entry(t4items, eid)); }
public static VHProgram Load(byte[] data, byte[] tonedata, bool isoldversion) { if (data.Length != 16) { throw new ArgumentException("Value must be 16 bytes long.", "data"); } if (tonedata.Length != 32 * 16) { throw new ArgumentException("Value must be 512 bytes long.", "tonedata"); } byte tonecount = data[0]; byte volume = data[1]; byte priority = data[2]; byte mode = data[3]; byte panning = data[4]; byte reserved1 = data[5]; short attribute = BitConv.FromInt16(data, 6); int reserved2 = BitConv.FromInt32(data, 8); int reserved3 = BitConv.FromInt32(data, 12); if (tonecount < 0 || tonecount > 16) { ErrorManager.SignalError("VHProgram: Tone count is wrong"); } if (reserved1 != (isoldversion ? 0x00 : 0xFF)) { ErrorManager.SignalIgnorableError("VHProgram: Reserved value 1 is wrong"); } if (reserved2 != -1) { ErrorManager.SignalIgnorableError("VHProgram: Reserved value 2 is wrong"); } if (reserved3 != -1) { ErrorManager.SignalIgnorableError("VHProgram: Reserved value 3 is wrong"); } VHTone[] tones = new VHTone [tonecount]; for (int i = 0; i < tonecount; i++) { byte[] thistonedata = new byte [32]; Array.Copy(tonedata, i * 32, thistonedata, 0, 32); tones[i] = VHTone.Load(thistonedata); } return(new VHProgram(isoldversion, volume, priority, mode, panning, attribute, tones)); }
public static UnprocessedChunk Load(byte[] data) { if (data == null) { throw new ArgumentNullException("data"); } if (data.Length != Length) { throw new ArgumentException("Value must be 65536 bytes long.", "data"); } short magic = BitConv.FromInt16(data, 0); if (magic != Magic) { ErrorManager.SignalIgnorableError("Chunk: Magic number is wrong"); } return(new UnprocessedChunk(data)); }
public static EntityProperty Load(byte type, byte elementsize, short unknown, bool last, byte[] data) { if (((type & 128) != 0) != last) { ErrorManager.SignalIgnorableError("EntityProperty: Flag 128 has an unexpected value"); } bool issparse = (type & 64) != 0; bool hasmetavalues = (type & 32) != 0; type &= 31; if (loaders.ContainsKey(type)) { return(loaders[type].Load(elementsize, unknown, issparse, hasmetavalues, data)); } else { return(new EntityUnknownProperty(type, elementsize, unknown, issparse, hasmetavalues, data)); } }
internal override void LoadToField(object obj, FieldInfo field) { if (field.FieldType == typeof(string)) { if (Rows.Count == 1) { if (Rows[0].MetaValue == null) { byte[] bytestr = new byte [Rows[0].Values.Count]; for (int i = 0; i < bytestr.Length; i++) { bytestr[i] = Rows[0].Values[i]; } string str = System.Text.Encoding.UTF8.GetString(bytestr); if (str.EndsWith("\0")) { str = str.Remove(str.Length - 1); } else { ErrorManager.SignalIgnorableError("EntityProperty: String is not null-terminated"); } field.SetValue(obj, str); } else { ErrorManager.SignalError("EntityProperty: Property has an unexpected metavalue"); } } else { ErrorManager.SignalError("EntityProperty: Property has more rows than expected"); } } else { base.LoadToField(obj, field); } }
public static SEP Load(byte[] data, int seqcount) { if (data == null) { throw new ArgumentNullException("data"); } if (seqcount < 0) { throw new ArgumentOutOfRangeException("seqcount"); } // All SEP/SEQ stuff is big-endian, like MIDI if (data.Length < 6) { ErrorManager.SignalError("SEP: Data is too short"); } int magic = BEBitConv.FromInt32(data, 0); short version = BEBitConv.FromInt16(data, 4); if (magic != Magic) { ErrorManager.SignalIgnorableError("SEP: Magic number is wrong"); } if (version != Version) { ErrorManager.SignalIgnorableError("SEP: Version number is wrong"); } int offset = 6; SEQ[] seqs = new SEQ [seqcount]; for (int i = 0; i < seqcount; i++) { if (data.Length < offset + 13) { ErrorManager.SignalError("SEP: Data is too short"); } short seqid = BEBitConv.FromInt16(data, offset); short resolution = BEBitConv.FromInt16(data, offset + 2); // tempo is 3 (yes, three) bytes int tempo = MIDIConv.From3BE(data, offset + 4); short rhythm = BEBitConv.FromInt16(data, offset + 7); int length = BEBitConv.FromInt32(data, offset + 9); if (seqid != i) { ErrorManager.SignalIgnorableError("SEP: Track number is wrong"); } if (length < 0) { ErrorManager.SignalError("SEP: Track length is negative"); } offset += 13; if (data.Length < offset + length) { ErrorManager.SignalError("SEP: Data is too short"); } byte[] seqdata = new byte [length]; Array.Copy(data, offset, seqdata, 0, length); seqs[i] = new SEQ(resolution, tempo, rhythm, seqdata); offset += length; } return(new SEP(seqs)); }
public sealed override EntityProperty Load(byte elementsize, short unknown, bool issparse, bool hasmetavalues, byte[] data) { if (elementsize != ElementSize) { ErrorManager.SignalError("EntityProperty: Element size is wrong"); } if (unknown < 0) { ErrorManager.SignalError("EntityProperty: Unknown value is invalid"); } List <EntityPropertyRow <T> > rows = new List <EntityPropertyRow <T> >(); for (int i = 0; i < unknown; i++) { rows.Add(new EntityPropertyRow <T>()); } int offset = 0; if (issparse) { if (offset + 2 * unknown > data.Length) { ErrorManager.SignalError("EntityProperty: Not enough data"); } foreach (EntityPropertyRow <T> row in rows) { int valuecount = (ushort)BitConv.FromInt16(data, offset); offset += 2; for (int i = 0; i < valuecount; i++) { row.Values.Add(new T()); } } } else { if (offset + 2 > data.Length) { ErrorManager.SignalError("EntityProperty: Not enough data"); } int valuecount = (ushort)BitConv.FromInt16(data, offset); offset += 2; foreach (EntityPropertyRow <T> row in rows) { for (int i = 0; i < valuecount; i++) { row.Values.Add(new T()); } } } if (hasmetavalues) { if (offset + 2 * unknown > data.Length) { ErrorManager.SignalError("EntityProperty: Not enough data"); } foreach (EntityPropertyRow <T> row in rows) { short metavalue = BitConv.FromInt16(data, offset); offset += 2; row.MetaValue = metavalue; } } Aligner.Align(ref offset, 4); byte[] elementdata = new byte [elementsize]; foreach (EntityPropertyRow <T> row in rows) { if (offset + row.Values.Count * elementsize > data.Length) { ErrorManager.SignalError("EntityProperty: Not enough data"); } for (int i = 0; i < row.Values.Count; i++) { Array.Copy(data, offset, elementdata, 0, elementsize); offset += elementsize; row.Values[i] = LoadElement(elementdata); } } Aligner.Align(ref offset, 4); if (offset != data.Length) { ErrorManager.SignalIgnorableError("EntityProperty: More data than expected"); } return(Load(rows)); }
public static VH Load(byte[] data) { if (data.Length < 2592) { ErrorManager.SignalError("VH: Data is too short"); } int magic = BitConv.FromInt32(data, 0); int version = BitConv.FromInt32(data, 4); if (magic != Magic) { ErrorManager.SignalIgnorableError("VH: Magic number is wrong"); } bool isoldversion; if (version == Version) { isoldversion = false; } else if (version == OldVersion) { ErrorManager.SignalIgnorableError("VH: VABv6 (crash 1) is not fully supported"); isoldversion = true; } else { ErrorManager.SignalIgnorableError("VH: Version number is wrong"); isoldversion = true; } int id = BitConv.FromInt32(data, 8); int size = BitConv.FromInt32(data, 12); short reserved1 = BitConv.FromInt16(data, 16); short programcount = BitConv.FromInt16(data, 18); short tonecount = BitConv.FromInt16(data, 20); short wavecount = BitConv.FromInt16(data, 22); byte volume = data[24]; byte panning = data[25]; byte attribute1 = data[26]; byte attribute2 = data[27]; int reserved2 = BitConv.FromInt32(data, 28); if (id != 0) { ErrorManager.SignalIgnorableError("VH: ID is wrong"); } if (size < data.Length) { ErrorManager.SignalError("VH: Size field mismatch"); } if ((size - data.Length) % 16 != 0) { ErrorManager.SignalError("VH: Size field is invalid"); } int vbsize = (size - data.Length) / 16; if (reserved1 != -0x1112) { ErrorManager.SignalIgnorableError("VH: Reserved value 1 is wrong"); } if (programcount < 0 || programcount > 128) { ErrorManager.SignalError("VH: Program count is invalid"); } if (tonecount < 0 || tonecount > 2048) { ErrorManager.SignalError("VH: Tone count is invalid"); } if (wavecount < 0 || wavecount > 254) { ErrorManager.SignalError("VH: Wave count is invalid"); } if (reserved2 != -1) { ErrorManager.SignalIgnorableError("VH: Reserved value 2 is wrong"); } if (data.Length < 2592 + 32 * 16 * programcount) { ErrorManager.SignalError("VH: Data is too short"); } Dictionary <int, VHProgram> programs = new Dictionary <int, VHProgram>(); for (int i = 0; i < 128; i++) { byte[] programdata = new byte [16]; Array.Copy(data, 32 + 16 * i, programdata, 0, 16); if (programdata[0] == 0) { continue; } if (programs.Count == programcount) { ErrorManager.SignalError("VH: Program count field mismatch"); } byte[] tonedata = new byte [32 * 16]; Array.Copy(data, 32 + 16 * 128 + 32 * 16 * programs.Count, tonedata, 0, 32 * 16); programs.Add(i, VHProgram.Load(programdata, tonedata, isoldversion)); } if (programs.Count != programcount) { ErrorManager.SignalError("VH: Program count field mismatch"); } int[] waves = new int [wavecount]; for (int i = 0; i < wavecount; i++) { int wave = BitConv.FromInt16(data, 32 + 16 * 128 + 32 * 16 * programcount + 2 + i * 2); if (wave % 2 != 0) { ErrorManager.SignalError("VH: Wave size is invalid"); } waves[i] = wave / 2; } return(new VH(isoldversion, vbsize, volume, panning, attribute1, attribute2, programs, waves)); }
private static byte[] ReadChunk(byte[] data, ref int offset, out bool compressed) { if (data == null) { throw new ArgumentNullException("data"); } if (offset < 0 || offset > data.Length) { throw new ArgumentOutOfRangeException("offset"); } if (data.Length < offset + 2) { ErrorManager.SignalError("NSF.ReadChunk: Data is too short"); } byte[] result = new byte [Chunk.Length]; short magic = BitConv.FromInt16(data, offset); if (magic == Chunk.Magic) { compressed = false; if (data.Length < offset + Chunk.Length) { ErrorManager.SignalError("NSF.ReadChunk: Data is too short"); } Array.Copy(data, offset, result, 0, Chunk.Length); offset += Chunk.Length; } else if (magic == Chunk.CompressedMagic) { compressed = true; int pos = 0; if (data.Length < offset + 12) { ErrorManager.SignalError("NSF.ReadChunk: Data is too short"); } short zero = BitConv.FromInt16(data, offset + 2); int length = BitConv.FromInt32(data, offset + 4); int skip = BitConv.FromInt32(data, offset + 8); if (zero != 0) { ErrorManager.SignalIgnorableError("NSF.ReadChunk: Zero value is wrong"); } if (length < 0 || length > Chunk.Length) { ErrorManager.SignalError("NSF.ReadChunk: Length field is invalid"); } if (skip < 0) { ErrorManager.SignalError("NSF.ReadChunk: Skip value is negative"); } offset += 12; while (pos < length) { if (data.Length < offset + 1) { ErrorManager.SignalError("NSF.ReadChunk: Data is too short"); } byte prefix = data[offset]; offset++; if ((prefix & 0x80) != 0) { prefix &= 0x7F; if (data.Length < offset + 1) { ErrorManager.SignalError("NSF.ReadChunk: Data is too short"); } int seek = data[offset]; offset++; int span = seek & 7; seek >>= 3; seek |= prefix << 5; if (span == 7) { span = 64; } else { span += 3; } if (pos - seek < 0) { ErrorManager.SignalError("NSF.ReadChunk: Repeat begins out of bounds"); } if (pos + span > Chunk.Length) { ErrorManager.SignalError("NSF.ReadChunk: Repeat ends out of bounds"); } // Do NOT use Array.Copy as // overlap is possible i.e. span // may be greater than seek for (int i = 0; i < span; i++) { result[pos + i] = result[pos - seek + i]; } pos += span; } else { if (data.Length < offset + prefix) { ErrorManager.SignalError("NSF.ReadChunk: Data is too short"); } Array.Copy(data, offset, result, pos, prefix); offset += prefix; pos += prefix; } } if (data.Length < offset + skip) { ErrorManager.SignalError("NSF.ReadChunk: Data is too short"); } offset += skip; if (data.Length < offset + (Chunk.Length - length)) { ErrorManager.SignalError("NSF.ReadChunk: Data is too short"); } Array.Copy(data, offset, result, pos, Chunk.Length - length); offset += (Chunk.Length - length); } else { compressed = false; // Fixes a stupid compile error ErrorManager.SignalError("NSF.ReadChunk: Unknown magic number"); } return(result); }
public static NSF Load(byte[] data) { if (data == null) { throw new ArgumentNullException("data"); } int offset = 0; int?firstid = null; List <UnprocessedChunk> prelude = null; List <Chunk> chunks = new List <Chunk>(); List <bool> preludecompression = null; List <bool> chunkcompression = new List <bool>(); while (offset < data.Length) { bool compressed; byte[] chunkdata = ReadChunk(data, ref offset, out compressed); UnprocessedChunk chunk = Chunk.Load(chunkdata); if (firstid == null) { firstid = chunk.ID; } else if (firstid == chunk.ID) { if (prelude != null) { ErrorManager.SignalError("NSF: Double prelude"); } prelude = new List <UnprocessedChunk>(); foreach (UnprocessedChunk unprocessedchunk in chunks) { prelude.Add(unprocessedchunk); } chunks.Clear(); preludecompression = chunkcompression; chunkcompression = new List <bool>(); } chunkcompression.Add(compressed); if (prelude != null && chunks.Count < prelude.Count) { for (int i = 0; i < Chunk.Length; i++) { if (prelude[chunks.Count].Data[i] != chunk.Data[i]) { ErrorManager.SignalIgnorableError("NSF: Prelude data mismatch"); break; } } } chunks.Add(chunk); } if (prelude != null && chunks.Count < prelude.Count) { ErrorManager.SignalIgnorableError("NSF: Prelude is longer than actual data"); } if (prelude != null) { ErrorManager.SignalIgnorableError("NSF: Prelude saving is not yet implemented"); } foreach (bool compressed in chunkcompression) { if (compressed) { ErrorManager.SignalIgnorableError("NSF: Non-prelude chunk was compressed"); } } return(new NSF(chunks)); }
public static Entity Load(byte[] data) { if (data.Length < 16) { ErrorManager.SignalError("Entity: Data is too short"); } int length = BitConv.FromInt32(data, 0); int blank1 = BitConv.FromInt32(data, 4); int blank2 = BitConv.FromInt32(data, 8); int propertycount = BitConv.FromInt32(data, 12); if (length != data.Length) { ErrorManager.SignalIgnorableError("Entity: Length field mismatch"); } if (blank1 != 0 || blank2 != 0) { ErrorManager.SignalIgnorableError("Entity: Blank value is wrong"); } if (propertycount < 0 || propertycount > ushort.MaxValue) { ErrorManager.SignalError("Entity: Property count is invalid"); } if (data.Length < 16 + propertycount * 8) { ErrorManager.SignalError("Entity: Data is too short"); } Dictionary <short, EntityProperty> properties = new Dictionary <short, EntityProperty>(); for (int i = 0; i < propertycount; i++) { short id = BitConv.FromInt16(data, 16 + i * 8); int offset = (ushort)BitConv.FromInt16(data, 18 + i * 8) + 12; int nextoffset = (i == propertycount - 1) ? data.Length : ((ushort)BitConv.FromInt16(data, 26 + i * 8) + 12); byte type = data[20 + i * 8]; byte elementsize = data[21 + i * 8]; short unknown = BitConv.FromInt16(data, 22 + i * 8); if (offset > data.Length) { ErrorManager.SignalError("Entity: Property begins out of bounds"); } if (nextoffset < offset) { ErrorManager.SignalError("Entity: Property ends before it begins"); } if (nextoffset > data.Length) { ErrorManager.SignalError("Entity: Property ends out of bounds"); } if (properties.ContainsKey(id)) { ErrorManager.SignalIgnorableError("Entity: Duplicate property"); } else { byte[] propertydata = new byte [nextoffset - offset]; Array.Copy(data, offset, propertydata, 0, propertydata.Length); EntityProperty property = EntityProperty.Load(type, elementsize, unknown, i == propertycount - 1, propertydata); properties.Add(id, property); } } return(new Entity(properties)); }