Пример #1
0
        public LfdLine(LfdLine parent, String comment, UInt32 actualLineNumber)
        {
            this.parent  = parent;
            this.id      = comment;
            this.fields  = null;
            this.comment = true;

            this.actualLineNumber = actualLineNumber;
        }
Пример #2
0
 public override void Handle(LfdLine lfdLine)
 {
     if (lfdLine.fields == null)
     {
         throw new FormatException(String.Format("Option '{0}' requires at least one field but got none", name));
     }
     for (int i = 0; i < lfdLine.fields.Length; i++)
     {
         strings.Add(lfdLine.fields[i]);
     }
 }
Пример #3
0
 public override void Handle(LfdLine lfdLine)
 {
     if (value)
     {
         throw new FormatException(String.Format("The '{0}' config option appeared more than once", name));
     }
     if (lfdLine.fields != null)
     {
         throw new FormatException(String.Format(
                                       "The '{0}' config option may not have any arguments", name));
     }
     value = true;
 }
Пример #4
0
        public LfdLine(LfdLine parent, String id, String[] fields, UInt32 actualLineNumber)
        {
            if (id == null)
            {
                throw new ArgumentNullException("id");
            }

            this.parent  = parent;
            this.id      = id;
            this.fields  = fields;
            this.comment = false;

            this.actualLineNumber = actualLineNumber;
        }
Пример #5
0
 public override void Handle(LfdLine lfdLine)
 {
     if (strings != null)
     {
         throw new FormatException(String.Format("The '{0}' config option appeared more than once", name));
     }
     if (lfdLine.fields == null)
     {
         strings = new String[0];
     }
     else
     {
         strings = lfdLine.fields;
     }
 }
Пример #6
0
 public override void Handle(LfdLine lfdLine)
 {
     if (value != null)
     {
         throw new FormatException(String.Format("The '{0}' config option appeared more than once", name));
     }
     if (lfdLine.fields == null)
     {
         throw new FormatException(
                   String.Format("The '{0}' config option requires a single argument", name));
     }
     if (lfdLine.fields.Length > 1)
     {
         throw new FormatException(
                   String.Format("The '{0}' config option can have at most 1 argument but it has {1}", name, lfdLine.fields.Length));
     }
     this.value = lfdLine.fields[0];
 }
