Esempio n. 1
0
        void ThrowFormatException(string expected, string found)
        {
            _state = LineInfoState.Invalid;
            string msg            = string.Format("Expected: '{0}'. '{1}' found instead.", expected, found);
            LineFormatException e = new LineFormatException(msg);

            e.Position = _content.Size;
        }
Esempio n. 2
0
        void CheckMaxLineLength(int newChunkLength)
        {
            int curLength = (null == _content)?0:_content.Size;

            if (newChunkLength + curLength >= _maxLineLength)
            {
                _state = LineInfoState.Invalid;
                throw new LineLengthExceededException();
            }
        }
Esempio n. 3
0
        internal void PutChunk(byte[] data, DataChunk chunk)
        {
            if (LineInfoState.Invalid == State)
            {
                throw new InvalidOperationException("Invalid line cannot be modified.");
            }

            CheckMaxLineLength(chunk.Length);
            if (false == _seekLF)
            {
                if (DataChunkType.CR == chunk.Type)
                {
                    _seekLF = true;
                }
                else
                {
                    if (DataChunkType.LF == chunk.Type)
                    {
                        if (_requiredCR)
                        {
                            ThrowFormatException("<CR> or <Data>", chunk.ToString());
                        }
                        else
                        {
                            _state = LineInfoState.Completed;
                        }
                    }
                }
                AppendToContent(data, chunk);
            }
            else
            {
                //Missing LF, let's handle it...

                if (DataChunkType.LF != chunk.Type)
                {
                    ThrowFormatException("<LF>", chunk.ToString());
                }

                AppendToContent(data, chunk);
                _state = LineInfoState.Completed;
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Parse the PO formatted file into a dictionary of entries.
        /// </summary>
        Dictionary <string /*MsgInfo.UniqueID*/, MsgInfo> BuildMsgInfoDictionary(IEnumerable <LineInfo> lines)
        {
            Dictionary <string /*MsgInfo.UniqueID*/, MsgInfo> result = new Dictionary <string, MsgInfo>();

            // Add a whitespace entry to the end of the list, so our state machine can rely on
            // whitespace as an end-of-entry marker.
            IEnumerable <LineInfo> linesPlusWhitespace = lines.Concat(new LineInfo[] { new LineInfo(LineType.Whitespace, -1, "") });

            LineInfoState state    = LineInfoState.FinishedEntry;
            MsgInfo       newEntry = new MsgInfo();

            foreach (LineInfo line in linesPlusWhitespace)
            {
                // The state machine is small enough to do with a switch.
                //
                // The .PO formats is roughly like this:
                //
                //    Whitespace, followed by
                //    [Optional]# Comments, followed by
                //    [Optional]msgctxt, optionally followed by multi-line context string, followed by
                //    msgid, optionally followed by multi-line id string, followed by
                //    [Optional]msgid_plural - I'm not supporting plural forms, followed by
                //    msgstr, optionally followed by multi-line msg string, followed by
                //    [Optional]msgstr[x] - I'm not supporting plural forms, followed by
                //    EOF or Whitespace
                switch (state)
                {
                case LineInfoState.FinishedEntry:
                    // We're looking for the start of the next entry

                    if (line.Type == LineType.Msgid)
                    {
                        state = LineInfoState.AddingMsgid;
                        newEntry.Msgid_Value = ExtractString(line);
                    }
                    else if (line.Type == LineType.Msgctxt)
                    {
                        // msgctxt is optional, but if present it appears before the msgid
                        state = LineInfoState.AddingMsgctxt;
                        newEntry.Msgctxt_Value = ExtractString(line);
                    }
                    else if (line.Type == LineType.Msgstr || line.Type == LineType.StrContinuation)
                    {
                        // An entry can't start with a msgstr or string-continuation
                        ErrorEncountered(line, "Unexpected string or msgstr");
                    }
                    break;

                case LineInfoState.AddingMsgctxt:

                    if (line.Type == LineType.StrContinuation)
                    {
                        newEntry.Msgctxt_Value += ExtractString(line);
                    }
                    else if (line.Type == LineType.Msgid)
                    {
                        state = LineInfoState.AddingMsgid;
                        newEntry.Msgid_Value = ExtractString(line);
                    }
                    else
                    {
                        // msgctxt is optional, but if present it appears before the msgid
                        ErrorEncountered(line, "msgid not found after msgctxt");
                    }
                    break;

                case LineInfoState.AddingMsgid:

                    if (line.Type == LineType.StrContinuation)
                    {
                        newEntry.Msgid_Value += ExtractString(line);
                    }
                    else if (line.Type == LineType.Msgstr)
                    {
                        state = LineInfoState.AddingMsgstr;
                        newEntry.Msgstr_Value = ExtractString(line);
                        newEntry.Msgstr_Info  = line;
                    }
                    else if (line.Type == LineType.Msgid)
                    {
                        // We can't have two msgids in a row!
                        if (line.Line.StartsWith("msgid_plural", true, CultureInfo.InvariantCulture))
                        {
                            ErrorEncountered(line, "Multiple msgids encountered, PO plural-forms are not currently supported :(");
                        }
                        else
                        {
                            ErrorEncountered(line, "Unexpected msgid");
                        }
                    }
                    break;

                case LineInfoState.AddingMsgstr:

                    if (line.Type == LineType.StrContinuation)
                    {
                        newEntry.Msgstr_Value += ExtractString(line);
                        newEntry.Msgstr_LineCount++;
                    }
                    else if (line.Type == LineType.Whitespace)
                    {
                        // We've found the end of the entry
                        state = LineInfoState.FinishedEntry;
                        if (newEntry.IsValid())
                        {
                            string uniqueID = newEntry.UniqueID(_options.CaseSensitiveIDs);
                            if (result.ContainsKey(uniqueID))
                            {
                                // Duplicate msgids encountered - Abort if the msgstr contains a reference, as duplicate msgids are now supported yet and will result in the reference not expanding
                                TestDuplicateEntry(newEntry);
                            }
                            else
                            {
                                result.Add(newEntry.UniqueID(_options.CaseSensitiveIDs), newEntry);
                            }
                        }
                        else
                        {
                            ErrorEncountered(line, "[End found of] invalid entry");
                        }
                        newEntry = new MsgInfo();
                    }
                    else if (line.Type == LineType.Msgstr)
                    {
                        // Multiple msgstrs encountered, PO plural-forms are not currently supported :(
                        TestPluralForm(line);
                    }
                    else
                    {
                        ErrorEncountered(line, "Unexpected line encountered at end of entry \"" + newEntry.Msgid_Value + "\" (was expecting whitespace)");
                    }
                    break;
                }
            }

            return(result);
        }