예제 #1
0
        /// <summary>
        /// Заполнить объект dest из файла срезов FileName
        /// </summary>
        protected void FillObj(object dest)
        {
            Stream       stream   = null;
            BinaryReader reader   = null;
            DateTime     fillTime = DateTime.Now;

            SrezTableLight srezTableLight = dest as SrezTableLight;
            DataTable      dataTable      = dest as DataTable;
            Trend          trend          = dest as Trend;

            SrezTable srezTable = srezTableLight as SrezTable;

            SrezTableLight.Srez lastStoredSrez = null;

            try
            {
                if (srezTableLight == null && dataTable == null && trend == null)
                {
                    throw new ScadaException("Destination object is invalid.");
                }

                // подготовка объекта для хранения данных
                if (srezTableLight != null)
                {
                    srezTableLight.Clear();
                    srezTableLight.TableName = tableName;

                    if (srezTable != null)
                    {
                        srezTable.BeginLoadData();
                    }
                }
                else if (dataTable != null)
                {
                    // формирование структуры таблицы
                    dataTable.BeginLoadData();
                    dataTable.DefaultView.Sort = "";

                    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));
                        dataTable.DefaultView.AllowNew    = false;
                        dataTable.DefaultView.AllowEdit   = false;
                        dataTable.DefaultView.AllowDelete = false;
                    }
                    else
                    {
                        dataTable.Rows.Clear();
                    }
                }
                else // trend != null
                {
                    trend.Clear();
                    trend.TableName = tableName;
                }

                // заполнение объекта данными
                stream = ioStream == null ?
                         new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) :
                         ioStream;
                reader = new BinaryReader(stream);

                DateTime            date      = ExtractDate(tableName); // определение даты срезов
                SrezTable.SrezDescr srezDescr = null;                   // описание среза
                int[] cnlNums = null;                                   // ссылка на номера входных каналов из описания среза
                while (stream.Position < stream.Length)
                {
                    // считывание списка номеров каналов и КС
                    int cnlNumCnt = reader.ReadUInt16();
                    if (cnlNumCnt > 0)
                    {
                        // загрузка номеров каналов в буфер для увеличения скорости работы
                        int    cnlNumSize = cnlNumCnt * 2;
                        byte[] buf        = new byte[cnlNumSize];
                        int    readSize   = reader.Read(buf, 0, cnlNumSize);

                        // создание описания среза и заполнение номеров каналов из буфера
                        // с проверкой их уникальности и упорядоченности
                        if (readSize == cnlNumSize)
                        {
                            int prevCnlNum = -1;
                            srezDescr = new SrezTable.SrezDescr(cnlNumCnt);
                            cnlNums   = srezDescr.CnlNums;
                            for (int i = 0; i < cnlNumCnt; i++)
                            {
                                int cnlNum = BitConverter.ToUInt16(buf, i * 2);
                                if (prevCnlNum >= cnlNum)
                                {
                                    throw new ScadaException("Table is incorrect.");
                                }
                                cnlNums[i] = prevCnlNum = cnlNum;
                            }
                            srezDescr.CalcCS();
                        }
                    }
                    else if (srezDescr == null)
                    {
                        throw new Exception("Table is incorrect.");
                    }

                    // считывание и проверка КС
                    ushort cs   = reader.ReadUInt16();
                    bool   csOk = cnlNumCnt > 0 ? srezDescr.CS == cs : cs == 1;

                    // считывание данных среза
                    int cnlCnt       = cnlNums.Length; // количество каналов в срезе
                    int srezDataSize = cnlCnt * 9;     // размер данных среза
                    if (csOk)
                    {
                        long   srezPos = stream.Position;
                        double time = reader.ReadDouble();
                        int    hour, min, sec;
                        ScadaUtils.DecodeTime(time, out hour, out min, out sec);
                        DateTime srezDT = new DateTime(date.Year, date.Month, date.Day, hour, min, sec);

                        // инициализация нового среза
                        SrezTableLight.Srez srez;
                        if (srezTable != null)
                        {
                            srez = new SrezTable.Srez(srezDT, srezDescr)
                            {
                                State    = DataRowState.Unchanged,
                                Position = srezPos
                            };
                        }
                        else if (srezTableLight != null)
                        {
                            srez = new SrezTableLight.Srez(srezDT, cnlCnt);
                            cnlNums.CopyTo(srez.CnlNums, 0);
                        }
                        else // srezTableLight == null
                        {
                            srez = null;
                        }

                        // считывание данных входных каналов
                        int    bufInd = 0;
                        double val;
                        byte   stat;
                        if (trend != null)
                        {
                            // выбор данных требуемого канала для тренда
                            int index = Array.BinarySearch <int>(cnlNums, trend.CnlNum);
                            if (index >= 0)
                            {
                                stream.Seek(index * 9, SeekOrigin.Current);
                                byte[] buf      = new byte[9];
                                int    readSize = reader.Read(buf, 0, 9);
                                if (readSize == 9)
                                {
                                    ExtractCnlData(buf, ref bufInd, out val, out stat);
                                    Trend.Point point = new Trend.Point(srezDT, val, stat);
                                    trend.Points.Add(point);
                                    stream.Seek(srezDataSize - (index + 1) * 9, SeekOrigin.Current);
                                }
                            }
                            else
                            {
                                stream.Seek(srezDataSize, SeekOrigin.Current);
                            }
                        }
                        else
                        {
                            // загрузка данных среза в буфер для увеличения скорости работы
                            byte[] buf      = new byte[srezDataSize];
                            int    readSize = reader.Read(buf, 0, srezDataSize);

                            // заполение таблицы срезов из буфера
                            if (srezTableLight != null)
                            {
                                for (int i = 0; i < cnlCnt; i++)
                                {
                                    ExtractCnlData(buf, ref bufInd, out val, out stat);

                                    srez.CnlNums[i]      = cnlNums[i];
                                    srez.CnlData[i].Val  = val;
                                    srez.CnlData[i].Stat = stat;

                                    if (bufInd >= readSize)
                                    {
                                        break;
                                    }
                                }

                                srezTableLight.AddSrez(srez);
                                lastStoredSrez = srez;
                            }
                            else // dataTable != null
                            {
                                for (int i = 0; i < cnlCnt; i++)
                                {
                                    ExtractCnlData(buf, ref bufInd, out val, out stat);

                                    DataRow row = dataTable.NewRow();
                                    row["DateTime"] = srezDT;
                                    row["CnlNum"]   = cnlNums[i];
                                    row["Val"]      = val;
                                    row["Stat"]     = stat;
                                    dataTable.Rows.Add(row);

                                    if (bufInd >= readSize)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        // пропустить срез, считая его размер так, как при повторяющемся списке номеров каналов
                        stream.Seek(srezDataSize + 8, SeekOrigin.Current);
                    }
                }
            }
            catch (EndOfStreamException)
            {
                // нормальная ситуация окончания файла
            }
            catch
            {
                fillTime = DateTime.MinValue;
                throw;
            }
            finally
            {
                if (fileMode)
                {
                    if (reader != null)
                    {
                        reader.Close();
                    }
                    if (stream != null)
                    {
                        stream.Close();
                    }
                }

                if (srezTableLight != null)
                {
                    srezTableLight.LastFillTime = fillTime;
                    if (srezTable != null)
                    {
                        srezTable.LastStoredSrez = (SrezTable.Srez)lastStoredSrez;
                        srezTable.EndLoadData();
                    }
                }
                else if (dataTable != null)
                {
                    dataTable.EndLoadData();
                    dataTable.AcceptChanges();
                    dataTable.DefaultView.Sort = "DateTime, CnlNum";
                }
                else if (trend != null)
                {
                    trend.LastFillTime = fillTime;
                    trend.Sort();
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Populate the dest object from the FileName slice file
        /// </summary>
        protected void FillObj(object dest)
        {
            Stream       stream   = null;
            BinaryReader reader   = null;
            var          fillTime = DateTime.Now;

            var srezTableLight = dest as SrezTableLight;
            var dataTable      = dest as DataTable;
            var trend          = dest as Trend;

            var srezTable = srezTableLight as SrezTable;

            SrezTableLight.Srez lastStoredSrez = null;

            try {
                if (srezTableLight == null && dataTable == null && trend == null)
                {
                    throw new ScadaException("Destination object is invalid.");
                }

                // storage facility preparation
                if (srezTableLight != null)
                {
                    srezTableLight.Clear();
                    srezTableLight.TableName = tableName;

                    srezTable?.BeginLoadData();
                }
                else if (dataTable != null)
                {
                    // forming the table structure
                    dataTable.BeginLoadData();
                    dataTable.DefaultView.Sort = "";

                    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));
                        dataTable.DefaultView.AllowNew    = false;
                        dataTable.DefaultView.AllowEdit   = false;
                        dataTable.DefaultView.AllowDelete = false;
                    }
                    else
                    {
                        dataTable.Rows.Clear();
                    }
                }
                else   // trend != null
                {
                    trend.Clear();
                    trend.TableName = tableName;
                }

                // filling the object with data
                stream = ioStream ?? new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                reader = new BinaryReader(stream);

                var date = ExtractDate(tableName);    // slice date determination
                SrezTable.SrezDescr srezDescr = null; // cut description
                int[] cnlNums = null;                 // link to input channel numbers from slice description
                while (stream.Position < stream.Length)
                {
                    // reading the list of channels and CS numbers
                    int cnlNumCnt = reader.ReadUInt16();
                    if (cnlNumCnt > 0)
                    {
                        // loading channel numbers to buffer to increase speed
                        int cnlNumSize = cnlNumCnt * 2;
                        var buf        = new byte[cnlNumSize];
                        int readSize   = reader.Read(buf, 0, cnlNumSize);

                        // creating a description of the slice and filling the numbers of the channels from the buffer
                        // with checking their uniqueness and orderliness
                        if (readSize == cnlNumSize)
                        {
                            int prevCnlNum = -1;
                            srezDescr = new SrezTable.SrezDescr(cnlNumCnt);
                            cnlNums   = srezDescr.CnlNums;
                            for (var i = 0; i < cnlNumCnt; i++)
                            {
                                int cnlNum = BitConverter.ToUInt16(buf, i * 2);
                                if (prevCnlNum >= cnlNum)
                                {
                                    throw new ScadaException("Table is incorrect.");
                                }
                                cnlNums[i] = prevCnlNum = cnlNum;
                            }

                            srezDescr.CalcCS();
                        }
                    }
                    else if (srezDescr == null)
                    {
                        throw new Exception("Table is incorrect.");
                    }

                    // reading and checking the cops
                    ushort cs   = reader.ReadUInt16();
                    bool   csOk = cnlNumCnt > 0 ? srezDescr.CS == cs : cs == 1;

                    // read slice data
                    int cnlCnt       = cnlNums.Length; // the number of channels in the slice
                    int srezDataSize = cnlCnt * 9;     // slice data size
                    if (csOk)
                    {
                        long   srezPos = stream.Position;
                        double time    = reader.ReadDouble();
                        var    srezDT  = ScadaUtils.CombineDateTime(date, time);

                        // initialize slice
                        SrezTableLight.Srez srez;
                        if (srezTable != null)
                        {
                            srez = new SrezTable.Srez(srezDT, srezDescr)
                            {
                                State    = DataRowState.Unchanged,
                                Position = srezPos
                            };
                        }
                        else if (srezTableLight != null)
                        {
                            srez = new SrezTableLight.Srez(srezDT, cnlCnt);
                            cnlNums.CopyTo(srez.CnlNums, 0);
                        }
                        else     // srezTableLight == null
                        {
                            srez = null;
                        }

                        // read input data
                        var    bufInd = 0;
                        double val;
                        byte   stat;
                        if (trend != null)
                        {
                            // select channel data for trend
                            int index = Array.BinarySearch <int>(cnlNums, trend.CnlNum);
                            if (index >= 0)
                            {
                                stream.Seek(index * 9, SeekOrigin.Current);
                                var buf      = new byte[9];
                                int readSize = reader.Read(buf, 0, 9);
                                if (readSize == 9)
                                {
                                    ExtractCnlData(buf, ref bufInd, out val, out stat);
                                    var point = new Trend.Point(srezDT, val, stat);
                                    trend.Points.Add(point);
                                    stream.Seek(srezDataSize - (index + 1) * 9, SeekOrigin.Current);
                                }
                            }
                            else
                            {
                                stream.Seek(srezDataSize, SeekOrigin.Current);
                            }
                        }
                        else
                        {
                            // loading slice data to buffer to increase speed
                            var buf      = new byte[srezDataSize];
                            int readSize = reader.Read(buf, 0, srezDataSize);

                            // filling the buffer table
                            if (srezTableLight != null)
                            {
                                for (var i = 0; i < cnlCnt; i++)
                                {
                                    ExtractCnlData(buf, ref bufInd, out val, out stat);

                                    srez.CnlNums[i]      = cnlNums[i];
                                    srez.CnlData[i].Val  = val;
                                    srez.CnlData[i].Stat = stat;

                                    if (bufInd >= readSize)
                                    {
                                        break;
                                    }
                                }

                                srezTableLight.AddSrez(srez);
                                lastStoredSrez = srez;
                            }
                            else     // dataTable != null
                            {
                                for (var i = 0; i < cnlCnt; i++)
                                {
                                    ExtractCnlData(buf, ref bufInd, out val, out stat);

                                    var row = dataTable.NewRow();
                                    row["DateTime"] = srezDT;
                                    row["CnlNum"]   = cnlNums[i];
                                    row["Val"]      = val;
                                    row["Stat"]     = stat;
                                    dataTable.Rows.Add(row);

                                    if (bufInd >= readSize)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        // skip the slice, considering its size as in the case of a repeated list of channel numbers
                        stream.Seek(srezDataSize + 8, SeekOrigin.Current);
                    }
                }
            } catch (EndOfStreamException) {
                // normal file end situation
            } catch {
                fillTime = DateTime.MinValue;
                throw;
            } finally {
                if (fileMode)
                {
                    reader?.Close();
                    stream?.Close();
                }

                if (srezTableLight != null)
                {
                    srezTableLight.LastFillTime = fillTime;
                    if (srezTable != null)
                    {
                        srezTable.LastStoredSrez = (SrezTable.Srez)lastStoredSrez;
                        srezTable.EndLoadData();
                    }
                }

                if (dataTable != null)
                {
                    dataTable.EndLoadData();
                    dataTable.AcceptChanges();
                    dataTable.DefaultView.Sort = "DateTime, CnlNum";
                }

                if (trend != null)
                {
                    trend.LastFillTime = fillTime;
                    trend.Sort();
                }
            }
        }