readObject method
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;
}