Пример #7
0
        public LfdLine ReadLine()
        {
            while (true)
            {
                String line = readLineDelegate();
                if (line == null)
                {
                    return(null);
                }
                lineNumber++;

                //
                // Identify line
                //
                for (int offset = 0; true; offset++)
                {
                    // Empty Line
                    if (offset >= line.Length)
                    {
                        break;
                    }
                    if (Char.IsWhiteSpace(line[offset]))
                    {
                        continue;
                    }

                    //
                    // If the first character is a '#' then the line is a comment
                    if (line[offset] == '#')
                    {
                        return(new LfdLine((context.Count > 0) ? context.Peek() : null, line, lineNumber));
                    }

                    //
                    // If the first character is '}' then the line must be a BLOCK_END line
                    //
                    if (line[offset] == '}')
                    {
                        // Verify whitespace till end of line
                        while (true)
                        {
                            offset++;
                            if (offset >= line.Length)
                            {
                                break;
                            }
                            if (!Char.IsWhiteSpace(line[offset]))
                            {
                                throw FormatError(line, "Line starting with '}' must be followed by only whitespace");
                            }
                        }

                        if (context.Count <= 0)
                        {
                            throw FormatError(line, "The block end '}' had no matching block begin");
                        }
                        context.Pop();
                        break;
                    }

                    //
                    // '{' and '"' are invalid characters to start a line
                    //
                    if (line[offset] == '{' || line[offset] == '"')
                    {
                        throw FormatError(line, "A line cannot start with '{0}'", line[offset]);
                    }
                    if (line[offset] == '\\')
                    {
                        // verify whitespace till end
                        while (true)
                        {
                            offset++;
                            if (offset >= line.Length)
                            {
                                line = readLineDelegate();
                                if (line == null)
                                {
                                    return(null);
                                }
                                offset = 0;
                                lineNumber++;
                                break;
                            }
                            if (!Char.IsWhiteSpace(line[offset]))
                            {
                                throw FormatError(line, "The '\\' character cannot have non whitespace after it");
                            }
                        }
                        continue;
                    }

                    //
                    // Get the line id
                    //
                    Int32 saveOffset = offset;
                    while (true)
                    {
                        offset++;
                        if (offset >= line.Length)
                        {
                            return(new LfdLine((context.Count > 0) ? context.Peek() : null,
                                               line.Substring(saveOffset), null, lineNumber));
                        }
                        if (line[offset] == '{')
                        {
                            String lineIdSpecialCase = line.Substring(saveOffset, offset - saveOffset);
                            //verify whitespace till the end
                            while (true)
                            {
                                offset++;
                                if (offset >= line.Length)
                                {
                                    break;
                                }
                                if (!Char.IsWhiteSpace(line[offset]))
                                {
                                    throw FormatError(line, "The '{' character just after the line Id can only be followed by whitespace");
                                }
                            }

                            LfdLine newLine = new LfdLine((context.Count > 0) ? context.Peek() : null,
                                                          lineIdSpecialCase, null, lineNumber);
                            context.Push(newLine);
                            return(newLine);
                        }
                        if (Char.IsWhiteSpace(line[offset]))
                        {
                            break;
                        }
                    }

                    String lineId = line.Substring(saveOffset, offset - saveOffset);

                    // Skip whitespace until you get to the first field (or end of line)
                    while (true)
                    {
                        offset++;
                        if (offset >= line.Length)
                        {
                            return(new LfdLine((context.Count > 0) ? context.Peek() : null,
                                               lineId, null, lineNumber));
                        }
                        if (!Char.IsWhiteSpace(line[offset]))
                        {
                            break;
                        }
                    }

                    //
                    // Get all fields in the line
                    //
                    List <String> fields = new List <String>();
                    while (true)
                    {
                        Int32 fieldStart = offset;

                        //
                        // A quoted field
                        //
                        if (line[offset] == '"')
                        {
                            fieldStart++;

                            Boolean continueLoop = false;
                            while (true)
                            {
                                offset++;
                                if (offset >= line.Length)
                                {
                                    throw FormatError(line, "Found a quoted field without an ending quote");
                                }
                                if (line[offset] == '"')
                                {
                                    if (line[offset - 1] != '\\')
                                    {
                                        fields.Add(line.Substring(fieldStart, offset - fieldStart));
                                        offset++;
                                        break;
                                    }
                                    else
                                    {
                                        continueLoop = true;
                                        break;
                                    }
                                }
                            }

                            //
                            // If there is an escaped quote in the string, then the rest of the characters
                            // must be added to a new string to remove any extra backslashes
                            //
                            if (continueLoop)
                            {
                                StringBuilder builder = new StringBuilder(line.Substring(fieldStart, offset - 1 - fieldStart));
                                builder.Append('"');
                                while (true)
                                {
                                    offset++;
                                    if (offset >= line.Length)
                                    {
                                        throw FormatError(line, "Found a quoted field without an ending quote");
                                    }

                                    if (line[offset] == '"')
                                    {
                                        fields.Add(builder.ToString());
                                        offset++;
                                        break;
                                    }
                                    if (line[offset] == '\\')
                                    {
                                        offset++;
                                        if (offset >= line.Length)
                                        {
                                            throw FormatError(line, "Line ended with '\\' but was in the middle of a quote");
                                        }
                                        if (line[offset] == '\\')
                                        {
                                            builder.Append('\\');
                                        }
                                        else if (line[offset] == '"')
                                        {
                                            builder.Append('"');
                                        }
                                        else
                                        {
                                            throw FormatError(line, "Unrecognized escape character '{0}', expected '\"' or '\\'", line[offset]);
                                        }
                                    }
                                    else
                                    {
                                        builder.Append(line[offset]);
                                    }
                                }
                            }
                        }
                        //
                        // An Open Brace field which must be the last field
                        //
                        else if (line[offset] == '{')
                        {
                            //verify whitespace till the end
                            while (true)
                            {
                                offset++;
                                if (offset >= line.Length)
                                {
                                    break;
                                }
                                if (!Char.IsWhiteSpace(line[offset]))
                                {
                                    throw FormatError(line, "A Field starting with the '{' character can only be followed by whitespace unless escaped with '\\{'");
                                }
                            }

                            LfdLine newLine = new LfdLine((context.Count > 0) ? context.Peek() : null,
                                                          lineId, fields.ToArray(), lineNumber);
                            context.Push(newLine);
                            return(newLine);
                        }
                        //
                        // An escape character '\' used for starting fields with the '{' character
                        // and continuing the fields on the next line
                        //
                        else if (line[offset] == '\\')
                        {
                            offset++;
                            if (offset >= line.Length)
                            {
                                line = readLineDelegate();
                                if (line == null)
                                {
                                    return(null);
                                }
                                offset = 0;
                                lineNumber++;
                            }
                            else
                            {
                                if (line[offset] == '{')
                                {
                                    fieldStart++;
                                    while (true)
                                    {
                                        offset++;
                                        if (offset >= line.Length)
                                        {
                                            fields.Add(line.Substring(fieldStart));
                                            return(new LfdLine((context.Count > 0) ? context.Peek() : null,
                                                               lineId, fields.ToArray(), lineNumber));
                                        }
                                        if (Char.IsWhiteSpace(line[offset]))
                                        {
                                            fields.Add(line.Substring(fieldStart, offset - fieldStart));
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    while (true)
                                    {
                                        offset++;
                                        if (offset >= line.Length)
                                        {
                                            line = readLineDelegate();
                                            if (line == null)
                                            {
                                                return(null);
                                            }
                                            offset = 0;
                                            lineNumber++;
                                            break;
                                        }
                                        if (!Char.IsWhiteSpace(line[offset]))
                                        {
                                            throw FormatError(line, "The '\\' character cannot have non whitespace after it");
                                        }
                                    }
                                }
                            }
                        }
                        //
                        // A normal field that ends when whitespace is encountered
                        //
                        else
                        {
                            while (true)
                            {
                                offset++;
                                if (offset >= line.Length)
                                {
                                    fields.Add(line.Substring(fieldStart));
                                    return(new LfdLine((context.Count > 0) ? context.Peek() : null,
                                                       lineId, fields.ToArray(), lineNumber));
                                }
                                if (Char.IsWhiteSpace(line[offset]))
                                {
                                    fields.Add(line.Substring(fieldStart, offset - fieldStart));
                                    break;
                                }
                            }
                        }

                        //
                        // Skip whitespace, or return a line if the end of line is found
                        //
                        while (true)
                        {
                            if (offset >= line.Length)
                            {
                                return(new LfdLine((context.Count > 0) ? context.Peek() : null,
                                                   lineId, fields.ToArray(), lineNumber));
                            }
                            if (!Char.IsWhiteSpace(line[offset]))
                            {
                                break;
                            }
                            offset++;
                        }
                    }
                }
            }
        }
Пример #8
0
        void Test(String lfdText, params ExpectedLine[] expectedLines)
        {
            //
            // Test using LfdReader
            //
            using (var reader = new LfdTextReader(new StringReader(lfdText)))
            {
                for (int i = 0; i < expectedLines.Length; i++)
                {
                    var line = reader.ReadLine();
                    Assert.AreEqual(expectedLines[i].id, line.id);
                    if (expectedLines[i].fields == null || expectedLines[i].fields.Length == 0)
                    {
                        Assert.IsNull(line.fields);
                    }
                    else
                    {
                        Assert.AreEqual(expectedLines[i].fields.Length, line.fields.Length);
                        for (int fieldIndex = 0; fieldIndex < line.fields.Length; fieldIndex++)
                        {
                            Assert.AreEqual(expectedLines[i].fields[fieldIndex], line.fields[fieldIndex]);
                        }
                    }
                }
                Assert.IsNull(reader.ReadLine());
            }


            Byte[] linesAsBytes = Encoding.UTF8.GetBytes(lfdText);

            //
            // Test using LineParser
            //
            for (uint initialBufferSize = 1; initialBufferSize <= lfdText.Length; initialBufferSize++)
            {
                OffsetLineParser lineParser = new OffsetLineParser(new ByteArrayReference(initialBufferSize));
                lineParser.Add(linesAsBytes, linesAsBytes.Length);

                List <String> fields = new List <String>();
                Byte[]        lineBuffer;
                Int32         lineOffset = 0, lineLength = 0;

                for (int i = 0; i < expectedLines.Length; i++)
                {
                    do
                    {
                        lineBuffer = lineParser.GetLine(ref lineOffset, ref lineLength);
                        Assert.IsNotNull(lineBuffer);
                        fields.Clear();
                        LfdLine.ParseLine(fields, lineBuffer, lineOffset, lineOffset + lineLength);
                    } while (fields.Count == 0);

                    Assert.AreEqual(expectedLines[i].id, fields[0]);
                    if (expectedLines[i].fields == null || expectedLines[i].fields.Length == 0)
                    {
                        Assert.AreEqual(1, fields.Count);
                    }
                    else
                    {
                        Assert.AreEqual(expectedLines[i].fields.Length, fields.Count - 1);
                        for (int fieldIndex = 0; fieldIndex < fields.Count - 1; fieldIndex++)
                        {
                            Assert.AreEqual(expectedLines[i].fields[fieldIndex], fields[fieldIndex + 1]);
                        }
                    }
                }
                Assert.IsNull(lineParser.GetLine(ref lineOffset, ref lineLength));
            }
        }
Пример #9
0
        public void GenericTestMethod()
        {
            StringBuilder builder = new StringBuilder();

            builder.AppendLine("");
            builder.AppendLine("LineWithNoValues \t  ");
            builder.AppendLine("Line1Fields \t field1  \t\t");
            builder.AppendLine("Line2Fields \t field1  \t\tfield2  ");
            builder.AppendLine("LineFieldWithWhitespace \t\t  \t \"this ; is a long field\"  \t");
            builder.AppendLine("LineWithEmptyFields \t\t\"\"  \"\"  \t");

            using (var reader = new LfdTextReader(new StringReader(builder.ToString())))
            {
                LfdLine line = reader.ReadLine();

                Assert.AreEqual("LineWithNoValues", line.id);

                line = reader.ReadLine();
                Assert.AreEqual("Line1Fields", line.id);
                Assert.AreEqual("field1", line.fields[0]);

                line = reader.ReadLine();
                Assert.AreEqual("Line2Fields", line.id);
                Assert.AreEqual("field1", line.fields[0]);
                Assert.AreEqual("field2", line.fields[1]);

                line = reader.ReadLine();
                Assert.AreEqual("LineFieldWithWhitespace", line.id);
                Assert.AreEqual("this ; is a long field", line.fields[0]);

                line = reader.ReadLine();
                Assert.AreEqual("LineWithEmptyFields", line.id);
                Assert.AreEqual(String.Empty, line.fields[0]);
                Assert.AreEqual("", line.fields[1]);

                Assert.IsNull(reader.ReadLine());
            }
            //
            // Test using line parser
            //
            OffsetLineParser lineParser = new OffsetLineParser(new ByteArrayReference(1));

            Byte[] linesAsBytes = Encoding.UTF8.GetBytes(builder.ToString());
            lineParser.Add(linesAsBytes, linesAsBytes.Length);

            List <String> fields = new List <String>();

            Byte[] lineBuffer;
            Int32  lineOffset = 0, lineLength = 0;

            lineBuffer = lineParser.GetLine(ref lineOffset, ref lineLength);
            LfdLine.ParseLine(fields, lineBuffer, lineOffset, lineOffset + lineLength);
            Assert.AreEqual(0, fields.Count);
            fields.Clear();

            lineBuffer = lineParser.GetLine(ref lineOffset, ref lineLength);
            LfdLine.ParseLine(fields, lineBuffer, lineOffset, lineOffset + lineLength);
            Assert.AreEqual("LineWithNoValues", fields[0]);
            fields.Clear();

            lineBuffer = lineParser.GetLine(ref lineOffset, ref lineLength);
            LfdLine.ParseLine(fields, lineBuffer, lineOffset, lineOffset + lineLength);
            Assert.AreEqual("Line1Fields", fields[0]);
            Assert.AreEqual("field1", fields[1]);
            fields.Clear();

            lineBuffer = lineParser.GetLine(ref lineOffset, ref lineLength);
            LfdLine.ParseLine(fields, lineBuffer, lineOffset, lineOffset + lineLength);
            Assert.AreEqual("Line2Fields", fields[0]);
            Assert.AreEqual("field1", fields[1]);
            Assert.AreEqual("field2", fields[2]);
            fields.Clear();

            lineBuffer = lineParser.GetLine(ref lineOffset, ref lineLength);
            LfdLine.ParseLine(fields, lineBuffer, lineOffset, lineOffset + lineLength);
            Assert.AreEqual("LineFieldWithWhitespace", fields[0]);
            Assert.AreEqual("this ; is a long field", fields[1]);
            fields.Clear();

            lineBuffer = lineParser.GetLine(ref lineOffset, ref lineLength);
            LfdLine.ParseLine(fields, lineBuffer, lineOffset, lineOffset + lineLength);
            Assert.AreEqual("LineWithEmptyFields", fields[0]);
            fields.Clear();
        }
Пример #10
0
 public abstract void Handle(LfdLine lfdLine);