/** * Initialize the auxiliary information for a disk block. * * <p>Return SQLITE_OK on success. If we see that the page does not contain a well-formed database * page, then return SQLITE_CORRUPT. Note that a return of SQLITE_OK does not guarantee that the * page is well-formed. It only shows that we failed to detect any corruption. */ public void initPage() throws SqlJetException { assert (pBt != null); assert (pBt.mutex.held()); assert (pgno == pDbPage.getPageNumber()); assert (this == pDbPage.getExtra()); assert (aData.getBuffer() == pDbPage.getData().getBuffer()); if (!isInit) { int pc; /* Address of a freeblock within pPage->aData[] */ byte hdr; /* Offset to beginning of page header */ int usableSize; /* Amount of usable space on each page */ int cellOffset; /* Offset from start of page to first cell pointer */ int nFree; /* Number of unused bytes on the page */ int top; /* First byte of the cell content area */ hdr = hdrOffset; decodeFlags(SqlJetUtility.getUnsignedByte(aData, hdr)); assert (pBt.pageSize >= 512 && pBt.pageSize <= 32768); maskPage = pBt.pageSize - 1; nOverflow = 0; usableSize = pBt.usableSize; this.cellOffset = cellOffset = hdr + 12 - 4 * (leaf ? 1 : 0); top = get2byte(aData, hdr + 5); nCell = get2byte(aData, hdr + 3); if (nCell > pBt.MX_CELL()) { /* To many cells for a single page. The page must be corrupt */ throw new SqlJetException(SqlJetErrorCode.CORRUPT); } int iCellFirst = cellOffset + 2 * this.nCell; /* Compute the total free space on the page */ pc = get2byte(aData, hdr + 1); nFree = SqlJetUtility.getUnsignedByte(aData, hdr + 7) + top; // - (cellOffset + 2 * nCell); while (pc > 0) { int next, size; if (pc > usableSize - 4) { /* Free block is off the page */ throw new SqlJetException(SqlJetErrorCode.CORRUPT); } next = get2byte(aData, pc); size = get2byte(aData, pc + 2); if (next > 0 && next <= pc + size + 3) { /* Free blocks must be in accending order */ throw new SqlJetException(SqlJetErrorCode.CORRUPT); } nFree += size; pc = next; } if (nFree > usableSize) { /* Free space cannot exceed total page size */ throw new SqlJetException(SqlJetErrorCode.CORRUPT); } this.nFree = (nFree - iCellFirst); isInit = true; } }