/// <summary> /// The read field definitions. /// </summary> /// <param name="ddfLeader">The ddf leader.</param> /// <param name="record">The record.</param> /// <param name="fieldEntryWidth">The field entry width.</param> /// <param name="fieldCount">The field count.</param> /// <exception cref="System.ApplicationException">Header record invalid on DDF file + this._path</exception> public void ReadFieldDefinitions(DdfLeader ddfLeader, char[] record, int fieldEntryWidth, int fieldCount) { for (int i = 0; i < fieldCount; i++) { int entryOffset = Constants.LeaderSize + i * fieldEntryWidth; var tag = new String(record.Skip(entryOffset).Take(ddfLeader.SizeFieldTag).ToArray()); entryOffset += ddfLeader.SizeFieldTag; int fieldLength = DdfUtils.ReadIntFromBuffer(record, entryOffset, ddfLeader.SizeFieldLength); entryOffset += ddfLeader.SizeFieldLength; int fieldPos = DdfUtils.ReadIntFromBuffer(record, entryOffset, ddfLeader.SizeFieldPosition); if (ddfLeader.FieldAreaStart + fieldPos < 0 || ddfLeader.RecordLength - (ddfLeader.FieldAreaStart + fieldPos) < fieldLength) { throw new ApplicationException("Header record invalid on DDF file " + this._path); } var fieldDef = new DdfFieldDefinition(); if (fieldDef.Initialize(ddfLeader, tag, fieldLength, record, ddfLeader.FieldAreaStart + fieldPos)) { this._fieldDefinitions.Add(fieldDef); } } }
/// <summary> /// The create leader. /// </summary> /// <param name="leader">The leader.</param> /// <param name="moduleLeader">The module leader.</param> /// <returns>The <see cref="DdfLeader" />.</returns> /// <exception cref="System.ApplicationException"> /// File is invalid /// or /// ISO8211 record leader appears to be corrupt. /// </exception> public static DdfLeader CreateLeader(char[] leader, bool moduleLeader) { DdfLeader ddfLeader; if (moduleLeader) { ddfLeader = new DdfLeader { RecordLength = ReadIntFromBuffer(leader, 0, 5), InterchangeLevel = leader[5].ToString(CultureInfo.InvariantCulture), LeaderIdentifier = leader[6].ToString(CultureInfo.InvariantCulture), InlineCodeExtensionIndicator = leader[7].ToString(CultureInfo.InvariantCulture), VersionNumber = leader[8].ToString(CultureInfo.InvariantCulture), AppIndicator = leader[9].ToString(CultureInfo.InvariantCulture), FieldControlLength = ReadIntFromBuffer(leader, 10, 2), FieldAreaStart = ReadIntFromBuffer(leader, 12, 5), ExtendedCharSet = new List <char> { leader[17], leader[18], leader[19], '\0' }, SizeFieldLength = ReadIntFromBuffer(leader, 20, 1), SizeFieldPosition = ReadIntFromBuffer(leader, 21, 1), SizeFieldTag = ReadIntFromBuffer(leader, 23, 1) }; if (ddfLeader.RecordLength < 12 || ddfLeader.FieldControlLength == 0 || ddfLeader.FieldAreaStart < 24 || ddfLeader.SizeFieldLength == 0 || ddfLeader.SizeFieldPosition == 0 || ddfLeader.SizeFieldTag == 0) { throw new ApplicationException("File is invalid"); } } else { ddfLeader = new DdfLeader { RecordLength = ReadIntFromBuffer(leader, 0, 5), LeaderIdentifier = leader[6].ToString(CultureInfo.InvariantCulture), FieldAreaStart = ReadIntFromBuffer(leader, 12, 5), SizeFieldLength = ReadIntFromBuffer(leader, 20, 1), SizeFieldPosition = ReadIntFromBuffer(leader, 21, 1), SizeFieldTag = ReadIntFromBuffer(leader, 23, 1) }; if (ddfLeader.SizeFieldLength < 0 || ddfLeader.SizeFieldLength > 9 || ddfLeader.SizeFieldPosition < 0 || ddfLeader.SizeFieldPosition > 9 || ddfLeader.SizeFieldTag < 0 || ddfLeader.SizeFieldTag > 9) { throw new ApplicationException("ISO8211 record leader appears to be corrupt."); } } return(ddfLeader); }
/// <summary> /// The read record. /// </summary> /// <param name="leader">The leader.</param> /// <param name="ddfLeader">The ddf leader.</param> /// <returns>The <see cref="char[]" />.</returns> public char[] ReadRecord(char[] leader, DdfLeader ddfLeader) { var record = new char[ddfLeader.RecordLength]; leader.CopyTo(record, 0); for (int i = 0; i < (ddfLeader.RecordLength - Constants.LeaderSize); i++) { byte[] entry = this._reader.ReadBytes(1); char[] charEntry = Encoding.UTF8.GetString(entry).ToCharArray(); charEntry.CopyTo(record, (charEntry.Length * i) + Constants.LeaderSize); } return(record); }
/// <summary> /// The read header. /// </summary> /// <param name="module">The module.</param> /// <returns>The <see cref="bool" />.</returns> /// <exception cref="System.ArgumentException"> /// Leader is short on file /// or /// Data record is short on DDF file. /// or /// Data record is short on DDF file. /// </exception> /// <exception cref="System.ApplicationException"> /// Data record appears to be corrupt on DDF file.\n ensure that the files were uncompressed without modifying\n carriage return/linefeeds (by default WINZIP does this). /// or /// or /// </exception> private bool ReadHeader(Iso8211Reader module) { if (module.Reader.BaseStream.Length == module.Reader.BaseStream.Position) { return(false); } var leader = new char[Constants.LeaderSize]; if (DdfUtils.ReadObjectsFromBuffer(module.Reader, leader, 0, Constants.LeaderSize, 1) != Constants.LeaderSize) { throw new ArgumentException("Leader is short on file"); } DdfLeader ddfLeader = DdfUtils.CreateLeader(leader, false); this._reuseHeader = ddfLeader.LeaderIdentifier == "R"; /* -------------------------------------------------------------------- */ /* Is there anything seemly screwy about this record? */ /* -------------------------------------------------------------------- */ if ((ddfLeader.RecordLength < 24 || ddfLeader.RecordLength > 100000000 || ddfLeader.FieldAreaStart < 24 || ddfLeader.FieldAreaStart > 100000) && (ddfLeader.RecordLength != 0)) { throw new ApplicationException( "Data record appears to be corrupt on DDF file.\n ensure that the files were uncompressed without modifying\n carriage return/linefeeds (by default WINZIP does this)."); } if (ddfLeader.RecordLength != 0) { int dataSize = ddfLeader.RecordLength - Constants.LeaderSize; this._data = new char[dataSize]; if (DdfUtils.ReadObjectsFromBuffer(module.Reader, this._data, 0, dataSize, 1) != dataSize) { throw new ArgumentException("Data record is short on DDF file."); } /* -------------------------------------------------------------------- */ /* If we don't find a field terminator at the end of the record */ /* we will read extra bytes till we get to it. */ /* -------------------------------------------------------------------- */ while (this._data[dataSize - 1] != Constants.DdfFieldTerminator && (dataSize == 0 || this._data[dataSize - 2] != Constants.DdfFieldTerminator)) { dataSize++; var moreData = new char[dataSize]; this._data.CopyTo(moreData, 0); if (DdfUtils.ReadObjectsFromBuffer(module.Reader, moreData, dataSize, 1, 1) != 1) { throw new ArgumentException("Data record is short on DDF file."); } this._data = moreData; } int fieldEntryWidth = ddfLeader.GetFieldEntryWidth(); /* -------------------------------------------------------------------- */ /* Loop over the directory entries, making a pass counting them. */ /* -------------------------------------------------------------------- */ int fieldCount = DdfUtils.CountDirectoryEntries(this._data, 0, dataSize, fieldEntryWidth); /* -------------------------------------------------------------------- */ /* Allocate, and read field definitions. */ /* -------------------------------------------------------------------- */ for (int i = 0; i < fieldCount; i++) { int entryOffset = i * fieldEntryWidth; /* -------------------------------------------------------------------- */ /* Read the position information and tag. */ /* -------------------------------------------------------------------- */ var tag = new String(this._data.Skip(entryOffset).Take(ddfLeader.SizeFieldTag).ToArray()); entryOffset += ddfLeader.SizeFieldTag; int fieldLength = DdfUtils.ReadIntFromBuffer(this._data, entryOffset, ddfLeader.SizeFieldLength); entryOffset += ddfLeader.SizeFieldLength; int fieldPos = DdfUtils.ReadIntFromBuffer(this._data, entryOffset, ddfLeader.SizeFieldPosition); DdfFieldDefinition fieldDefn = module.FieldDefinitions.FirstOrDefault(f => f.Tag == tag); if (fieldDefn == null) { throw new ApplicationException( string.Format("Undefined field {0} encountered in data record.", tag)); } if (ddfLeader.FieldAreaStart + fieldPos - Constants.LeaderSize < 0 || dataSize - (ddfLeader.FieldAreaStart + fieldPos - Constants.LeaderSize) < fieldLength) { throw new ApplicationException(string.Format("Not enough byte to initialize field {0}.", tag)); } /* Assign info the DDFField. */ /* -------------------------------------------------------------------- */ this.Fields.Add( new DdfField { FieldDefinition = fieldDefn, Data = this._data, Offset = ddfLeader.FieldAreaStart + fieldPos - Constants.LeaderSize, DataSize = fieldLength }); } return(true); } return(true); }
/// <summary> /// The initialize. /// </summary> /// <param name="leader">The leader.</param> /// <param name="tag">The tag.</param> /// <param name="size">The size.</param> /// <param name="record">The record.</param> /// <param name="offset">The offset.</param> /// <returns>The <see cref="bool" />.</returns> /// <exception cref="System.ArgumentNullException">leader</exception> /// <exception cref="System.ApplicationException"> /// Unrecognised data_struct_code value + record[offset] + Field + tag /// + initialization incorrect. /// or /// Unrecognised data_type_code value + record[offset + 1] + Field + tag /// + initialization incorrect. /// </exception> public bool Initialize(DdfLeader leader, string tag, int size, char[] record, int offset) { if (leader == null) { throw new ArgumentNullException("leader"); } this.Tag = tag; int charsConsumed; /* -------------------------------------------------------------------- */ /* Set the data struct and type codes. */ /* -------------------------------------------------------------------- */ switch (record[offset]) { case ' ': /* for ADRG, DIGEST USRP, DIGEST ASRP files */ case '0': this._dataStructureCode = DdfDataStructCode.DscElementary; break; case '1': this._dataStructureCode = DdfDataStructCode.DscVector; break; case '2': this._dataStructureCode = DdfDataStructCode.DscArray; break; case '3': this._dataStructureCode = DdfDataStructCode.DscConcatenated; break; default: throw new ApplicationException( "Unrecognised data_struct_code value " + record[offset] + " Field " + tag + " initialization incorrect."); // dataStructureCode = DDF_data_struct_code.dsc_elementary; } switch (record[offset + 1]) { case ' ': /* for ADRG, DIGEST USRP, DIGEST ASRP files */ case '0': break; case '1': break; case '2': break; case '3': break; case '4': break; case '5': break; case '6': break; default: throw new ApplicationException( "Unrecognised data_type_code value " + record[offset + 1] + " Field " + tag + "initialization incorrect."); // dataTypeCode = dtc_char_string; } /* -------------------------------------------------------------------- */ /* Capture the field name, description (sub field names), and */ /* format statements. */ /* -------------------------------------------------------------------- */ int fieldDataOffset = leader.FieldControlLength; this.FieldName = DdfUtils.ReadStringFromBufffer( record, offset + fieldDataOffset, size - fieldDataOffset, Constants.DdfUnitTerminator, Constants.DdfFieldTerminator, out charsConsumed); fieldDataOffset += charsConsumed; this._arrayDescription = DdfUtils.ReadStringFromBufffer( record, offset + fieldDataOffset, size - fieldDataOffset, Constants.DdfUnitTerminator, Constants.DdfFieldTerminator, out charsConsumed); fieldDataOffset += charsConsumed; this._formatControls = DdfUtils.ReadStringFromBufffer( record, offset + fieldDataOffset, size - fieldDataOffset, Constants.DdfUnitTerminator, Constants.DdfFieldTerminator, out charsConsumed); if (this._dataStructureCode != DdfDataStructCode.DscElementary) { if (!this.BuildSubfields()) { return false; } if (!this.ApplyFormats()) { return false; } } return true; }
/// <summary> /// The initialize. /// </summary> /// <param name="leader">The leader.</param> /// <param name="tag">The tag.</param> /// <param name="size">The size.</param> /// <param name="record">The record.</param> /// <param name="offset">The offset.</param> /// <returns>The <see cref="bool" />.</returns> /// <exception cref="System.ArgumentNullException">leader</exception> /// <exception cref="System.ApplicationException"> /// Unrecognised data_struct_code value + record[offset] + Field + tag /// + initialization incorrect. /// or /// Unrecognised data_type_code value + record[offset + 1] + Field + tag /// + initialization incorrect. /// </exception> public bool Initialize(DdfLeader leader, string tag, int size, char[] record, int offset) { if (leader == null) { throw new ArgumentNullException("leader"); } this.Tag = tag; int charsConsumed; /* -------------------------------------------------------------------- */ /* Set the data struct and type codes. */ /* -------------------------------------------------------------------- */ switch (record[offset]) { case ' ': /* for ADRG, DIGEST USRP, DIGEST ASRP files */ case '0': this._dataStructureCode = DdfDataStructCode.DscElementary; break; case '1': this._dataStructureCode = DdfDataStructCode.DscVector; break; case '2': this._dataStructureCode = DdfDataStructCode.DscArray; break; case '3': this._dataStructureCode = DdfDataStructCode.DscConcatenated; break; default: throw new ApplicationException( "Unrecognised data_struct_code value " + record[offset] + " Field " + tag + " initialization incorrect."); // dataStructureCode = DDF_data_struct_code.dsc_elementary; } switch (record[offset + 1]) { case ' ': /* for ADRG, DIGEST USRP, DIGEST ASRP files */ case '0': break; case '1': break; case '2': break; case '3': break; case '4': break; case '5': break; case '6': break; default: throw new ApplicationException( "Unrecognised data_type_code value " + record[offset + 1] + " Field " + tag + "initialization incorrect."); // dataTypeCode = dtc_char_string; } /* -------------------------------------------------------------------- */ /* Capture the field name, description (sub field names), and */ /* format statements. */ /* -------------------------------------------------------------------- */ int fieldDataOffset = leader.FieldControlLength; this.FieldName = DdfUtils.ReadStringFromBufffer( record, offset + fieldDataOffset, size - fieldDataOffset, Constants.DdfUnitTerminator, Constants.DdfFieldTerminator, out charsConsumed); fieldDataOffset += charsConsumed; this._arrayDescription = DdfUtils.ReadStringFromBufffer( record, offset + fieldDataOffset, size - fieldDataOffset, Constants.DdfUnitTerminator, Constants.DdfFieldTerminator, out charsConsumed); fieldDataOffset += charsConsumed; this._formatControls = DdfUtils.ReadStringFromBufffer( record, offset + fieldDataOffset, size - fieldDataOffset, Constants.DdfUnitTerminator, Constants.DdfFieldTerminator, out charsConsumed); if (this._dataStructureCode != DdfDataStructCode.DscElementary) { if (!this.BuildSubfields()) { return(false); } if (!this.ApplyFormats()) { return(false); } } return(true); }
/// <summary> /// The read record. /// </summary> /// <param name="leader">The leader.</param> /// <param name="ddfLeader">The ddf leader.</param> /// <returns>The <see cref="char[]" />.</returns> public char[] ReadRecord(char[] leader, DdfLeader ddfLeader) { var record = new char[ddfLeader.RecordLength]; leader.CopyTo(record, 0); for (int i = 0; i < (ddfLeader.RecordLength - Constants.LeaderSize); i++) { byte[] entry = this._reader.ReadBytes(1); char[] charEntry = Encoding.UTF8.GetString(entry).ToCharArray(); charEntry.CopyTo(record, (charEntry.Length * i) + Constants.LeaderSize); } return record; }