dslinux/user/pixil/pixilDT/NxDb Makefile NxDb.dsp NxDb.dsw blkio.c db.c index.c nxdb.cxx use.c
amadeus
dslinux_amadeus at user.in-berlin.de
Tue Oct 3 13:26:49 CEST 2006
Update of /cvsroot/dslinux/dslinux/user/pixil/pixilDT/NxDb
In directory antilope:/tmp/cvs-serv11916/pixilDT/NxDb
Added Files:
Makefile NxDb.dsp NxDb.dsw blkio.c db.c index.c nxdb.cxx use.c
Log Message:
adding pristine copy of pixil to HEAD so I can branch from it
--- NEW FILE: NxDb.dsw ---
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "NxDb"=.\NxDb.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
--- NEW FILE: use.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <stdio.h>
#include <string.h>
#include "file.h"
#include "VCMemoryLeak.h"
/*
* use.c - common database record get/put routines
*
* from 8/6/85 mt15b
*/
/* local data*/
static struct usefile usefile[NUSEFILES];
static struct field *p;
static char *cp;
/* local procs*/
static void chguse(int fileno);
static void chkuse(int fileno);
static void setpcp(int var);
int
get16(char *addr)
{
return ((unsigned char) addr[0]) | (((int) (unsigned char) addr[1]) << 8);
}
void
put16(char *addr, unsigned short val16)
{
*addr++ = val16;
*addr = val16 >> 8;
}
long
get32(char *addr)
{
return ((unsigned char) addr[0]) |
(((long) (unsigned char) addr[1]) << 8) |
(((long) (unsigned char) addr[2]) << 16) |
(((long) (unsigned char) addr[3]) << 24);
}
void
put32(char *addr, long val32)
{
*addr++ = val32;
*addr++ = val32 >> 8;
*addr++ = val32 >> 16;
*addr = val32 >> 24;
}
void
use(int fileno, struct fildes *fp, struct ndxfile *nfp)
{
chguse(fileno);
usefile[fileno].fp = fp;
if (fp != NULL) {
fp->ndxfp = nfp;
}
usefile[fileno].recno = -1;
}
static void
chguse(int fileno)
{
if (usefile[fileno].uchanged) {
putrec(usefile[fileno].recno, usefile[fileno].fp,
usefile[fileno].rbuf);
usefile[fileno].uchanged = 0;
}
}
static void
chkuse(int fileno)
{
struct fildes *fp;
if (fileno < 0 || fileno > NUSEFILES)
fatal(5); /* chkuse: bad fileno */
fp = usefile[fileno].fp;
if (fp->currec != usefile[fileno].recno) {
chguse(fileno);
getrec(fp->currec, fp, usefile[fileno].rbuf);
usefile[fileno].recno = fp->currec;
}
}
/*
* return value of file variable
* on entry, hi byte of var is fileno, lo byte is fieldno
*/
char *
val(int var)
{
register int len;
static char varbuf[65]; /* max var len is 64! */
setpcp(var);
if ((len = p->size) > 64)
len = 64;
fcopy(cp, varbuf, len);
return (varbuf);
}
short
ival(int var)
{
setpcp(var);
return (get16(cp));
}
long
lval(int var)
{
setpcp(var);
return (get32(cp));
}
void
replace(int var, union w newval)
{
setpcp(var);
switch (p->type) {
case 'c':
memcpy(cp, newval.ptr, p->size);
break;
case 'd':
case 'i':
put16(cp, newval.word);
break;
case 'l':
put32(cp, newval.lword);
break;
}
usefile[var >> 8].uchanged = 1;
}
int
find(int fileno, char *key)
{
struct fildes *fp;
fp = usefile[fileno].fp;
return (fp->currec = search(key, fp->ndxfp, 0));
}
void
store(void *dst, int var)
{
setpcp(var);
switch (p->type) {
case 'c':
fcopy(cp, (char *) dst, p->size);
break;
case 'd':
case 'i':
put16((char *) dst, get16(cp));
break;
case 'l':
put32((char *) dst, get32(cp));
break;
}
}
static void
setpcp(int var)
{
register int fileno, fieldno;
fileno = var >> 8;
fieldno = var & 0xff;
chkuse(fileno);
p = &usefile[fileno].fp->fieldp[fieldno];
cp = &usefile[fileno].rbuf[p->offset];
}
/*
* delete current record in usefile
*/
void
udelrec(int fileno)
{
chkuse(fileno);
usefile[fileno].rbuf[0] = '*';
usefile[fileno].uchanged = 1;
}
/*
* copy a string field replacing nulls with blanks
*/
char *
fcopy(char *src, char *dst, int len)
{
#if 0
while (len--)
if (*src)
*dst++ = *src++;
else {
*dst++ = ' ';
src++;
}
*dst++ = 0; /* null terminate */
return (dst);
#else
while (len--)
*dst++ = *src++;
*dst++ = 0;
return (dst);
#endif
}
--- NEW FILE: index.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <stdio.h>
#include "file.h"
#include "VCMemoryLeak.h"
/*
* index.c - B* tree index file access routines
*
* from 11/18/85 mt15b by greg haerr
*/
#define RECNOSIZE sizeof(short) /* sizeof record number */
/* leaf & ptr block struct*/
#define PAGETYPE(p) (p->buf[ 0]) /* Leaf or Ptr, != 0 is ptr */
#define NKEYS(p) (get16(&p->buf[ 1])) /* # keys this page */
#define setNKEYS(p,v) (put16(&p->buf[ 1],v)) /* # keys this page */
/* ptr block struct*/
#define BLK0(p) (get16(&p->buf[ 3])) /* blk 0 ptr */
#define setBLK0(p,v) (put16(&p->buf[ 3],v)) /* blk 0 ptr */
#define PKEY1(p) (&p->buf[ 5]) /* address of first key, pblk */
#define BLKNO(p) (get16(&p[ gkeylen])) /* address of next block at p */
#define setBLKNO(p,v) (put16(&p[ gkeylen],v)) /* address of next block at p */
/* leaf block struct*/
#define FPTR(p) (get16(&p->buf[ 3])) /* forward block ptr */
#define setFPTR(p,v) (put16(&p->buf[ 3],v)) /* forward block ptr */
#define BPTR(p) (get16(&p->buf[ 5])) /* backward block ptr */
#define setBPTR(p,v) (put16(&p->buf[ 5],v)) /* backward block ptr */
#define LKEY1(p) (&p->buf[ 7]) /* address of first key, lblk */
#define RECNO(p) (get16(&p[ gkeylen])) /* address of recno at p */
#define setRECNO(p,v) (put16(&p[ gkeylen],v)) /* address of recno at p */
#define KEY1OFF 7 /* offset of key #1 in buf */
#define moveleft(s,d,c) memcpy(d,s,c)
#define F_INT 02 /* char/integer index */
#define F_MULT 04 /* unique/multiple keys */
struct passup
{ /* key pass-up structure */
char key[11]; /* key, max len = 10 */
short pblkno; /* block # */
};
/* local data*/
static char gkeylen; /* global key length */
static char *gkey; /* global key ptr */
static char gkeytyp; /* key type, 0=char, 1=integer */
static struct ndxfile *gfp; /* global index file */
static int gmode; /* global mode, 0 = search only */
static int grec; /* global rec# */
/* local procs*/
static int isrch(int blkno, struct passup *v);
static int dsrch(int blk, struct passup *v);
static void keycopy(char *src, char *dst);
static int keycomp(char *key);
static void moveright(char *asrc, char *adst, int cnt);
static int ierr(int n);
/*
* search for key in index file fp, if mode != 0, insert as record #mode if
* not found
*/
int
search(char *key, struct ndxfile *fp, int mode)
{
register struct buffer *bp;
register struct buffer *nbp;
register char *p;
register int n;
struct passup v;
short kbuf;
gfp = fp;
gmode = mode;
gkeylen = gfp->keylen;
if ((gkeytyp = (gfp->ftype & F_INT)) != 0) {
gkey = (char *) &kbuf;
put16((char *) &kbuf, (int) key);
} else
gkey = key;
n = isrch(0, &v);
if (gmode == 0) /* search only */
return (n);
if (n) { /* allocate new root node */
//fprintf(stderr, "search: root passup key=%9s, blkno=%d\n", v.key, v.pblkno);
if ((nbp = lockb(newblk((struct fildes *) gfp))) == NULL)
return (ierr(0)); /* isrch: new root bp fail */
if ((bp = getblk(0, (struct fildes *) gfp)) == NULL) {
unlock(nbp);
return (ierr(1)); /* search: bp getblk fail */
}
memcpy(nbp->buf, bp->buf, BLKSIZ); /* copy block 0 */
PAGETYPE(bp) = 'P';
setNKEYS(bp, 1);
setBLK0(bp, nbp->blkno);
p = PKEY1(bp);
keycopy(v.key, p);
setBLKNO(p, v.pblkno);
bp->changed = 1;
if (n = FPTR(nbp)) {
bp = getblk(n, (struct fildes *) gfp);
setBPTR(bp, nbp->blkno);
bp->changed = 1;
}
if (n = BPTR(nbp)) {
bp = getblk(n, (struct fildes *) gfp);
setFPTR(bp, nbp->blkno);
bp->changed = 1;
}
unlock(nbp);
}
return (gmode);
}
/*
* recursive B* tree search (two level only for now)
*/
static int
isrch(int blkno, struct passup *v)
{
register struct buffer *bp, *nbp;
char *p, *ap;
int n, r;
struct passup u;
again:
if ((bp = getblk(blkno, (struct fildes *) gfp)) == NULL)
return (ierr(2)); /* isrch: bp getblk fail */
n = NKEYS(bp);
#ifdef UNIV
if ((gfp == &FAndx2 || gfp == &FAndx3) && n == RECMAX - 5 && gmode) {
printf("\007***Warning: 5 activities left, space to continue");
chrin();
}
if ((gfp == &FAndx2 || gfp == &FAndx3) && n > RECMAX)
return (fatal(8));
#endif
if (PAGETYPE(bp) == 0) { /* leaf node */
p = LKEY1(bp);
while (n > 0 && keycomp(p) < 0) {
p += gkeylen + 2;
n--;
}
if (gmode == 0) { /* search only */
if ((gfp->ftype & F_MULT) && n <= 0) /* mult keys */
if ((blkno = FPTR(bp)) != 0) {
/*dprintf( "isrch: mult next blk"); */
goto again;
}
if (n <= 0 || keycomp(p) != 0)
return (0);
else {
gfp->curblk = bp->blkno;
gfp->curoff = NKEYS(bp) - n + 1;
return (RECNO(p));
}
}
if (gfp->maxkeys > NKEYS(bp)) { /* insert, no split needed */
while (n > 0 && keycomp(p) == 0) {
p += gkeylen + 2;
n--;
}
if (n != 0)
moveright(p, p + gkeylen + 2, n * (gkeylen + 2));
keycopy(gkey, p);
setRECNO(p, gmode); /* gmode = recno */
setNKEYS(bp, NKEYS(bp) + 1);
bp->changed = 1;
return (0); /* no passup */
} else { /* insert, split leaf */
/*dprintf( "isrch: lnode split\n"); */
lockb(bp);
if ((nbp = lockb(newblk((struct fildes *) gfp))) == NULL) {
unlock(bp);
return (ierr(3)); /* isrch: nbp getblk fail */
}
r = (gfp->maxkeys + 1) / 2;
/* copy right page to new block */
memcpy(LKEY1(nbp),
LKEY1(bp) + (gkeylen + 2) * (gfp->maxkeys / 2),
(gkeylen + 2) * (gfp->maxkeys - (gfp->maxkeys / 2)));
setNKEYS(nbp, r);
setNKEYS(bp, r);
bp->changed = 1;
if (n >= r) { /* insert left page */
n -= r;
setNKEYS(bp, NKEYS(bp) + 1);
} else { /* insert right page */
p = LKEY1(nbp) + (p - LKEY1(bp)) -
(gkeylen + 2) * (gfp->maxkeys / 2);
setNKEYS(nbp, NKEYS(nbp) + 1);
}
if (n != 0)
moveright(p, p + gkeylen + 2, n * (gkeylen + 2));
keycopy(gkey, p);
setRECNO(p, gmode);
setFPTR(nbp, n = FPTR(bp));
setFPTR(bp, nbp->blkno);
setBPTR(nbp, bp->blkno);
unlock(bp);
if (n != 0) {
if ((bp = getblk(n, (struct fildes *) gfp)) == NULL) {
unlock(nbp);
return (ierr(4)); /* isrch: bptr getblk fail */
}
setBPTR(bp, nbp->blkno);
bp->changed = 1;
}
keycopy(LKEY1(nbp), v->key);
v->pblkno = nbp->blkno;
unlock(nbp);
return (1); /* passup */
}
} else { /* ptr node */
ap = p = PKEY1(bp);
if (gfp->ftype & F_MULT) /* multiple keys */
for (r = 0; r < n; r++) {
if (keycomp(ap) >= 0)
break;
p = ap;
ap += gkeylen + 2;
} else /* unique keys */
for (r = 0; r < n; r++) {
if (keycomp(ap) > 0)
break;
p = ap;
ap += gkeylen + 2;
}
if (r == 0)
n = BLK0(bp);
else
n = BLKNO(p);
/*dprintf( "psrch %d\n", n); */
lockb(bp);
n = isrch(n, &u);
unlock(bp);
if (gmode == 0)
return (n);
if (n) { /* passup */
/*dprintf( "isrch: passup key=%9s, blkno=%d\n", u.key, u.pblkno); */
n = NKEYS(bp);
if (n >= gfp->maxkeys)
return (ierr(5)); /* isrch: pnode overflow */
if (r < n)
moveright(ap, ap + gkeylen + 2, (n - r) * (gkeylen + 2));
keycopy(u.key, ap);
setBLKNO(ap, u.pblkno);
setNKEYS(bp, NKEYS(bp) + 1);
bp->changed = 1;
}
return (0);
}
}
/*
* delete key with record # rec from index file fp
*/
int
Delete(char *key, int rec, struct ndxfile *fp)
{
struct passup v;
short kbuf;
grec = rec;
gfp = fp;
gkeylen = gfp->keylen;
if ((gkeytyp = (gfp->ftype & F_INT)) != 0) {
gkey = (char *) &kbuf;
put16((char *) &kbuf, (int) key);
} else
gkey = key;
gfp->curblk = -1;
dsrch(0, &v);
return (grec);
}
/*
* recursive B* tree delete
*/
static int
dsrch(int blk, struct passup *v)
{
register struct buffer *bp, *nbp;
char *p, *ap;
int n, r;
struct passup u;
again:
if ((bp = getblk(blk, (struct fildes *) gfp)) == NULL)
return (0);
n = NKEYS(bp);
if (PAGETYPE(bp) == 0) { /* root node is leaf node */
p = LKEY1(bp);
while (n > 0 && RECNO(p) != grec) {
if (keycomp(p) > 0)
break;
p += gkeylen + 2;
n--;
}
if ((gfp->ftype & F_MULT) && n <= 0) /* mult keys */
if ((blk = FPTR(bp)) != 0) {
/*dprintf( "dsrch: mult nxt blk"); */
goto again;
}
if (n <= 0 || keycomp(p) != 0 || RECNO(p) != grec) {
grec = 0;
return (ierr(6)); /* dsrch: key not found */
}
if (n > 1)
moveleft(p + gkeylen + 2, p, (n - 1) * (gkeylen + 2));
setNKEYS(bp, NKEYS(bp) - 1);
bp->changed = 1;
if ((NKEYS(bp) > gfp->maxkeys / 2) || (blk == 0))
return (0); /* aok */
lockb(bp);
if ((r = FPTR(bp)) != 0) { /* fwd blk not empty */
if ((nbp = getblk(r, (struct fildes *) gfp)) == NULL) {
unlock(bp);
return (ierr(7)); /* dsrch: nbp getblk fail */
}
p = LKEY1(bp) + (NKEYS(bp) * (gkeylen + 2));
ap = LKEY1(nbp);
if (NKEYS(nbp) > gfp->maxkeys / 2) { /* annect 1 */
/*dprintf( "dsrch: annect 1\n"); */
memcpy(p, ap, gkeylen + 2); /* copy key */
setNKEYS(bp, NKEYS(bp) + 1);
moveleft(ap + gkeylen + 2, ap,
(NKEYS(nbp) - 1) * (gkeylen + 2));
setNKEYS(nbp, NKEYS(nbp) - 1);
nbp->changed = 1;
keycopy(ap, v->key);
v->pblkno = nbp->blkno;
unlock(bp);
return (1); /* change key in ptr blk */
}
/*dprintf( "dsrch: annect all\n"); */
v->pblkno = nbp->blkno; /* save blk # to delete */
memcpy(p, ap, NKEYS(nbp) * (gkeylen + 2)); /* annect all */
setNKEYS(bp, NKEYS(bp) + NKEYS(nbp));
setFPTR(bp, r = FPTR(nbp)); /* relink fwd ptr */
unlock(bp);
if (r != 0) {
n = bp->blkno;
if ((bp = getblk(r, (struct fildes *) gfp)) == NULL) {
ierr(21); /* dsrch: nbp fptr fail */
return (2);
}
setBPTR(bp, n);
bp->changed = 1;
}
return (2); /* delete blk # in ptr blk */
}
if (NKEYS(bp) == 0) { /* fptr null, no keys */
/*dprintf( "dsrch: fptr null, no keys\n"); */
v->pblkno = bp->blkno;
r = BPTR(bp); /* set bwd ptr to NULL */
unlock(bp);
if (r != 0) {
if ((bp = getblk(r, (struct fildes *) gfp)) == NULL) {
ierr(22); /* dsrch: nbp bptr fail */
return (2);
}
setFPTR(bp, 0);
bp->changed = 1;
}
return (2);
}
unlock(bp);
return (0); /* aok */
} else { /* ptr node */
ap = p = PKEY1(bp);
if (gfp->ftype & F_MULT) /* mult keys */
for (r = 0; r < n; r++) {
if (keycomp(ap) >= 0)
break;
p = ap;
ap += gkeylen + 2;
} else /* unique keys */
for (r = 0; r < n; r++) {
if (keycomp(ap) > 0)
break;
p = ap;
ap += gkeylen + 2;
}
if (r == 0)
n = BLK0(bp);
else
n = BLKNO(p);
lockb(bp);
/*dprintf( "dsrch %d\n", n); */
n = dsrch(n, &u);
switch (n) {
case 2: /* delete passup blk # from ptr blk */
/*dprintf( "dsrch: delete blk #%d\n", u.pblkno); */
if (NKEYS(bp) == 1) { /* ptr back to leaf node */
if (u.pblkno == BLK0(bp)) {
p = PKEY1(bp);
blk = BLKNO(p);
} else
blk = BLK0(bp);
if ((nbp = getblk(blk, (struct fildes *) gfp)) == NULL) {
unlock(bp);
return (ierr(8)); /* dsrch: nbp leaf fail */
}
memcpy(bp->buf, nbp->buf, BLKSIZ);
setFPTR(bp, 0);
setBPTR(bp, 0);
bp->changed = 1;
unlock(bp);
return (0); // was ;
}
p = PKEY1(bp);
n = NKEYS(bp);
if (u.pblkno == BLK0(bp)) {
setBLK0(bp, BLKNO(p));
r = 0;
} else {
for (r = 0; r < n; r++) {
if (u.pblkno == BLKNO(p))
break;
p += gkeylen + 2;
}
if (r >= n) {
unlock(bp);
return (ierr(9)); /* dsrch: blk find fail */
}
}
if (n - r - 1 > 0)
moveleft(p + gkeylen + 2, p, (n - r - 1) * (gkeylen + 2));
setNKEYS(bp, NKEYS(bp) - 1);
bp->changed = 1;
unlock(bp);
return (0); // was ;
case 1: /* change passup blk #'s key */
n = NKEYS(bp);
p = PKEY1(bp);
/*dprintf( "dsrch: change blk #%d key to %9s\n", u.pblkno, u.key); */
for (r = 0; r < n; r++) {
if (u.pblkno == BLKNO(p)) {
keycopy(u.key, p);
bp->changed = 1;
unlock(bp);
return (0); // was ;
}
p += gkeylen + 2;
}
unlock(bp);
return (ierr(10));
}
unlock(bp);
}
}
int
next(struct fildes *fp)
{
register struct ndxfile *nfp;
register struct buffer *bp;
register int blk;
register int n;
char rbuf[MAXRECSIZ];
//fprintf(stderr, "next(fp)\n");
fp->eof = 0;
if (!fp->ndxfp) {
//fprintf(stderr, "\t!fp->ndxfp()\n");
do {
if (++fp->currec > fp->nrecs) {
fp->currec = fp->nrecs;
fp->eof = 1;
return (0);
}
getrec(fp->currec, fp, rbuf);
} while (rbuf[0] == '*');
//fprintf(stderr, "\treturn fp->currec\n");
return (fp->currec);
}
nfp = fp->ndxfp;
gfp = nfp;
if ((blk = nfp->curblk) == -1) {
//fp->eof = 1;
return (ierr(12)); /* next: no currency */
}
nxtblk:
if ((bp = getblk(blk, (struct fildes *) nfp)) == NULL)
return (ierr(11)); /* next: bp getblk fail */
#ifdef UNIV
n = NKEYS(bp);
if ((gfp == &FAndx2 || gfp == &FAndx3) && n > RECMAX)
return (fatal(8));
#endif
if (++(nfp->curoff) > NKEYS(bp)) {
if ((blk = FPTR(bp)) != 0) {
nfp->curblk = blk;
nfp->curoff = 0;
goto nxtblk;
}
nfp->curoff = NKEYS(bp);
fp->eof = 1;
return (0);
}
n = (nfp->keylen + 2) * (nfp->curoff - 1) + nfp->keylen + KEY1OFF;
fp->currec = get16(&bp->buf[n]);
if (fp->currec > fp->nrecs || fp->currec <= 0)
return (ierr(13)); /* next: invalid currec */
return (fp->currec);
}
int
prev(struct fildes *fp)
{
register struct ndxfile *nfp;
register struct buffer *bp;
register int blk;
register int n;
char rbuf[MAXRECSIZ];
fp->eof = 0;
if (!fp->ndxfp) {
do {
if (--fp->currec <= 0) {
fp->currec = 1;
fp->eof = 1;
return (0);
}
getrec(fp->currec, fp, rbuf);
} while (rbuf[0] == '*');
return (fp->currec);
}
nfp = fp->ndxfp;
gfp = nfp;
if ((blk = nfp->curblk) == -1)
return (ierr(14)); /* prev: no currency */
if ((bp = getblk(blk, (struct fildes *) nfp)) == NULL)
return (ierr(15)); /* prev: bp getblk fail */
if (--(nfp->curoff) <= 0) {
if ((blk = BPTR(bp)) != 0) {
if ((bp = getblk(blk, (struct fildes *) nfp)) == NULL)
return (ierr(16)); /* prev: bptr getblk fail */
nfp->curblk = blk;
nfp->curoff = NKEYS(bp);
goto ok;
}
nfp->curoff = 1;
fp->eof = 1;
return (0);
}
ok:
n = (nfp->keylen + 2) * (nfp->curoff - 1) + nfp->keylen + KEY1OFF;
fp->currec = get16(&bp->buf[n]);
return (fp->currec);
}
int
gotop(struct fildes *fp)
{
register struct ndxfile *nfp;
register struct buffer *bp;
fp->eof = 0;
if (!fp->ndxfp) {
fp->currec = 0;
return (next(fp));
}
nfp = fp->ndxfp;
gfp = nfp;
if ((bp = getblk(0, (struct fildes *) nfp)) == NULL)
return (ierr(17)); /* gotop: bp getblk fail */
if (PAGETYPE(bp) != 0)
if ((bp = getblk(BLK0(bp), (struct fildes *) nfp)) == NULL)
return (ierr(18)); /* gotop: blk0 getblk fail */
nfp->curblk = bp->blkno;
if (NKEYS(bp) == 0) {
nfp->curoff = 0;
fp->eof = 1;
return (0);
}
nfp->curoff = 1;
return (fp->currec = get16(&bp->buf[nfp->keylen + KEY1OFF]));
}
int
gobot(struct fildes *fp)
{
register struct ndxfile *nfp;
register struct buffer *bp;
register char *p;
register int n;
fp->eof = 0;
if (!fp->ndxfp) {
fp->currec = fp->nrecs + 1;
return (prev(fp));
}
nfp = fp->ndxfp;
gfp = nfp;
if ((bp = getblk(0, (struct fildes *) nfp)) == NULL)
return (ierr(19)); /* gobot: bp getblk fail */
gkeylen = nfp->keylen;
if (PAGETYPE(bp) != 0) {
p = PKEY1(bp) + ((NKEYS(bp) - 1) * (gkeylen + 2));
if ((bp = getblk(BLKNO(p), (struct fildes *) nfp)) == NULL)
return (ierr(20)); /* gobot: blkno getblk fail */
}
nfp->curblk = bp->blkno;
if (NKEYS(bp) == 0) {
nfp->curoff = 0;
fp->eof = 1;
return (0);
}
nfp->curoff = NKEYS(bp);
n = (nfp->keylen + 2) * (nfp->curoff - 1) + nfp->keylen + KEY1OFF;
return (fp->currec = get16(&bp->buf[n]));
}
int
gotorec(struct fildes *fp, int rec)
{
fp->eof = 0;
if (fp->nrecs == 0 || rec == 0) {
fp->currec = 0;
fp->eof = 1;
} else {
fp->currec = rec - 1;
next(fp);
}
return (fp->currec);
}
static void
keycopy(char *src, char *dst)
{
register int n;
if (gkeytyp)
put16(dst, (int) get16(src));
else {
n = gkeylen;
while (n--)
*dst++ = *src++;
}
}
static int
keycomp(char *key)
{
register int n;
register char *p;
if (gkeytyp)
return (get16(key) - get16(gkey));
n = gkeylen;
p = gkey;
while (--n >= 0 && *p++ == *key++)
continue;
return (n < 0 ? 0 : *--key - *--p);
}
static void
moveright(char *asrc, char *adst, int cnt)
{
register char *src, *dst;
src = asrc + cnt;
dst = adst + cnt;
while (cnt--)
*--dst = *--src;
}
static int
ierr(int n)
{
printf("\007*** Index Error #%d, file=%s, ", n, gfp->filext);
if (gkeytyp)
printf("key=%d", get16(gkey));
else
printf("key=%9s", gkey);
printf("\n");
return (0);
}
--- NEW FILE: nxdb.cxx ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "nxdb.h"
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
#include <stdlib.h>
#endif
#ifdef WIN32
#include <iostream>
#include <direct.h>
#include "../getopt/getopt.h"
#include "VCMemoryLeak.h"
#endif
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>
#ifndef WIN32
#include <unistd.h>
#endif
#define OPTIONS "p:k:d:m:"
char *p_arg = 0;
NxDb::NxDb(int argc, char *argv[])
{
int c;
path = ".";
while ((c = getopt(argc, argv, OPTIONS)) != -1) {
switch (c) {
case 'p':
path = optarg;
/*
p_arg = optarg;
struct stat dir;
if ( stat(p_arg, &dir) == 0) {
path = p_arg;
}
*/
break;
default:
break;
} // switch
} // while
dbNum = 0;
dbinit(0);
}
int
NxDb::Open(string _dbName, fildes * _dbDesc,
field * _dbField, int var, int path_flag)
{
Register(_dbName, _dbDesc, _dbField, var);
// Open Database
string path_dbName;
if (path_flag)
path_dbName = _dbName;
else {
int len = path.length() - 1;
if (path[len] != '/' && _dbName[0] != '/')
path += '/';
path_dbName = path + _dbName;
}
struct stat dir;
if (0 != stat(path.c_str(), &dir)) {
#ifndef WIN32
mkdir(path.c_str(), S_IRWXU);
#else /*
*/
_mkdir(path.c_str());
#endif
}
if (!dbopen(_dbDesc, (char *) path_dbName.c_str())) {
fprintf(stderr, "(1) Unable to open:[%s.%s]\n", path_dbName.c_str(),
_dbDesc->filext);
return 0;
} else {
fprintf(stderr, "Open DB: [%s] fp: %d\n", path_dbName.c_str(),
_dbDesc->fildesc);
}
return 1;
}
int
NxDb::Close(string _dbName)
{
int dbNumber = db[_dbName];
fildes *_dbDesc = dbDesc[dbNumber];
dbclose(_dbDesc);
#ifdef WIN32
return (0);
#endif
}
void
NxDb::Register(string _dbName, fildes * _dbDesc, field * _dbField, int var)
{
TDatabase::iterator p = db.find(_dbName);
if (p == db.end()) {
db.insert(TValue(_dbName, dbNum));
dbNum++;
}
TDatabase::iterator result = db.find(_dbName);
if (result == db.end()) {
exit(-1);
} else {
int dbNumber = db[_dbName];
dbDesc[dbNumber] = _dbDesc;
dbField[dbNumber] = _dbField;
}
}
int
NxDb::Create(string _dbName, fildes * _dbDesc, field * _dbField, int var,
int path_flag)
{
string path_dbName;
if (path_flag)
path_dbName = _dbName;
else
path_dbName = path + _dbName;
if (!dbcreat(_dbDesc, (char *) path_dbName.c_str())) {
cerr << "NxDb::Could not create: " << path_dbName << _dbDesc->
filext << endl;
exit(-1);
}
Register(_dbName, _dbDesc, _dbField, var);
// use(0, NULL, NULL);
Close(_dbName);
return 1;
}
int
NxDb::SetFlags(const string _dbName, const int &recno, const int &flags)
{
#ifdef DEBUG
//assert(db.find(_dbName) != db.end());
#endif /* */
char buf[MAXRECSIZ];
int dbNumber = db[_dbName];
struct fildes *fp = dbDesc[dbNumber];
int ok = getrec(recno, fp, &buf[0]);
if (ok)
fp->flags = flags;
else
return -1;
ok = putrec(recno, fp, &buf[0]);
dbsave(fp);
if (ok)
return 0;
else
return -2;
}
int
NxDb::GetFlags(const string _dbName, const int &recno, int &flags)
{
#ifdef DEBUG
//assert(db.find(_dbName) != db.end());
#endif /* */
char buf[MAXRECSIZ];
int dbNumber = db[_dbName];
struct fildes *fp = dbDesc[dbNumber];
int ok = getrec(recno, fp, &buf[0]);
//if (ok)
flags = fp->flags;
//cout << "GetFlags(): fp->flags = " << fp->flags << endl;
//else
// return -1;
return ok;
}
void
NxDb::Insert(string _dbName, char *record)
{
cerr << "Insert\n";
int dbNumber = db[_dbName];
fildes *fp = dbDesc[dbNumber];
int recno = APPEND;
char ret_buf[MAXRECSIZ];
for (int i = 1; i <= fp->nrecs; i++) {
getrec(i, fp, ret_buf);
if (recerased(fp)) {
break;
}
}
fp->flags = NEW;
putrec(recno, fp, record);
//cout << "Insert(): recno = " << fp->currec << endl;
dbsave(fp);
}
void
NxDb::Insert(string _dbName, char *record, int &rec)
{
#ifdef DEBUG
//assert(db.find(_dbName) != db.end());
#endif /* */
int dbNumber = db[_dbName];
fildes *fp = dbDesc[dbNumber];
int recno = APPEND;
char ret_buf[MAXRECSIZ];
// look for an empty spot
for (int i = 1; i <= fp->nrecs; i++) {
getrec(i, fp, ret_buf);
if (recerased(fp)) {
break;
}
}
fp->flags = NEW;
putrec(recno, fp, record);
//cout << "fp->currec = " << fp->currec << endl;
rec = fp->currec;
dbsave(fp);
}
void
NxDb::Edit(string _dbName, int recno, char *record)
{
cerr << "Edit." << endl;
int dbNumber = db[_dbName];
fildes *fp = dbDesc[dbNumber];
// If record has NEW bit set, keep the new bit
// or else set the bit to changed
if (!(fp->flags & NEW))
fp->flags = CHANGED;
//cout << "Edit() recno = " << recno << endl;
putrec(recno, fp, record);
dbsave(fp);
}
void
NxDb::DeleteRec(string _dbName, int recno)
{
int dbNumber = db[_dbName];
fildes *fp = dbDesc[dbNumber];
char ret_buf[MAXRECSIZ];
getrec(recno, fp, ret_buf);
// If a NEW occurs and then is immediately
// delete, it would send the deleted record
// across during a sync, which the other side
// would not know about. Therefore, ERASE instead
// of DELETED.
//////////////////////////////////////////////////
if (fp->flags & NxDb::NEW)
fp->flags = NxDb::ERASED;
else
fp->flags = NxDb::DELETED;
//cout << "DeleteRec(): fp->flags = " << fp->flags << endl;
putrec(recno, fp, ret_buf);
//fp->flags = 0;
dbsave(fp);
}
void
NxDb::EraseRec(string _dbName, int recno)
{
#ifdef DEBUG
//assert(db.find(_dbName) != db.end());
#endif /* */
int dbNumber = db[_dbName];
fildes *fp = dbDesc[dbNumber];
char ret_buf[MAXRECSIZ];
getrec(recno, fp, ret_buf);
fp->flags = NxDb::ERASED;
putrec(recno, fp, ret_buf);
fp->flags = 0;
dbsave(fp);
}
int
NxDb::NumRecs(string _dbName)
{
int dbNumber = db[_dbName];
struct fildes *fp = dbDesc[dbNumber];
return fp->nrecs;
}
int
NxDb::Select(string _dbName, int ret[], int ret_size, bool bDeleteFlag,
int flags)
{
int dbNumber = db[_dbName];
struct fildes *fp = dbDesc[dbNumber];
char ret_buf[MAXRECSIZ];
int idx = 0;
for (int i = 1; i <= fp->nrecs; i++) {
getrec(i, fp, ret_buf);
if (flags != -1) {
//cout << "fp->flags = " << fp->flags << endl;
//cout << "flags = " << flags << endl;
if (!(fp->flags & flags))
continue;
} else {
if (fp->flags & NxDb::ERASED || // Skip erase records
(fp->flags & NxDb::DELETED && !bDeleteFlag)) { // Skip logically deleted records if bDeleteFlag not set
continue;
}
}
ret[idx] = i;
idx++;
}
return idx;
}
int
NxDb::Select(string _dbName, char *value, int fieldNo, int ret[],
int ret_size, bool bDeleteFlag)
{
int dbNumber = db[_dbName];
struct fildes *fp = dbDesc[dbNumber];
field *_dbField = dbField[dbNumber];
char ret_buf[MAXRECSIZ];
int idx = 0;
char type;
type = _dbField[fieldNo].type;
for (int i = 1; i <= fp->nrecs; i++) {
if (idx == ret_size) {
return idx;
}
memset(ret_buf, 0, MAXRECSIZ);
getrec(i, fp, ret_buf);
//cout << "\tSelect(): recno = " << i << endl;
if (recdeleted(fp) && !bDeleteFlag) {
//cout << "recdeleted()\n";
continue;
}
if (type == 'c') {
if (strcmp(value, &ret_buf[_dbField[fieldNo].offset]) == 0) {
ret[idx] = i;
idx++;
}
} else if ((type == 'd') || (type == 'i')) {
int num = get16(&ret_buf[_dbField[fieldNo].offset]);
if (num == atoi(value)) {
ret[idx] = i;
idx++;
}
} else if (type == 'l') {
long num = get32(&ret_buf[_dbField[fieldNo].offset]);
if (num == strtol(value, NULL, 10)) {
ret[idx] = i;
idx++;
}
} else {
return idx;
}
}
return idx;
}
int
NxDb::Extract(string _dbName, int recno, char *ret_buf)
{
int dbNumber = db[_dbName];
struct fildes *fp = dbDesc[dbNumber];
return getrec(recno, fp, ret_buf);
}
int
NxDb::Extract(string _dbName, int recno, int fieldNo, char *ret_buf)
{
int dbNumber = db[_dbName];
struct fildes *fp = dbDesc[dbNumber];
field *_dbField = dbField[dbNumber];
char type;
char rec_buf[MAXRECSIZ];
int ival = 0;
long lval = 0;
type = _dbField[fieldNo].type;
if (getrec(recno, fp, rec_buf) == 0)
return 0;
switch (type) {
case 'c':{
//cout << "Extract(): c\n";
//int size = int(_dbField[fieldNo].size);
//size = size - 1;
//cerr << "Extract(): size = " << size << endl;
//memset(ret_buf, 0, size);
strcpy(ret_buf, &rec_buf[_dbField[fieldNo].offset]);
//ret_buf[size] = 0;
return 1;
}
case 'd':
case 'i':
ival = get16(&rec_buf[_dbField[fieldNo].offset]);
//cout << "Extract(): i = " << ival << endl;
sprintf(ret_buf, "%d", ival);
return 1;
case 'l':
lval = get32(&rec_buf[_dbField[fieldNo].offset]);
//cout << "Extract(): l\n";
sprintf(ret_buf, "%ld", lval);
return 1;
default:
break;
}
return 0;
}
int
NxDb::ExtractDeleted(string _dbName, int recno, int fieldNo, char *ret_buf)
{
#ifdef DEBUG
//assert(db.find(_dbName) != db.end());
#endif /* */
int dbNumber = db[_dbName];
struct fildes *fp = dbDesc[dbNumber];
field *_dbField = dbField[dbNumber];
char type;
char rec_buf[MAXRECSIZ];
int ival = 0;
long lval = 0;
type = _dbField[fieldNo].type;
if (getrec(recno, fp, rec_buf) == 1)
return 0;
switch (type) {
case 'c':
//cout << "Extract(): c\n";
strcpy(ret_buf, &rec_buf[_dbField[fieldNo].offset]);
return 1;
case 'd':
case 'i':
ival = get16(&rec_buf[_dbField[fieldNo].offset]);
//cout << "Extract(): i = " << ival << endl;
sprintf(ret_buf, "%d", ival);
return 1;
case 'l':
lval = get32(&rec_buf[_dbField[fieldNo].offset]);
//cout << "Extract(): l\n";
sprintf(ret_buf, "%ld", lval);
return 1;
default:
break;
}
return 0;
}
field *
NxDb::GetField(string _dbName)
{
int dbNumber = db[_dbName];
struct field *fp = dbField[dbNumber];
return fp;
}
fildes *
NxDb::GetFilDes(string _dbName)
{
int dbNumber = db[_dbName];
struct fildes *fp = dbDesc[dbNumber];
return fp;
}
void
NxDb::Purge(string _dbName, int fieldNo, char *value)
{
int dbNumber = db[_dbName];
fildes *fp = dbDesc[dbNumber];
char ret_buf[MAXRECSIZ];
if (fieldNo != -1) {
// Purge specific records
for (int i = 1; i <= fp->nrecs; i++) {
Extract(_dbName, i, fieldNo, ret_buf);
if (strcmp(ret_buf, value) == 0)
DeleteRec(_dbName, i);
}
} else {
// Purge all records
for (int i = 1; i < fp->nrecs; i++)
DeleteRec(_dbName, i);
}
}
void
fatal(int n)
{
printf("*** Fatal Error #%d\n", n);
}
--- NEW FILE: NxDb.dsp ---
# Microsoft Developer Studio Project File - Name="NxDb" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=NxDb - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "NxDb.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "NxDb.mak" CFG="NxDb - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "NxDb - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "NxDb - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "NxDb - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "." /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "HAVE_CONFIG_H" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "NxDb - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /I "." /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "HAVE_CONFIG_H" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "NxDb - Win32 Release"
# Name "NxDb - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\blkio.c
# End Source File
# Begin Source File
SOURCE=.\db.c
# End Source File
# Begin Source File
SOURCE=.\index.c
# End Source File
# Begin Source File
SOURCE=.\nxdb.cxx
# End Source File
# Begin Source File
SOURCE=.\use.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\config.h
# End Source File
# Begin Source File
SOURCE=.\file.h
# End Source File
# Begin Source File
SOURCE=.\nxdb.h
# End Source File
# End Group
# End Target
# End Project
--- NEW FILE: db.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <stdio.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <fcntl.h>
#ifdef WIN32
#include <io.h>
#endif
#include "file.h"
#include "VCMemoryLeak.h"
/*
* db.c - database & index file open/close/create routines
*
* from 9/9/85 mt15b
*/
#ifndef WIN32
#define O_BINARY 0
#endif
static char *str2cat(char *f1, char *ext);
struct buffer *getblk();
extern struct buffer *startbuf, *endbuf;
extern char apflag;
/*
* create a database or index file
*/
int
dbcreat(struct fildes *fp, char *name)
{
int fd, ret;
if ((fd = creat(str2cat(name, fp->filext), 0666)) < 0)
return (0);
close(fd);
apflag = 1;
ret = dbopen(fp, name);
apflag = 0;
return (ret);
}
/*
* open a database or index file
*/
int
dbopen(struct fildes *fp, char *name)
{
int fd, off, x;
struct buffer *bp;
if ((fd = open(str2cat(name, fp->filext), O_RDWR | O_BINARY)) < 0)
return (0);
fp->fildesc = fd;
fp->fchanged = 0;
bp = getblk(0, fp);
if (fp->ftype) { /* index file */
((struct ndxfile *) fp)->maxkeys =
((BLKSIZ - 7) / (2 + ((struct ndxfile *) fp)->keylen));
((struct ndxfile *) fp)->curblk = -1;
return (1);
}
fp->nrecs = get16(&bp->buf[0]);
fp->currec = 1;
off = 1; /* byte 0 is deleted flag */
for (fd = 0; fp->fieldp[fd].type; fd++) {
//if( fd >= MAXFIELDS)
//fatal( x);
fp->fieldp[fd].offset = off;
x = fp->fieldp[fd].size;
switch (fp->fieldp[fd].type) {
case 'c':
case 'n': /* pt only */
off += x;
break;
case 'd':
case 'i':
off += x * sizeof(short);
break;
case 'l':
off += x * sizeof(long);
break;
}
}
x = 1;
fp->fieldp[fd].offset = off;
off += x * sizeof(long);
fp->nfields++;
fp->nfields = fd;
fp->recsiz = off;
if (off > MAXRECSIZ)
fatal(4); /* max rec size overflow */
return (1);
}
/*
* close and write database or index file
*/
void
dbclose(struct fildes *fp)
{
struct buffer *bp;
if (fp->fchanged) {
bp = getblk(0, fp);
if (!fp->ftype)
put16(&bp->buf[0], fp->nrecs);
putblk(bp);
}
for (bp = startbuf; bp < endbuf; bp++)
if (bp->fptr == fp) {
if (bp->changed)
putblk(bp);
bp->usecnt = 0;
bp->fptr = NULL;
}
close(fp->fildesc);
}
/*
* write the database or index file
*/
void
dbsave(struct fildes *fp)
{
struct buffer *bp;
if (fp->fchanged) {
bp = getblk(0, fp);
if (!fp->ftype)
put16(&bp->buf[0], fp->nrecs);
putblk(bp);
}
for (bp = startbuf; bp < endbuf; bp++)
if (bp->fptr == fp) {
if (bp->changed)
putblk(bp);
bp->usecnt = 0;
bp->fptr = NULL;
}
}
static char *
str2cat(char *f1, char *ext)
{
char *p;
static char buf[69];
p = buf;
while (*f1)
*p++ = *f1++;
*p++ = '.';
while ((*p++ = *ext++) != 0)
continue;
return (buf);
}
--- NEW FILE: Makefile ---
CXX = g++
CC = gcc
ifeq ($(CONFIG_DEBUG),y)
CFLAGS+=-g -O0 -Wall -DDEBUG
endif
CFLAGS += -Wall -I../include
%.o:%.c
$(CC) $(CFLAGS) -c $<
%.o:%.cpp
$(CXX) $(CFLAGS) -c $<
%.o:%.cxx
$(CXX) $(CFLAGS) -c $<
libNxDb.a: blkio.o db.o nxdb.o index.o use.o
$(AR) -ru $@ $^
blkio.o: blkio.c
db.o: db.c
nxdb.o: nxdb.cxx
index.o: index.c
use.o: use.c
clean:
@ rm -f ide
@ rm -f *.o
@ rm -f *.a
install:
--- NEW FILE: blkio.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <malloc.h>
#ifdef WIN32
#include <io.h>
#include <memory.h>
#endif
#include "file.h"
#include "VCMemoryLeak.h"
/*
* blkio.c - block i/o routines
*
* from 8/25/85 mt15b
*/
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define dprintf printf
#define MAXBUFS 20 /* max number of in-core buffers */
#define LOCKVAL 32767 /* value of usecnt to lock buffer incore */
struct buffer *startbuf; /* ptr to first buffer */
struct buffer *endbuf; /* ptr past last buffer */
char apflag = 0; /* append mode flag for getblk() */
/* local data*/
static int lockclock = 0;
/* local procs*/
static int bread(int fd, char *buf, int blk);
static int bwrite(int fd, char *buf, int blk);
static int bfilesize(int fd);
static struct buffer *berr(char *str, int blk, struct fildes *fp);
/*
* read record recno from file fp into recbuf, return 1 if ok
*/
int
getrec(int recno, struct fildes *fp, char *recbuf)
{
int off, cnt, n, blk;
struct buffer *bp;
long offset;
char *tmpBuf;
if ((recno == 0))
return (0);
cnt = fp->recsiz;
offset = (recno - 1) * (long) cnt + RECOFF;
tmpBuf = recbuf;
do {
blk = (int) (offset >> BLKSHFT); /* logical blk # */
off = (int) (offset & BLKMSK); /* offset in blk */
n = umin(BLKSIZ - off, cnt); /* calc read cnt */
if ((bp = getblk(blk, fp)) == NULL)
return (0);
memcpy(recbuf, &bp->buf[off], n);
recbuf += n;
cnt -= n;
offset += n;
} while (cnt != 0);
fp->flags = get32(&tmpBuf[fp->recsiz - sizeof(long)]);
#if 0
if (fp->flags) {
fprintf(stderr, "getrec: %ld\n", fp->flags);
}
#endif /* */
return (!recdeleted(fp));
}
// returns true if the record can be safely overwritten
int
recerased(struct fildes *fp)
{
return (fp->flags & 0xF0);
}
int
recdeleted(struct fildes *fp)
{
/*printf("blkio.c recdeleted may need to check more flags\n"); */
return ((fp->flags & 0xF0) | (fp->flags & 0x01));
}
int
putrec(int recno, struct fildes *fp, char *recbuf)
{
int off, cnt, n, blk;
struct buffer *bp;
long offset;
#ifndef WIN32
int i;
#endif
if (recno == 0 || recno > fp->nrecs) {
fprintf(stderr, "\007*** Putrec: invalid record number %d\n", recno);
return (0);
}
if (recno == APPEND) { /* check for append mode */
recno = fp->currec = ++fp->nrecs;
fp->fchanged = 1;
apflag = 1;
}
cnt = fp->recsiz;
offset = (recno - 1) * (long) cnt + RECOFF;
put32(&recbuf[cnt - sizeof(long)], fp->flags);
do {
blk = (int) (offset >> BLKSHFT);
off = (int) (offset & BLKMSK);
n = umin(BLKSIZ - off, cnt);
if ((bp = getblk(blk, fp)) == NULL) {
return (0);
}
memcpy(&bp->buf[off], recbuf, n);
bp->changed = 1;
recbuf += n;
cnt -= n;
offset += n;
} while (cnt != 0);
apflag = 0;
return (1);
}
struct buffer *
getblk(int blk, struct fildes *fp)
{
struct buffer *bp, *savbp;
if (++lockclock >= LOCKVAL) /* lru timing */
lockclock = 1;
savbp = NULL;
for (bp = startbuf; bp < endbuf; bp++) {
if (bp->blkno == blk && bp->fptr == fp) {
bp->usecnt = lockclock;
return (bp);
}
if (savbp == NULL || bp->usecnt < savbp->usecnt)
savbp = bp;
}
if (savbp->usecnt == LOCKVAL)
return berr("all bufs locked", blk, fp);
if (savbp->changed) { /* write buffer if modified */
putblk(savbp);
}
if (!bread(fp->fildesc, savbp->buf, blk)) {
if (apflag) {
memset(savbp->buf, 0, BLKSIZ);
savbp->changed = 1;
} else {
return berr("read error", blk, fp);
}
}
savbp->blkno = blk;
savbp->fptr = fp;
savbp->usecnt = lockclock;
return (savbp);
}
void
putblk(struct buffer *bp)
{
if (bp == NULL)
return;
bwrite(bp->fptr->fildesc, bp->buf, bp->blkno);
bp->changed = 0;
}
struct buffer *
newblk(struct fildes *fp)
{
struct buffer *bp;
int blk;
blk = 0;
for (bp = startbuf; bp < endbuf; bp++)
if (bp->fptr == fp)
blk = MAX(blk, bp->blkno);
fprintf(stderr, "newblk: filesize=%d, max incore blk=%d,",
bfilesize(fp->fildesc), blk);
blk = MAX(bfilesize(fp->fildesc), blk + 1);
fprintf(stderr, "new=%d\n", blk);
apflag = 1;
bp = getblk(blk, fp);
apflag = 0;
return (bp);
}
struct buffer *
lockb(struct buffer *bp)
{
if (bp)
bp->usecnt = LOCKVAL;
return (bp);
}
void
unlock(struct buffer *bp)
{
if (++lockclock >= LOCKVAL) /* lru timing */
lockclock = 1;
bp->usecnt = lockclock;
}
void
dbinit(int maxbufs)
{
register struct buffer *bp;
if (maxbufs <= 0)
maxbufs = MAXBUFS;
while ((startbuf = malloc(sizeof(struct buffer) * maxbufs)) == NULL) {
if (--maxbufs < 4)
fatal(9); /* no memory */
}
endbuf = startbuf + maxbufs;
for (bp = startbuf; bp < endbuf; bp++) {
bp->usecnt = 0;
bp->fptr = NULL;
bp->changed = 0;
}
}
static int
bread(int fd, char *buf, int blk)
{
lseek(fd, (long) blk << 10, 0);
if (read(fd, buf, 1024) != 1024)
return (0);
return (1);
}
static int
bwrite(int fd, char *buf, int blk)
{
#ifndef WIN32
int i;
#endif
lseek(fd, (long) blk << 10, 0);
if (write(fd, buf, 1024) != 1024) {
return (0);
}
return (1);
}
/*
* return file size in 1K blocks
*/
static int
bfilesize(int fd)
{
#if UNIX
struct stat sbuf;
if (fstat(fd, &sbuf) < 0)
return (0);
return ((int) (sbuf.st_size / (long) BLKSIZ));
#else
return ((int) (lseek(fd, 0L, 2) / (long) BLKSIZ));
#endif
}
unsigned int
umin(unsigned int a, unsigned int b)
{
if (a < b)
return (a);
return (b);
}
static struct buffer *
berr(char *str, int blk, struct fildes *fp)
{
printf("\007*** getblk: %s, blk=%d, file=%s\n", str, blk, fp->filext);
return (NULL);
}
More information about the dslinux-commit
mailing list