decode static method

WalBinRecord? decode(
  1. Uint8List buf,
  2. int offset
)

Implementation

static WalBinRecord? decode(Uint8List buf, int offset) {
  if (offset + headerSize > buf.length) return null;

  final bd = ByteData.sublistView(buf);

  final m = bd.getUint32(offset, Endian.little);
  if (m != magic) return null;

  final lsn       = bdGetUint64(bd, offset +  4);
  final txnId     = bdGetUint64(bd, offset + 12);
  final prevLsn   = bdGetUint64(bd, offset + 20);
  final opCode    = buf[offset + 28];
  final flags     = buf[offset + 29];
  final tableId   = bd.getUint16(offset + 30, Endian.little);
  final rowId     = bdGetUint64(bd, offset + 32);
  final beforeLen = bd.getUint32(offset + 40, Endian.little);
  final afterLen  = bd.getUint32(offset + 44, Endian.little);
  final storedCrc = bd.getUint32(offset + 48, Endian.little);

  final totalPayload = beforeLen + afterLen;
  if (offset + headerSize + totalPayload > buf.length) return null;

  final slice = buf.sublist(offset, offset + headerSize + totalPayload);
  ByteData.sublistView(slice).setUint32(48, 0, Endian.little);
  final freshCrc = _computeCrcWithPayloadAt(slice);
  if (freshCrc != storedCrc) return null;

  WalBinOp op;
  try { op = WalBinOp.fromCode(opCode); }
  catch (_) { return null; }

  Uint8List? before;
  Uint8List? after;
  Map<String, dynamic>? ddl;

  if (beforeLen > 0) {
    before = Uint8List.fromList(
        buf.sublist(offset + headerSize, offset + headerSize + beforeLen));
  }
  if (afterLen > 0) {
    final afterBytes = Uint8List.fromList(
        buf.sublist(offset + headerSize + beforeLen,
            offset + headerSize + totalPayload));
    if (op == WalBinOp.createTable || op == WalBinOp.dropTable ||
        op == WalBinOp.checkpoint) {
      try {
        ddl = Map<String, dynamic>.from(
            jsonDecode(utf8.decode(afterBytes)) as Map);
      } catch (_) {
        ddl = {};
      }
    } else {
      after = afterBytes;
    }
  }

  return WalBinRecord(
    lsn:          lsn,
    txnId:        txnId,
    prevLsn:      prevLsn,
    op:           op,
    flags:        flags,
    tableId:      tableId,
    rowId:        rowId,
    beforeImage:  before,
    afterImage:   after,
    ddlPayload:   ddl,
  );
}