void CReb::locate(unsigned int n) { UInt32 jl = 0,jh = nopages-1,jm = (jl+jh)/2; while (jh > jl+1) { if (m_pagedetails[jm].pagestart > n) { jh = jm; } else { jl = jm; } jm = (jl+jh)/2; } unsuspend(); Page_detail rs = m_pagedetails[jl]; UInt32 val = n - rs.pagestart; if (jl != currentpage.pageno()) readindex(jl); currentpage.setoffset(page2pos(jl), jl, ((rs.flags & 8) != 0), rs.len, val); if (noparas > 0) { UInt32 jl = 0,jh = noparas-1,jm = (jl+jh)/2; while (jh > jl+1) { if (paras[jm].pos > val) { jh = jm; } else { jl = jm; } jm = (jl+jh)/2; } qDebug("TAGS:%s", (const char*)tags[paras[jl].tag]); tagstring = tags[paras[jl].tag]+"<br>"; // Add br to set extra space to 0 tagoffset = 0; } unsigned long current = locate(); if (m_currentstart > current || current > m_currentend) { start2endSection(); } if (current != n) qDebug("ERROR:Ended up at %u", current); }
/*========================================= * check_index -- Validate one index node of btree * Created: 2003/09/05, Perry Rapp *=======================================*/ static BOOLEAN check_index (BTREE btr, INDEX index, TABLE fkeytab, RKEY * lo, RKEY * hi) { INT n = nkeys(index); INT i; if (!check_keys((BLOCK)index, lo, hi)) return FALSE; for (i = 0; i <= n; i++) { INDEX newix=0; char scratch[200]; FKEY fkey = fkeys(index, i); RKEY *lox, *hix; get_index_file(scratch, btr, fkey); if (in_table(fkeytab, scratch)) { printf(_("Cycle in indexes, file %s found again!\n"), scratch); return FALSE; } else { insert_table_int(fkeytab, scratch, 1); } newix = readindex(btr, fkey, TRUE); if (!newix) { printf(_("Error loading index at key")); printf("%ld\n", i); printblock((BLOCK)index); } /* figure upper & lower bounds of what keys should be in the child */ lox = (i==0 ? lo : &rkeys(index, i)); hix = (i==n ? hi : &rkeys(index, i+1)); if (ixtype(newix) == BTINDEXTYPE) { if (!check_index(btr, newix, fkeytab, lox, hix)) return FALSE; } else { if (!check_block((BLOCK)newix, lox, hix)) return FALSE; } } /* TODO: use fkeytab */ return TRUE; }
/*============================================ * bt_openbtree -- Alloc and init BTREE structure * If it fails, it returns NULL and sets the *lldberr * dir: [IN] btree base dir * cflag: [IN] create btree if no exist? * writ: [IN] requesting write access? 1=yes, 2=requiring * immut: [I/O] user can/will not change anything including keyfile * lldberr: [OUT] error code (if returns NULL) * If this succeeds, it sets readonly & immutable flags in btree structure * as appropriate (eg, if keyfile couldn't be opened in readwrite mode) *==========================================*/ BTREE bt_openbtree (STRING dir, BOOLEAN cflag, INT writ, BOOLEAN immut, INT *lldberr) { BTREE btree; char scratch[200]; FILE *fk=NULL; struct stat sbuf; KEYFILE1 kfile1; KEYFILE2 kfile2; BOOLEAN keyed2 = FALSE; STRING dbmode; /* we only allow 150 characters in base directory name */ *lldberr = 0; if (strlen(dir) > 150) { *lldberr = BTERR_LNGDIR; goto failopenbtree; } /* See if base directory exists */ if (stat(dir, &sbuf)) { /* db directory not found */ if (!cflag || !writ || immut) { *lldberr = BTERR_NODB; goto failopenbtree; } /* create flag set, so try to create it & stat again */ sprintf(scratch, "%s/", dir); if (!mkalldirs(scratch) || stat(dir, &sbuf)) { *lldberr = BTERR_DBCREATEFAILED; goto failopenbtree; } } else if (!S_ISDIR(sbuf.st_mode)) { /* found but not directory */ *lldberr = BTERR_DBBLOCKEDBYFILE; goto failopenbtree; } /* db dir was found, or created & then found */ if (access(dir, 0)) { *lldberr = BTERR_DBACCESS; goto failopenbtree; } /* See if key file exists */ sprintf(scratch, "%s/key", dir); if (stat(scratch, &sbuf)) { /* no keyfile */ if (!cflag) { *lldberr = BTERR_NOKEY; goto failopenbtree; } /* create flag set, so try to create it & stat again */ if (!initbtree(dir, lldberr) || stat(scratch, &sbuf)) { /* initbtree actually set *lldberr, but we ignore it */ *lldberr = BTERR_DBCREATEFAILED; goto failopenbtree; } } else { if (cflag) { /* keyfile found - don't create on top of it */ *lldberr = BTERR_EXISTS; goto failopenbtree; } } if (!S_ISREG(sbuf.st_mode)) { /* keyfile is a directory! */ *lldberr = BTERR_KFILE; goto failopenbtree; } /* Open and read key file (KEYFILE1) */ immutretry: dbmode = immut ? LLREADBINARY : LLREADBINARYUPDATE; if (!(fk = fopen(scratch, dbmode))) { if (!immut && writ<2) { /* maybe it is read-only media */ immut = TRUE; goto immutretry; } *lldberr = BTERR_KFILE; goto failopenbtree; } if (fread(&kfile1, sizeof(kfile1), 1, fk) != 1) { *lldberr = BTERR_KFILE; goto failopenbtree; } /* Read & validate KEYFILE2 - if not present, we'll add it below */ /* see btree.h for explanation of KEYFILE2 */ if (fread(&kfile2, sizeof(kfile2), 1, fk) == 1) { if (!validate_keyfile2(&kfile2, lldberr)) goto failopenbtree; /* validate set *lldberr */ keyed2=TRUE; } if (writ < 2 && kfile1.k_ostat == -2) immut = TRUE; /* keyfile contains the flag for immutable access only */ /* if not immutable, handle reader/writer protection update */ if (!immut) { if (kfile1.k_ostat == -1) { *lldberr = BTERR_WRITER; goto failopenbtree; } if (kfile1.k_ostat == -2) { *lldberr = BTERR_LOCKED; goto failopenbtree; } /* Update key file for this new opening */ if (writ>0 && (kfile1.k_ostat == 0)) kfile1.k_ostat = -1; else kfile1.k_ostat++; rewind(fk); if (fwrite(&kfile1, sizeof(kfile1), 1, fk) != 1) { *lldberr = BTERR_KFILE; goto failopenbtree; } if (!keyed2) { /* add KEYFILE2 structure */ init_keyfile2(&kfile2); if (fwrite(&kfile2, sizeof(kfile2), 1, fk) != 1) { *lldberr = BTERR_KFILE; goto failopenbtree; } } if (fflush(fk) != 0) { *lldberr = BTERR_KFILE; goto failopenbtree; } } /* Create BTREE structure */ btree = (BTREE) stdalloc(sizeof *btree); bbasedir(btree) = dir; bmaster(btree) = readindex(btree, kfile1.k_mkey, TRUE); if (!(bmaster(btree))) { stdfree(btree); *lldberr = BTERR_MASTER_INDEX; goto failopenbtree; } bwrite(btree) = !immut && writ && (kfile1.k_ostat == -1); bimmut(btree) = immut; /* includes case that ostat is -2 */ bkfp(btree) = fk; btree->b_kfile.k_mkey = kfile1.k_mkey; btree->b_kfile.k_fkey = kfile1.k_fkey; btree->b_kfile.k_ostat = kfile1.k_ostat; initcache(btree, 20); return btree; failopenbtree: if (fk) fclose(fk); return NULL; }