nextRecord method

Future<Record?> nextRecord()

Fetch the next record information.

@return The record instance associated with this reader.

Implementation

Future<Record?> nextRecord() async {
  // need to update position
  var offset = await getNextOffset();
  await positionBufferForOffset(buffer, offset);
  if (currentShape != UNKNOWN) currentShape++;

  // record header is big endian
  buffer.endian = Endian.big;

  // read shape record header
  int recordNumberTmp = buffer.getInt32();
  // silly ESRI say contentLength is in 2-byte words
  // and ByteByffer uses bytes.
  // track the record location
  int recordLength = buffer.getInt32() * 2;

  if (!buffer.isReadOnly) {
    // capacity is less than required for the record
    // copy the old into the newly allocated
    if (buffer.capacity < recordLength + 8) {
      currentOffset += buffer.position;
      LByteBuffer old = buffer;
      // ensure enough capacity for one more record header
      buffer = ensureCapacity(buffer, recordLength + 8);
      buffer.put(old);
      await fill(buffer, channel);
      buffer.position = 0;
    } else
    // remaining is less than record length
    // compact the remaining data and read again,
    // allowing enough room for one more record header
    if (buffer.remaining < recordLength + 8) {
      currentOffset += buffer.position;
      buffer.compact();
      await fill(buffer, channel);
      buffer.position = 0;
    }
  }

  // shape record is all little endian
  buffer.endian = Endian.little;

  // read the type, handlers don't need it
  var typeInt = buffer.getInt32();
  ShapeType recordType = ShapeType.forID(typeInt);

  // this usually happens if the handler logic is bunk,
  // but bad files could exist as well...
  if (recordType != ShapeType.NULL && recordType != fileShapeType) {
    throw StateError(
        "ShapeType changed illegally from $fileShapeType to $recordType");
  }

  // peek at bounds, then reset for handler
  // many handler's may ignore bounds reading, but we don't want to
  // second guess them...
  buffer.mark();
  record = Record(geometryFactory!, handler!, flatGeometry);
  if (recordType.isMultiPoint()) {
    record!.minX = buffer.getDouble64();
    record!.minY = buffer.getDouble64();
    record!.maxX = buffer.getDouble64();
    record!.maxY = buffer.getDouble64();
  } else if (recordType != ShapeType.NULL) {
    record!.minX = record!.maxX = buffer.getDouble64();
    record!.minY = record!.maxY = buffer.getDouble64();
  }
  buffer.reset();

  record!.offset = recordEnd;
  // update all the record info.
  record!.length = recordLength;
  record!.type = recordType;
  recordNumber = recordNumberTmp;
  // remember, we read one int already...
  recordEnd = toFileOffset(buffer.position) + recordLength - 4;
  // mark this position for the reader
  record!.start = buffer.position;
  // clear any cached shape
  record!.shape = null;

  return record;
}