using System; using System.Collections; /* * Copyright 2012 Mario Vernari (http://cetdevelop.codeplex.com/) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace ModbusLib { /// /// Wrapper around a byte array for a forward-only reading access /// public class ByteArrayReader : IEnumerable, IByteArray { /// /// Create the instance from a byte array source /// /// public ByteArrayReader(byte[] source) { _buffer = source.ToArray(); Length = _buffer.Length; Reset(); } /// /// Create the instance from the specified part of the byte array source /// /// /// /// public ByteArrayReader( byte[] source, int offset, int count) { _buffer = source .ToArray(offset, count); Length = count; Reset(); } private readonly byte[] _buffer; public int Position { get; private set; } public int Length { get; private set; } /// /// Allow to reset the reader pointer /// public void Reset() { Position = -1; } /// /// Convert the reader content to a normal byte array /// /// public byte[] ToArray() { return _buffer .ToArray(); } /// /// Indicate whether the pointer has reached the end of the internal buffer /// public bool EndOfBuffer { get { return Position >= Length - 1; } } /// /// Tell whether the specified amount of bytes could be read from the reader /// /// /// public bool CanRead(int count) { int len = Length - Position - 1; return (count <= len); } /// /// Read the current pointed byte, but without moving the pointer /// /// public byte Peek() { return _buffer[Position]; } /// /// Read the current byte and move the pointer accordingly /// /// public byte ReadByte() { return _buffer[++Position]; } /// /// Try to read a byte, if available, and return true if succeeded /// /// /// public bool TryReadByte(out byte value) { if (CanRead(1)) { value = ReadByte(); return true; } else { value = 0; return false; } } /// /// Read the specified amount of bytes, /// and move the pointer accordingly /// /// /// public byte[] ReadBytes(int count) { var collection = new byte[count]; for (int i = 0; i < count; i++) { collection[i] = _buffer[++Position]; } return collection; } /// /// Read the remaining bytes up to the end, /// and move the pointer accordingly /// /// public byte[] ReadToEnd() { return ReadBytes(Length - (Position + 1)); } /// /// Read an (Little-endian), /// and move the pointer accordingly /// /// public Int16 ReadInt16LE() { int ptr = Position + 1; Position += 2; return ByteArrayHelpers.ReadInt16LE( _buffer, ptr); } /// /// Read an (Big-endian), /// and move the pointer accordingly /// /// public Int16 ReadInt16BE() { int ptr = Position + 1; Position += 2; return ByteArrayHelpers.ReadInt16BE( _buffer, ptr); } #region NON CLS-Compliant members #pragma warning disable 3001, 3002 /// /// Read an (Little-endian), /// and move the pointer accordingly /// /// public UInt16 ReadUInt16LE() { int ptr = Position + 1; Position += 2; return ByteArrayHelpers.ReadUInt16LE( _buffer, ptr); } /// /// Read an (Big-endian), /// and move the pointer accordingly /// /// public UInt16 ReadUInt16BE() { int ptr = Position + 1; Position += 2; return ByteArrayHelpers.ReadUInt16BE( _buffer, ptr); } #pragma warning restore 3001, 3002 #endregion /// /// Read an (Little-endian), /// and move the pointer accordingly /// /// public Int32 ReadInt32LE() { int ptr = Position + 1; Position += 4; return ByteArrayHelpers.ReadInt32LE( _buffer, ptr); } /// /// Read an (Big-endian), /// and move the pointer accordingly /// /// public Int32 ReadInt32BE() { int ptr = Position + 1; Position += 4; return ByteArrayHelpers.ReadInt32BE( _buffer, ptr); } #region IEnumerable members System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return _buffer .GetEnumerator(); } #endregion /// /// Facility for data exchange /// /// /// Avoid to use this member unless strictly necessary /// byte[] IByteArray.Data { get { return _buffer; } } } }