unsafe public static void SaveTestLabFrame(Frame frame, FileWriter writer) { TestLabFrameHeader frameHeader = (TestLabFrameHeader)frame.Header.Convert(StorageFormat.TestLab); ChannelCollection channels = frame.Channels; writer.Position = 0; writer.WriteUInt64(0x42414C54534554UL); WriteASCIIString(writer, frameHeader.Title, 61, true); WriteASCIIString(writer, frameHeader.Character, 121, true); WriteASCIIString(writer, frameHeader.Region, 121, true); WriteASCIIString(writer, frameHeader.Time.ToString("dd.MM.yyyy"), 11, true); WriteASCIIString(writer, frameHeader.Time.ToString("HH:mm:ss"), 9, true); writer.WriteUInt16((ushort)channels.Count); for (int i = 0; i != 17; ++i) { writer.WriteUInt8(0); } foreach (Channel channel in channels) { TestLabChannelHeader channelHeader = (TestLabChannelHeader)channel.Header.Convert(StorageFormat.TestLab); WriteASCIIString(writer, channelHeader.Name, 13, true); WriteASCIIString(writer, channelHeader.Description, 121, true); WriteASCIIString(writer, channelHeader.Unit, 13, true); writer.WriteFloat32((float)channelHeader.Offset); writer.WriteFloat32((float)channelHeader.Scale); writer.WriteFloat32((float)channelHeader.Cutoff); writer.WriteUInt16((ushort)channelHeader.Sampling); writer.WriteUInt8((byte)channelHeader.Type); writer.WriteUInt8((byte)channelHeader.DataFormat); writer.WriteUInt32((uint)channel.Length); for (int i = 0; i != 25; ++i) { writer.WriteUInt8(0); } } foreach (Channel channel in channels) { TestLabChannelHeader header = (TestLabChannelHeader)channel.Header.Convert(StorageFormat.TestLab); int length = channel.Length; double offset = header.Offset; double factor = 0; if (header.Scale != 0) { factor = 1 / header.Scale; } double *source = (double *)channel.Vector.Pointer; byte[] buffer = new byte[length * TestLabChannelHeader.GetItemSize(header.DataFormat)]; switch (header.DataFormat) { case TestLabDataFormat.UInt8: fixed(void *pointer = buffer) { byte *destination = (byte *)pointer; for (int i = 0; i != length; ++i) { destination[i] = (byte)(offset + factor * source[i]); } } break; case TestLabDataFormat.UInt16: fixed(void *pointer = buffer) { ushort *destination = (ushort *)pointer; for (int i = 0; i != length; ++i) { destination[i] = (ushort)(offset + factor * source[i]); } } break; case TestLabDataFormat.UInt32: fixed(void *pointer = buffer) { uint *destination = (uint *)pointer; for (int i = 0; i != length; ++i) { destination[i] = (uint)(offset + factor * source[i]); } } break; case TestLabDataFormat.Int8: fixed(void *pointer = buffer) { sbyte *destination = (sbyte *)pointer; for (int i = 0; i != length; ++i) { destination[i] = (sbyte)(offset + factor * source[i]); } } break; case TestLabDataFormat.Int16: fixed(void *pointer = buffer) { short *destination = (short *)pointer; for (int i = 0; i != length; ++i) { destination[i] = (short)(offset + factor * source[i]); } } break; case TestLabDataFormat.Int32: fixed(void *pointer = buffer) { int *destination = (int *)pointer; for (int i = 0; i != length; ++i) { destination[i] = (int)(offset + factor * source[i]); } } break; case TestLabDataFormat.Float32: fixed(void *pointer = buffer) { float *destination = (float *)pointer; for (int i = 0; i != length; ++i) { destination[i] = (float)(offset + factor * source[i]); } } break; case TestLabDataFormat.Float64: fixed(void *pointer = buffer) { double *destination = (double *)pointer; for (int i = 0; i != length; ++i) { destination[i] = offset + factor * source[i]; } } break; } writer.Write(buffer, 0, buffer.Length); writer.WriteUInt16(65535); } }
public static void SaveCatmanFrame(Frame frame, FileWriter writer) { Action <string> writeString = (string text) => { writer.WriteInt16((short)text.Length); if (text.Length > 0) { WriteASCIIString(writer, text, text.Length, false); } }; try { writer.Position = 0; CatmanFrameHeader frameHeader = (CatmanFrameHeader)frame.Header.Convert(StorageFormat.Catman); int numberOfChannels = frame.Channels.Count; int[] offsetChannelLength = new int[numberOfChannels]; List <CatmanChannelHeader> channelHeaders = new List <CatmanChannelHeader>(); int dataOffset = 2 + 4 + 2 + frameHeader.Comment.Length; for (int i = 0; i != 32; ++i) { dataOffset += 2 + frameHeader.Reserve[i].Length; } dataOffset += 2 + 4 + numberOfChannels * 4 + 4; for (int i = 0; i != numberOfChannels; ++i) { Channel channel = frame.Channels[i]; CatmanChannelHeader channelHeader = (CatmanChannelHeader)channel.Header.Convert(StorageFormat.Catman); channelHeaders.Add(channelHeader); offsetChannelLength[i] = dataOffset + 2; dataOffset += 2 + 4 + (2 + channelHeader.Name.Length) + (2 + channelHeader.Unit.Length) + (2 + channelHeader.Comment.Length); dataOffset += 2 + 2 + 8 + 4 + 8 + 8 + 2 + 2 + 2 + 2 + 4 + 4 + 4 + 4 * 4 + 32 + 8 + 8 + 2 * 4 + 2 * 4 + 2 * 3 + 2 + 4 + 4 + 4 * 2 + 2 + 9 + channelHeader.NumberOfPointsScaleTable * 8 + 2 + (2 + channelHeader.Formula.Length) + 4 + 2 + 50 + 16; } writer.WriteUInt16(0x1394); // 2 writer.WriteInt32(dataOffset); // 4 writeString(frameHeader.Comment); for (int i = 0; i != 32; ++i) { writeString(frameHeader.Reserve[i]); } writer.WriteInt16((short)numberOfChannels); // 2 writer.WriteInt32(frameHeader.MaximumChannelLength); // 4 for (int i = 0; i != numberOfChannels; ++i) { writer.WriteInt32(offsetChannelLength[i]); // 4 } writer.WriteInt32(0); // 4 if (numberOfChannels > 0) { for (int i = 0; i != numberOfChannels; ++i) { if (offsetChannelLength[i] != writer.Position + 2) { throw new Exception(); } Channel channel = frame.Channels[i]; CatmanChannelHeader channelHeader = channelHeaders[i]; int channelLength = channel.Length; writer.WriteInt16((short)channelHeader.LocationInDatabase); // 2 writer.WriteInt32(channelLength); // 4 writeString(channelHeader.Name); writeString(channelHeader.Unit); writeString(channelHeader.Comment); writer.WriteInt16((short)channelHeader.DataFormat); // 2 writer.WriteInt16((short)channelHeader.DataWidth); // 2 writer.WriteFloat64(channelHeader.Time.ToOADate()); // 8 writer.WriteInt32(148); // 4 writer.WriteFloat64(channelHeader.StartTime.ToOADate()); // 8 writer.WriteFloat64(channelHeader.SamplingTimeStep); // 8 writer.WriteInt16((short)channelHeader.CodeOfSensorType); // 2 writer.WriteInt16((short)channelHeader.CodeOfSupplyVoltage); // 2 writer.WriteInt16((short)channelHeader.CodeOfFilterCharacteristics); // 2 writer.WriteInt16((short)channelHeader.CodeOfFilterFrequency); // 2 writer.WriteFloat32((float)channelHeader.TareValue); // 4 writer.WriteFloat32((float)channelHeader.ZeroValue); // 4 writer.WriteFloat32((float)channelHeader.CodeOfMeasuringRange); // 4 writer.WriteFloat32((float)channelHeader.InputCharacteristics[0]); // 4 writer.WriteFloat32((float)channelHeader.InputCharacteristics[1]); // 4 writer.WriteFloat32((float)channelHeader.InputCharacteristics[2]); // 4 writer.WriteFloat32((float)channelHeader.InputCharacteristics[3]); // 4 WriteASCIIString(writer, channelHeader.AmplifierSerialNumber, 32, false); // 32 WriteASCIIString(writer, channelHeader.PhysicalUnit, 8, false); // 8 WriteASCIIString(writer, channelHeader.NativeUnit, 8, false); // 8 writer.WriteInt16((short)channelHeader.HardwareSlotNumber); // 2 writer.WriteInt16((short)channelHeader.HardwareSubSlotNumber); // 2 writer.WriteInt16((short)channelHeader.CodeOfAmplifierType); // 2 writer.WriteInt16((short)channelHeader.CodeOfAPConnectorType); // 2 writer.WriteFloat32((float)channelHeader.GageFactor); // 4 writer.WriteFloat32((float)channelHeader.BridgeFactor); // 4 writer.WriteInt16((short)channelHeader.CodeOfMeasurementSignal); // 2 writer.WriteInt16((short)channelHeader.CodeOfAmplifierInput); // 2 writer.WriteInt16((short)channelHeader.CodeOfHighpassFilter); // 2 writer.WriteUInt8((byte)channelHeader.OnlineImportInfo); // 1 writer.WriteUInt8((byte)channelHeader.CodeOfScaleType); // 1 writer.WriteFloat32((float)channelHeader.SoftwareZeroValue); // 4 writer.WriteUInt8((byte)channelHeader.WriteProtected); // 1 writer.WriteUInt8(0); // 1 writer.WriteUInt8(0); // 1 writer.WriteUInt8(0); // 1 writer.WriteFloat32((float)channelHeader.NominalRange); // 4 writer.WriteFloat32((float)channelHeader.CableLengthCompensation); // 4 writer.WriteUInt8((byte)channelHeader.ExportFormat); // 1 writer.WriteInt8((sbyte)channelHeader.ChannelType); // 1 writer.WriteUInt8((byte)channelHeader.EDaqConnectorOnLayer); // 1 writer.WriteUInt8((byte)channelHeader.EDaqLayer); // 1 writer.WriteUInt8((byte)channelHeader.ContentType); // 1 writer.WriteUInt8(0); // 1 writer.WriteUInt8(0); // 1 writer.WriteUInt8(0); // 1 writer.WriteUInt8((byte)channelHeader.LinearisationMode); // 1 writer.WriteUInt8((byte)channelHeader.UserScaleType); // 1 writer.WriteUInt8((byte)channelHeader.NumberOfPointsScaleTable); // 1 if (channelHeader.NumberOfPointsScaleTable != 0) { for (int j = 0; j != channelHeader.NumberOfPointsScaleTable; ++j) { writer.WriteFloat64(channelHeader.PointsScaleTable[j]); // 8 } } writer.WriteInt16((short)channelHeader.ThermoType); // 2 writeString(channelHeader.Formula); writer.WriteInt32(68); // 4 writer.WriteInt16((short)(channelHeader.SensorInfo.InUse? 1: 0)); // 2 WriteASCIIString(writer, channelHeader.SensorInfo.Description, 50, false); // 50 WriteASCIIString(writer, channelHeader.SensorInfo.Tid, 16, false); // 16 } // dataOffset = stream.Position for (int i = 0; i != numberOfChannels; ++i) { Channel channel = frame.Channels[i]; CatmanChannelHeader channelHeader = channelHeaders[i]; switch (channelHeader.ExportFormat) { case 0: for (int j = 0; j != channel.Length; ++j) { writer.WriteFloat64(channel[j]); } break; case 1: for (int j = 0; j != channel.Length; ++j) { writer.WriteFloat32((float)channel[j]); } break; case 2: writer.WriteFloat64(channelHeader.MinValueFactor); writer.WriteFloat64(channelHeader.MinValueFactor); for (int j = 0; j != channel.Length; ++j) { writer.WriteInt16((short)(32767 * (channel[j] - channelHeader.MinValueFactor) / (channelHeader.MinValueFactor - channelHeader.MinValueFactor))); } break; default: throw new InvalidDataException("Произошла попытка сохранить файл некорректного формата."); } } writer.WriteInt16((short)4001); for (int i = 0; i != numberOfChannels; ++i) { CatmanChannelHeader channelHeader = channelHeaders[i]; writeString(channelHeader.FormatString); } } } catch (Exception ex) { throw new InvalidOperationException("Произошла ошибка при записи файла.", ex); } }