if (payloadSize == 0) {
return;
}
int i; /* Loop counter */
ISqlJetMemoryPointer zData; /* Part of the record being decoded */
/* For storing the record being decoded */
SqlJetVdbeMem sMem = new SqlJetVdbeMem();
ISqlJetMemoryPointer zIdx; /* Index into header */
ISqlJetMemoryPointer zEndHdr; /*
* Pointer to first byte after the
* header
*/
int[] offset = { 0 }; /* Offset into the data */
int szHdrSz; /* Size of the header size field at start of record */
int[] avail = { 0 }; /* Number of bytes of available data */
assert (aType != null);
assert (aOffset != null);
/* Figure out how many bytes are in the header */
if (isIndex) {
zData = cursor.keyFetch(avail);
} else {
zData = cursor.dataFetch(avail);
}
/*
* The following assert is true in all cases accept when* the
* database file has been corrupted externally.* assert( zRec!=0 ||
* avail>=payloadSize || avail>=9 );
*/
szHdrSz = SqlJetUtility.getVarint32(zData, offset);
/*
* The KeyFetch() or DataFetch() above are fast and will get the
* entire* record header in most cases. But they will fail to get
* the complete* record header if the record header does not fit on
* a single page* in the B-Tree. When that happens, use
* sqlite3VdbeMemFromBtree() to* acquire the complete header text.
*/
if (avail[0] < offset[0]) {
sMem.fromBtree(cursor, 0, offset[0], isIndex);
zData = sMem.z;
}
zEndHdr = SqlJetUtility.pointer(zData, offset[0]);
zIdx = SqlJetUtility.pointer(zData, szHdrSz);
/*
* Scan the header and use it to fill in the aType[] and aOffset[]*
* arrays. aType[i] will contain the type integer for the i-th*
* column and aOffset[i] will contain the offset from the beginning*
* of the record to the start of the data for the i-th column
*/
fieldsCount = 0;
for (i = 0; i < ISqlJetLimits.SQLJET_MAX_COLUMN && zIdx.getPointer() < zEndHdr.getPointer()
&& offset[0] <= payloadSize; i++, fieldsCount++) {
aOffset.add(i, offset[0]);
int[] a = { 0 };
SqlJetUtility.movePtr(zIdx, SqlJetUtility.getVarint32(zIdx, a));
aType.add(i, a[0]);
offset[0] += SqlJetVdbeSerialType.serialTypeLen(a[0]);
fields.add(i, getField(i));
}
sMem.release();
sMem.flags = SqlJetUtility.of(SqlJetVdbeMemFlags.Null);
/*
* If we have read more header data than was contained in the
* header,* or if the end of the last field appears to be past the
* end of the* record, or if the end of the last field appears to be
* before the end* of the record (when all fields present), then we
* must be dealing* with a corrupt database.
*/
if (zIdx.getPointer() > zEndHdr.getPointer() || offset[0] > payloadSize
|| (zIdx.getPointer() == zEndHdr.getPointer() && offset[0] != payloadSize)) {
throw new SqlJetException(SqlJetErrorCode.CORRUPT);
}
} finally {
cursor.leaveCursor();