private DataDescriptiveRecordFields ReadDataDescriptiveRecordFields(RecordLeader leader, RecordDirectory directory) { var fieldArea = new DataDescriptiveRecordFields(); foreach (DirectoryEntry entry in directory) { bool isFileControlField = false; int result; if (Int32.TryParse(entry.FieldTag, out result)) { switch (result) { case 0: isFileControlField = true; //tag is 0..0 (e.g. '0000') break; case 1: //Record Identifier field - this is processed as a normal DataField (or DataDescriptiveField in the DataDescriptiveRecord) break; case 2: throw new NotImplementedException("Processing User application field"); case 3: throw new NotImplementedException("Processing Announcer sequence or feature identifier field"); case 4 - 8: throw new NotImplementedException("Processing Special field tag reserved for future standardisation - " + entry.FieldTag); case 9: throw new NotImplementedException("Processing Recursive tree LINKS field"); } } if (isFileControlField) { //This is a special field tag - the file control field byte[] fieldControls = bufferedReader.ReadBytes(leader.FieldControlLength); string externalFileTitle = ReadStringToTerminator(); string listOfFieldTagPairs = ReadStringToTerminator(); var fcf = new FileControlField(entry.FieldTag, fieldControls, externalFileTitle, listOfFieldTagPairs, leader.EntryMap.SizeOfTagField); fieldArea.Add(fcf); } else { byte[] fieldControls = bufferedReader.ReadBytes(leader.FieldControlLength); string dataFieldName = ReadStringToTerminator(); string arrayDescriptor = ReadStringToTerminator(); string formatControls = ReadStringToTerminator(); var ddf = new DataDescriptiveField(entry.FieldTag, fieldControls, dataFieldName, arrayDescriptor, formatControls); fieldArea.Add(ddf); } } return(fieldArea); }
Encoding iso8859; // to chache encoding (getencoding is pretty expensive) public DataField(string tag, DataDescriptiveField fieldDescription, byte[] bytes) : base(tag) { _fieldDescription = fieldDescription; _bytes = bytes; iso8859 = Encoding.GetEncoding("iso-8859-1"); int currentIndex = 0; int start = 0; int tagCount = _fieldDescription.SubFieldDefinitions.Count; if (tagCount > 0) { string[] tags = new string[tagCount]; for (int i = 0; i < tagCount; i++) { tags[i] = _fieldDescription.SubFieldDefinitions[i].Tag; } subFields = new SubFields(tags); //while (bytes[currentIndex] != FieldTerminator && currentIndex < Bytes.Length) //need to ignore fieldterminator as it can be part of a valid coordiante in sg2d field while (currentIndex < Bytes.Length - 1) { subFieldRow = new object[tagCount]; parseSubfields(ref tag, ref _fieldDescription, ref start, ref currentIndex, ref _bytes); subFields.Values.Add(subFieldRow); } } }
public DataField(string tag, DataDescriptiveField fieldDescription, ArraySegment <byte> bytes) : base(tag) { _fieldDescription = fieldDescription; int currentIndex = 0; int start = 0; int tagCount = _fieldDescription.SubFieldDefinitions.Count; if (tagCount > 0) { List <string> tags = new List <string>(tagCount); for (int i = 0; i < tagCount; i++) { tags.Add(_fieldDescription.SubFieldDefinitions[i].Tag); } subFields = new SubFields(tags); //while (bytes[currentIndex] != FieldTerminator && currentIndex < Bytes.Length) //need to ignore fieldterminator as it can be part of a valid coordiante in sg2d field while (currentIndex < bytes.Count - 1) { subFieldRow = new SFcontainer[tagCount]; parseSubfields(ref tag, ref _fieldDescription, ref start, ref currentIndex, ref bytes); subFields.Values.Add(subFieldRow); } } }
public DataField(string tag, DataDescriptiveField fieldDescription, byte[] bytes) : base(tag) { _fieldDescription = fieldDescription; _bytes = bytes; int currentIndex = 0; int start = 0; foreach (SubFieldDefinition subFieldDefinition in _fieldDescription.SubFieldDefinitions) { if (subFieldDefinition.FormatTypeCode == FormatTypeCode.CharacterData) { string s; start = currentIndex; if (subFieldDefinition.SubFieldWidth == 0) { while (_bytes[currentIndex] != UnitTerminator) { currentIndex++; } s = Encoding.ASCII.GetString(bytes, start, currentIndex - start); //Consume the Terminator currentIndex++; } else { currentIndex += subFieldDefinition.SubFieldWidth; s = Encoding.ASCII.GetString(bytes, start, subFieldDefinition.SubFieldWidth); } SubFields.Add(subFieldDefinition.Tag, s); } else if (subFieldDefinition.FormatTypeCode == FormatTypeCode.LsofBinaryForm) { switch (subFieldDefinition.BinaryFormSubType) { case ExtendedBinaryForm.IntegerSigned: if (subFieldDefinition.BinaryFormPrecision != 4) { throw new NotImplementedException("Only handle Signed Ints of 4 bytes"); } int signedValue = 0; for (int i = 0; i < subFieldDefinition.BinaryFormPrecision; i++) { int tempVal = _bytes[currentIndex++]; for (int j = 0; j < i; j++) { tempVal = tempVal << 8; } signedValue += tempVal; } SubFields.Add(subFieldDefinition.Tag, signedValue); break; case ExtendedBinaryForm.IntegerUnsigned: if (subFieldDefinition.BinaryFormPrecision > 4) { throw new NotImplementedException("Only handle unsigned Ints 4 bytes or less"); } UInt32 unsignedValue = 0; for (int i = 0; i < subFieldDefinition.BinaryFormPrecision; i++) { UInt32 tempVal = _bytes[currentIndex++]; for (int j = 0; j < i; j++) { tempVal = tempVal << 8; } unsignedValue += tempVal; } SubFields.Add(subFieldDefinition.Tag, unsignedValue); break; default: throw new NotImplementedException("Unhandled LsofBinaryForm"); } } else if (subFieldDefinition.FormatTypeCode == FormatTypeCode.ExplicitPoint) { string s; start = currentIndex; if (subFieldDefinition.SubFieldWidth == 0) { //throw new Exception("Expected a subfield width for Explicit Point Type"); //no need to throw exception, open ended floating point values (terminated by Unit terminator) are permitted, //see S57 specification (3.1 Main, section 7.4.1) while (_bytes[currentIndex] != UnitTerminator) { currentIndex++; } s = Encoding.ASCII.GetString(bytes, start, currentIndex - start); //Consume the Terminator currentIndex++; } else { currentIndex += subFieldDefinition.SubFieldWidth; s = Encoding.ASCII.GetString(bytes, start, subFieldDefinition.SubFieldWidth); } double value = 0; Double.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out value); SubFields.Add(subFieldDefinition.Tag, value); } else if (subFieldDefinition.FormatTypeCode == FormatTypeCode.ImplicitPoint) //added begin { if (subFieldDefinition.SubFieldWidth == 0) { throw new Exception("Expected a subfield width for Implicit Point Type"); } int value = 0; for (int i = 0; i < subFieldDefinition.SubFieldWidth; i++) { value += ((_bytes[currentIndex] - '0') * (int)Math.Pow(10, subFieldDefinition.SubFieldWidth - i - 1)); currentIndex++; } SubFields.Add(subFieldDefinition.Tag, value); }//added end else if (subFieldDefinition.FormatTypeCode == FormatTypeCode.BitStringData) { if (subFieldDefinition.SubFieldWidth == 0) { throw new Exception("Expected a subfield width for Bit String Data"); } //divide by 8 and round up int bytesToRead = (subFieldDefinition.SubFieldWidth + (8 - 1)) / 8; byte[] newByteArray = new byte[bytesToRead]; for (int i = 0; i < bytesToRead; i++) { newByteArray[i] = _bytes[currentIndex]; currentIndex++; } SubFields.Add(subFieldDefinition.Tag, newByteArray); } else { throw new Exception("Unhandled subField type :" + subFieldDefinition.FormatTypeCode); } //if (bytes[bytes.Length - 1] != FieldTerminator) throw new Exception("Expected Field Terminator"); } }
private void parseSubfields(ref string tag, ref DataDescriptiveField _fieldDescription, ref int start, ref int currentIndex, ref byte[] _bytes) { int subFieldCounter = 0; foreach (SubFieldDefinition subFieldDefinition in _fieldDescription.SubFieldDefinitions) { if (subFieldDefinition.FormatTypeCode == FormatTypeCode.CharacterData) { string s = null; start = currentIndex; if (subFieldDefinition.SubFieldWidth == 0) { while (_bytes[currentIndex] != UnitTerminator) { currentIndex++; } if (_fieldDescription.iso8211LexicalLevel == ISO8211LexicalLevel.ASCIIText) { s = Encoding.ASCII.GetString(_bytes, start, currentIndex - start); } else if (_fieldDescription.iso8211LexicalLevel == ISO8211LexicalLevel.ISO8859) { s = iso8859.GetString(_bytes, start, currentIndex - start); } else if (_fieldDescription.iso8211LexicalLevel == ISO8211LexicalLevel.ISO10646) { s = Encoding.Unicode.GetString(_bytes, start, currentIndex + 1 - start); currentIndex++; //unicode Terminator has 2 bytes, consume first one } currentIndex++; //Consume the Terminator } else { currentIndex += subFieldDefinition.SubFieldWidth; if (_fieldDescription.iso8211LexicalLevel == ISO8211LexicalLevel.ASCIIText) { s = Encoding.ASCII.GetString(_bytes, start, subFieldDefinition.SubFieldWidth); } else if (_fieldDescription.iso8211LexicalLevel == ISO8211LexicalLevel.ISO8859) { s = iso8859.GetString(_bytes, start, subFieldDefinition.SubFieldWidth); } else if (_fieldDescription.iso8211LexicalLevel == ISO8211LexicalLevel.ISO10646) { s = Encoding.Unicode.GetString(_bytes, start, subFieldDefinition.SubFieldWidth); } } subFieldRow[subFieldCounter] = s; } else if (subFieldDefinition.FormatTypeCode == FormatTypeCode.LsofBinaryForm) { switch (subFieldDefinition.BinaryFormSubType) { case ExtendedBinaryForm.IntegerSigned: if (subFieldDefinition.BinaryFormPrecision != 4) { throw new NotImplementedException("Only handle Signed Ints of 4 bytes"); } int signedValue = 0; for (int i = 0; i < subFieldDefinition.BinaryFormPrecision; i++) { int tempVal = _bytes[currentIndex++]; for (int j = 0; j < i; j++) { tempVal = tempVal << 8; } signedValue += tempVal; } subFieldRow[subFieldCounter] = signedValue; break; case ExtendedBinaryForm.IntegerUnsigned: if (subFieldDefinition.BinaryFormPrecision > 4) { throw new NotImplementedException("Only handle unsigned Ints 4 bytes or less"); } UInt32 unsignedValue = 0; for (int i = 0; i < subFieldDefinition.BinaryFormPrecision; i++) { UInt32 tempVal = _bytes[currentIndex++]; for (int j = 0; j < i; j++) { tempVal = tempVal << 8; } unsignedValue += tempVal; } subFieldRow[subFieldCounter] = unsignedValue; break; default: throw new NotImplementedException("Unhandled LsofBinaryForm"); } } else if (subFieldDefinition.FormatTypeCode == FormatTypeCode.ExplicitPoint) { string s; start = currentIndex; if (subFieldDefinition.SubFieldWidth == 0) { //throw new Exception("Expected a subfield width for Explicit Point Type"); //no need to throw exception, open ended floating point values (terminated by Unit terminator) are permitted, //see S57 specification (3.1 Main, section 7.4.1) while (_bytes[currentIndex] != UnitTerminator) { currentIndex++; } s = Encoding.ASCII.GetString(_bytes, start, currentIndex - start); //Consume the Terminator currentIndex++; } else { currentIndex += subFieldDefinition.SubFieldWidth; s = Encoding.ASCII.GetString(_bytes, start, subFieldDefinition.SubFieldWidth); } double value = 0; Double.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out value); subFieldRow[subFieldCounter] = value; } else if (subFieldDefinition.FormatTypeCode == FormatTypeCode.ImplicitPoint) //added begin { if (subFieldDefinition.SubFieldWidth == 0) { throw new Exception("Expected a subfield width for Implicit Point Type"); } int value = 0; for (int i = 0; i < subFieldDefinition.SubFieldWidth; i++) { value += ((_bytes[currentIndex] - '0') * (int)Math.Pow(10, subFieldDefinition.SubFieldWidth - i - 1)); currentIndex++; } subFieldRow[subFieldCounter] = value; }//added end else if (subFieldDefinition.FormatTypeCode == FormatTypeCode.BitStringData) { if (subFieldDefinition.SubFieldWidth == 0) { throw new Exception("Expected a subfield width for Bit String Data"); } //divide by 8 and round up int bytesToRead = (subFieldDefinition.SubFieldWidth + (8 - 1)) / 8; byte[] newByteArray = new byte[bytesToRead]; for (int i = 0; i < bytesToRead; i++) { newByteArray[i] = _bytes[currentIndex]; currentIndex++; } subFieldRow[subFieldCounter] = newByteArray; } else { throw new Exception("Unhandled subField type :" + subFieldDefinition.FormatTypeCode); } subFieldCounter++; //if (bytes[bytes.Length - 1] != FieldTerminator) throw new Exception("Expected Field Terminator"); } }
public DataField(string tag, DataDescriptiveField fieldDescription, byte[] bytes) : base(tag) { _fieldDescription = fieldDescription; _bytes = bytes; int currentIndex = 0; foreach (SubFieldDefinition subFieldDefinition in _fieldDescription.SubFieldDefinitions) { if (subFieldDefinition.FormatTypeCode == FormatTypeCode.CharacterData) { var sb = new StringBuilder(); if (subFieldDefinition.SubFieldWidth == 0) { while (_bytes[currentIndex] != UnitTerminator) { sb.Append((char)_bytes[currentIndex]); currentIndex++; } //Consume the Terminator currentIndex++; } else { for (int i = 0; i < subFieldDefinition.SubFieldWidth; i++) { sb.Append((char)_bytes[currentIndex]); currentIndex++; } } var s = sb.ToString(); SubFields.Add(subFieldDefinition.Tag, s); } else if (subFieldDefinition.FormatTypeCode == FormatTypeCode.LsofBinaryForm) { switch (subFieldDefinition.BinaryFormSubType) { case ExtendedBinaryForm.IntegerSigned: if (subFieldDefinition.BinaryFormPrecision != 4) { throw new NotImplementedException("Only handle Signed Ints of 4 bytes"); } int signedValue = 0; for (int i = 0; i < subFieldDefinition.BinaryFormPrecision; i++) { int tempVal = _bytes[currentIndex++]; for (int j = 0; j < i; j++) { tempVal = tempVal << 8; } signedValue += tempVal; } SubFields.Add(subFieldDefinition.Tag, signedValue); break; case ExtendedBinaryForm.IntegerUnsigned: if (subFieldDefinition.BinaryFormPrecision > 4) { throw new NotImplementedException("Only handle unsigned Ints 4 bytes or less"); } UInt32 unsignedValue = 0; for (int i = 0; i < subFieldDefinition.BinaryFormPrecision; i++) { UInt32 tempVal = _bytes[currentIndex++]; for (int j = 0; j < i; j++) { tempVal = tempVal << 8; } unsignedValue += tempVal; } SubFields.Add(subFieldDefinition.Tag, unsignedValue); break; default: throw new NotImplementedException("Unhandled LsofBinaryForm"); } } else if (subFieldDefinition.FormatTypeCode == FormatTypeCode.ExplicitPoint) { if (subFieldDefinition.SubFieldWidth == 0) { throw new Exception("Expected a subfield width for Explicit Point Type"); } var tempSb = new StringBuilder(); for (int i = 0; i < subFieldDefinition.SubFieldWidth; i++) { tempSb.Append((char)_bytes[currentIndex]); currentIndex++; } double value = 0; value = Double.Parse(tempSb.ToString(), CultureInfo.InvariantCulture); SubFields.Add(subFieldDefinition.Tag, value); } else if (subFieldDefinition.FormatTypeCode == FormatTypeCode.BitStringData) { if (subFieldDefinition.SubFieldWidth == 0) { throw new Exception("Expected a subfield width for Bit String Data"); } //divide by 8 and round up int bytesToRead = (subFieldDefinition.SubFieldWidth + (8 - 1)) / 8; byte[] newByteArray = new byte[bytesToRead]; for (int i = 0; i < bytesToRead; i++) { newByteArray[i] = _bytes[currentIndex]; currentIndex++; } SubFields.Add(subFieldDefinition.Tag, newByteArray); } else { throw new Exception("Unhandled subField type :" + subFieldDefinition.FormatTypeCode); } //if (bytes[bytes.Length - 1] != FieldTerminator) throw new Exception("Expected Field Terminator"); } }