コード例 #1
0
        private string LookAheadForNonMissingValue(StreamReaderRandomAccess In, int w)
        {
            if (In.EndOfStream)
            {
                return("?");
            }

            int Pos = In.Position;

            StringCollection Words = new StringCollection();

            while (GetNextLine(In, ref Words) && Words[w] == "?")
            {
                ;
            }

            In.Position = Pos;

            if (Words.Count > w)
            {
                return(Words[w]);
            }
            else
            {
                return("?");
            }
        }
コード例 #2
0
        private void ReadApsimHeaderLines(StreamReaderRandomAccess In,
                                          ref StringCollection ConstantLines,
                                          ref StringCollection HeadingLines)
        {
            string PreviousLine = "";

            string Line = In.ReadLine();

            while (Line != "" || !In.EndOfStream)
            {
                int PosEquals = Line.IndexOf('=');
                if (PosEquals != -1)
                {
                    // constant found.
                    ConstantLines.Add(Line);
                }
                else
                {
                    char[] whitespace           = { ' ', '\t' };
                    int    PosFirstNonBlankChar = StringManip.IndexNotOfAny(Line, whitespace);
                    if (PosFirstNonBlankChar != -1 && Line[PosFirstNonBlankChar] == '(')
                    {
                        HeadingLines.Add(PreviousLine);
                        HeadingLines.Add(Line);
                        break;
                    }
                }
                PreviousLine = Line;
                Line         = In.ReadLine();
            }
        }
コード例 #3
0
        public void TestBomParsing(string inputFile)
        {
            string[] expected = new string[4]
            {
                "x,y",
                "0,1",
                "1,2",
                "2,4"
            };
            long[] endOfLinePositions = new long[expected.Length];

            using (Stream stream = GetResourceStream(inputFile))
            {
                StreamReaderRandomAccess reader = new StreamReaderRandomAccess(stream);
                for (int i = 0; i < expected.Length; i++)
                {
                    string line = reader.ReadLine();
                    Assert.AreEqual(expected[i], line);
                    endOfLinePositions[i] = reader.Position;
                }

                // Seek to the end of each line, and read a line, and ensure
                // that we get the expected result. This should probably be a
                // separate test.
                for (int i = 1; i < expected.Length - 1; i++)
                {
                    reader.Seek(endOfLinePositions[i], SeekOrigin.Begin);
                    string input = reader.ReadLine();
                    Assert.AreEqual(expected[i + 1], input);
                }
            }
        }
コード例 #4
0
 public void TestPositionAfterSeek(string input, int seekPosition, SeekOrigin origin, int expectedPosition)
 {
     using (Stream stream = CreateStream(input))
     {
         StreamReaderRandomAccess reader = new StreamReaderRandomAccess(stream);
         reader.Seek(seekPosition, SeekOrigin.Begin);
         Assert.AreEqual(expectedPosition, reader.Position);
     }
 }
コード例 #5
0
 public void TestPositionAfterRead(string input, int expectedPosition)
 {
     using (Stream stream = CreateStream(input))
     {
         StreamReaderRandomAccess reader = new StreamReaderRandomAccess(stream);
         reader.ReadLine();
         Assert.AreEqual(expectedPosition, reader.Position);
     }
 }
コード例 #6
0
        /// <summary>
        /// Open the file ready for reading.
        /// </summary>
        public void Open(string FileName)
        {
            if (FileName == "")
            {
                return;
            }

            if (!File.Exists(FileName))
            {
                throw new Exception("Cannot find file: " + FileName);
            }

            _FileName = FileName;
            CSV       = Path.GetExtension(FileName).ToLower() == ".csv";

            _Constants.Clear();

            In = new StreamReaderRandomAccess(_FileName);
            ReadApsimHeader(In);
            FirstLinePosition = In.Position;

            // Read in first line.
            StringCollection Words = new StringCollection();

            GetNextLine(In, ref Words);
            ColumnTypes = DetermineColumnTypes(In, Words);

            // Get first date.
            object[] Values = ConvertWordsToObjects(Words, ColumnTypes);
            _FirstDate = GetDateFromValues(Values);

            // Now we need to seek to the end of file and find the last full line in the file.
            In.Seek(0, SeekOrigin.End);
            if (In.Position >= 1000 && In.Position - 1000 > FirstLinePosition)
            {
                In.Seek(-1000, SeekOrigin.End);
                In.ReadLine(); // throw away partial line.
            }
            else
            {
                In.Seek(FirstLinePosition, SeekOrigin.Begin);
            }
            while (GetNextLine(In, ref Words))
            {
            }

            In.Seek(FirstLinePosition, SeekOrigin.Begin);

            // Get the date from the last line.
            if (Words.Count == 0)
            {
                throw new Exception("Cannot find last row of file: " + FileName);
            }
            Values    = ConvertWordsToObjects(Words, ColumnTypes);
            _LastDate = GetDateFromValues(Values);
        }
