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 ) {
628 d->tablenamessize = 0;
630 d->tablenamefill = 0;
635 "new database") ) == 0 ) {
636 M_free(d->iblocks,
"new database");
640 if ( ( f = fopen(name,
"w+b") ) == 0 ) {
641 MesPrint(
"Could not create new file %s\n",name);
646 d->name = str_dup(name);
647 d->fullname = str_dup(name);
650 d->info.entriesinindex = number;
651 d->info.numberofindexblocks = numblocks;
652 d->info.numberofnamesblocks = numnameblocks;
653 d->info.firstindexblock = 0;
654 d->info.lastindexblock = 0;
655 d->info.numberoftables = 0;
656 d->info.firstnameblock = 0;
657 d->info.lastnameblock = 0;
659 if ( WriteIniInfo(d) ) {
663 if ( d->name ) { M_free(d->name,
"name tablebase"); d->name = 0; }
664 if ( d->fullname ) { M_free(d->fullname,
"fullname tablebase"); d->fullname = 0; }
665 M_free(d->nblocks,
"new database");
666 M_free(d->iblocks,
"new database");
670 for ( i = 0; i < numblocks; i++ ) {
672 "index blocks of new database") ) == 0 ) {
673 while ( --i >= 0 ) M_free(d->iblocks[i],
"index blocks of new database");
676 if ( i > 0 ) d->iblocks[i]->previousblock = d->iblocks[i-1]->position;
677 else d->iblocks[i]->previousblock = -1;
678 d->iblocks[i]->position = ftell(f);
680 d->iblocks[i]->flags = -1;
685 for ( j = 0; j < NUMOBJECTS; j++ ) {
686 d->iblocks[i]->objects[j].date = t;
687 d->iblocks[i]->objects[j].size = 0;
688 d->iblocks[i]->objects[j].position = -1;
689 d->iblocks[i]->objects[j].tablenumber = 0;
690 d->iblocks[i]->objects[j].uncompressed = 0;
691 d->iblocks[i]->objects[j].spare1 = 0;
692 d->iblocks[i]->objects[j].spare2 = 0;
693 d->iblocks[i]->objects[j].spare3 = 0;
694 for ( jj = 0; jj < ELEMENTSIZE; jj++ ) d->iblocks[i]->objects[j].element[jj] = 0;
696 convertblock(d->iblocks[i],&scratchblock,TODISK);
697 if ( minoswrite(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
698 MesPrint(
"Error while writing new index blocks\n");
702 for ( i = 0; i < numnameblocks; i++ ) {
704 "names blocks of new database") ) == 0 ) {
705 while ( --i >= 0 ) { M_free(d->nblocks[i],
"names blocks of new database"); }
706 for ( i = 0; i < numblocks; i++ ) M_free(d->iblocks[i],
"index blocks of new database");
709 if ( i > 0 ) d->nblocks[i]->previousblock = d->nblocks[i-1]->position;
710 else d->nblocks[i]->previousblock = -1;
711 d->nblocks[i]->position = ftell(f);
712 s = d->nblocks[i]->names;
713 for ( j = 0; j < NAMETABLESIZE; j++ ) *s++ = 0;
714 convertnamesblock(d->nblocks[i],&scratchnamesblock,TODISK);
715 if ( minoswrite(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
716 MesPrint(
"Error while writing new names blocks\n");
717 for ( i = 0; i < numnameblocks; i++ ) M_free(d->nblocks[i],
"names blocks of new database");
718 for ( i = 0; i < numblocks; i++ ) M_free(d->iblocks[i],
"index blocks of new database");
722 d->info.firstindexblock = d->iblocks[0]->position;
723 d->info.lastindexblock = d->iblocks[numblocks-1]->position;
724 d->info.firstnameblock = d->nblocks[0]->position;
725 d->info.lastnameblock = d->nblocks[numnameblocks-1]->position;
726 if ( WriteIniInfo(d) ) {
727 for ( i = 0; i < numnameblocks; i++ ) M_free(d->nblocks[i],
"names blocks of new database");
728 for ( i = 0; i < numblocks; i++ ) M_free(d->iblocks[i],
"index blocks of new database");
739void FreeTableBase(
DBASE *d)
741 int i, j, *old, *newL;
743 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) M_free(d->nblocks[i],
"nblocks[i]");
744 for ( i = 0; i < d->info.numberofindexblocks; i++ ) M_free(d->iblocks[i],
"iblocks[i]");
745 M_free(d->nblocks,
"nblocks");
746 M_free(d->iblocks,
"iblocks");
747 if ( d->tablenames ) M_free(d->tablenames,
"d->tablenames");
748 if ( d->name ) M_free(d->name,
"d->name");
749 if ( d->fullname ) M_free(d->fullname,
"d->fullname");
751 if ( i < ( NumTableBases - 1 ) ) {
752 L = &(AC.TableBaseList);
753 j = ( ( NumTableBases - i - 1 ) * L->
size ) /
sizeof(int);
754 old = (
int *)d; newL = (
int *)(d+1);
755 while ( --j >= 0 ) *newL++ = *old++;
756 j = L->
size /
sizeof(int);
757 while ( --j >= 0 ) *newL++ = 0;
771int ComposeTableNames(
DBASE *d)
777 i = 0; s = d->nblocks[i]->names; j = NAMETABLESIZE;
779 if ( *s ) d->topnumber++;
780 for ( k = 0; k < 2; k++ ) {
784 i++;
if ( i >= d->info.numberofnamesblocks )
goto gotall;
785 s = d->nblocks[i]->names; j = NAMETABLESIZE;
791 i++;
if ( i >= d->info.numberofnamesblocks )
goto gotall;
792 s = d->nblocks[i]->names; j = NAMETABLESIZE;
798 nsize = (d->info.numberofnamesblocks-1)*NAMETABLESIZE +
799 (s-d->nblocks[i]->names)+1;
800 if ( ( d->tablenames = (
char *)Malloc1((2*nsize+30)*
sizeof(
char),
"tablenames") )
801 == 0 ) {
return(-1); }
803 d->tablenamessize = 2*nsize+30;
804 d->tablenamefill = nsize-1;
805 for ( k = 0; k < i; k++ ) {
806 ss = d->nblocks[k]->names;
807 for ( j = 0; j < NAMETABLESIZE; j++ ) *t++ = *ss++;
809 ss = d->nblocks[i]->names;
810 while ( ss < s ) *t++ = *ss++;
820DBASE *OpenDbase(
char *filename)
825 if ( ( f = LocateBase(&filename,&newname,
"r+b") ) == 0 ) {
826 MesPrint(
"Cannot open file %s\n",filename);
830 d = (
DBASE *)From0List(&(AC.TableBaseList));
833 if ( ReadIniInfo(d) || ReadIndex(d) ) { M_free(d,
"OpenDbase"); fclose(f);
return(0); }
834 if ( ComposeTableNames(d) ) {
839 d->name = str_dup(filename);
840 d->fullname = newname;
857 int namesize, tailsize;
858 MLONG newsize, i, num;
862 if ( d->tablenames ) {
868 while ( ( *s == *t ) && *t ) { s++; t++; }
869 if ( *s == *t ) {
return(-num); }
879 MesPrint(
"We add the name %s\n",name);
881 while ( *t ) { t++; }
883 if ( ( t = (
char *)(T->
argtail) ) != 0 ) {
884 while ( *t ) { t++; }
885 tailsize = t - (
char *)(T->
argtail);
887 else { tailsize = 0; }
888 if ( d->tablenames == 0 ) {
889 if ( ComposeTableNames(d) ) {
891 M_free(d,
"AddTableName");
895 d->info.numberoftables++;
896 while ( ( d->tablenamefill+namesize+tailsize+3 > d->tablenamessize )
897 || ( d->tablenames == 0 ) ) {
898 newsize = 2*d->tablenamessize + 2*namesize + 2*tailsize + 6;
899 if ( ( t = (
char *)Malloc1(newsize*
sizeof(
char),
"AddTableName") ) == 0 )
902 if ( d->tablenames ) {
904 for ( i = 0; i < d->tablenamefill; i++ ) *t++ = *s++;
906 M_free(d->tablenames,
"d->tablenames");
909 d->tablenamessize = newsize;
911 s = d->tablenames + d->tablenamefill;
913 while ( *t ) *s++ = *t++;
916 while ( *t ) *s++ = *t++;
919 d->tablenamefill = s - d->tablenames;
924 if ( PutTableNames(d) )
return(0);
925 return(d->topnumber);
937MLONG GetTableName(
DBASE *d,
char *name)
944 if ( d->tablenames ) {
950 while ( ( *s == *t ) && *t ) { s++; t++; }
951 if ( *s == *t ) {
return(num); }
969int PutTableNames(
DBASE *d)
978 MLONG numblocks = d->tablenamefill/NAMETABLESIZE + 1;
979 if ( d->info.numberofnamesblocks < numblocks ) {
984 "new names block") ) == 0 ) {
987 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
988 nnew[i] = d->nblocks[i];
992 for ( ; i < numblocks; i++ ) {
994 "additional names blocks ") ) == 0 ) {
998 d->nblocks[i]->previousblock = -1;
999 d->nblocks[i]->position = -1;
1000 s = d->nblocks[i]->names;
1001 for ( j = 0; j < NAMETABLESIZE; j++ ) *s++ = 0;
1003 d->info.numberofnamesblocks = numblocks;
1009 i = 0; t = d->nblocks[i]->names; j = 0; s = d->tablenames;
1010 for ( m = 0; m < d->tablenamefill; m++ ) {
1013 if ( j >= NAMETABLESIZE ) {
1015 t = d->nblocks[i]->names;
1021 for ( ; m < d->tablenamefill; m++ ) {
1023 if ( j >= NAMETABLESIZE ) {
1025 t = d->nblocks[i]->names;
1033 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
1034 if ( i == firstdif )
break;
1035 if ( d->nblocks[i]->position < 0 ) { firstdif = i;
break; }
1040 for ( i = firstdif; i < d->info.numberofnamesblocks; i++ ) {
1041 if ( i > 0 ) d->nblocks[i]->previousblock = d->nblocks[i-1]->position;
1042 else d->nblocks[i]->previousblock = -1;
1043 if ( d->nblocks[i]->position < 0 ) {
1044 fseek(d->handle,0,SEEK_END);
1045 d->nblocks[i]->position = ftell(d->handle);
1047 else fseek(d->handle,d->nblocks[i]->position,SEEK_SET);
1048 convertnamesblock(d->nblocks[i],&scratchnamesblock,TODISK);
1049 if ( minoswrite(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
1050 MesPrint(
"Error while writing names blocks\n");
1055 d->info.lastnameblock = d->nblocks[d->info.numberofnamesblocks-1]->position;
1056 d->info.firstnameblock = d->nblocks[0]->position;
1057 return(WriteIniInfo(d));
1065int AddToIndex(
DBASE *d,MLONG number)
1067 MLONG i, oldnumofindexblocks = d->info.numberofindexblocks;
1068 MLONG j, newnumofindexblocks, jj;
1070 MLONG t = (MLONG)(time(0));
1071 if ( number == 0 )
return(0);
1072 else if ( number < 0 ) {
1073 if ( d->info.entriesinindex < -number ) {
1074 MesPrint(
"There are only %ld entries in the index of file %s\n",
1075 d->info.entriesinindex,d->name);
1078 d->info.entriesinindex += number;
1080 if ( WriteIniInfo(d) ) {
1081 d->info.entriesinindex -= number;
1082 MesPrint(
"File may be corrupted\n");
1086 else if ( d->info.entriesinindex+number <=
1087 NUMOBJECTS*d->info.numberofindexblocks ) {
1088 d->info.entriesinindex += number;
1092 d->info.entriesinindex += number;
1093 newnumofindexblocks = d->info.numberofindexblocks + ((number -
1094 (NUMOBJECTS*d->info.numberofindexblocks - d->info.entriesinindex))
1095 +NUMOBJECTS-1)/NUMOBJECTS;
1097 "index") ) == 0 )
return(-1);
1098 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1099 ib[i] = d->iblocks[i];
1101 for ( i = d->info.numberofindexblocks; i < newnumofindexblocks; i++ ) {
1106 if ( i > 0 ) ib[i]->previousblock = ib[i-1]->position;
1107 else ib[i]->previousblock = -1;
1111 for ( j = 0; j < NUMOBJECTS; j++ ) {
1112 ib[i]->objects[j].date = t;
1113 ib[i]->objects[j].size = 0;
1114 ib[i]->objects[j].position = -1;
1115 ib[i]->objects[j].tablenumber = 0;
1116 ib[i]->objects[j].uncompressed = 0;
1117 ib[i]->objects[j].spare1 = 0;
1118 ib[i]->objects[j].spare2 = 0;
1119 ib[i]->objects[j].spare3 = 0;
1120 for ( jj = 0; jj < ELEMENTSIZE; jj++ ) ib[i]->
objects[j].element[jj] = 0;
1122 fseek(d->handle,0,SEEK_END);
1123 ib[i]->position = ftell(d->handle);
1124 convertblock(ib[i],&scratchblock,TODISK);
1125 if ( minoswrite(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
1126 MesPrint(
"Error while writing new index of file %s",d->name);
1131 d->info.lastindexblock = ib[newnumofindexblocks-1]->position;
1132 d->info.firstindexblock = ib[0]->position;
1133 d->info.numberofindexblocks = newnumofindexblocks;
1134 if ( WriteIniInfo(d) ) {
1135 d->info.numberofindexblocks = oldnumofindexblocks;
1136 d->info.entriesinindex -= number;
1137 MesPrint(
"File may be corrupted\n");
1141 M_free(d->iblocks,
"AddToIndex");
1152MLONG AddObject(
DBASE *d,MLONG tablenumber,
char *arguments,
char *rhs)
1155 number = d->info.entriesinindex;
1156 if ( AddToIndex(d,1) )
return(-1);
1157 if ( WriteObject(d,tablenumber,arguments,rhs,number) )
return(-1);
1166MLONG FindTableNumber(
DBASE *d,
char *name)
1168 char *s = d->tablenames, *t, *ss;
1170 ss = d->tablenames + d->tablenamefill;
1174 while ( *s == *t && *t ) {
1177 if ( *s == 0 && *t == 0 )
return(num);
1194int WriteObject(
DBASE *d,MLONG tablenumber,
char *arguments,
char *rhs,MLONG number)
1199 uLongf newsize = 0, oldsize = 0;
1203 MLONG i, j, position, size, n;
1205 if ( ( d->mode & INPUTONLY ) == INPUTONLY ) {
1206 MesPrint(
"Not allowed to write to input\n");
1209 if ( number >= d->info.entriesinindex ) {
1210 MesPrint(
"Reference to non-existing object number %ld\n",number+1);
1213 j = number/NUMOBJECTS;
1214 i = number%NUMOBJECTS;
1215 obj = &(d->iblocks[j]->objects[i]);
1218 a++; n = a - arguments;
1219 if ( n > ELEMENTSIZE ) {
1220 MesPrint(
"Table element %s has more than %ld characters.\n",arguments,
1221 (MLONG)ELEMENTSIZE);
1226 while ( *a ) *s++ = *a++;
1228 while ( n < ELEMENTSIZE ) { *s++ = 0; n++; }
1229 obj->spare1 = obj->spare2 = obj->spare3 = 0;
1231 fseek(d->handle,0,SEEK_END);
1232 position = ftell(d->handle);
1238 if ( ( d->mode & NOCOMPRESS ) == 0 ) {
1239 newsize = size + size/1000 + 20;
1240 if ( ( buffer = (
char *)Malloc1(newsize*
sizeof(
char),
"compress buffer") )
1242 MesPrint(
"No compress used for element %s in file %s\n",arguments,d->name);
1251 const int old_isUsingZSTDcompression = ZWRAP_isUsingZSTDcompression();
1252 ZWRAP_useZSTDcompression(0);
1254 if ( ( error = compress((Bytef *)buffer,&newsize,(Bytef *)rhs,ssize) ) != Z_OK ) {
1255 MesPrint(
"Error = %d\n",error);
1256 MesPrint(
"Due to error no compress used for element %s in file %s\n",arguments,d->name);
1257 M_free(buffer,
"tb,WriteObject");
1261 ZWRAP_useZSTDcompression(old_isUsingZSTDcompression);
1270 if ( minoswrite(d->handle,rhs,size) ) {
1271 MesPrint(
"Error while writing rhs\n");
1274 obj->position = position;
1276 obj->date = (MLONG)(time(0));
1277 obj->tablenumber = tablenumber;
1279 obj->uncompressed = oldsize;
1280 if ( buffer ) M_free(buffer,
"tb,WriteObject");
1282 obj->uncompressed = 0;
1284 return(WriteIndexBlock(d,j));
1294char *ReadObject(
DBASE *d,MLONG tablenumber,
char *arguments)
1298 char *buffer1, *s, *t;
1301 uLongf finallength = 0;
1303 if ( tablenumber > d->topnumber ) {
1304 MesPrint(
"Reference to non-existing table number in tablebase %s: %ld\n",
1305 d->name,tablenumber);
1311 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1312 for ( j = 0; j < NUMOBJECTS; j++ ) {
1313 if ( d->iblocks[i]->objects[j].tablenumber != tablenumber )
continue;
1314 s = arguments; t = d->iblocks[i]->objects[j].element;
1315 while ( *s == *t && *s ) { s++; t++; }
1316 if ( *t == 0 && *s == 0 )
goto foundelement;
1319 s = d->tablenames; i = 1;
1321 if ( i == tablenumber )
break;
1328 MesPrint(
"%s(%s) not found in tablebase %s\n",s,arguments,d->name);
1332 obj = &(d->iblocks[i]->objects[j]);
1333 fseek(d->handle,obj->position,SEEK_SET);
1334 if ( ( buffer1 = (
char *)Malloc1(obj->size,
"reading rhs buffer1") ) == 0 ) {
1338 if ( obj->uncompressed > 0 ) {
1339 if ( ( buffer2 = (
char *)Malloc1(obj->uncompressed,
"reading rhs buffer2") ) == 0 ) {
1345 if ( minosread(d->handle,buffer1,obj->size) ) {
1346 MesPrint(
"Could not read rhs %s in file %s\n",arguments,d->name);
1347 M_free(buffer1,
"tb,ReadObject");
1349 if ( buffer2 ) M_free(buffer2,
"tb,ReadObject");
1354 if ( buffer2 == 0 )
return(buffer1);
1355 finallength = obj->uncompressed;
1356 if ( uncompress((Bytef *)buffer2,&finallength,(Bytef *)buffer1,obj->size) != Z_OK ) {
1357 MesPrint(
"Cannot uncompress element %s in file %s\n",arguments,d->name);
1358 M_free(buffer1,
"tb,ReadObject"); M_free(buffer2,
"tb,ReadObject");
1361 M_free(buffer1,
"tb,ReadObject");
1375char *ReadijObject(
DBASE *d,MLONG i,MLONG j,
char *arguments)
1381 uLongf finallength = 0;
1383 obj = &(d->iblocks[i]->objects[j]);
1384 fseek(d->handle,obj->position,SEEK_SET);
1385 if ( ( buffer1 = (
char *)Malloc1(obj->size,
"reading rhs buffer1") ) == 0 ) {
1389 if ( obj->uncompressed > 0 ) {
1390 if ( ( buffer2 = (
char *)Malloc1(obj->uncompressed,
"reading rhs buffer2") ) == 0 ) {
1396 if ( minosread(d->handle,buffer1,obj->size) ) {
1397 MesPrint(
"Could not read rhs %s in file %s\n",arguments,d->name);
1398 if ( buffer1 ) M_free(buffer1,
"rhs buffer1");
1400 if ( buffer2 ) M_free(buffer2,
"rhs buffer2");
1405 if ( buffer2 == 0 )
return(buffer1);
1406 finallength = obj->uncompressed;
1407 if ( uncompress((Bytef *)buffer2,&finallength,(Bytef *)buffer1,obj->size) != Z_OK ) {
1408 MesPrint(
"Cannot uncompress element %s in file %s\n",arguments,d->name);
1409 if ( buffer1 ) M_free(buffer1,
"rhs buffer1");
1410 if ( buffer2 ) M_free(buffer2,
"rhs buffer2");
1413 M_free(buffer1,
"rhs buffer1");
1427int ExistsObject(
DBASE *d,MLONG tablenumber,
char *arguments)
1431 if ( tablenumber > d->topnumber ) {
1432 MesPrint(
"Reference to non-existing table number in tablebase %s: %ld\n",
1433 d->name,tablenumber);
1439 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1440 for ( j = 0; j < NUMOBJECTS; j++ ) {
1441 if ( d->iblocks[i]->objects[j].tablenumber != tablenumber )
continue;
1442 s = arguments; t = d->iblocks[i]->objects[j].element;
1443 while ( *s == *t && *s ) { s++; t++; }
1444 if ( *t == 0 && *s == 0 )
return(1);
1459int DeleteObject(
DBASE *d,MLONG tablenumber,
char *arguments)
1463 if ( tablenumber > d->topnumber ) {
1464 MesPrint(
"Reference to non-existing table number in tablebase %s: %ld\n",
1465 d->name,tablenumber);
1471 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1472 for ( j = 0; j < NUMOBJECTS; j++ ) {
1473 if ( d->iblocks[i]->objects[j].tablenumber != tablenumber )
continue;
1474 s = arguments; t = d->iblocks[i]->objects[j].element;
1475 while ( *s == *t && *s ) { s++; t++; }
1476 if ( *t == 0 && *s == 0 ) {
1477 d->iblocks[i]->objects[j].tablenumber =
1478 -d->iblocks[i]->objects[j].tablenumber - 1;