コード例 #1
0
        /// <summary>
        /// Fills the specified table by reading data from a file or stream.
        /// </summary>
        public void Fill(DataTable dataTable)
        {
            if (dataTable == null)
            {
                throw new ArgumentNullException(nameof(dataTable));
            }

            Stream       stream;
            BinaryReader reader = null;

            try
            {
                stream = Stream ?? new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                reader = new BinaryReader(stream, Encoding.UTF8, Stream != null);

                // prepare the data table
                dataTable.Rows.Clear();
                dataTable.BeginLoadData();
                dataTable.DefaultView.Sort = "";

                // create table columns
                if (dataTable.Columns.Count == 0)
                {
                    dataTable.Columns.Add("DateTime", typeof(DateTime));
                    dataTable.Columns.Add("CnlNum", typeof(int));
                    dataTable.Columns.Add("Val", typeof(double));
                    dataTable.Columns.Add("Stat", typeof(int));
                }

                // read header
                byte[] buffer = new byte[HeaderSize];
                if (!ReadHeader(reader, buffer))
                {
                    return;
                }

                // read slices
                int[] cnlNums = null;

                while (true)
                {
                    if (reader.ReadUInt16() != BlockMarker)
                    {
                        throw new ScadaException("Slice marker not found.");
                    }

                    DateTime timestamp = ScadaUtils.TicksToTime(reader.ReadInt64());
                    int      cnlCnt    = reader.ReadInt32();

                    if (cnlCnt != 0)
                    {
                        int cnlDataSize = cnlCnt * 10;
                        int cnlNumsSize = cnlCnt * 4;
                        ResizeBuffer(ref buffer, cnlDataSize);

                        // read channel numbers
                        if (cnlCnt > 0)
                        {
                            ReadData(reader, buffer, 0, cnlNumsSize + 4, true);
                            cnlNums = new int[cnlCnt];
                            Buffer.BlockCopy(buffer, 0, cnlNums, 0, cnlNumsSize);

                            if (ScadaUtils.CRC32(buffer, 0, cnlNumsSize) != BitConverter.ToUInt32(buffer, cnlNumsSize))
                            {
                                throw new ScadaException("CRC error.");
                            }
                        }
                        else if (cnlCnt < 0) // channel numbers are the same
                        {
                            cnlCnt = ~cnlCnt;

                            if (cnlNums == null)
                            {
                                throw new ScadaException("Channel numbers are undefined.");
                            }

                            if (cnlNums.Length != cnlCnt)
                            {
                                throw new ScadaException("Invalid channel count.");
                            }
                        }

                        // read channel data
                        ReadData(reader, buffer, 0, cnlDataSize, true);

                        for (int i = 0, index = 0; i < cnlCnt; i++)
                        {
                            DataRow row = dataTable.NewRow();
                            row["DateTime"] = timestamp;
                            row["CnlNum"]   = cnlNums[i];
                            row["Val"]      = GetDouble(buffer, ref index);
                            row["Stat"]     = GetUInt16(buffer, ref index);
                            dataTable.Rows.Add(row);
                        }
                    }
                }
            }
            catch (EndOfStreamException)
            {
                // normal file ending case
            }
            finally
            {
                reader?.Close();
                dataTable.EndLoadData();
                dataTable.AcceptChanges();

                if (dataTable.Columns.Count > 0)
                {
                    dataTable.DefaultView.Sort = "DateTime, CnlNum";
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Reads a single slice from a file or stream.
        /// </summary>
        public Slice ReadSingleSlice()
        {
            Stream       stream;
            BinaryReader reader = null;

            try
            {
                stream = Stream ?? new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                reader = new BinaryReader(stream, Encoding.UTF8, Stream != null);

                // read header
                byte[] buffer = new byte[HeaderSize];
                if (!ReadHeader(reader, buffer))
                {
                    return(null);
                }

                // read the first slice
                if (reader.ReadUInt16() != BlockMarker)
                {
                    throw new ScadaException("Slice marker not found.");
                }

                DateTime timestamp = ScadaUtils.TicksToTime(reader.ReadInt64());
                int      cnlCnt    = reader.ReadInt32();

                if (cnlCnt > 0)
                {
                    // read channel numbers
                    int cnlDataSize = cnlCnt * 10;
                    int cnlNumsSize = cnlCnt * 4;
                    buffer = new byte[cnlDataSize];
                    ReadData(reader, buffer, 0, cnlNumsSize + 4, true);

                    int[] cnlNums = new int[cnlCnt];
                    Buffer.BlockCopy(buffer, 0, cnlNums, 0, cnlNumsSize);

                    if (ScadaUtils.CRC32(buffer, 0, cnlNumsSize) != BitConverter.ToUInt32(buffer, cnlNumsSize))
                    {
                        throw new ScadaException("CRC error.");
                    }

                    // read channel data
                    ReadData(reader, buffer, 0, cnlDataSize, true);
                    CnlData[] cnlData = new CnlData[cnlCnt];

                    for (int i = 0, index = 0; i < cnlCnt; i++)
                    {
                        cnlData[i] = GetCnlData(buffer, ref index);
                    }

                    return(new Slice(timestamp, cnlNums, cnlData));
                }
                else if (cnlCnt == 0)
                {
                    return(new Slice(timestamp, 0));
                }
                else
                {
                    throw new ScadaException("Invalid channel count.");
                }
            }
            catch (EndOfStreamException)
            {
                // unable to read slice
                return(null);
            }
            finally
            {
                reader?.Close();
            }
        }