Example #1
0
            public override bool ProcessLine(string line)
            {
                base.ProcessLine();
                Module Mod = new Module(line);

                ModulesL.Add(Mod);
                return(true);
            }
Example #2
0
            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);
            }