using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace PFCRip { public class PFCDataRecord { #region Declarations private byte[] _data; private Dictionary _subItems; #endregion #region Constructors / Teardown public PFCDataRecord(byte[] data) { byte[] header = {(byte)'A', (byte)'O', (byte)'L', (byte)'H'}; byte[] footer = {(byte)'A', (byte)'O', (byte)'L', (byte)'F'}; _data = data; //If we don't have the AOLH and AOLF headers, freak out if (_data.Length > 0 && _data.Length < (header.Length + footer.Length)) throw new InvalidOperationException(String.Format("PFCDataRecord: Invalid length {0}", _data.Length)); //Verify the header is there for (int i = 0; i < header.Length; i++) if (header[i] != _data[i]) throw new InvalidOperationException("PFCDataRecord: Invalid header: " + BitConverter.ToString(_data, 0, 4)); //Verify the footer is there for (int i = 0; i < footer.Length; i++) if (footer[i] != _data[_data.Length - 4 + i]) throw new InvalidOperationException("PFCDataRecord: Invalid footer: " + BitConverter.ToString(_data, _data.Length - 4 - 1, 4)); //Parse into individual items uint index = (uint)(4 + header.Length); _subItems = new Dictionary(); while (index < _data.Length - footer.Length) { ushort itemId = LittleEndianConverter.ToUInt16(_data, index); index += 2; byte itemType = _data[index]; index++; uint size; switch (itemType) { case 0x01: case 0x02: case 0x03: case 0x04: { size = itemType; break; } default: { size = LittleEndianConverter.ToUInt32(_data, index); index += 4; break; } } var subData = new byte[size]; for (int i = 0; i < size; i++) subData[i] = _data[index + i]; index += size; _subItems.Add(itemId, new DataSubItem(itemId, itemType, subData)); } } #endregion #region Public Properties public Dictionary SubItems { get { return _subItems; } } #endregion } }