/// <summary> /// Calculates the CRC of the channel numbers. /// </summary> protected uint CalculateCRC() { int dataLength = CnlNums.Length * 4; byte[] buffer = new byte[dataLength]; Buffer.BlockCopy(CnlNums, 0, buffer, 0, dataLength); return(ScadaUtils.CRC32(buffer, 0, dataLength)); }
/// <summary> /// Writes the single slice to a file or stream. /// </summary> public void WriteSingleSlice(Slice slice) { if (slice == null) { throw new ArgumentNullException(nameof(slice)); } Stream stream; BinaryWriter writer = null; try { stream = Stream ?? new FileStream(FileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite); writer = new BinaryWriter(stream, Encoding.UTF8, Stream != null); // write header writer.Write(TableType.SliceTable); writer.Write(MajorVersion); writer.Write(MinorVersion); writer.Write(ReserveBuffer, 0, 14); // write slice int cnlCnt = slice.CnlNums.Length; int sliceSize = cnlCnt > 0 ? cnlCnt * 14 + 18 : 14; ResizeBuffer(ref sliceBuffer, sliceSize); byte[] buffer = sliceBuffer; int index = 0; CopyUInt16(BlockMarker, buffer, ref index); CopyTime(slice.Timestamp, buffer, ref index); CopyInt32(cnlCnt, buffer, ref index); if (cnlCnt > 0) { int dataLength = cnlCnt * 4; Buffer.BlockCopy(slice.CnlNums, 0, buffer, index, dataLength); uint crc = ScadaUtils.CRC32(buffer, index, dataLength); index += dataLength; CopyInt32((int)crc, buffer, ref index); foreach (CnlData cnlData in slice.CnlData) { CopyCnlData(cnlData, buffer, ref index); } } writer.Write(buffer, 0, index); } finally { writer?.Close(); } }
/// <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"; } } }
/// <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(); } }