/// <summary> /// Заполнить объект dest из файла событий FileName /// </summary> protected void FillObj(object dest) { Stream stream = null; BinaryReader reader = null; DateTime fillTime = DateTime.Now; EventTableLight eventTableLight = null; DataTable dataTable = null; try { if (dest is EventTableLight) { eventTableLight = dest as EventTableLight; } else if (dest is DataTable) { dataTable = dest as DataTable; } else { throw new ScadaException("Destination object is invalid."); } // определение даты событий в таблице DateTime date = ExtractDate(tableName); // подготовка объекта для хранения данных if (eventTableLight != null) { eventTableLight.Clear(); eventTableLight.TableName = tableName; } else // dataTable != null { // формирование структуры таблицы dataTable.BeginLoadData(); dataTable.DefaultView.Sort = ""; if (dataTable.Columns.Count == 0) { dataTable.Columns.Add("Number", typeof(int)); dataTable.Columns.Add("DateTime", typeof(DateTime)).DefaultValue = date; dataTable.Columns.Add("ObjNum", typeof(int)).DefaultValue = 0; dataTable.Columns.Add("KPNum", typeof(int)).DefaultValue = 0; dataTable.Columns.Add("ParamID", typeof(int)).DefaultValue = 0; dataTable.Columns.Add("CnlNum", typeof(int)).DefaultValue = 0; dataTable.Columns.Add("OldCnlVal", typeof(double)).DefaultValue = 0.0; dataTable.Columns.Add("OldCnlStat", typeof(int)).DefaultValue = 0; dataTable.Columns.Add("NewCnlVal", typeof(double)).DefaultValue = 0.0; dataTable.Columns.Add("NewCnlStat", typeof(int)).DefaultValue = 0; dataTable.Columns.Add("Checked", typeof(bool)).DefaultValue = false; dataTable.Columns.Add("UserID", typeof(int)).DefaultValue = 0; dataTable.Columns.Add("Descr", typeof(string)); dataTable.Columns.Add("Data", typeof(string)); dataTable.DefaultView.AllowNew = false; dataTable.DefaultView.AllowEdit = false; dataTable.DefaultView.AllowDelete = false; } else { DataColumn colDateTime = dataTable.Columns["DateTime"]; if (colDateTime != null) { colDateTime.DefaultValue = date; } dataTable.Rows.Clear(); } } // заполнение таблицы из файла stream = ioStream == null ? new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) : ioStream; reader = new BinaryReader(stream); Byte[] eventBuf = new byte[EventDataSize]; // буфер данных события int evNum = 1; // порядковый номер события while (stream.Position < stream.Length) { int readSize = reader.Read(eventBuf, 0, EventDataSize); if (readSize == EventDataSize) { // создание события на основе считанных данных EventTableLight.Event ev = new EventTableLight.Event(); ev.Number = evNum; evNum++; double time = BitConverter.ToDouble(eventBuf, 0); int hour, min, sec; ScadaUtils.DecodeTime(time, out hour, out min, out sec); ev.DateTime = new DateTime(date.Year, date.Month, date.Day, hour, min, sec); ev.ObjNum = BitConverter.ToUInt16(eventBuf, 8); ev.KPNum = BitConverter.ToUInt16(eventBuf, 10); ev.ParamID = BitConverter.ToUInt16(eventBuf, 12); ev.CnlNum = BitConverter.ToUInt16(eventBuf, 14); ev.OldCnlVal = BitConverter.ToDouble(eventBuf, 16); ev.OldCnlStat = eventBuf[24]; ev.NewCnlVal = BitConverter.ToDouble(eventBuf, 25); ev.NewCnlStat = eventBuf[33]; ev.Checked = eventBuf[34] > 0; ev.UserID = BitConverter.ToUInt16(eventBuf, 35); ev.Descr = BytesToStr(eventBuf, 37); ev.Data = BytesToStr(eventBuf, 138); // создание строки заполняемой таблицы if (eventTableLight != null) { eventTableLight.AllEvents.Add(ev); // быстрее, чем eventTableLight.AddEvent(ev) } else // dataTable != null { DataRow row = dataTable.NewRow(); row["Number"] = ev.Number; row["DateTime"] = ev.DateTime; row["ObjNum"] = ev.ObjNum; row["KPNum"] = ev.KPNum; row["ParamID"] = ev.ParamID; row["CnlNum"] = ev.CnlNum; row["OldCnlVal"] = ev.OldCnlVal; row["OldCnlStat"] = ev.OldCnlStat; row["NewCnlVal"] = ev.NewCnlVal; row["NewCnlStat"] = ev.NewCnlStat; row["Checked"] = ev.Checked; row["UserID"] = ev.UserID; row["Descr"] = ev.Descr; row["Data"] = ev.Data; dataTable.Rows.Add(row); } } } } catch (EndOfStreamException) { // нормальная ситуация окончания файла } catch { fillTime = DateTime.MinValue; throw; } finally { if (fileMode) { if (reader != null) { reader.Close(); } if (stream != null) { stream.Close(); } } if (eventTableLight != null) { eventTableLight.LastFillTime = fillTime; } else if (dataTable != null) { dataTable.EndLoadData(); dataTable.AcceptChanges(); dataTable.DefaultView.Sort = "Number"; } } }
/// <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(); } } }