コード例 #7
0
 public void TestSeek(string input, int position, SeekOrigin origin, string expectedOutput)
 {
     using (Stream stream = CreateStream(input))
     {
         StreamReaderRandomAccess reader = new StreamReaderRandomAccess(stream);
         reader.Seek(position, origin);
         string actualOutput = reader.ReadLine();
         Assert.AreEqual(expectedOutput, actualOutput);
     }
 }
コード例 #8
0
 public void TestReadLine(string input, params string[] expectedOutputs)
 {
     using (Stream stream = CreateStream(input))
     {
         StreamReaderRandomAccess reader = new StreamReaderRandomAccess(stream);
         for (int i = 0; i < expectedOutputs.Length; i++)
         {
             Assert.AreEqual(expectedOutputs[i], reader.ReadLine());
         }
     }
 }
コード例 #9
0
 /// <summary>
 /// Determine and return the data types of the specfied words.
 /// </summary>
 private Type[] DetermineColumnTypes(StreamReaderRandomAccess In, StringCollection Words)
 {
     Type[] Types = new Type[Words.Count];
     for (int w = 0; w != Words.Count; w++)
     {
         if (Words[w] == "?" || Words[w] == "*" || Words[w] == "")
         {
             Types[w] = StringManip.DetermineType(LookAheadForNonMissingValue(In, w), Units[w]);
         }
         else
         {
             Types[w] = StringManip.DetermineType(Words[w], Units[w]);
         }
     }
     return(Types);
 }
コード例 #10
0
        /// <summary>
        /// Return the next line in the file as a collection of words.
        /// </summary>
        private bool GetNextLine(StreamReaderRandomAccess In, ref StringCollection Words)
        {
            if (In.EndOfStream)
            {
                return(false);
            }

            string Line = In.ReadLine();

            if (Line == null || Line.Length == 0)
            {
                return(false);
            }

            if (Line.IndexOf("!") > 0) //used to ignore "!" in a row
            {
                Line = Line.Substring(0, Line.IndexOf("!") - 1);
            }

            if (CSV)
            {
                Words.Clear();
                Line = Line.TrimEnd(',');
                Words.AddRange(Line.Split(",".ToCharArray()));
            }
            else
            {
                Words = StringManip.SplitStringHonouringQuotes(Line, " \t");
            }
            if (Words.Count != Headings.Count)
            {
                throw new Exception("Invalid number of values on line: " + Line + "\r\nin file: " + _FileName);
            }

            // Remove leading / trailing double quote chars.
            for (int i = 0; i < Words.Count; i++)
            {
                Words[i] = Words[i].Trim("\"".ToCharArray());
            }
            return(true);
        }
コード例 #11
0
        /// <summary>
        /// Read in the APSIM header - headings/units and constants.
        /// </summary>
        private void ReadApsimHeader(StreamReaderRandomAccess In)
        {
            StringCollection ConstantLines = new StringCollection();
            StringCollection HeadingLines  = new StringCollection();

            ReadApsimHeaderLines(In, ref ConstantLines, ref HeadingLines);

            bool TitleFound = false;

            foreach (string ConstantLine in ConstantLines)
            {
                string Line    = ConstantLine;
                string Comment = StringManip.SplitOffAfterDelimiter(ref Line, "!");
                Comment.Trim();
                int PosEquals = Line.IndexOf('=');
                if (PosEquals != -1)
                {
                    string Name = Line.Substring(0, PosEquals).Trim();
                    if (Name.ToLower() == "title")
                    {
                        TitleFound = true;
                        Name       = "Title";
                    }
                    string Value = Line.Substring(PosEquals + 1).Trim();
                    string Unit  = StringManip.SplitOffBracketedValue(ref Value, '(', ')');
                    _Constants.Add(new APSIMConstant(Name, Value, Unit, Comment));
                }
            }
            if (HeadingLines.Count >= 2)
            {
                if (CSV)
                {
                    HeadingLines[0] = HeadingLines[0].TrimEnd(',');
                    HeadingLines[1] = HeadingLines[1].TrimEnd(',');
                    Headings        = new StringCollection();
                    Units           = new StringCollection();
                    Headings.AddRange(HeadingLines[0].Split(",".ToCharArray()));
                    Units.AddRange(HeadingLines[1].Split(",".ToCharArray()));
                    for (int i = 0; i < Headings.Count; i++)
                    {
                        Headings[i] = Headings[i].Trim();
                    }
                    for (int i = 0; i < Units.Count; i++)
                    {
                        Units[i] = Units[i].Trim();
                    }
                }
                else
                {
                    Headings = StringManip.SplitStringHonouringQuotes(HeadingLines[0], " \t");
                    Units    = StringManip.SplitStringHonouringQuotes(HeadingLines[1], " \t");
                }
                TitleFound = TitleFound || StringManip.IndexOfCaseInsensitive(Headings, "title") != -1;
                if (Headings.Count != Units.Count)
                {
                    throw new Exception("The number of headings and units doesn't match in file: " + _FileName);
                }
            }
            if (!TitleFound)
            {
                _Constants.Add(new APSIMConstant("Title", Path.GetFileNameWithoutExtension(_FileName), "", ""));
            }
        }