/// <summary> /// The open. /// </summary> /// <exception cref="System.ApplicationException">File is invalid</exception> public void Open() { char[] leader = this._reader.ReadChars(24); // chek if the leader is valid if (!this.LeaderIsValid(leader)) { throw new ApplicationException("File is invalid"); } // populate the leader record this.Leader = DdfUtils.CreateLeader(leader, true); // read the record char[] record = this.ReadRecord(leader, this.Leader); int fieldEntryWidth = this.Leader.GetFieldEntryWidth(); int fieldCount = DdfUtils.CountDirectoryEntries( record, Constants.LeaderSize, this.Leader.RecordLength, fieldEntryWidth); this.ReadFieldDefinitions(this.Leader, record, fieldEntryWidth, fieldCount); }
/// <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 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); }