addColumn method

void addColumn(
  1. String? inFieldName,
  2. String inFieldType,
  3. int inFieldLength,
  4. int inDecimalCount,
)

Add a column to this DbaseFileHeader. The type is one of (C N L or D) character, number, logical(true/false), or date. The Field length is the total length in bytes reserved for this column. The decimal count only applies to numbers(N), and floating point values (F), and refers to the number of characters to reserve after the decimal point. Don't expect miracles from this...

Field Type MaxLength
---------- ---------
C          254
D          8
@          8
F          20
N          18

@param inFieldName The name of the field, must be less than 10 characters or it gets truncated. @param inFieldType A character representing the dBase field, ( see above ). Case insensitive. @param inFieldLength The length of the field, in bytes ( see above ) @param inDecimalCount For numeric fields, the number of decimal places to track. @throws DbaseFileException If the type is not recognized.

Implementation

void addColumn(String? inFieldName, String inFieldType, int inFieldLength,
    int inDecimalCount) {
  if (inFieldLength <= 0) {
    throw DbaseFileException('field length <= 0');
  }
  // fields ??= [];

  int tempLength = 1; // the length is used for the offset, and there is a
  // * for deleted as the first byte
  List<DbaseField> tempFieldDescriptors = []; //List(fields.length + 1);
  for (int i = 0; i < fields.length; i++) {
    fields[i].fieldDataAddress = tempLength;
    tempLength = tempLength + fields[i].fieldLength;
    tempFieldDescriptors.add(fields[i]);
    // tempFieldDescriptors[i] = fields[i];
  }
  tempFieldDescriptors.add(DbaseField());
  // tempFieldDescriptors[fields.length] = DbaseField();
  tempFieldDescriptors[fields.length].fieldLength = inFieldLength;
  tempFieldDescriptors[fields.length].decimalCount = inDecimalCount;
  tempFieldDescriptors[fields.length].fieldDataAddress = tempLength;

  inFieldName ??= 'NoName';

  // set the field name
  String? tempFieldName = inFieldName;
  // tempFieldName ??= 'NoName';
  // Fix for GEOT-42, ArcExplorer will not handle field names > 10 chars
  // Sorry folks.
  if (tempFieldName.length > 10) {
    tempFieldName = tempFieldName.substring(0, 10);
    ShpLogger().w('FieldName ' +
        inFieldName +
        ' is longer than 10 characters, truncating to ' +
        tempFieldName);
  }
  tempFieldDescriptors[fields.length].fieldName = tempFieldName;

  // the field type
  if ((inFieldType == 'C') || (inFieldType == 'c')) {
    tempFieldDescriptors[fields.length].fieldType = 'C'.codeUnitAt(0);
    if (inFieldLength > 254) {
      ShpLogger().v('Field Length for ' +
          inFieldName +
          ' set to $inFieldLength Which is longer than 254, not consistent with dbase III');
    }
  } else if ((inFieldType == 'S') || (inFieldType == 's')) {
    tempFieldDescriptors[fields.length].fieldType = 'C'.codeUnitAt(0);
    ShpLogger().w('Field type for ' +
        inFieldName +
        ' set to S which is flat out wrong people!, I am setting this to C, in the hopes you meant character.');
    if (inFieldLength > 254) {
      ShpLogger().v('Field Length for ' +
          inFieldName +
          ' set to $inFieldLength Which is longer than 254, not consistent with dbase III');
    }
    tempFieldDescriptors[fields.length].fieldLength = 8;
  } else if ((inFieldType == 'D') || (inFieldType == 'd')) {
    tempFieldDescriptors[fields.length].fieldType = 'D'.codeUnitAt(0);
    if (inFieldLength != 8) {
      ShpLogger().v('Field Length for ' +
          inFieldName +
          ' set to $inFieldLength Setting to 8 digits YYYYMMDD');
    }
    tempFieldDescriptors[fields.length].fieldLength = 8;
  } else if (inFieldType == '@') {
    tempFieldDescriptors[fields.length].fieldType = '@'.codeUnitAt(0);
    if (inFieldLength != 8) {
      ShpLogger().v('Field Length for ' +
          inFieldName +
          ' set to $inFieldLength Setting to 8 digits - two longs,' +
          'one long for date and one long for time');
    }
    tempFieldDescriptors[fields.length].fieldLength = 8;
  } else if ((inFieldType == 'F') || (inFieldType == 'f')) {
    tempFieldDescriptors[fields.length].fieldType = 'F'.codeUnitAt(0);
    if (inFieldLength > 20) {
      ShpLogger().v('Field Length for ' +
          inFieldName +
          ' set to $inFieldLength Preserving length, but should be set to Max of 20 not valid for dbase IV, and UP specification, not present in dbaseIII.');
    }
  } else if ((inFieldType == 'N') || (inFieldType == 'n')) {
    tempFieldDescriptors[fields.length].fieldType = 'N'.codeUnitAt(0);
    if (inFieldLength > 18) {
      ShpLogger().v('Field Length for ' +
          inFieldName +
          ' set to $inFieldLength Preserving length, but should be set to Max of 18 for dbase III specification.');
    }
    if (inDecimalCount < 0) {
      ShpLogger().v('Field Decimal Position for ' +
          inFieldName +
          ' set to $inDecimalCount Setting to 0 no decimal data will be saved.');
      tempFieldDescriptors[fields.length].decimalCount = 0;
    }
    if (inDecimalCount > inFieldLength - 1) {
      ShpLogger().w('Field Decimal Position for ' +
          inFieldName +
          ' set to $inDecimalCount Setting to ${inFieldLength - 1} no non decimal data will be saved.');
      tempFieldDescriptors[fields.length].decimalCount = inFieldLength - 1;
    }
  } else if ((inFieldType == 'L') || (inFieldType == 'l')) {
    tempFieldDescriptors[fields.length].fieldType = 'L'.codeUnitAt(0);
    if (inFieldLength != 1) {
      ShpLogger().v('Field Length for ' +
          inFieldName +
          ' set to $inFieldLength Setting to length of 1 for logical fields.');
    }
    tempFieldDescriptors[fields.length].fieldLength = 1;
  } else {
    throw DbaseFileException(
        'Undefined field type ' + inFieldType + ' For column ' + inFieldName);
  }
  // the length of a record
  tempLength = tempLength + tempFieldDescriptors[fields.length].fieldLength;

  // set the fields.
  fields = tempFieldDescriptors;
  fieldCnt = fields.length;
  headerLength = MINIMUM_HEADER + 32 * fields.length;
  recordLength = tempLength;
}