readObject method

Future readObject(
  1. int fieldOffset,
  2. int fieldNum
)

Implementation

Future<dynamic> readObject(final int fieldOffset, final int fieldNum) async {
  final type = fieldTypes![fieldNum];
  final fieldLen = fieldLengths![fieldNum];
  dynamic object;
  if (fieldLen > 0) {
    switch (String.fromCharCode(type)) {
      // (L)logical (T,t,F,f,Y,y,N,n)
      case 'l':
      case 'L':
        final c = String.fromCharCode(bytes![fieldOffset]);
        switch (c) {
          case 't':
          case 'T':
          case 'Y':
          case 'y':
            object = true;
            break;
          case 'f':
          case 'F':
          case 'N':
          case 'n':
            object = false;
            break;
          default:
            // 0x20 should be interpreted as null, but we're going to be a bit more
            // lax
            object = null;
        }
        break;
      // (C)character (String)
      case 'c':
      case 'C':
        if (bytes![fieldOffset] != NULL_CHAR.codeUnitAt(0)) {
          // var str = String.fromCharCode(bytes[fieldOffset]);
          // if (str != '\0') {
          // remember we need to skip trailing and leading spaces
          if (oneBytePerChar) {
            object = fastParse(bytes!, fieldOffset, fieldLen).trim();
          } else {
            var sublist = bytes!.sublist(fieldOffset, fieldOffset + fieldLen);
            var string = (await stringCharset!.decode(sublist)).trim();
            var characters = Characters(string);

            if (characters.endsWith(NULL_CHARACTERS)) {
              string = Characters(string)
                  .skipLastWhile((c) => c == NULL_CHARACTERS.toString())
                  .toString();
            }
            object = string;
            // String(bytes, fieldOffset, fieldLen, stringCharset.name())
            //         .trim();
          }
        }
        // }
        break;
      // (D)date (Date)
      case 'd':
      case 'D':
        // If the first 8 characters are '0', this is a null date
        for (var i = 0; i < 8; i++) {
          if (String.fromCharCode(bytes![fieldOffset + i]) != '0') {
            try {
              var tempString = fastParse(bytes!, fieldOffset, 4);
              final tempYear = int.parse(tempString);
              tempString = fastParse(bytes!, fieldOffset + 4, 2);
              final tempMonth = int.parse(tempString);
              tempString = fastParse(bytes!, fieldOffset + 6, 2);
              final tempDay = int.parse(tempString);
              object = DateTime.utc(tempYear, tempMonth, tempDay);
            } catch (nfe) {
              // todo: use progresslistener, this isn't a grave error.
            }
            break;
          }
        }
        break;
      // (@) Timestamp (Date)
      case '@':
        try {
          var timestampBytes = [
            // Time in millis, after reverse.
            bytes![fieldOffset + 7], bytes![fieldOffset + 6],
            bytes![fieldOffset + 5],
            bytes![fieldOffset + 4]
          ];

          var daysBytes = [
            // Days, after reverse.
            bytes![fieldOffset + 3], bytes![fieldOffset + 2],
            bytes![fieldOffset + 1],
            bytes![fieldOffset]
          ];

          var data = Uint8List.fromList(timestampBytes);
          var time = ByteConversionUtilities.getInt32(data, endian);
          data = Uint8List.fromList(daysBytes);
          var days = ByteConversionUtilities.getInt32(data, endian);

          object = DateTime.fromMillisecondsSinceEpoch(
              days * MILLISECS_PER_DAY +
                  DbaseFileHeader.MILLIS_SINCE_4713 +
                  time);
        } catch (nfe) {
          // todo: use progresslistener, this isn't a grave error.
        }
        break;
      // (N)umeric (Integer, Long or Fallthrough to Double)
      case 'n':
      case 'N':
        // numbers that begin with '*' are considered null
        if (String.fromCharCode(bytes![fieldOffset]) == '*') {
          break;
        } else {
          final string = fastParse(bytes!, fieldOffset, fieldLen).trim();
          var clazz = header!.getFieldClass(fieldNum);
          if (clazz == int) {
            try {
              object = int.parse(string);
              break;
            } catch (e) {
              // fall through to the floating point number

            }
          }
        }
        // do not break, fall through to the 'f' case
        object = handleFloat(fieldOffset, object, fieldLen);
        break;
      // (F)loating point number
      case 'f':
      case 'F':
        object = handleFloat(fieldOffset, object, fieldLen);
        break;
      default:
        throw ArgumentError('Invalid field type : $type');
    }
  }
  return object;
}