Beispiel #1
0
        private void WriteComponentData(BinaryWriter writer, FamosFileComponent component, int start, Span <byte> data, int length)
        {
            var packInfo   = component.PackInfo;
            var buffer     = packInfo.Buffers.First();
            var fileOffset = buffer.RawBlock.FileWriteOffset + buffer.RawBlockOffset + buffer.Offset + packInfo.Offset;

            var valueLength = component.GetSize(start, length);

            // write all data at once
            if (packInfo.IsContiguous)
            {
                var valueOffset = start * packInfo.ValueSize;

                writer.BaseStream.Seek(fileOffset + valueOffset, SeekOrigin.Begin);
                writer.Write(data);
            }

            // write grouped data
            else
            {
                var bufferByteLength = buffer.ConsumedBytes - buffer.Offset - packInfo.Offset;
                var valueOffset      = start * packInfo.ByteRowSize;

                writer.BaseStream.Seek(fileOffset + valueOffset, SeekOrigin.Begin);

                var bytePosition  = 0;
                var valuePosition = 0;

                while (true)
                {
                    // write x subsequent values
                    for (int j = 0; j < packInfo.GroupSize; j++)
                    {
                        // write a single value
                        if (valueLength - valuePosition >= 1)
                        {
                            for (int k = 0; k < packInfo.ValueSize; k++)
                            {
                                var position = valuePosition * packInfo.ValueSize + k;
                                writer.Write(data[position]);
                            }

                            bytePosition  += packInfo.ValueSize;
                            valuePosition += 1;
                        }
                    }

                    // skip x bytes
                    if (bufferByteLength - bytePosition >= packInfo.ByteGapSize)
                    {
                        writer.BaseStream.Seek(packInfo.ByteGapSize, SeekOrigin.Current);
                        bytePosition += packInfo.ByteGapSize;
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
        /// <summary>
        /// This method should be called in the action block that has been passed to the 'famosFile.Save(...)' or <see cref="FamosFile.Edit(Action{BinaryWriter})"/> method to write the actual data of type <typeparamref name="T"/>.
        /// </summary>
        /// <typeparam name="T">The data type parameter.</typeparam>
        /// <param name="writer">The binary writer that has been provided in the action block.</param>
        /// <param name="component">The component that describes the data to write.</param>
        /// <param name="start">The number of values to skip.</param>
        /// <param name="data">The actual data of type <typeparamref name="T"/>.</param>
        public void WriteSingle <T>(BinaryWriter writer, FamosFileComponent component, int start, ReadOnlySpan <T> data) where T : unmanaged
        {
            if (!this.Fields.Any(field => field.Components.Contains(component)))
            {
                throw new FormatException($"The provided component is not part of any {nameof(FamosFileField)} instance.");
            }

            var dataByteLength = data.Length * Marshal.SizeOf <T>();

            var bufferValueLength = component.GetSize(start);
            var bufferByteLength  = bufferValueLength * component.PackInfo.ValueSize;

            // data:     [0000] [0000] [0000] [0000] [0000]
            // buffer:   [0000] [0000] [0000] [0000]
            if (dataByteLength > bufferByteLength)
            {
                throw new InvalidOperationException("The start offset plus the size of the provided data array exceed the size of the component's buffer.");
            }

            // data:     [0000] [0000] [000]
            // buffer:   [0000] [0000] [0000] [0000]
            if (dataByteLength % component.PackInfo.ValueSize != 0)
            {
                throw new Exception("The length of the provided data array is not aligned to the component's buffer length, i.e. an incomplete value of the component's data type would be written to file.");
            }

            this.WriteComponentData(writer, component, start, MemoryMarshal.Cast <T, byte>(data), dataByteLength / component.PackInfo.ValueSize);
        }
Beispiel #3
0
        private protected FamosFileComponentData(FamosFileComponent component,
                                                 FamosFileXAxisScaling?xAxisScaling,
                                                 FamosFileZAxisScaling?zAxisScaling,
                                                 FamosFileTriggerTime?triggerTime,
                                                 byte[] data)
        {
            this.Type = component.Type;

            this.XAxisScaling = xAxisScaling?.Clone();
            this.ZAxisScaling = zAxisScaling?.Clone();
            this.TriggerTime  = triggerTime?.Clone();

            this.PackInfo = component.PackInfo;

            this.DisplayInfo    = component.DisplayInfo;
            this.EventReference = component.EventReference;

            this.RawData = data;
        }
Beispiel #4
0
 /// <summary>
 /// This method should be called in the action block that has been passed to the 'famosFile.Save(...)' method to write the actual data of type <typeparamref name="T"/>.
 /// </summary>
 /// <typeparam name="T">The data type parameter.</typeparam>
 /// <param name="writer">The binary writer that has been provided in the action block.</param>
 /// <param name="component">The component that describes the data to write.</param>
 /// <param name="start">The number of values to skip.</param>
 /// <param name="data">The actual data of type <typeparamref name="T"/>.</param>
 public void WriteSingle <T>(BinaryWriter writer, FamosFileComponent component, int start, T[] data) where T : unmanaged
 {
     this.WriteSingle(writer, component, start, data.AsSpan());
 }
Beispiel #5
0
 /// <summary>
 /// This method should be called in the action block that has been passed to the 'famosFile.Save(...)' method to write the actual data of type <typeparamref name="T"/>.
 /// </summary>
 /// <typeparam name="T">The data type parameter.</typeparam>
 /// <param name="writer">The binary writer that has been provided in the action block.</param>
 /// <param name="component">The component that describes the data to write.</param>
 /// <param name="data">The actual data of type <typeparamref name="T"/>.</param>
 public void WriteSingle <T>(BinaryWriter writer, FamosFileComponent component, Span <T> data) where T : unmanaged
 {
     this.WriteSingle(writer, component, 0, data);
 }
Beispiel #6
0
        private byte[] ReadComponentData(FamosFileComponent component, int start, int length)
        {
            var packInfo   = component.PackInfo;
            var buffer     = packInfo.Buffers.First();
            var fileOffset = buffer.RawBlock.FileOffset + buffer.RawBlockOffset + buffer.Offset + packInfo.Offset;

            var valueLength    = component.GetSize(start, length);
            var dataByteLength = valueLength * packInfo.ValueSize;

            // read all data at once
            if (packInfo.IsContiguous)
            {
                var valueOffset = start * packInfo.ValueSize;

                this.Reader.BaseStream.TrySeek(fileOffset + valueOffset, SeekOrigin.Begin);
                return(this.Reader.ReadBytes(dataByteLength));
            }

            // read grouped data
            else
            {
                var valueOffset      = start * packInfo.ByteRowSize;
                var bufferByteLength = buffer.ConsumedBytes - buffer.Offset - packInfo.Offset - valueOffset;

                var data = new byte[dataByteLength];

                this.Reader.BaseStream.TrySeek(fileOffset + valueOffset, SeekOrigin.Begin);

                var bytePosition  = 0;
                var valuePosition = 0;

                while (true)
                {
                    // read x subsequent values
                    for (int j = 0; j < packInfo.GroupSize; j++)
                    {
                        // read a single value
                        if (valueLength - valuePosition >= 1)
                        {
                            for (int k = 0; k < packInfo.ValueSize; k++)
                            {
                                var position = valuePosition * packInfo.ValueSize + k;
                                data[position] = this.Reader.ReadByte();
                            }

                            bytePosition  += packInfo.ValueSize;
                            valuePosition += 1;
                        }
                    }

                    // skip x bytes
                    if (bufferByteLength - bytePosition >= packInfo.ByteGapSize)
                    {
                        this.Reader.BaseStream.TrySeek(packInfo.ByteGapSize, SeekOrigin.Current);
                        bytePosition += packInfo.ByteGapSize;
                    }
                    else
                    {
                        break;
                    }
                }

                return(data);
            }
        }