55#define CFD(y,s,type,x,j) for(x=0,j=0;j<((int)sizeof(type));j++) \
56 {x=(x<<8)+((*s++)&0x00FF);} y=x;
57#define CTD(y,s,type,x,j) x=y;for(j=sizeof(type)-1;j>=0;j--){s[j]=x&0xFF; \
58 x>>=8;} s += sizeof(type);
66int minosread(FILE *f,
char *buffer,MLONG size)
70 x = fread(buffer,
sizeof(
char),size,f);
71 if ( x <= 0 )
return(-1);
83int minoswrite(FILE *f,
char *buffer,MLONG size)
87 x = fwrite(buffer,
sizeof(
char),size,f);
88 if ( x <= 0 )
return(-1);
92 if ( withoutflush == 0 ) fflush(f);
101char *str_dup(
char *str)
108 if ( ( s = (
char *)Malloc1((
size_t)i,
"a string copy") ) == 0 )
return(0);
110 while ( *str ) *t++ = *str++;
129 CTD(in->flags,s,MLONG,x,j)
130 CTD(in->previousblock,s,MLONG,x,j)
131 CTD(in->position,s,MLONG,x,j)
132 for ( i = 0, obj = in->objects; i < NUMOBJECTS; i++, obj++ ) {
133 CTD(obj->position,s,MLONG,x,j)
134 CTD(obj->size,s,MLONG,x,j)
135 CTD(obj->date,s,MLONG,x,j)
136 CTD(obj->tablenumber,s,MLONG,x,j)
137 CTD(obj->uncompressed,s,MLONG,x,j)
138 CTD(obj->spare1,s,MLONG,x,j)
139 CTD(obj->spare2,s,MLONG,x,j)
140 CTD(obj->spare3,s,MLONG,x,j)
142 for ( j = 0; j < ELEMENTSIZE; j++ ) *s++ = *t++;
147 CFD(out->flags,s,MLONG,x,j)
148 CFD(out->previousblock,s,MLONG,x,j)
149 CFD(out->position,s,MLONG,x,j)
150 for ( i = 0, obj = out->objects; i < NUMOBJECTS; i++, obj++ ) {
151 CFD(obj->position,s,MLONG,x,j)
152 CFD(obj->size,s,MLONG,x,j)
153 CFD(obj->date,s,MLONG,x,j)
154 CFD(obj->tablenumber,s,MLONG,x,j)
155 CFD(obj->uncompressed,s,MLONG,x,j)
156 CFD(obj->spare1,s,MLONG,x,j)
157 CFD(obj->spare2,s,MLONG,x,j)
158 CFD(obj->spare3,s,MLONG,x,j)
160 for ( j = 0; j < ELEMENTSIZE; j++ ) *t++ = *s++;
179 CTD(in->previousblock,s,MLONG,x,j)
180 CTD(in->position,s,MLONG,x,j)
181 for ( j = 0; j < NAMETABLESIZE; j++ ) out->names[j] = in->names[j];
185 CFD(out->previousblock,s,MLONG,x,j)
186 CFD(out->position,s,MLONG,x,j)
187 for ( j = 0; j < NAMETABLESIZE; j++ ) out->names[j] = in->names[j];
204 s = (
char *)out; y = (MLONG *)in;
205 for ( i =
sizeof(
INIINFO)/
sizeof(MLONG); i > 0; i-- ) {
211 s = (
char *)in; y = (MLONG *)out;
212 for ( i =
sizeof(
INIINFO)/
sizeof(MLONG); i > 0; i-- ) {
225FILE *LocateBase(
char **name,
char **newname,
char *iomode)
229 UBYTE *s, *to, *u1, *u2, *indir;
231 if ( ( handle = fopen(*name,iomode) ) != 0 ) {
232 *newname = (
char *)strDup1((UBYTE *)(*name),
"LocateBase");
235 namesize = 2; s = (UBYTE *)(*name);
236 while ( *s ) { s++; namesize++; }
240 while ( *s ) { s++; i++; }
241 *newname = (
char *)Malloc1(namesize+i,
"LocateBase");
242 s = indir; to = (UBYTE *)(*newname);
243 while ( *s ) *to++ = *s++;
244 if ( to > (UBYTE *)(*newname) && to[-1] != SEPARATOR ) *to++ = SEPARATOR;
245 s = (UBYTE *)(*name);
246 while ( *s ) *to++ = *s++;
248 if ( ( handle = fopen(*newname,iomode) ) != 0 ) {
251 M_free(*newname,
"LocateBase, incdir/file");
257 while ( *u1 && *u1 !=
':' ) {
258 if ( *u1 ==
'\\' ) u1++;
261 *newname = (
char *)Malloc1(namesize+i,
"LocateBase");
262 s = u2; to = (UBYTE *)(*newname);
264 if ( *s ==
'\\' ) s++;
267 if ( to > (UBYTE *)(*newname) && to[-1] != SEPARATOR ) *to++ = SEPARATOR;
268 s = (UBYTE *)(*name);
269 while ( *s ) *to++ = *s++;
271 if ( ( handle = fopen(*newname,iomode) ) != 0 ) {
274 M_free(*newname,
"LocateBase Path/file");
288int ReadIndex(
DBASE *d)
293 MLONG position, size;
297 if ( d->info.numberofindexblocks <= 0 )
return(0);
298 if (
sizeof(
INDEXBLOCK)*d->info.numberofindexblocks > MAXINDEXSIZE ) {
299 MesPrint(
"We need more than %ld bytes for the index.\n",MAXINDEXSIZE);
300 MesPrint(
"The file %s may not be a proper database\n",d->name);
303 size =
sizeof(
INDEXBLOCK *)*d->info.numberofindexblocks;
304 if ( ( ib = (
INDEXBLOCK **)Malloc1(size,
"tb,index") ) == 0 )
return(-1);
305 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
307 for ( --i; i >= 0; i-- ) M_free(ib[i],
"tb,indexblock");
308 M_free(ib,
"tb,index");
312 size =
sizeof(
NAMESBLOCK *)*d->info.numberofnamesblocks;
313 if ( ( ina = (
NAMESBLOCK **)Malloc1(size,
"tb,indexnames") ) == 0 )
return(-1);
314 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
316 for ( --i; i >= 0; i-- ) M_free(ina[i],
"index names block");
317 M_free(ina,
"tb,indexnames");
318 for ( i = 0; i < d->info.numberofindexblocks; i++ ) M_free(ib[i],
"tb,indexblock");
319 M_free(ib,
"tb,index");
327 position = d->info.lastindexblock;
328 for ( i = d->info.numberofindexblocks - 1; i >= 0; i-- ) {
329 fseek(d->handle,position,SEEK_SET);
330 if ( minosread(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
331 MesPrint(
"Error while reading file %s\n",d->name);
333 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) M_free(ina[i],
"index names block");
334 M_free(ina,
"tb,indexnames");
335 for ( i = 0; i < d->info.numberofindexblocks; i++ ) M_free(ib[i],
"tb,indexblock");
336 M_free(ib,
"tb,index");
339 convertblock(&scratchblock,ib[i],FROMDISK);
340 if ( ib[i]->position != position ||
341 ( ib[i]->previousblock <= 0 && i > 0 ) ) {
342 MesPrint(
"File %s has inconsistent contents\n",d->name);
345 position = ib[i]->previousblock;
347 d->info.firstindexblock = ib[0]->position;
348 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
349 ib[i]->flags &= MCLEANFLAG;
355 position = d->info.lastnameblock;
356 for ( i = d->info.numberofnamesblocks - 1; i >= 0; i-- ) {
357 fseek(d->handle,position,SEEK_SET);
358 if ( minosread(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
359 MesPrint(
"Error while reading file %s\n",d->name);
362 convertnamesblock(&scratchnamesblock,ina[i],FROMDISK);
363 if ( ina[i]->position != position ||
364 ( ina[i]->previousblock <= 0 && i > 0 ) ) {
365 MesPrint(
"File %s has inconsistent contents\n",d->name);
368 position = ina[i]->previousblock;
370 d->info.firstnameblock = ina[0]->position;
375 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
376 if ( d->iblocks[i] ) M_free(d->iblocks[i],
"d->iblocks[i]");
378 M_free(d->iblocks,
"d->iblocks");
381 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
382 if ( d->nblocks[i] ) M_free(d->nblocks[i],
"d->nblocks[i]");
384 M_free(d->nblocks,
"d->nblocks");
399int WriteIndexBlock(
DBASE *d,MLONG num)
401 if ( num >= d->info.numberofindexblocks ) {
402 MesPrint(
"Illegal number specified for number of index blocks\n");
405 fseek(d->handle,d->iblocks[num]->position,SEEK_SET);
406 convertblock(d->iblocks[num],&scratchblock,TODISK);
407 if ( minoswrite(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
408 MesPrint(
"Error while writing an index block in file %s\n",d->name);
409 MesPrint(
"File may be unreliable now\n");
420int WriteNamesBlock(
DBASE *d,MLONG num)
422 if ( num >= d->info.numberofnamesblocks ) {
423 MesPrint(
"Illegal number specified for number of names blocks\n");
426 fseek(d->handle,d->nblocks[num]->position,SEEK_SET);
427 convertnamesblock(d->nblocks[num],&scratchnamesblock,TODISK);
428 if ( minoswrite(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
429 MesPrint(
"Error while writing a names block in file %s\n",d->name);
430 MesPrint(
"File may be unreliable now\n");
443int WriteIndex(
DBASE *d)
446 if ( d->iblocks == 0 )
return(0);
447 if ( d->nblocks == 0 )
return(0);
448 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
449 if ( d->iblocks[i] == 0 ) {
450 MesPrint(
"Error: unassigned index blocks. Cannot write\n");
454 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
455 if ( d->nblocks[i] == 0 ) {
456 MesPrint(
"Error: unassigned names blocks. Cannot write\n");
460 d->info.lastindexblock = -1;
461 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
462 position = d->iblocks[i]->position;
463 if ( position <= 0 ) {
464 fseek(d->handle,0,SEEK_END);
465 position = ftell(d->handle);
466 d->iblocks[i]->position = position;
467 if ( i <= 0 ) d->iblocks[i]->previousblock = -1;
468 else d->iblocks[i]->previousblock = d->iblocks[i-1]->position;
470 else fseek(d->handle,position,SEEK_SET);
471 convertblock(d->iblocks[i],&scratchblock,TODISK);
472 if ( minoswrite(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
473 MesPrint(
"Error while writing index of file %s",d->name);
474 d->iblocks[i]->position = -1;
477 d->info.lastindexblock = position;
479 d->info.lastnameblock = -1;
480 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
481 position = d->nblocks[i]->position;
482 if ( position <= 0 ) {
483 fseek(d->handle,0,SEEK_END);
484 position = ftell(d->handle);
485 d->nblocks[i]->position = position;
486 if ( i <= 0 ) d->nblocks[i]->previousblock = -1;
487 else d->nblocks[i]->previousblock = d->nblocks[i-1]->position;
489 else fseek(d->handle,position,SEEK_SET);
490 convertnamesblock(d->nblocks[i],&scratchnamesblock,TODISK);
491 if ( minoswrite(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
492 MesPrint(
"Error while writing index of file %s",d->name);
493 d->nblocks[i]->position = -1;
496 d->info.lastnameblock = position;
506int WriteIniInfo(
DBASE *d)
509 fseek(d->handle,0,SEEK_SET);
510 convertiniinfo(&(d->info),&inf,TODISK);
511 if ( minoswrite(d->handle,(
char *)(&inf),
sizeof(
INIINFO)) ) {
512 MesPrint(
"Error while writing masterindex of file %s",d->name);
523int ReadIniInfo(
DBASE *d)
526 fseek(d->handle,0,SEEK_SET);
527 if ( minosread(d->handle,(
char *)(&inf),
sizeof(
INIINFO)) ) {
528 MesPrint(
"Error while reading masterindex of file %s",d->name);
531 convertiniinfo(&inf,&(d->info),FROMDISK);
532 if ( d->info.entriesinindex < 0
533 || d->info.numberofindexblocks < 0
534 || d->info.lastindexblock < 0 ) {
535 MesPrint(
"The file %s is not a proper database\n",d->name);
546DBASE *GetDbase(
char *filename, MLONG rwmode)
552 if ( ( f = LocateBase(&filename,&newname,
"rb") ) == 0 ) {
554 MesPrint(
"&Trying to open non-existent TableBase in readonly mode: %s", filename);
558 if ( ( f = LocateBase(&filename,&newname,
"r+b") ) == 0 ) {
560 return(NewDbase(filename,0));
565 d = (
DBASE *)From0List(&(AC.TableBaseList));
567 d->tablenamessize = 0;
569 d->tablenamefill = 0;
575 d->info.entriesinindex = 0;
576 d->info.numberofindexblocks = 0;
577 d->info.firstindexblock = 0;
578 d->info.lastindexblock = 0;
579 d->info.numberoftables = 0;
580 d->info.numberofnamesblocks = 0;
581 d->info.firstnameblock = 0;
582 d->info.lastnameblock = 0;
584 d->name = str_dup(filename);
586 if ( ReadIniInfo(d) || ReadIndex(d) ) { M_free(d,
"index-d"); fclose(f);
return(0); }
587 if ( ComposeTableNames(d) < 0 ) { FreeTableBase(d); fclose(f);
return(0); }
589 M_free(d->name,
"from str_dup");
590 d->name = str_dup(filename);
591 d->fullname = newname;
602DBASE *NewDbase(
char *name,MLONG number)
606 MLONG numblocks, numnameblocks, i;
610 MLONG t = (MLONG)(time(0));
612 if ( number < 0 ) number = 0;
613 if ( ( f = fopen(name,
"w+b") ) == 0 ) {
614 MesPrint(
"Could not create a new file with name %s\n",name);
617 numblocks = (number+NUMOBJECTS-1)/NUMOBJECTS;
619 if ( numblocks <= 0 ) numblocks = 1;
620 if ( numnameblocks <= 0 ) numnameblocks = 1;
621 d = (
DBASE *)From0List(&(AC.TableBaseList));
623 "new database") ) == 0 ) {
629 d->tablenamessize = 0;
631 d->tablenamefill = 0;
636 "new database") ) == 0 ) {
637 M_free(d->iblocks,
"new database");
642 if ( ( f = fopen(name,
"w+b") ) == 0 ) {
643 MesPrint(
"Could not create new file %s\n",name);
648 d->name = str_dup(name);
649 d->fullname = str_dup(name);
652 d->info.entriesinindex = number;
653 d->info.numberofindexblocks = numblocks;
654 d->info.numberofnamesblocks = numnameblocks;
655 d->info.firstindexblock = 0;
656 d->info.lastindexblock = 0;
657 d->info.numberoftables = 0;
658 d->info.firstnameblock = 0;
659 d->info.lastnameblock = 0;
661 if ( WriteIniInfo(d) ) {
665 if ( d->name ) { M_free(d->name,
"name tablebase"); d->name = 0; }
666 if ( d->fullname ) { M_free(d->fullname,
"fullname tablebase"); d->fullname = 0; }
667 M_free(d->nblocks,
"new database");
668 M_free(d->iblocks,
"new database");
672 for ( i = 0; i < numblocks; i++ ) {
674 "index blocks of new database") ) == 0 ) {
675 while ( --i >= 0 ) M_free(d->iblocks[i],
"index blocks of new database");
678 if ( i > 0 ) d->iblocks[i]->previousblock = d->iblocks[i-1]->position;
679 else d->iblocks[i]->previousblock = -1;
680 d->iblocks[i]->position = ftell(f);
682 d->iblocks[i]->flags = -1;
687 for ( j = 0; j < NUMOBJECTS; j++ ) {
688 d->iblocks[i]->objects[j].date = t;
689 d->iblocks[i]->objects[j].size = 0;
690 d->iblocks[i]->objects[j].position = -1;
691 d->iblocks[i]->objects[j].tablenumber = 0;
692 d->iblocks[i]->objects[j].uncompressed = 0;
693 d->iblocks[i]->objects[j].spare1 = 0;
694 d->iblocks[i]->objects[j].spare2 = 0;
695 d->iblocks[i]->objects[j].spare3 = 0;
696 for ( jj = 0; jj < ELEMENTSIZE; jj++ ) d->iblocks[i]->objects[j].element[jj] = 0;
698 convertblock(d->iblocks[i],&scratchblock,TODISK);
699 if ( minoswrite(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
700 MesPrint(
"Error while writing new index blocks\n");
704 for ( i = 0; i < numnameblocks; i++ ) {
706 "names blocks of new database") ) == 0 ) {
707 while ( --i >= 0 ) { M_free(d->nblocks[i],
"names blocks of new database"); }
708 for ( i = 0; i < numblocks; i++ ) M_free(d->iblocks[i],
"index blocks of new database");
711 if ( i > 0 ) d->nblocks[i]->previousblock = d->nblocks[i-1]->position;
712 else d->nblocks[i]->previousblock = -1;
713 d->nblocks[i]->position = ftell(f);
714 s = d->nblocks[i]->names;
715 for ( j = 0; j < NAMETABLESIZE; j++ ) *s++ = 0;
716 convertnamesblock(d->nblocks[i],&scratchnamesblock,TODISK);
717 if ( minoswrite(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
718 MesPrint(
"Error while writing new names blocks\n");
719 for ( i = 0; i < numnameblocks; i++ ) M_free(d->nblocks[i],
"names blocks of new database");
720 for ( i = 0; i < numblocks; i++ ) M_free(d->iblocks[i],
"index blocks of new database");
724 d->info.firstindexblock = d->iblocks[0]->position;
725 d->info.lastindexblock = d->iblocks[numblocks-1]->position;
726 d->info.firstnameblock = d->nblocks[0]->position;
727 d->info.lastnameblock = d->nblocks[numnameblocks-1]->position;
728 if ( WriteIniInfo(d) ) {
729 for ( i = 0; i < numnameblocks; i++ ) M_free(d->nblocks[i],
"names blocks of new database");
730 for ( i = 0; i < numblocks; i++ ) M_free(d->iblocks[i],
"index blocks of new database");
741void FreeTableBase(
DBASE *d)
743 int i, j, *old, *newL;
745 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) M_free(d->nblocks[i],
"nblocks[i]");
746 for ( i = 0; i < d->info.numberofindexblocks; i++ ) M_free(d->iblocks[i],
"iblocks[i]");
747 M_free(d->nblocks,
"nblocks");
748 M_free(d->iblocks,
"iblocks");
749 if ( d->tablenames ) M_free(d->tablenames,
"d->tablenames");
750 if ( d->name ) M_free(d->name,
"d->name");
751 if ( d->fullname ) M_free(d->fullname,
"d->fullname");
753 if ( i < ( NumTableBases - 1 ) ) {
754 L = &(AC.TableBaseList);
755 j = ( ( NumTableBases - i - 1 ) * L->
size ) /
sizeof(int);
756 old = (
int *)d; newL = (
int *)(d+1);
757 while ( --j >= 0 ) *newL++ = *old++;
758 j = L->
size /
sizeof(int);
759 while ( --j >= 0 ) *newL++ = 0;
773int ComposeTableNames(
DBASE *d)
779 i = 0; s = d->nblocks[i]->names; j = NAMETABLESIZE;
781 if ( *s ) d->topnumber++;
782 for ( k = 0; k < 2; k++ ) {
786 i++;
if ( i >= d->info.numberofnamesblocks )
goto gotall;
787 s = d->nblocks[i]->names; j = NAMETABLESIZE;
793 i++;
if ( i >= d->info.numberofnamesblocks )
goto gotall;
794 s = d->nblocks[i]->names; j = NAMETABLESIZE;
800 nsize = (d->info.numberofnamesblocks-1)*NAMETABLESIZE +
801 (s-d->nblocks[i]->names)+1;
802 if ( ( d->tablenames = (
char *)Malloc1((2*nsize+30)*
sizeof(
char),
"tablenames") )
803 == 0 ) {
return(-1); }
805 d->tablenamessize = 2*nsize+30;
806 d->tablenamefill = nsize-1;
807 for ( k = 0; k < i; k++ ) {
808 ss = d->nblocks[k]->names;
809 for ( j = 0; j < NAMETABLESIZE; j++ ) *t++ = *ss++;
811 ss = d->nblocks[i]->names;
812 while ( ss < s ) *t++ = *ss++;
822DBASE *OpenDbase(
char *filename)
827 if ( ( f = LocateBase(&filename,&newname,
"r+b") ) == 0 ) {
828 MesPrint(
"Cannot open file %s\n",filename);
832 d = (
DBASE *)From0List(&(AC.TableBaseList));
835 if ( ReadIniInfo(d) || ReadIndex(d) ) { M_free(d,
"OpenDbase"); fclose(f);
return(0); }
836 if ( ComposeTableNames(d) ) {
841 d->name = str_dup(filename);
842 d->fullname = newname;
859 int namesize, tailsize;
860 MLONG newsize, i, num;
864 if ( d->tablenames ) {
870 while ( ( *s == *t ) && *t ) { s++; t++; }
871 if ( *s == *t ) {
return(-num); }
881 MesPrint(
"We add the name %s\n",name);
883 while ( *t ) { t++; }
885 if ( ( t = (
char *)(T->
argtail) ) != 0 ) {
886 while ( *t ) { t++; }
887 tailsize = t - (
char *)(T->
argtail);
889 else { tailsize = 0; }
890 if ( d->tablenames == 0 ) {
891 if ( ComposeTableNames(d) ) {
893 M_free(d,
"AddTableName");
897 d->info.numberoftables++;
898 while ( ( d->tablenamefill+namesize+tailsize+3 > d->tablenamessize )
899 || ( d->tablenames == 0 ) ) {
900 newsize = 2*d->tablenamessize + 2*namesize + 2*tailsize + 6;
901 if ( ( t = (
char *)Malloc1(newsize*
sizeof(
char),
"AddTableName") ) == 0 )
904 if ( d->tablenames ) {
906 for ( i = 0; i < d->tablenamefill; i++ ) *t++ = *s++;
908 M_free(d->tablenames,
"d->tablenames");
911 d->tablenamessize = newsize;
913 s = d->tablenames + d->tablenamefill;
915 while ( *t ) *s++ = *t++;
918 while ( *t ) *s++ = *t++;
921 d->tablenamefill = s - d->tablenames;
926 if ( PutTableNames(d) )
return(0);
927 return(d->topnumber);
939MLONG GetTableName(
DBASE *d,
char *name)
946 if ( d->tablenames ) {
952 while ( ( *s == *t ) && *t ) { s++; t++; }
953 if ( *s == *t ) {
return(num); }
971int PutTableNames(
DBASE *d)
980 MLONG numblocks = d->tablenamefill/NAMETABLESIZE + 1;
981 if ( d->info.numberofnamesblocks < numblocks ) {
986 "new names block") ) == 0 ) {
989 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
990 nnew[i] = d->nblocks[i];
994 for ( ; i < numblocks; i++ ) {
996 "additional names blocks ") ) == 0 ) {
1000 d->nblocks[i]->previousblock = -1;
1001 d->nblocks[i]->position = -1;
1002 s = d->nblocks[i]->names;
1003 for ( j = 0; j < NAMETABLESIZE; j++ ) *s++ = 0;
1005 d->info.numberofnamesblocks = numblocks;
1011 i = 0; t = d->nblocks[i]->names; j = 0; s = d->tablenames;
1012 for ( m = 0; m < d->tablenamefill; m++ ) {
1015 if ( j >= NAMETABLESIZE ) {
1017 t = d->nblocks[i]->names;
1023 for ( ; m < d->tablenamefill; m++ ) {
1025 if ( j >= NAMETABLESIZE ) {
1027 t = d->nblocks[i]->names;
1035 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
1036 if ( i == firstdif )
break;
1037 if ( d->nblocks[i]->position < 0 ) { firstdif = i;
break; }
1042 for ( i = firstdif; i < d->info.numberofnamesblocks; i++ ) {
1043 if ( i > 0 ) d->nblocks[i]->previousblock = d->nblocks[i-1]->position;
1044 else d->nblocks[i]->previousblock = -1;
1045 if ( d->nblocks[i]->position < 0 ) {
1046 fseek(d->handle,0,SEEK_END);
1047 d->nblocks[i]->position = ftell(d->handle);
1049 else fseek(d->handle,d->nblocks[i]->position,SEEK_SET);
1050 convertnamesblock(d->nblocks[i],&scratchnamesblock,TODISK);
1051 if ( minoswrite(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
1052 MesPrint(
"Error while writing names blocks\n");
1057 d->info.lastnameblock = d->nblocks[d->info.numberofnamesblocks-1]->position;
1058 d->info.firstnameblock = d->nblocks[0]->position;
1059 return(WriteIniInfo(d));
1067int AddToIndex(
DBASE *d,MLONG number)
1069 MLONG i, oldnumofindexblocks = d->info.numberofindexblocks;
1070 MLONG j, newnumofindexblocks, jj;
1072 MLONG t = (MLONG)(time(0));
1073 if ( number == 0 )
return(0);
1074 else if ( number < 0 ) {
1075 if ( d->info.entriesinindex < -number ) {
1076 MesPrint(
"There are only %ld entries in the index of file %s\n",
1077 d->info.entriesinindex,d->name);
1080 d->info.entriesinindex += number;
1082 if ( WriteIniInfo(d) ) {
1083 d->info.entriesinindex -= number;
1084 MesPrint(
"File may be corrupted\n");
1088 else if ( d->info.entriesinindex+number <=
1089 NUMOBJECTS*d->info.numberofindexblocks ) {
1090 d->info.entriesinindex += number;
1094 d->info.entriesinindex += number;
1095 newnumofindexblocks = d->info.numberofindexblocks + ((number -
1096 (NUMOBJECTS*d->info.numberofindexblocks - d->info.entriesinindex))
1097 +NUMOBJECTS-1)/NUMOBJECTS;
1099 "index") ) == 0 )
return(-1);
1100 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1101 ib[i] = d->iblocks[i];
1103 for ( i = d->info.numberofindexblocks; i < newnumofindexblocks; i++ ) {
1108 if ( i > 0 ) ib[i]->previousblock = ib[i-1]->position;
1109 else ib[i]->previousblock = -1;
1113 for ( j = 0; j < NUMOBJECTS; j++ ) {
1114 ib[i]->objects[j].date = t;
1115 ib[i]->objects[j].size = 0;
1116 ib[i]->objects[j].position = -1;
1117 ib[i]->objects[j].tablenumber = 0;
1118 ib[i]->objects[j].uncompressed = 0;
1119 ib[i]->objects[j].spare1 = 0;
1120 ib[i]->objects[j].spare2 = 0;
1121 ib[i]->objects[j].spare3 = 0;
1122 for ( jj = 0; jj < ELEMENTSIZE; jj++ ) ib[i]->
objects[j].element[jj] = 0;
1124 fseek(d->handle,0,SEEK_END);
1125 ib[i]->position = ftell(d->handle);
1126 convertblock(ib[i],&scratchblock,TODISK);
1127 if ( minoswrite(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
1128 MesPrint(
"Error while writing new index of file %s",d->name);
1133 d->info.lastindexblock = ib[newnumofindexblocks-1]->position;
1134 d->info.firstindexblock = ib[0]->position;
1135 d->info.numberofindexblocks = newnumofindexblocks;
1136 if ( WriteIniInfo(d) ) {
1137 d->info.numberofindexblocks = oldnumofindexblocks;
1138 d->info.entriesinindex -= number;
1139 MesPrint(
"File may be corrupted\n");
1143 M_free(d->iblocks,
"AddToIndex");
1154MLONG AddObject(
DBASE *d,MLONG tablenumber,
char *arguments,
char *rhs)
1157 number = d->info.entriesinindex;
1158 if ( AddToIndex(d,1) )
return(-1);
1159 if ( WriteObject(d,tablenumber,arguments,rhs,number) )
return(-1);
1168MLONG FindTableNumber(
DBASE *d,
char *name)
1170 char *s = d->tablenames, *t, *ss;
1172 ss = d->tablenames + d->tablenamefill;
1176 while ( *s == *t && *t ) {
1179 if ( *s == 0 && *t == 0 )
return(num);
1196int WriteObject(
DBASE *d,MLONG tablenumber,
char *arguments,
char *rhs,MLONG number)
1201 uLongf newsize = 0, oldsize = 0;
1205 MLONG i, j, position, size, n;
1207 if ( ( d->mode & INPUTONLY ) == INPUTONLY ) {
1208 MesPrint(
"Not allowed to write to input\n");
1211 if ( number >= d->info.entriesinindex ) {
1212 MesPrint(
"Reference to non-existing object number %ld\n",number+1);
1215 j = number/NUMOBJECTS;
1216 i = number%NUMOBJECTS;
1217 obj = &(d->iblocks[j]->objects[i]);
1220 a++; n = a - arguments;
1221 if ( n > ELEMENTSIZE ) {
1222 MesPrint(
"Table element %s has more than %ld characters.\n",arguments,
1223 (MLONG)ELEMENTSIZE);
1228 while ( *a ) *s++ = *a++;
1230 while ( n < ELEMENTSIZE ) { *s++ = 0; n++; }
1231 obj->spare1 = obj->spare2 = obj->spare3 = 0;
1233 fseek(d->handle,0,SEEK_END);
1234 position = ftell(d->handle);
1240 if ( ( d->mode & NOCOMPRESS ) == 0 ) {
1241 newsize = size + size/1000 + 20;
1242 if ( ( buffer = (
char *)Malloc1(newsize*
sizeof(
char),
"compress buffer") )
1244 MesPrint(
"No compress used for element %s in file %s\n",arguments,d->name);
1253 const int old_isUsingZSTDcompression = ZWRAP_isUsingZSTDcompression();
1254 ZWRAP_useZSTDcompression(0);
1256 if ( ( error = compress((Bytef *)buffer,&newsize,(Bytef *)rhs,ssize) ) != Z_OK ) {
1257 MesPrint(
"Error = %d\n",error);
1258 MesPrint(
"Due to error no compress used for element %s in file %s\n",arguments,d->name);
1259 M_free(buffer,
"tb,WriteObject");
1263 ZWRAP_useZSTDcompression(old_isUsingZSTDcompression);
1272 if ( minoswrite(d->handle,rhs,size) ) {
1273 MesPrint(
"Error while writing rhs\n");
1276 obj->position = position;
1278 obj->date = (MLONG)(time(0));
1279 obj->tablenumber = tablenumber;
1281 obj->uncompressed = oldsize;
1282 if ( buffer ) M_free(buffer,
"tb,WriteObject");
1284 obj->uncompressed = 0;
1286 return(WriteIndexBlock(d,j));
1296char *ReadObject(
DBASE *d,MLONG tablenumber,
char *arguments)
1300 char *buffer1, *s, *t;
1303 uLongf finallength = 0;
1305 if ( tablenumber > d->topnumber ) {
1306 MesPrint(
"Reference to non-existing table number in tablebase %s: %ld\n",
1307 d->name,tablenumber);
1313 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1314 for ( j = 0; j < NUMOBJECTS; j++ ) {
1315 if ( d->iblocks[i]->objects[j].tablenumber != tablenumber )
continue;
1316 s = arguments; t = d->iblocks[i]->objects[j].element;
1317 while ( *s == *t && *s ) { s++; t++; }
1318 if ( *t == 0 && *s == 0 )
goto foundelement;
1321 s = d->tablenames; i = 1;
1323 if ( i == tablenumber )
break;
1330 MesPrint(
"%s(%s) not found in tablebase %s\n",s,arguments,d->name);
1334 obj = &(d->iblocks[i]->objects[j]);
1335 fseek(d->handle,obj->position,SEEK_SET);
1336 if ( ( buffer1 = (
char *)Malloc1(obj->size,
"reading rhs buffer1") ) == 0 ) {
1340 if ( obj->uncompressed > 0 ) {
1341 if ( ( buffer2 = (
char *)Malloc1(obj->uncompressed,
"reading rhs buffer2") ) == 0 ) {
1347 if ( minosread(d->handle,buffer1,obj->size) ) {
1348 MesPrint(
"Could not read rhs %s in file %s\n",arguments,d->name);
1349 M_free(buffer1,
"tb,ReadObject");
1351 if ( buffer2 ) M_free(buffer2,
"tb,ReadObject");
1356 if ( buffer2 == 0 )
return(buffer1);
1357 finallength = obj->uncompressed;
1358 if ( uncompress((Bytef *)buffer2,&finallength,(Bytef *)buffer1,obj->size) != Z_OK ) {
1359 MesPrint(
"Cannot uncompress element %s in file %s\n",arguments,d->name);
1360 M_free(buffer1,
"tb,ReadObject"); M_free(buffer2,
"tb,ReadObject");
1363 M_free(buffer1,
"tb,ReadObject");
1377char *ReadijObject(
DBASE *d,MLONG i,MLONG j,
char *arguments)
1383 uLongf finallength = 0;
1385 obj = &(d->iblocks[i]->objects[j]);
1386 fseek(d->handle,obj->position,SEEK_SET);
1387 if ( ( buffer1 = (
char *)Malloc1(obj->size,
"reading rhs buffer1") ) == 0 ) {
1391 if ( obj->uncompressed > 0 ) {
1392 if ( ( buffer2 = (
char *)Malloc1(obj->uncompressed,
"reading rhs buffer2") ) == 0 ) {
1398 if ( minosread(d->handle,buffer1,obj->size) ) {
1399 MesPrint(
"Could not read rhs %s in file %s\n",arguments,d->name);
1400 if ( buffer1 ) M_free(buffer1,
"rhs buffer1");
1402 if ( buffer2 ) M_free(buffer2,
"rhs buffer2");
1407 if ( buffer2 == 0 )
return(buffer1);
1408 finallength = obj->uncompressed;
1409 if ( uncompress((Bytef *)buffer2,&finallength,(Bytef *)buffer1,obj->size) != Z_OK ) {
1410 MesPrint(
"Cannot uncompress element %s in file %s\n",arguments,d->name);
1411 if ( buffer1 ) M_free(buffer1,
"rhs buffer1");
1412 if ( buffer2 ) M_free(buffer2,
"rhs buffer2");
1415 M_free(buffer1,
"rhs buffer1");
1429int ExistsObject(
DBASE *d,MLONG tablenumber,
char *arguments)
1433 if ( tablenumber > d->topnumber ) {
1434 MesPrint(
"Reference to non-existing table number in tablebase %s: %ld\n",
1435 d->name,tablenumber);
1441 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1442 for ( j = 0; j < NUMOBJECTS; j++ ) {
1443 if ( d->iblocks[i]->objects[j].tablenumber != tablenumber )
continue;
1444 s = arguments; t = d->iblocks[i]->objects[j].element;
1445 while ( *s == *t && *s ) { s++; t++; }
1446 if ( *t == 0 && *s == 0 )
return(1);
1461int DeleteObject(
DBASE *d,MLONG tablenumber,
char *arguments)
1465 if ( tablenumber > d->topnumber ) {
1466 MesPrint(
"Reference to non-existing table number in tablebase %s: %ld\n",
1467 d->name,tablenumber);
1473 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1474 for ( j = 0; j < NUMOBJECTS; j++ ) {
1475 if ( d->iblocks[i]->objects[j].tablenumber != tablenumber )
continue;
1476 s = arguments; t = d->iblocks[i]->objects[j].element;
1477 while ( *s == *t && *s ) { s++; t++; }
1478 if ( *t == 0 && *s == 0 ) {
1479 d->iblocks[i]->objects[j].tablenumber =
1480 -d->iblocks[i]->objects[j].tablenumber - 1;