Example #1
0
        public List<Interchange> ParseMultiple(Stream stream, Encoding encoding)
        {
            var envelopes = new List<Interchange>();

            using (X12StreamReader reader = new X12StreamReader(stream, encoding))
            {
                Interchange envelop = new Interchange(_specFinder, reader.CurrentIsaSegment);
                envelopes.Add(envelop);
                Container currentContainer = envelop;
                FunctionGroup fg = null;
                Transaction tr = null;
                Dictionary<string, HierarchicalLoop> hloops = new Dictionary<string, HierarchicalLoop>();

                string segmentString = reader.ReadNextSegment();
                string segmentId = reader.ReadSegmentId(segmentString);
                int segmentIndex = 1;
                while (segmentString.Length > 0)
                {
                    switch (segmentId)
                    {
                        case "ISA":
                            envelop = new Interchange(_specFinder, segmentString + reader.Delimiters.SegmentTerminator);
                            envelopes.Add(envelop);
                            currentContainer = envelop;
                            fg = null;
                            tr = null;
                            hloops = new Dictionary<string, HierarchicalLoop>();
                            break;
                        case "IEA":
                            if (envelop == null)
                                throw new InvalidOperationException(string.Format("Segment {0} does not have a matching ISA segment preceding it.", segmentString));
                            envelop.SetTerminatingTrailerSegment(segmentString);
                            break;
                        case "GS":
                            if (envelop == null)
                                throw new InvalidOperationException(String.Format("Segment '{0}' cannot occur before and ISA segment.", segmentString));

                            currentContainer = fg = envelop.AddFunctionGroup(segmentString); ;
                            break;
                        case "GE":
                            if (fg == null)
                                throw new InvalidOperationException(String.Format("Segment '{0}' does not have a matching GS segment precending it.", segmentString));
                            fg.SetTerminatingTrailerSegment(segmentString);
                            fg = null;
                            break;
                        case "ST":
                            if (fg == null)
                                throw new InvalidOperationException(string.Format("segment '{0}' cannot occur without a preceding GS segment.", segmentString));
                            segmentIndex = 1;
                            currentContainer = tr = fg.AddTransaction(segmentString);
                            hloops = new Dictionary<string, HierarchicalLoop>();
                            break;
                        case "SE":
                            if (tr == null)
                                throw new InvalidOperationException(string.Format("Segment '{0}' does not have a matching ST segment preceding it.", segmentString));

                            tr.SetTerminatingTrailerSegment(segmentString);
                            tr = null;
                            break;
                        case "HL":
                            Segment hlSegment = new Segment(null, reader.Delimiters, segmentString);
                            string id = hlSegment.GetElement(1);
                            string parentId = hlSegment.GetElement(2);

                            if (parentId == "")
                                currentContainer = tr.AddHLoop(segmentString);
                            else
                            {
                                if (hloops.ContainsKey(parentId))
                                    currentContainer = hloops[parentId].AddHLoop(segmentString);
                                else
                                    throw new InvalidOperationException(String.Format("Hierarchical Loop {0} expects Parent ID {1} which did not occur preceding it.", id, parentId));
                            }
                            if (hloops.ContainsKey(id))
                                throw new InvalidOperationException(String.Format("Hierarchical Loop {0} cannot be added to transaction {1} because the ID {2} already exists.", segmentString, tr.ControlNumber, id));
                            hloops.Add(id, (HierarchicalLoop)currentContainer);
                            break;
                        case "TA1": // Technical acknowledgement
                            if (envelop == null)
                                throw new InvalidOperationException(string.Format("Segment {0} does not have a matching ISA segment preceding it.", segmentString));
                            envelop.AddSegment(segmentString);
                            break;
                        default:
                            while (currentContainer != null)
                            {
                                if (currentContainer.AddSegment(segmentString) != null)
                                    break;
                                else
                                {
                                    if (currentContainer is LoopContainer)
                                    {
                                        LoopContainer loopContainer = (LoopContainer)currentContainer;

                                        Loop newLoop = loopContainer.AddLoop(segmentString);
                                        if (newLoop != null)
                                        {
                                            currentContainer = newLoop;
                                            break;
                                        }
                                        else
                                        {
                                            if (currentContainer is Transaction)
                                            {
                                                var tran = (Transaction)currentContainer;

                                                throw new TransactionValidationException(
                                                    "Segment '{3}' in segment position {4} within transaction '{1}' cannot be identified within the supplied specification for transaction set {0}.", tran.IdentifierCode, tran.ControlNumber, "", segmentString, segmentIndex);
                                            }
                                            else
                                            {
                                                currentContainer = currentContainer.Parent;
                                                continue;
                                            }
                                        }
                                    }
                                    else
                                        break;
                                }
                            }
                            break;

                    }
                    segmentString = reader.ReadNextSegment();
                    segmentId = reader.ReadSegmentId(segmentString);
                    segmentIndex++;
                }
                return envelopes;
            }
        }