Ejemplo n.º 1
0
  /**
   * 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;
    }
  }