public override bool ProcessLine(string line) { base.ProcessLine(); Module Mod = new Module(line); ModulesL.Add(Mod); return(true); }
public override bool ProcessBinaryFile(byte[] data) { bool GenerateTxtFile = true; // set to true to generate text version of the file FileStream TextFile = null; StartTimer(); if (Binary_size == 0) { return(false); } if (GenerateTxtFile) { if (ExtractFiles) { TextFile = File.Open("Data.txt", FileMode.OpenOrCreate); } } try { using (MemoryStream ms = new MemoryStream(data)) { UInt32 pos = 0; uint size = (uint)ms.Length; BinaryReader br = new BinaryReader(ms, System.Text.Encoding.UTF8); ms.Seek(pos, SeekOrigin.Begin); List <UInt32> Starts = new List <UInt32>(); // look for record starts { Stopwatch timer = new Stopwatch(); timer.Start(); // signature is // byte 02 // int32 length // byte strlen = length - 1 // string strlen ascci chars // bytes 01 00 00 00 while (pos < size) { ms.Seek(pos, SeekOrigin.Begin); byte recordtype = br.ReadByte(); // should be 2 if (recordtype == 2) { // possible start UInt32 nextnamelength = br.ReadUInt32(); if (nextnamelength < 256) { uint l = br.ReadByte(); // string length if (l == nextnamelength - 1) { // everything ok so far // now check bytes in string are ASCII bool found = true; for (int i = 0; i < l; i++) { byte c = br.ReadByte(); if (c < 0x20 || c > 0x7F) { found = false; } } if (br.ReadByte() != 1) { found = false; } if (br.ReadByte() != 0) { found = false; } if (br.ReadByte() != 0) { found = false; } if (br.ReadByte() != 0) { found = false; } if (br.ReadByte() != 0) { found = false; } if (found) { // OutputString($"Found header at {pos:x08}"); Starts.Add(pos); } } } } pos = pos + 1; } } pos = 0; int index = -1; Int16 Component; byte[] r = br.ReadBytes(2); try { UInt32 Longest = 0; UInt32 len; // find the length of the logest pad record foreach (var p in Starts) { index++; if (index < Starts.Count - 1) { len = Starts[index + 1] - Starts[index]; } else { len = size - Starts[index]; } if (len > Longest) { Longest = len; } } index = -1; if (GenerateTxtFile && ExtractFiles) { AddText(TextFile, $"Altium Version {VersionString}\n"); // generate headers for .txt file string Header1 = "Pos "; for (int i = 0; i < Longest; i++) { Header1 += $"{(i / 100),-3:D2}"; } string Header2 = " "; for (int i = 0; i < Longest; i++) { Header2 += $"{(i % 100),-3:D2}"; } string Header3 = "--------------------"; for (int i = 0; i < Longest; i++) { Header3 += $"---"; } if (ExtractFiles) { AddText(TextFile, Header1 + "\n"); AddText(TextFile, Header2 + "\n"); AddText(TextFile, Header3 + "\n"); } } foreach (var p in Starts) { pos = p; //OutputString($"Processing pad record at {pos:x08}"); index++; base.ProcessLine(); ms.Seek(p, SeekOrigin.Begin); byte recordtype = br.ReadByte(); // should be 2 UInt32 next = br.ReadUInt32(); uint l = br.ReadByte(); // string length //pos = (uint)ms.Position; string name; if (l != 0) { name = new string(br.ReadChars((int)l)); } else { name = ""; } pos = (uint)ms.Position; // find out how many bytes to read if (index < Starts.Count - 1) { len = Starts[index + 1] - Starts[index]; } else { len = size - Starts[index]; } // we are now pointing to the pad record // Layers Layer; byte shape; bool plated; double X, Y, XSize, YSize, HoleSize; //, MIDXSize, MIDYSize, BottomXSize, BottomYSize; double Rotation = 0; double RRatio = 0; Int16 Net; Int16 JumperID; byte[] bytes = br.ReadBytes((int)len - 6); // get record after header stuff if (GenerateTxtFile) { if (p == 0) { r = bytes; // get reference bytes } StringBuilder text = new StringBuilder(""); int count = 0; int CompareLimit = Math.Min(r.Length, bytes.Length); foreach (var c in bytes) { if (count < CompareLimit && r[count] != bytes[count]) { text.Append($"|{c:X2}"); } else { text.Append($" {c:X2}"); } count++; } if (ExtractFiles) { AddText(TextFile, $"{pos:X8} " + $"{len - name.Length,4} {name,4} {text.ToString()}\n"); } } PadStruct pad = ByteArrayToStructure <PadStruct>(bytes); ms.Seek(pos + pad.Offset, SeekOrigin.Begin); int LayersSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(PadLayers)); byte[] layerbytes = br.ReadBytes(LayersSize); // get layers data PadLayers PadLayers = ByteArrayToStructure <PadLayers>(layerbytes); Layer = (Layers)pad.Layer; Net = pad.Net; Net++; string n = NetsL[Net].Name; Component = pad.Component; if (Component != -1 && Component != 0) { X = 0; } X = ToMM(pad.X) - originX; Y = ToMM(pad.Y) - originY; XSize = ToMM(pad.XSize); YSize = ToMM(pad.YSize); HoleSize = ToMM(pad.HoleSize); unsafe { shape = pad.TopShape; if (len > 160 && shape == 1) // TODO this can't be right { shape = PadLayers.PadShapes[0]; RRatio = (double)PadLayers.RRatios[0] / 200; } else { RRatio = 0; } } if (shape > 5) { shape = 5; } string[] shapes = { "circle", "circle", "rect", "octagonal", "oval", "roundrect" }; if (shapes[shape] == "circle" && XSize != YSize) { shape = 4; // oval pad } Rotation = pad.Rotation; plated = pad.Plated != 0; JumperID = pad.JumperID; bool InComponent = Component != -1; string type; if (Layer == Layers.Multi_Layer) { if (plated) { type = "thru_hole"; } else { type = "np_thru_hole"; // name = "\"\""; } if (HoleSize < 0.01) { OutputError($"Zero size hole through hole pad at {X} {Y}"); } } else { type = "smd"; } string layer = Brd.GetLayer(Layer); if (!Brd.IsCopperLayer(Layer)) { OutputError($"Pad on non copper layer = {Layer} at {X} {-Y}"); // TODO generate circular polygon instead continue; } if (layer == "Margin") // TODO sort this keepout layer malarky { layer = "Dwgs.User"; } if (type == "smd") { layer += layer == "F.Cu" ? " F.Mask F.Paste" : (layer == "B.Cu") ? " B.Mask B.Paste" : ""; } else { layer += " *.Mask"; } if (XSize < HoleSize | YSize < HoleSize) { XSize = YSize = HoleSize; } Pad Pad = new Pad(name, type, shapes[shape], X, Y, Rotation, XSize, YSize, HoleSize, layer, Net, RRatio) { Component = Component }; if (pad.UsePasteMaskRules == 1) { Pad.PasteMaskExpansion = GetRuleValue(Pad, "PasteMaskExpansion", "PasteMaskExpansion"); } else { Pad.PasteMaskExpansion = ToMM(pad.PasteMaskExpansion); } if (pad.UseSolderMaskRules == 1) { Pad.SolderMaskExpansion = GetRuleValue(Pad, "SolderMaskExpansion", "SolderMaskExpansion"); } else { Pad.SolderMaskExpansion = ToMM(pad.SolderMaskExpansion); } if (!InComponent) { PadsL.Add(Pad); // free pads not allowed (at present) in PcbNew so generate a single pad module Module M = new Module($"FreePad{ModulesL.Count}", X, Y, XSize, YSize, Pad); ModulesL.Add(M); } else { try { ModulesL[Component].Pads.Add(Pad); } catch (Exception Ex) { CheckThreadAbort(Ex, $"At position {pos} in Pads file"); } } } } catch (Exception Ex) { CheckThreadAbort(Ex); } if (GenerateTxtFile && TextFile != null) { TextFile.Close(); } } } catch (Exception Ex) { CheckThreadAbort(Ex); } return(true); }