Example #1
0
        public static List <ImageSelfDefiningField> GetAllSDFs(byte[] sdfData)
        {
            List <ImageSelfDefiningField> sdfList = new List <ImageSelfDefiningField>();

            // Container info
            byte[] beginCodes = new byte[4] {
                0x70, 0x8C, 0x8E, 0x91
            };
            byte[] endCodes = new byte[4] {
                0x71, 0x8D, 0x8F, 0x93
            };
            List <Container> activeContainers = new List <Container>();

            for (int i = 0; i < sdfData.Length;)
            {
                // Check the first byte of the code. If it's 0xFE, this is an extended format SDF and will have two byte codes and lengths instead of one
                bool isExtended = sdfData[i] == 0xFE;

                // Get the ID, length, introducer, and data bytes
                byte[] idArray = isExtended ? new byte[2] {
                    0xFE, sdfData[i + 1]
                } : new byte[1] {
                    sdfData[i]
                };
                byte id     = idArray.Last();
                int  length = isExtended ? GetNumericValue <ushort>(new[] { sdfData[i + 2], sdfData[i + 3] })
                    : GetNumericValue <byte>(new[] { sdfData[i + 1] });
                byte[] data = new byte[length];
                Array.ConstrainedCopy(sdfData, i + (isExtended ? 4 : 2), data, 0, length);

                // Create an instance of the lookup type
                Type iSDFType = typeof(ImageSelfDefiningFields.UNKNOWN);
                if (Lookups.ImageSelfDefiningFields.ContainsKey(id))
                {
                    iSDFType = Lookups.ImageSelfDefiningFields[id];
                }
                ImageSelfDefiningField sdf = (ImageSelfDefiningField)Activator.CreateInstance(iSDFType, idArray, data);

                // If this is a begin tag, add a new container to our active list
                if (beginCodes.Contains(id))
                {
                    activeContainers.Add(new Container());
                }

                // Sync active containers
                sdf.Containers = new List <Container>(activeContainers);

                // Add this field to all containers
                foreach (Container c in activeContainers)
                {
                    c.Structures.Add(sdf);
                }

                // If this is the last structure in a container, close it up and parse any specific container data
                if (endCodes.Contains(id))
                {
                    Container c = activeContainers.Last();
                    activeContainers.Remove(c);
                }

                sdfList.Add(sdf);

                // Go to next block
                i += (isExtended ? 4 : 2) + length;
            }

            return(sdfList);
        }
Example #2
0
        // This method can be overridden if it is complicated to parse
        protected override string GetOffsetDescriptions()
        {
            StringBuilder sb = new StringBuilder();

            if (Offsets.Count == 0)
            {
                sb.AppendLine("Not yet implemented...");
                sb.AppendLine();
                sb.AppendLine("Raw data:");
                sb.AppendLine(DataHex);
                sb.AppendLine();
                sb.AppendLine("Raw data (EBCDIC):");
                sb.Append(DataEBCDIC);
                return(sb.ToString());
            }

            // If this is a repeating group identifier, loop through each subsection of offsets
            int skip          = IsRepeatingGroup ? RepeatingGroupStart : Offsets[0].StartingIndex;
            int sectionLength = RepeatingGroupLength;

            do
            {
                for (int i = 0; i < Offsets.Count; i++)
                {
                    // If we are past the data length, break out of the loop
                    if (skip > Data.Length)
                    {
                        break;
                    }

                    // Get the length of the current repeating group if it is retrieved in each section (if there is not a fixed length)
                    if (IsRepeatingGroup && RepeatingGroupLength == 0 && i == 0)
                    {
                        int rgOffsetLength = Offsets[i + 1].StartingIndex;
                        sectionLength = GetNumericValueFromData <int>(skip, rgOffsetLength);
                    }

                    // Calculate section of bytes to take from data
                    int    nextOffsetIdx = i == Offsets.Count - 1 ? 0 : Offsets[i + 1].StartingIndex;
                    int    take          = (nextOffsetIdx == 0 ? sectionLength : nextOffsetIdx) - Offsets[i].StartingIndex;
                    byte[] sectionedData = GetSectionedData(skip, take);

                    // Build description by data type
                    switch (Offsets[i].DataType)
                    {
                    // For special sub sectioned data types, call the static parser
                    case Lookups.DataTypes.IMAGESDFS:
                        if (i > 0)
                        {
                            sb.AppendLine();
                        }
                        sb.AppendLine(ImageSelfDefiningField.GetAllDescriptions(sectionedData));
                        break;

                    // For Triplets, parse them all at once
                    case Lookups.DataTypes.TRIPS:
                        sb.AppendLine();
                        foreach (Triplet t in Triplets)
                        {
                            sb.AppendLine(t.GetFullDescription());
                        }
                        break;

                    // Everything else
                    default:
                        sb.Append(GetSingleOffsetDescription(Offsets[i], sectionedData));
                        break;
                    }

                    // Increment the skip value so we take the correct offset of data next iteration
                    skip += take;
                }

                sb.AppendLine();
            } while (skip < Data.Length);

            return(sb.ToString().Trim());
        }