/// <summary> /// liest die Daten in <see cref="poi"/> ein /// </summary> /// <param name="br"></param> /// <param name="bRelaxed"></param> void Decode_POIData(BinaryReaderWriter br, bool bRelaxed) { if (PointTableBlock.Count > 0) { StringBuilder sb = new StringBuilder(); // Tabelle für Typen und Offsets zu den eigentlichen Daten einlesen PointTableItems = new List <TableItem>(); br.Seek(PointTableBlock.Offset); for (int i = 0; i < PointTableBlock.Count; i++) { PointTableItems.Add(new TableItem(br, PointTableBlock.Recordsize)); } // Tabelle der POI-Daten einlesen poi.Clear(); for (int i = 0; i < PointTableItems.Count; i++) { br.Seek(PointTableItems[i].Offset + PointDatablock.Offset); int datalen = i < PointTableItems.Count - 1 ? PointTableItems[i + 1].Offset - PointTableItems[i].Offset : (int)PointTableBlock.Offset - (PointTableItems[i].Offset + (int)PointDatablock.Offset); try { long startpos = br.Position; POI p = new POI(PointTableItems[i].Type, PointTableItems[i].Subtype); p.Read(br); Debug.WriteLineIf(startpos + datalen != br.BaseStream.Position, string.Format("Diff. {0} der Datenlänge beim Lesen des Objektes 0x{1:x} 0x{2:x} (größer 0 bedeutet: zuviel gelesen)", br.Position - (startpos + datalen), PointTableItems[i].Type, PointTableItems[i].Subtype)); poi.Add(p, 0); } catch (Exception ex) { if (bRelaxed) { sb.AppendFormat("Fehler beim Einlesen von Punkt 0x{0:x2}, 0x{1:x2}: {2}", PointTableItems[i].Type, PointTableItems[i].Subtype, ex.Message); sb.AppendLine(); } else { throw new Exception(ex.Message); } } } if (bRelaxed) { RelaxedModeErrors += sb.ToString(); } } }
public override void Write(BinaryReaderWriter bw, uint headeroffset = 0, UInt16 headerlength = 0x5B, uint gapoffset = 0, uint dataoffset = 0, bool setsectiondata = true) { HeaderOffset = headeroffset; if (headerlength > 0) { Headerlength = headerlength; } CreationDate = DateTime.Now; GapOffset = gapoffset; DataOffset = dataoffset; bw.SetEncoding(Codepage); bw.Seek(Headerlength); Encode_PolygoneData(bw); Encode_PolylineData(bw); Encode_POIData(bw); Encode_Draworder(bw); SetSectionsAlign(); Encode_Header(bw); // Header mit den akt. Offsets neu erzeugen Filesections.WriteSections(bw); }
/// <summary> /// liest den allgemeinen Header ab <see cref="HeaderOffset"/> ein /// <para>Ist der eingelesene Typ nicht der erwartete Typ, wird eine Exception ausgelöst.</para> /// </summary> /// <param name="br"></param> /// <param name="expectedtyp">Extension des erwarteten Typs z.B. 'LBL', sonst null</param> protected void ReadCommonHeader(BinaryReaderWriter br, string expectedtyp = null) { br.Seek(HeaderOffset); Headerlength = br.Read2AsUShort(); GarminTyp = br.ReadString(10); // z.B. "GARMIN RGN" if (GarminTyp.Length != 10 || GarminTyp.Substring(0, 7) != "GARMIN ") { throw new Exception("Das ist kein Garmin-SUB-File."); } if (!string.IsNullOrEmpty(expectedtyp) && GarminTyp.Substring(7) != expectedtyp) { throw new Exception("Das ist nicht der erwartete Dateityp (" + expectedtyp + ")."); } Unknown_0x0C = br.ReadByte(); Locked = br.ReadByte(); try { CreationDate = new DateTime(br.Read2AsShort(), br.ReadByte(), // "echter" Monat br.ReadByte(), br.ReadByte(), br.ReadByte(), br.ReadByte()); } catch { // Datum/Uhrzeit nicht erkannt } }
/// <summary> /// Die Daten werden encodiert und in den entsprechenden Abschnitt geschrieben. Ex. der Abschnitt schon, erfolgt KEIN Schreiben! /// </summary> /// <param name="filesectiontype"></param> /// <param name="overwrite">wenn true, werden ev. schon vorhandene Daten überschrieben</param> /// <returns>false, wenn der Abschnitt nicht überschrieben werden kann oder keine Daten ex.</returns> protected bool SetData2Filesection(int filesectiontype, bool overwrite) { if (!overwrite && Filesections.ContainsType(filesectiontype)) { return(false); } BinaryReaderWriter bw = new BinaryReaderWriter(); Encode_Filesection(bw, filesectiontype); // Daten nur in den temp. Writer schreiben if (bw.Length > 0) { if (!Filesections.ContainsType(filesectiontype)) { Filesections.AddSection(filesectiontype); } bw.Seek(0); Filesections.SetSectionDataFromWriter(filesectiontype, bw); } else { if (Filesections.ContainsType(filesectiontype)) { Filesections.RemoveSection(filesectiontype); } return(false); } return(true); }
/// <summary> /// lese die Daten aus einer MDX-Datei ein /// </summary> /// <param name="br"></param> public void Read(BinaryReaderWriter br) { br.Seek(0); byte[] id = br.ReadBytes(6); if (id[0] != 'M' || id[1] != 'i' || id[2] != 'd' || id[3] != 'x' || id[4] != 'd' || id[5] != 0) { throw new Exception("Keine MDX-Datei."); } Unknown1 = br.Read2AsUShort(); Unknown2 = br.Read2AsUShort(); Count = br.Read4UInt(); Maps.Clear(); for (int i = 0; i < Count; i++) { MapEntry entry = new MapEntry(); entry.Read(br); Maps.Add(entry); } }
/// <summary> /// liefert die aktuellen Dateidaten (über den <see cref="BinaryReaderWriter"/> des Dateisystems oder aus der Backup-Datei) /// <para>Wegen der Funktion Stream.Read() darf die internen Datei nicht größer als 0x3FFFFFFF (2 GB) sein.</para> /// <para>Wenn der IMG-BinaryReaderWriter geliefert wird, werden die Datei-Daten in einen neuen Speicherbereich kopiert und dieser geliefert.</para> /// </summary> /// <param name="file"></param> /// <param name="br"></param> /// <returns></returns> protected byte[] getFiledata(FileProps file, BinaryReaderWriter br) { if (br == null || preblocks4read < 0 || File.Exists(file.Backgroundfile)) { if (File.Exists(file.Backgroundfile)) { return(File.ReadAllBytes(file.Backgroundfile)); } // dann ex. noch keine Daten return(new byte[0]); } else { if (br != null && preblocks4read > 0) // aus dem Originalstream Daten einlesen { byte[] data = new byte[file.Filesize]; // neuer Speicherbereich UInt16[] blocks = file.PseudoFileBlocks(); for (int i = 0; i < blocks.Length; i++) { int offset = ImgHeader.FileBlockLength * i; br.Seek(ImgHeader.FileBlockLength * (long)(preblocks4read + blocks[i])); br.BaseStream.Read(data, offset, file.Filesize - offset >= ImgHeader.FileBlockLength ? ImgHeader.FileBlockLength : (int)file.Filesize - offset); } return(data); } } return(null); }
public override void ReadHeader(BinaryReaderWriter br) { base.ReadCommonHeader(br, Type); br.ReadBytes(Unknown_0x15); // die Header- also Sub-Dateianfänge einlesen for (int i = 0; i < SubHeaderOffsets.Length; i++) { SubHeaderOffsets[i] = br.Read4UInt(); } if (Headerlength > 0x35) { Unknown_0x35 = br.ReadBytes(Headerlength - 0x35); } // echte Sub-Dateiheaderlängen aus dem jeweiligen Sub-Datei-Header einlesen for (int i = 0; i < SubHeaderOffsets.Length; i++) { if (SubHeaderOffsets[i] != 0) { br.Seek(SubHeaderOffsets[i]); SubHeaderLength[i] = br.Read2AsUShort(); } else { SubHeaderLength[i] = 0; } } // Subdateiheaderdistanzen berechnen // - bei SubHeaderOffsets==0 ist auch SubHeaderDistance==0 weil der Header ungültig ist // - beim letzten SubHeader ist SubHeaderDistance==uint.MaxValue, da es nicht anders geht for (int i = 0; i < SubHeaderOffsets.Length; i++) { if (SubHeaderOffsets[i] > 0 && i < SubHeaderOffsets.Length - 1) { // nächsten gültigen Subheader suchen int j = SubHeaderOffsets.Length; for (j = i + 1; j < SubHeaderOffsets.Length; j++) { if (SubHeaderOffsets[j] >= SubHeaderOffsets[i] + SubHeaderLength[i]) { break; } } if (j < SubHeaderOffsets.Length) { SubHeaderDistance[i] = SubHeaderOffsets[j] - SubHeaderOffsets[i]; } } else { SubHeaderDistance[i] = uint.MaxValue; } } }
void Decode_DescriptionBlock(BinaryReaderWriter br, DataBlock block) { if (br != null && block != null && block.Length > 0) { br.Seek(block.Offset); Description = br.ReadString((int)block.Length); } }
/// <summary> /// In den Stream werden entsprechend der gespeicherten Position die Daten geschrieben. /// </summary> /// <param name="bw"></param> public void Write(BinaryReaderWriter bw) { if (Data != null && Data.Length > 0) { bw.Seek(Position.Offset); bw.Write(Data); } }
/// <summary> /// lese die Daten aus einer TDB-Datei ein /// </summary> /// <param name="br"></param> public void Read(BinaryReaderWriter br) { BlockHeader blh = new BlockHeader(); Tilemap.Clear(); BlockHeaderTypList.Clear(); br.Seek(0); blh.Read(br); if (blh.ID != BlockHeader.Typ.Header) { throw new Exception("Keine TDB-Datei."); } Head = new Header(blh); Head.ReadData(br); BlockHeaderTypList.Add(blh.ID); BlockLength.Add(blh.Length); do { blh.Read(br); BlockHeaderTypList.Add(blh.ID); BlockLength.Add(blh.Length); switch (blh.ID) { case BlockHeader.Typ.Copyright: Copyright = new SegmentedCopyright(new BlockHeader(blh)); Copyright.ReadData(br); break; case BlockHeader.Typ.Overviewmap: Overviewmap = new OverviewMap(new BlockHeader(blh)); Overviewmap.ReadData(br); break; case BlockHeader.Typ.Tilemap: TileMap dm = new TileMap(new BlockHeader(blh)); dm.ReadData(br); Tilemap.Add(dm); break; case BlockHeader.Typ.Description: Mapdescription = new Description(new BlockHeader(blh)); Mapdescription.ReadData(br); break; case BlockHeader.Typ.Crc: Crc = new PseudoCRC(new BlockHeader(blh)); Crc.ReadData(br); break; default: // unbekannter Block br.Position += blh.Length; break; } } while (br.Position < br.Length); }
/// <summary> /// lese die Daten aus einer MDX-Datei ein /// </summary> /// <param name="br"></param> public void Read(BinaryReaderWriter br) { br.Seek(0); while (br.BaseStream.Position < br.BaseStream.Length) { MapEntry me = new MapEntry(); me.Read(br); Maps.Add(me); } }
void Decode_ContentsBlock(BinaryReaderWriter br, DataBlock block) { if (br != null && block != null && block.Length > 0) { br.Seek(block.Offset); DescriptionBlock = new DataBlock(br); CharacterLookupTableBlock = new DataBlock(br); Filesections.AddSection((int)InternalFileSections.DescriptionBlock, DescriptionBlock); Filesections.AddSection((int)InternalFileSections.CharacterLookupTableBlock, CharacterLookupTableBlock); } }
/// <summary> /// /// </summary> /// <param name="br"></param> /// <param name="dataendpos">Pointer auf das 1. Byte NACH den Höhendaten</param> public void ReadData(BinaryReaderWriter br, uint dataendpos) { int items = (ZoomlevelItem.MaxIdxHoriz + 1) * (ZoomlevelItem.MaxIdxVert + 1); long pos = br.Position; br.Seek(ZoomlevelItem.PtrSubtileTable); List <SubtileTableitem> stilst = new List <SubtileTableitem>(); for (int i = 0; i < items; i++) { stilst.Add(new SubtileTableitem()); stilst[stilst.Count - 1].Read(br, ZoomlevelItem.Structure_OffsetSize, ZoomlevelItem.Structure_BaseheightSize, ZoomlevelItem.Structure_DiffSize, ZoomlevelItem.Structure_CodingtypeSize); } br.Seek(ZoomlevelItem.PtrHeightdata); for (int i = 0; i < stilst.Count; i++) { byte[] data = null; if (stilst[i].Diff > 0) { // Datenlänge: vom akt. Offset bis zum nächsten gültigen Offset int j = i + 1; for (; j < stilst.Count; j++) { if (stilst[j].Offset > 0) { break; } } uint len = j < stilst.Count - 1 ? stilst[j].Offset - stilst[i].Offset : dataendpos - (uint)br.Position; data = br.ReadBytes((int)len); } Subtiles.Add(new Subtile(data, stilst[i])); } br.Seek(pos); }
public override void Read(BinaryReaderWriter br, bool raw = false, uint headeroffset = 0, uint gapoffset = 0) { base.Read(br, raw, headeroffset, gapoffset); if (Locked != 0) { RawRead = true; return; } // Zoomlevel-Tabelle einlesen ZoomLevel = new List <Zoomlevel>(); br.Seek(PtrZoomlevel); for (int i = 0; i < ZoomlevelCount; i++) { Zoomlevel zl = new Zoomlevel(); zl.Read(br, ZoomlevelRecordSize); ZoomLevel.Add(zl); } // Subtile-Daten einlesen for (int i = 0; i < ZoomLevel.Count; i++) { Zoomlevel zl = ZoomLevel[i]; uint end = PtrZoomlevel; if (i < ZoomLevel.Count - 1) { end = ZoomLevel[i + 1].ZoomlevelItem.PtrSubtileTable; } br.Seek(ZoomLevel[i].ZoomlevelItem.PtrSubtileTable); zl.ReadData(br, end); } if (raw) // keine Entschlüsselung der Höhendaten { RawRead = true; return; } // Decodierung der Höhendaten }
/// <summary> /// schreibt den Blockheader und die Blockdaten /// </summary> /// <param name="wr"></param> public new void Write(BinaryReaderWriter wr) { BinaryReaderWriter wrtmp = new BinaryReaderWriter(); base.Write(wrtmp); SubCount = (UInt16)DataSize.Count; //Unknown1 = (UInt16)(SubCount + 1); wrtmp.Write(Unknown1); wrtmp.Write(SubCount); for (int i = 0; i < DataSize.Count; i++) { wrtmp.Write(DataSize[i]); } wrtmp.Write(HasCopyright); wrtmp.Write(Unknown2); wrtmp.Write(Unknown3); wrtmp.Write(Unknown4); wrtmp.Write(Unknown5); wrtmp.Write(Unknown6); wrtmp.Write(Unknown7); for (int i = 0; i < Name.Count; i++) { wrtmp.WriteString(Name[i]); } wrtmp.Write(Unknown8); wrtmp.Write(Unknown9); wrtmp.Seek(1); wrtmp.Write((short)(wrtmp.Length - 3)); // Länge des Datenbereiches schreiben wrtmp.Seek(0); wr.Write(wrtmp.ToArray()); wrtmp.Dispose(); }
void Decode_Copyright(BinaryReaderWriter br, DataBlock block) { Copyright.Clear(); if (br != null) { br.Seek(block.Offset); while (br.Position < block.Offset + block.Length) { Copyright.Add(br.ReadString()); } } }
void Decode_CharacterLookupTableBlock(BinaryReaderWriter br, DataBlock block) { if (br != null && block != null && block.Length > 0) { br.Seek(block.Offset); Sortheader.Read(br); if (Locked == 0) { //throw new Exception("Decode_CharacterLookupTableBlock() ist noch nicht implementiert."); } } }
protected string GetNTLabel(BinaryReaderWriter br, uint offset) { br.Seek(NT_PointLabelblock.Offset + offset); return(br.ReadString()); //List<char> chars = new List<char>(); //char c; //do { // c = br.ReadChar(); // if (c != 0x0) chars.Add(c); //} while (c != 0x0); //return new string(chars.ToArray()); }
public override void Write(BinaryReaderWriter bw, uint headeroffset = 0, UInt16 headerlength = 0x29, uint gapoffset = 0, uint dataoffset = 0, bool setsectiondata = true) { HeaderOffset = headeroffset; if (headerlength > 0) { Headerlength = headerlength; } CreationDate = DateTime.Now; GapOffset = gapoffset; DataOffset = dataoffset; PtrZoomlevel = Headerlength; for (int z = 0; z < ZoomlevelCount; z++) { ZoomLevel[z].CalculateStructureLength(); ZoomLevel[z].ZoomlevelItem.PtrSubtileTable = PtrZoomlevel; PtrZoomlevel += (uint)ZoomLevel[z].GetTablelength(); ZoomLevel[z].ZoomlevelItem.PtrHeightdata = PtrZoomlevel; PtrZoomlevel += (uint)ZoomLevel[z].GetDatalength(); } Encode_Header(bw); bw.Seek(headerlength); for (int z = 0; z < ZoomlevelCount; z++) { // Subtile-Tabelle schreiben for (int i = 0; i < ZoomLevel[z].Subtiles.Count; i++) { ZoomlevelTableitem zti = ZoomLevel[z].ZoomlevelItem; ZoomLevel[z].Subtiles[i].Tableitem.Write(bw, zti.Structure_OffsetSize, zti.Structure_BaseheightSize, zti.Structure_DiffSize, zti.Structure_CodingtypeSize); } // Subtile-Daten schreiben for (int i = 0; i < ZoomLevel[z].Subtiles.Count; i++) { bw.Write(ZoomLevel[z].Subtiles[i].Data); } } // Zoomleveltabelle schreiben for (int z = 0; z < ZoomlevelCount; z++) { ZoomLevel[z].ZoomlevelItem.Write(bw); } bw.Flush(); }
/// <summary> /// schreibt den allgemeinen Header /// </summary> /// <param name="wr"></param> /// <param name="typ">nur angeben wenn der akt. <see cref="GarminTyp"/> überschrieben werden soll</param> protected void WriteCommonHeader(BinaryReaderWriter wr, string typ = null) { wr.Seek(HeaderOffset); wr.Write(Headerlength); if (!string.IsNullOrEmpty(typ)) { GarminTyp = "GARMIN " + typ; } wr.WriteString(GarminTyp, null, false); wr.Write(Unknown_0x0C); wr.Write(Locked); wr.Write((Int16)(CreationDate.Year)); wr.Write((byte)(CreationDate.Month)); wr.Write((byte)(CreationDate.Day)); wr.Write((byte)(CreationDate.Hour)); wr.Write((byte)(CreationDate.Minute)); wr.Write((byte)(CreationDate.Second)); }
/// <summary> /// Ab dem vorgegeben Offset des Streams werden (max.) die gewünschten Anzahl Bytes eingelesen und die vorgegeben Positionsangaben gespeichert. /// </summary> /// <param name="br"></param> /// <param name="streamoffset"></param> /// <param name="newoffset"></param> /// <param name="length"></param> /// <returns>Anzahl der tatsächlich gelesenen Bytes</returns> public uint Read(BinaryReaderWriter br, uint streamoffset, uint newoffset, uint length) { br.Seek(streamoffset); return(Read(br, newoffset, length)); }
/// <summary> /// liest das gesamte Dateisystem (aber ohne die Daten interner Dateien) ein und "behält" den <see cref="BinaryReaderWriter"/> /// <para>Der Dateiinhalt wird immer nur bei Bedarf eingelesen.</para> /// </summary> /// <param name="br"></param> public void Read(BinaryReaderWriter br) { binreader = br; // Header einlesen binreader.Seek(0); ImgHeader.Read(binreader); List <FATBlock> root = new List <FATBlock>(); List <FATBlock> fat = new List <FATBlock>(); // gesamte FAT einlesen int sumfatblocks = -1; while (sumfatblocks != 0) { FATBlock bl = new FATBlock((uint)ImgHeader.FATBlockLength); bl.Read(binreader); if (sumfatblocks < 0) { sumfatblocks = ((int)bl.Filesize - ImgHeader.HeaderLength) / ImgHeader.FATBlockLength; // Anzahl der FAT-Blocks aus dem 1. Block ("Dateigröße") ermitteln } if (bl.FullName == ".") { root.Add(bl); } else { fat.Add(bl); } sumfatblocks--; } // Dateiliste erzeugen file4block.Clear(); Files.Clear(); preblocks4read = (UInt16)(root[0].Filesize / ImgHeader.FileBlockLength); // Anzahl der Datenblöcke bis zum Start des echten Dateiinhaltbereiches if (root[0].Filesize % ImgHeader.FileBlockLength != 0) { preblocks4read++; } FATSize = (int)root[0].Filesize - ImgHeader.HeaderLength; for (int block = 0; block < fat.Count; block++) { FATBlock bl = fat[block]; if (bl.Used) { FileProps file; if (bl.Part == 0) { string name = bl.FullName; if (name != ".") { file = new FileProps(name, bl.Filesize, string.IsNullOrEmpty(backgroundpath) ? null : getBackFilename(name)); Files.Add(file); } } int fileidx = Files.Count - 1; file = Files[fileidx]; for (int j = 0; j < bl.BlockNumberCount; j++) // alle Blocknummern registrieren { UInt16 blockno = (UInt16)(bl.GetBlockNumber(j) - preblocks4read); file.PseudoFileBlockAdd(blockno); // 0-basierte Blocknummern speichern file4block.Add(blockno, fileidx); } } } }
/* * Der Header besteht aus x Sectoren der festen Länge SECTOR_BLOCKSIZE. * I.A. bildet 1 Sektor einen Block, so dass der Header aus y (=x) Blöcken besteht. * * Der IMG-Dateibereich vom Dateianfang bis zum Ende der FAT wird als Pseudodatei aufgefasst die aus z Blöcken mit FileBlockLength besteht. * Diese z Blöcke (0 .. z-1) müssen in der Root registriert sein. Sollte der Root-Größe dafür nicht ausreichen, muss sie entsprechend * vergrößert werden. Damit vergrößert sich natürlich die Pseudodatei, d.h. die Root muss entsprechend mehr Einträge aufnehmen können. * Deshalb ist es zweckmäßig, die Root-Größe iterativ zu bestimmen. * * Die FileBlockLength ist eine 2er Potenz von FATBlockLength (ev. also auch gleich). * * * */ /// <summary> /// schreibt die gesamte IMG-Datei /// </summary> /// <param name="wr"></param> public void Write(BinaryReaderWriter wr) { int prefileblocks = 0; // alle Blocks vor den fileblocks (Blocklänge: FileBlockLength) int fileblocks = 0; // alle Blocks für die Dateiinhalte (Blocklänge: FileBlockLength) int rootblocks = 1; // Blocks für die Root (Blocklänge: FATBlockLength) int fatblocks = 0; // Blocks für die FAT (Blocklänge: FATBlockLength) do { // Anzahl der Blöcke für die Dateidaten und die FAT bestimmen (abh. von den akt. Blockgrößen) fileblocks = 0; fatblocks = 0; foreach (FileProps file in Files) { fileblocks += blocks4File((int)file.Filesize); fatblocks += FATBlocks4File((int)file.Filesize); } // Anzahl der Rootblocks und Preblocks bestimmen int newrootblocks = 0; rootblocks = 1; do { prefileblocks = blocks4File(ImgHeader.HeaderLength + (rootblocks + fatblocks) * ImgHeader.FATBlockLength); newrootblocks = FATBlocks4File(prefileblocks * ImgHeader.FileBlockLength); if (newrootblocks != rootblocks) // Platz in der aktuellen Root ist noch nicht ausreichend { rootblocks = newrootblocks; } else { break; } } while (true); // ev. noch Blocklänge vergrößern if (prefileblocks + fileblocks > 0xffff) // mehr Blöcke können im Header nicht angegeben werden (UInt16) -> Vergrößerung der Blockgröße nötig { ImgHeader.FileBlockLength *= 2; } /* Blockgröße max. Dateigröße * 512 Byte -> 33553920 Byte, etwa 32 MB * 1024 Byte -> 67107840 Byte, etwa 64 MB * 2048 Byte -> 134215680 Byte, etwa 127 MB * 4096 Byte -> 268431360 Byte, etwa 256 MB * 8192 Byte -> 536862720 Byte, etwa 512 MB * 16384 Byte -> 1073725440 Byte, etwa 1024 MB, 1GB * 32768 Byte -> 2147450880 Byte, etwa 2048 MB, 2GB * 65536 Byte -> 4294901760 Byte, etwa 4096 MB, 4GB */ else { ImgHeader.Blocks4Img = (UInt16)(prefileblocks + fileblocks); break; } } while (true); // Header schreiben wr.Seek(0); ImgHeader.Write(wr); UInt16 block = 0; // Root schreiben (Datei ".") List <FATBlock> fatbl = buildFATEntry(".", (uint)(prefileblocks * ImgHeader.FileBlockLength), ref block); foreach (FATBlock item in fatbl) { item.Write(wr); } // die eigentliche FAT schreiben block = (UInt16)prefileblocks; // 1. Blocknummer des Dateibereiches foreach (FileProps file in Files) { fatbl = buildFATEntry(file.Name, file.Filesize, ref block); foreach (FATBlock item in fatbl) { item.Write(wr); } } // ev. leere, ungenutzte Blöcke schreiben long filestart = prefileblocks * ImgHeader.FileBlockLength; while (wr.Position < filestart) { fatbl = buildFATEntry(null, 0, ref block); foreach (FATBlock item in fatbl) { item.Write(wr); } } FATSize = (int)wr.Position - ImgHeader.HeaderLength; // Daten schreiben foreach (FileProps file in Files) { byte[] data = getFiledata(file, binreader); int offset = 0; do { if (offset + ImgHeader.FileBlockLength <= data.Length) // vollständigen Block schreiben { wr.Write(data, offset, ImgHeader.FileBlockLength); } else { wr.Write(data, offset, data.Length - offset); // restliche Bytes schreiben int i = data.Length % ImgHeader.FileBlockLength; for (; i < ImgHeader.FileBlockLength; i++) // ungenutzte Bytes mit 0x00 füllen { wr.Write((byte)0x00); } } offset += ImgHeader.FileBlockLength; } while (offset < data.Length); } }
protected void Test(BinaryReaderWriter br) { int txtcount = 0; uint offset = 0; string txt = ""; while (offset < NT_PointLabelblock.Length) { txt = GetNTLabel(br, offset); offset = (uint)br.Position - NT_PointLabelblock.Offset; txtcount++; } Debug.WriteLine(string.Format("{0} Texte", txtcount)); List <NTTableItem> block1 = new List <NTTableItem>(); br.Seek(NT_LabelblockTable1.Offset); uint len = NT_LabelblockTable1.Length; while (len > 4) { block1.Add(new NTTableItem(br)); len -= 4; } Debug.WriteLine(string.Format("{0} Einträge in nt2_block1", block1.Count)); List <NTTableItem> block2 = new List <NTTableItem>(); br.Seek(NT_LabelblockTable2.Offset); len = NT_LabelblockTable2.Length; while (len > 4) { block2.Add(new NTTableItem(br)); len -= 4; } Debug.WriteLine(string.Format("{0} Einträge in nt2_block2", block2.Count)); for (int i = 0; i < block1.Count; i++) { uint offs1 = block1[i].v1; uint key1 = block1[i].v2; string txt1 = GetNTLabel(br, offs1); //if (offs1 == 0xa552) { // Debug.WriteLine(block1[i].ToString()); //} bool found = false; for (int j = 0; j < block2.Count; j++) { uint key2 = block2[j].v1; if (key1 == key2) { found = true; uint offs2 = block2[j].v2; string txt2 = GetNTLabel(br, offs2); if (txt1 != txt2) { Debug.WriteLine(string.Format("{0}: {1} <--> {2} key 0x{3:x}", i, txt1, txt2, key1)); } //else // Debug.WriteLine(string.Format("{0}: {1} OK", i, txt1)); break; } } if (!found) { Debug.WriteLine(string.Format("{0}: {1} nicht gefunden", i, txt1)); } } }
/// <summary> /// liest die Daten in <see cref="polygone"/> ein /// </summary> /// <param name="br"></param> /// <param name="bRelaxed"></param> void Decode_PolygoneData(BinaryReaderWriter br, bool bRelaxed) { if (PolygoneTableBlock.Count > 0) { StringBuilder sb = new StringBuilder(); // Tabelle für Typen und Offsets zu den eigentlichen Daten einlesen PolygonTableItems = new List <TableItem>(); br.Seek(PolygoneTableBlock.Offset); for (int i = 0; i < PolygoneTableBlock.Count; i++) { PolygonTableItems.Add(new TableItem(br, PolygoneTableBlock.Recordsize)); } // Draworder-Tabelle einlesen PolygonDraworderTableItems = new List <PolygonDraworderTableItem>(); uint iLevel = 1; br.Seek(PolygoneDraworderTableBlock.Offset); int blocklen = (int)PolygoneDraworderTableBlock.Length; if (blocklen > 0) { while (blocklen >= PolygoneDraworderTableBlock.Recordsize) { PolygonDraworderTableItem dro = new PolygonDraworderTableItem(br, PolygoneDraworderTableBlock.Recordsize, iLevel); blocklen -= PolygoneDraworderTableBlock.Recordsize; PolygonDraworderTableItems.Add(dro); if (dro.Type == 0) // nächster Level { iLevel++; } } } // Tabelle der Polygondaten einlesen polygone.Clear(); for (int i = 0; i < PolygonTableItems.Count; i++) { br.Seek(PolygonTableItems[i].Offset + PolygoneDatablock.Offset); int datalen = i < PolygonTableItems.Count - 1 ? PolygonTableItems[i + 1].Offset - PolygonTableItems[i].Offset : (int)PolygoneTableBlock.Offset - (PolygonTableItems[i].Offset + (int)PolygoneDatablock.Offset); try { long startpos = br.Position; Polygone p = new Polygone(PolygonTableItems[i].Type, PolygonTableItems[i].Subtype); p.Read(br); Debug.WriteLineIf(startpos + datalen != br.Position, string.Format("Diff. {0} der Datenlänge beim Lesen des Objektes 0x{1:x} 0x{2:x} (größer 0 bedeutet: zuviel gelesen)", br.Position - (startpos + datalen), PolygonTableItems[i].Type, PolygonTableItems[i].Subtype)); // zugehörige Draworder suchen for (int j = 0; j < PolygonDraworderTableItems.Count; j++) { if (p.Type == PolygonDraworderTableItems[j].Type) // Haupttyp gefunden { for (int k = 0; k < PolygonDraworderTableItems[j].Subtypes.Count; k++) { if (p.Subtype == PolygonDraworderTableItems[j].Subtypes[k]) // auch Subtyp gefunden { p.Draworder = PolygonDraworderTableItems[j].Level; j = PolygonDraworderTableItems.Count; // 2. Schleifenabbruch break; } } } } polygone.Add(p, 0); } catch (Exception ex) { if (bRelaxed) { sb.AppendFormat("Fehler beim Einlesen von Polygon 0x{0:x2}, 0x{1:x2}: {2}", PolygonTableItems[i].Type, PolygonTableItems[i].Subtype, ex.Message); sb.AppendLine(); } else { throw new Exception(ex.Message); } } } if (bRelaxed) { RelaxedModeErrors += sb.ToString(); } } }