/// <summary> /// Reads the string list. /// </summary> /// <param name="ms"></param> /// <param name="owner"></param> /// <returns></returns> protected ObservableCollection <NdfStringReference> ReadStrings(Stream ms, NdfBinary owner) { var strings = new ObservableCollection <NdfStringReference>(); NdfFooterEntry stringEntry = owner.Footer.Entries.Single(x => x.Name == "STRG"); ms.Seek(stringEntry.Offset, SeekOrigin.Begin); int i = 0; var buffer = new byte[4]; while (ms.Position < stringEntry.Offset + stringEntry.Size) { var nstring = new NdfStringReference { Id = i }; ms.Read(buffer, 0, buffer.Length); int strLen = BitConverter.ToInt32(buffer, 0); var strBuffer = new byte[strLen]; ms.Read(strBuffer, 0, strBuffer.Length); nstring.Value = Encoding.GetEncoding("ISO-8859-1").GetString(strBuffer); i++; strings.Add(nstring); } return(strings); }
/// <summary> /// Reads the trans list /// </summary> /// <param name="ms"></param> /// <param name="owner"></param> /// <returns></returns> protected ObservableCollection <NdfTranReference> ReadTrans(Stream ms, NdfBinary owner) { var trans = new ObservableCollection <NdfTranReference>(); NdfFooterEntry stringEntry = owner.Footer.Entries.Single(x => x.Name == "TRAN"); ms.Seek(stringEntry.Offset, SeekOrigin.Begin); int i = 0; var buffer = new byte[4]; while (ms.Position < stringEntry.Offset + stringEntry.Size) { var ntran = new NdfTranReference { Id = i }; ms.Read(buffer, 0, buffer.Length); int strLen = BitConverter.ToInt32(buffer, 0); var strBuffer = new byte[strLen]; ms.Read(strBuffer, 0, strBuffer.Length); ntran.Value = Encoding.GetEncoding("ISO-8859-1").GetString(strBuffer); i++; trans.Add(ntran); } // TODO: Trans is actually more a tree than a list, this is still not fully implemented/reversed. return(trans); }
/// <summary> /// Reads the Properties dictionary and relates each one to its owning class. /// </summary> /// <param name="ms"></param> /// <param name="owner"></param> protected void ReadProperties(Stream ms, NdfBinary owner) { NdfFooterEntry propEntry = owner.Footer.Entries.Single(x => x.Name == "PROP"); ms.Seek(propEntry.Offset, SeekOrigin.Begin); int i = 0; var buffer = new byte[4]; while (ms.Position < propEntry.Offset + propEntry.Size) { var property = new NdfProperty(i); ms.Read(buffer, 0, buffer.Length); int strLen = BitConverter.ToInt32(buffer, 0); var strBuffer = new byte[strLen]; ms.Read(strBuffer, 0, strBuffer.Length); property.Name = Encoding.GetEncoding("ISO-8859-1").GetString(strBuffer); ms.Read(buffer, 0, buffer.Length); NdfClass cls = owner.Classes.Single(x => x.Id == BitConverter.ToUInt32(buffer, 0)); property.Class = cls; cls.Properties.Add(property); i++; } }
/// <summary> /// Reads the Classes dictionary. /// </summary> /// <param name="ms"></param> /// <param name="owner"></param> /// <returns></returns> protected ObservableCollection <NdfClass> ReadClasses(Stream ms, NdfBinary owner) { var classes = new ObservableCollection <NdfClass>(); NdfFooterEntry classEntry = owner.Footer.Entries.Single(x => x.Name == "CLAS"); ms.Seek(classEntry.Offset, SeekOrigin.Begin); uint i = 0; var buffer = new byte[4]; while (ms.Position < classEntry.Offset + classEntry.Size) { var nclass = new NdfClass(owner, i); ms.Read(buffer, 0, buffer.Length); int strLen = BitConverter.ToInt32(buffer, 0); var strBuffer = new byte[strLen]; ms.Read(strBuffer, 0, strBuffer.Length); nclass.Name = Encoding.GetEncoding("ISO-8859-1").GetString(strBuffer); i++; classes.Add(nclass); } return(classes); }
/// <summary> /// Reads the object instances. /// </summary> /// <param name="ms"></param> /// <param name="owner"></param> /// <returns></returns> protected List <NdfObject> ReadObjects(Stream ms, NdfBinary owner) { var objects = new List <NdfObject>(); uint instanceCount = ReadChunk(ms, owner); NdfFooterEntry objEntry = owner.Footer.Entries.Single(x => x.Name == "OBJE"); ms.Seek(objEntry.Offset, SeekOrigin.Begin); for (uint i = 0; i < instanceCount; i++) { long objOffset = ms.Position; try { NdfObject obj = ReadObject(ms, i, owner); obj.Offset = objOffset; objects.Add(obj); }catch (Exception e) { throw e; } } return(objects); }
/// <summary> /// Reads the footer data which is the Ndfbin Dictionary. /// </summary> /// <returns></returns> protected NdfFooter ReadFooter() { // Footer is 224 bytes const int footerLength = 224; var footer = new NdfFooter(); using (var ms = new MemoryStream(ContentData, ContentData.Length - footerLength, footerLength)) { var qwdbuffer = new byte[8]; var dwdbufer = new byte[4]; ms.Read(qwdbuffer, 0, qwdbuffer.Length); footer.Header = Encoding.ASCII.GetString(qwdbuffer); while (ms.Position < ms.Length) { var entry = new NdfFooterEntry(); ms.Read(dwdbufer, 0, dwdbufer.Length); entry.Name = Encoding.ASCII.GetString(dwdbufer); ms.Seek(4, SeekOrigin.Current); ms.Read(qwdbuffer, 0, qwdbuffer.Length); entry.Offset = BitConverter.ToInt64(qwdbuffer, 0); ms.Read(qwdbuffer, 0, qwdbuffer.Length); entry.Size = BitConverter.ToInt64(qwdbuffer, 0); footer.Entries.Add(entry); } } return(footer); }
/// <summary> /// Reads the amount of instances this file contains. /// </summary> /// <param name="ms"></param> /// <param name="owner"></param> /// <returns></returns> protected uint ReadChunk(Stream ms, NdfBinary owner) { NdfFooterEntry chnk = owner.Footer.Entries.Single(x => x.Name == "CHNK"); ms.Seek(chnk.Offset, SeekOrigin.Begin); var buffer = new byte[4]; ms.Read(buffer, 0, buffer.Length); ms.Read(buffer, 0, buffer.Length); return(BitConverter.ToUInt32(buffer, 0)); }
/// <summary> /// Reads a list of UInt32, this is needed for the topobjects, import and export tables. /// </summary> /// <param name="ms"></param> /// <param name="owner"></param> /// <param name="lst"></param> /// <returns></returns> protected List <uint> ReadUIntList(Stream ms, NdfBinary owner, string lst) { var uintList = new List <uint>(); NdfFooterEntry uintEntry = owner.Footer.Entries.Single(x => x.Name == lst); ms.Seek(uintEntry.Offset, SeekOrigin.Begin); var buffer = new byte[4]; while (ms.Position < uintEntry.Offset + uintEntry.Size) { ms.Read(buffer, 0, buffer.Length); uintList.Add(BitConverter.ToUInt32(buffer, 0)); } return(uintList); }
/// <summary> /// Reads the footer data which is the Ndfbin Dictionary. /// </summary> /// <returns></returns> protected NdfFooter ReadFooter(Stream ms, NdfHeader head) { var footer = new NdfFooter(); ms.Seek((long)head.FooterOffset, SeekOrigin.Begin); var dwdBuffer = new byte[4]; var qwdbuffer = new byte[8]; ms.Read(dwdBuffer, 0, dwdBuffer.Length); if (BitConverter.ToUInt32(dwdBuffer, 0) != 809717588) { throw new InvalidDataException("Footer doesnt start with TOC0"); } ms.Read(dwdBuffer, 0, dwdBuffer.Length); uint footerEntryCount = BitConverter.ToUInt32(dwdBuffer, 0); for (int i = 0; i < footerEntryCount; i++) { var entry = new NdfFooterEntry(); ms.Read(qwdbuffer, 0, qwdbuffer.Length); entry.Name = Encoding.ASCII.GetString(qwdbuffer).TrimEnd('\0'); ms.Read(qwdbuffer, 0, qwdbuffer.Length); entry.Offset = BitConverter.ToInt64(qwdbuffer, 0); ms.Read(qwdbuffer, 0, qwdbuffer.Length); entry.Size = BitConverter.ToInt64(qwdbuffer, 0); footer.Entries.Add(entry); } return(footer); }