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 ) {
300 MesPrint(
"!>We need more than %ld bytes for the index.\n",MAXINDEXSIZE);
301 MesPrint(
"The file %s may not be a proper database\n",d->name);
305 size =
sizeof(
INDEXBLOCK *)*d->info.numberofindexblocks;
306 if ( ( ib = (
INDEXBLOCK **)Malloc1(size,
"tb,index") ) == 0 )
return(-1);
307 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
309 for ( --i; i >= 0; i-- ) M_free(ib[i],
"tb,indexblock");
310 M_free(ib,
"tb,index");
314 size =
sizeof(
NAMESBLOCK *)*d->info.numberofnamesblocks;
315 if ( ( ina = (
NAMESBLOCK **)Malloc1(size,
"tb,indexnames") ) == 0 )
return(-1);
316 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
318 for ( --i; i >= 0; i-- ) M_free(ina[i],
"index names block");
319 M_free(ina,
"tb,indexnames");
320 for ( i = 0; i < d->info.numberofindexblocks; i++ ) M_free(ib[i],
"tb,indexblock");
321 M_free(ib,
"tb,index");
329 position = d->info.lastindexblock;
330 for ( i = d->info.numberofindexblocks - 1; i >= 0; i-- ) {
331 fseek(d->handle,position,SEEK_SET);
332 if ( minosread(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
334 MesPrint(
"!>Error while reading file %s\n",d->name);
336 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) M_free(ina[i],
"index names block");
337 M_free(ina,
"tb,indexnames");
338 for ( i = 0; i < d->info.numberofindexblocks; i++ ) M_free(ib[i],
"tb,indexblock");
339 M_free(ib,
"tb,index");
343 convertblock(&scratchblock,ib[i],FROMDISK);
344 if ( ib[i]->position != position ||
345 ( ib[i]->previousblock <= 0 && i > 0 ) ) {
347 MesPrint(
"!>File %s has inconsistent contents\n",d->name);
351 position = ib[i]->previousblock;
353 d->info.firstindexblock = ib[0]->position;
354 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
355 ib[i]->flags &= MCLEANFLAG;
361 position = d->info.lastnameblock;
362 for ( i = d->info.numberofnamesblocks - 1; i >= 0; i-- ) {
363 fseek(d->handle,position,SEEK_SET);
364 if ( minosread(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
366 MesPrint(
"!>Error while reading file %s\n",d->name);
370 convertnamesblock(&scratchnamesblock,ina[i],FROMDISK);
371 if ( ina[i]->position != position ||
372 ( ina[i]->previousblock <= 0 && i > 0 ) ) {
374 MesPrint(
"!>File %s has inconsistent contents\n",d->name);
378 position = ina[i]->previousblock;
380 d->info.firstnameblock = ina[0]->position;
385 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
386 if ( d->iblocks[i] ) M_free(d->iblocks[i],
"d->iblocks[i]");
388 M_free(d->iblocks,
"d->iblocks");
391 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
392 if ( d->nblocks[i] ) M_free(d->nblocks[i],
"d->nblocks[i]");
394 M_free(d->nblocks,
"d->nblocks");
409int WriteIndexBlock(
DBASE *d,MLONG num)
411 if ( num >= d->info.numberofindexblocks ) {
413 MesPrint(
"!>Illegal number specified for number of index blocks\n");
417 fseek(d->handle,d->iblocks[num]->position,SEEK_SET);
418 convertblock(d->iblocks[num],&scratchblock,TODISK);
419 if ( minoswrite(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
421 MesPrint(
"!>Error while writing an index block in file %s\n",d->name);
422 MesPrint(
"File may be unreliable now\n");
434int WriteNamesBlock(
DBASE *d,MLONG num)
436 if ( num >= d->info.numberofnamesblocks ) {
438 MesPrint(
"!>Illegal number specified for number of names blocks\n");
442 fseek(d->handle,d->nblocks[num]->position,SEEK_SET);
443 convertnamesblock(d->nblocks[num],&scratchnamesblock,TODISK);
444 if ( minoswrite(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
446 MesPrint(
"!>Error while writing a names block in file %s\n",d->name);
447 MesPrint(
"File may be unreliable now\n");
461int WriteIndex(
DBASE *d)
464 if ( d->iblocks == 0 )
return(0);
465 if ( d->nblocks == 0 )
return(0);
466 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
467 if ( d->iblocks[i] == 0 ) {
469 MesPrint(
"!>Error: unassigned index blocks. Cannot write\n");
474 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
475 if ( d->nblocks[i] == 0 ) {
477 MesPrint(
"!>Error: unassigned names blocks. Cannot write\n");
482 d->info.lastindexblock = -1;
483 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
484 position = d->iblocks[i]->position;
485 if ( position <= 0 ) {
486 fseek(d->handle,0,SEEK_END);
487 position = ftell(d->handle);
488 d->iblocks[i]->position = position;
489 if ( i <= 0 ) d->iblocks[i]->previousblock = -1;
490 else d->iblocks[i]->previousblock = d->iblocks[i-1]->position;
492 else fseek(d->handle,position,SEEK_SET);
493 convertblock(d->iblocks[i],&scratchblock,TODISK);
494 if ( minoswrite(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
496 MesPrint(
"!>Error while writing index of file %s",d->name);
497 d->iblocks[i]->position = -1;
501 d->info.lastindexblock = position;
503 d->info.lastnameblock = -1;
504 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
505 position = d->nblocks[i]->position;
506 if ( position <= 0 ) {
507 fseek(d->handle,0,SEEK_END);
508 position = ftell(d->handle);
509 d->nblocks[i]->position = position;
510 if ( i <= 0 ) d->nblocks[i]->previousblock = -1;
511 else d->nblocks[i]->previousblock = d->nblocks[i-1]->position;
513 else fseek(d->handle,position,SEEK_SET);
514 convertnamesblock(d->nblocks[i],&scratchnamesblock,TODISK);
515 if ( minoswrite(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
517 MesPrint(
"!>Error while writing index of file %s",d->name);
518 d->nblocks[i]->position = -1;
522 d->info.lastnameblock = position;
532int WriteIniInfo(
DBASE *d)
535 fseek(d->handle,0,SEEK_SET);
536 convertiniinfo(&(d->info),&inf,TODISK);
537 if ( minoswrite(d->handle,(
char *)(&inf),
sizeof(
INIINFO)) ) {
539 MesPrint(
"!>Error while writing masterindex of file %s",d->name);
551int ReadIniInfo(
DBASE *d)
554 fseek(d->handle,0,SEEK_SET);
555 if ( minosread(d->handle,(
char *)(&inf),
sizeof(
INIINFO)) ) {
557 MesPrint(
"!>Error while reading masterindex of file %s",d->name);
561 convertiniinfo(&inf,&(d->info),FROMDISK);
562 if ( d->info.entriesinindex < 0
563 || d->info.numberofindexblocks < 0
564 || d->info.lastindexblock < 0 ) {
566 MesPrint(
"!>The file %s is not a proper database\n",d->name);
578DBASE *GetDbase(
char *filename, MLONG rwmode)
584 if ( ( f = LocateBase(&filename,&newname,
"rb") ) == 0 ) {
586 MesPrint(
"&Trying to open non-existent TableBase in readonly mode: %s", filename);
590 if ( ( f = LocateBase(&filename,&newname,
"r+b") ) == 0 ) {
592 return(NewDbase(filename,0));
597 d = (
DBASE *)From0List(&(AC.TableBaseList));
599 d->tablenamessize = 0;
601 d->tablenamefill = 0;
607 d->info.entriesinindex = 0;
608 d->info.numberofindexblocks = 0;
609 d->info.firstindexblock = 0;
610 d->info.lastindexblock = 0;
611 d->info.numberoftables = 0;
612 d->info.numberofnamesblocks = 0;
613 d->info.firstnameblock = 0;
614 d->info.lastnameblock = 0;
616 d->name = str_dup(filename);
618 if ( ReadIniInfo(d) || ReadIndex(d) ) { M_free(d,
"index-d"); fclose(f);
return(0); }
619 if ( ComposeTableNames(d) < 0 ) { FreeTableBase(d); fclose(f);
return(0); }
621 M_free(d->name,
"from str_dup");
622 d->name = str_dup(filename);
623 d->fullname = newname;
634DBASE *NewDbase(
char *name,MLONG number)
638 MLONG numblocks, numnameblocks, i;
642 MLONG t = (MLONG)(time(0));
644 if ( number < 0 ) number = 0;
645 if ( ( f = fopen(name,
"w+b") ) == 0 ) {
646 MesPrint(
"Could not create a new file with name %s\n",name);
649 numblocks = (number+NUMOBJECTS-1)/NUMOBJECTS;
651 if ( numblocks <= 0 ) numblocks = 1;
652 if ( numnameblocks <= 0 ) numnameblocks = 1;
653 d = (
DBASE *)From0List(&(AC.TableBaseList));
655 "new database") ) == 0 ) {
661 d->tablenamessize = 0;
663 d->tablenamefill = 0;
668 "new database") ) == 0 ) {
669 M_free(d->iblocks,
"new database");
674 if ( ( f = fopen(name,
"w+b") ) == 0 ) {
675 MesPrint(
"Could not create new file %s\n",name);
680 d->name = str_dup(name);
681 d->fullname = str_dup(name);
684 d->info.entriesinindex = number;
685 d->info.numberofindexblocks = numblocks;
686 d->info.numberofnamesblocks = numnameblocks;
687 d->info.firstindexblock = 0;
688 d->info.lastindexblock = 0;
689 d->info.numberoftables = 0;
690 d->info.firstnameblock = 0;
691 d->info.lastnameblock = 0;
693 if ( WriteIniInfo(d) ) {
698 if ( d->name ) { M_free(d->name,
"name tablebase"); d->name = 0; }
699 if ( d->fullname ) { M_free(d->fullname,
"fullname tablebase"); d->fullname = 0; }
700 M_free(d->nblocks,
"new database");
701 M_free(d->iblocks,
"new database");
706 for ( i = 0; i < numblocks; i++ ) {
708 "index blocks of new database") ) == 0 ) {
710 while ( --i >= 0 ) M_free(d->iblocks[i],
"index blocks of new database");
714 if ( i > 0 ) d->iblocks[i]->previousblock = d->iblocks[i-1]->position;
715 else d->iblocks[i]->previousblock = -1;
716 d->iblocks[i]->position = ftell(f);
718 d->iblocks[i]->flags = -1;
723 for ( j = 0; j < NUMOBJECTS; j++ ) {
724 d->iblocks[i]->objects[j].date = t;
725 d->iblocks[i]->objects[j].size = 0;
726 d->iblocks[i]->objects[j].position = -1;
727 d->iblocks[i]->objects[j].tablenumber = 0;
728 d->iblocks[i]->objects[j].uncompressed = 0;
729 d->iblocks[i]->objects[j].spare1 = 0;
730 d->iblocks[i]->objects[j].spare2 = 0;
731 d->iblocks[i]->objects[j].spare3 = 0;
732 for ( jj = 0; jj < ELEMENTSIZE; jj++ ) d->iblocks[i]->objects[j].element[jj] = 0;
734 convertblock(d->iblocks[i],&scratchblock,TODISK);
735 if ( minoswrite(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
737 MesPrint(
"!>Error while writing new index blocks\n");
742 for ( i = 0; i < numnameblocks; i++ ) {
744 "names blocks of new database") ) == 0 ) {
745 while ( --i >= 0 ) { M_free(d->nblocks[i],
"names blocks of new database"); }
746 for ( i = 0; i < numblocks; i++ ) M_free(d->iblocks[i],
"index blocks of new database");
749 if ( i > 0 ) d->nblocks[i]->previousblock = d->nblocks[i-1]->position;
750 else d->nblocks[i]->previousblock = -1;
751 d->nblocks[i]->position = ftell(f);
752 s = d->nblocks[i]->names;
753 for ( j = 0; j < NAMETABLESIZE; j++ ) *s++ = 0;
754 convertnamesblock(d->nblocks[i],&scratchnamesblock,TODISK);
755 if ( minoswrite(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
757 MesPrint(
"!>Error while writing new names blocks\n");
758 for ( i = 0; i < numnameblocks; i++ ) M_free(d->nblocks[i],
"names blocks of new database");
759 for ( i = 0; i < numblocks; i++ ) M_free(d->iblocks[i],
"index blocks of new database");
764 d->info.firstindexblock = d->iblocks[0]->position;
765 d->info.lastindexblock = d->iblocks[numblocks-1]->position;
766 d->info.firstnameblock = d->nblocks[0]->position;
767 d->info.lastnameblock = d->nblocks[numnameblocks-1]->position;
768 if ( WriteIniInfo(d) ) {
769 for ( i = 0; i < numnameblocks; i++ ) M_free(d->nblocks[i],
"names blocks of new database");
770 for ( i = 0; i < numblocks; i++ ) M_free(d->iblocks[i],
"index blocks of new database");
781void FreeTableBase(
DBASE *d)
783 int i, j, *old, *newL;
785 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) M_free(d->nblocks[i],
"nblocks[i]");
786 for ( i = 0; i < d->info.numberofindexblocks; i++ ) M_free(d->iblocks[i],
"iblocks[i]");
787 M_free(d->nblocks,
"nblocks");
788 M_free(d->iblocks,
"iblocks");
789 if ( d->tablenames ) M_free(d->tablenames,
"d->tablenames");
790 if ( d->name ) M_free(d->name,
"d->name");
791 if ( d->fullname ) M_free(d->fullname,
"d->fullname");
793 if ( i < ( NumTableBases - 1 ) ) {
794 L = &(AC.TableBaseList);
795 j = ( ( NumTableBases - i - 1 ) * L->
size ) /
sizeof(int);
796 old = (
int *)d; newL = (
int *)(d+1);
797 while ( --j >= 0 ) *newL++ = *old++;
798 j = L->
size /
sizeof(int);
799 while ( --j >= 0 ) *newL++ = 0;
813int ComposeTableNames(
DBASE *d)
819 i = 0; s = d->nblocks[i]->names; j = NAMETABLESIZE;
821 if ( *s ) d->topnumber++;
822 for ( k = 0; k < 2; k++ ) {
826 i++;
if ( i >= d->info.numberofnamesblocks )
goto gotall;
827 s = d->nblocks[i]->names; j = NAMETABLESIZE;
833 i++;
if ( i >= d->info.numberofnamesblocks )
goto gotall;
834 s = d->nblocks[i]->names; j = NAMETABLESIZE;
840 nsize = (d->info.numberofnamesblocks-1)*NAMETABLESIZE +
841 (s-d->nblocks[i]->names)+1;
842 if ( ( d->tablenames = (
char *)Malloc1((2*nsize+30)*
sizeof(
char),
"tablenames") )
843 == 0 ) {
return(-1); }
845 d->tablenamessize = 2*nsize+30;
846 d->tablenamefill = nsize-1;
847 for ( k = 0; k < i; k++ ) {
848 ss = d->nblocks[k]->names;
849 for ( j = 0; j < NAMETABLESIZE; j++ ) *t++ = *ss++;
851 ss = d->nblocks[i]->names;
852 while ( ss < s ) *t++ = *ss++;
862DBASE *OpenDbase(
char *filename)
867 if ( ( f = LocateBase(&filename,&newname,
"r+b") ) == 0 ) {
868 MesPrint(
"Cannot open file %s\n",filename);
872 d = (
DBASE *)From0List(&(AC.TableBaseList));
875 if ( ReadIniInfo(d) || ReadIndex(d) ) { M_free(d,
"OpenDbase"); fclose(f);
return(0); }
876 if ( ComposeTableNames(d) ) {
881 d->name = str_dup(filename);
882 d->fullname = newname;
899 int namesize, tailsize;
900 MLONG newsize, i, num;
904 if ( d->tablenames ) {
910 while ( ( *s == *t ) && *t ) { s++; t++; }
911 if ( *s == *t ) {
return(-num); }
921 MesPrint(
"We add the name %s\n",name);
923 while ( *t ) { t++; }
925 if ( ( t = (
char *)(T->
argtail) ) != 0 ) {
926 while ( *t ) { t++; }
927 tailsize = t - (
char *)(T->
argtail);
929 else { tailsize = 0; }
930 if ( d->tablenames == 0 ) {
931 if ( ComposeTableNames(d) ) {
933 M_free(d,
"AddTableName");
937 d->info.numberoftables++;
938 while ( ( d->tablenamefill+namesize+tailsize+3 > d->tablenamessize )
939 || ( d->tablenames == 0 ) ) {
940 newsize = 2*d->tablenamessize + 2*namesize + 2*tailsize + 6;
941 if ( ( t = (
char *)Malloc1(newsize*
sizeof(
char),
"AddTableName") ) == 0 )
944 if ( d->tablenames ) {
946 for ( i = 0; i < d->tablenamefill; i++ ) *t++ = *s++;
948 M_free(d->tablenames,
"d->tablenames");
951 d->tablenamessize = newsize;
953 s = d->tablenames + d->tablenamefill;
955 while ( *t ) *s++ = *t++;
958 while ( *t ) *s++ = *t++;
961 d->tablenamefill = s - d->tablenames;
966 if ( PutTableNames(d) )
return(0);
967 return(d->topnumber);
979MLONG GetTableName(
DBASE *d,
char *name)
986 if ( d->tablenames ) {
992 while ( ( *s == *t ) && *t ) { s++; t++; }
993 if ( *s == *t ) {
return(num); }
1011int PutTableNames(
DBASE *d)
1020 MLONG numblocks = d->tablenamefill/NAMETABLESIZE + 1;
1021 if ( d->info.numberofnamesblocks < numblocks ) {
1026 "new names block") ) == 0 ) {
1029 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
1030 nnew[i] = d->nblocks[i];
1034 for ( ; i < numblocks; i++ ) {
1036 "additional names blocks ") ) == 0 ) {
1040 d->nblocks[i]->previousblock = -1;
1041 d->nblocks[i]->position = -1;
1042 s = d->nblocks[i]->names;
1043 for ( j = 0; j < NAMETABLESIZE; j++ ) *s++ = 0;
1045 d->info.numberofnamesblocks = numblocks;
1051 i = 0; t = d->nblocks[i]->names; j = 0; s = d->tablenames;
1052 for ( m = 0; m < d->tablenamefill; m++ ) {
1055 if ( j >= NAMETABLESIZE ) {
1057 t = d->nblocks[i]->names;
1063 for ( ; m < d->tablenamefill; m++ ) {
1065 if ( j >= NAMETABLESIZE ) {
1067 t = d->nblocks[i]->names;
1075 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
1076 if ( i == firstdif )
break;
1077 if ( d->nblocks[i]->position < 0 ) { firstdif = i;
break; }
1082 for ( i = firstdif; i < d->info.numberofnamesblocks; i++ ) {
1083 if ( i > 0 ) d->nblocks[i]->previousblock = d->nblocks[i-1]->position;
1084 else d->nblocks[i]->previousblock = -1;
1085 if ( d->nblocks[i]->position < 0 ) {
1086 fseek(d->handle,0,SEEK_END);
1087 d->nblocks[i]->position = ftell(d->handle);
1089 else fseek(d->handle,d->nblocks[i]->position,SEEK_SET);
1090 convertnamesblock(d->nblocks[i],&scratchnamesblock,TODISK);
1091 if ( minoswrite(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
1093 MesPrint(
"!>Error while writing names blocks\n");
1099 d->info.lastnameblock = d->nblocks[d->info.numberofnamesblocks-1]->position;
1100 d->info.firstnameblock = d->nblocks[0]->position;
1101 return(WriteIniInfo(d));
1109int AddToIndex(
DBASE *d,MLONG number)
1111 MLONG i, oldnumofindexblocks = d->info.numberofindexblocks;
1112 MLONG j, newnumofindexblocks, jj;
1114 MLONG t = (MLONG)(time(0));
1115 if ( number == 0 )
return(0);
1116 else if ( number < 0 ) {
1117 if ( d->info.entriesinindex < -number ) {
1119 MesPrint(
"!>There are only %ld entries in the index of file %s\n",
1120 d->info.entriesinindex,d->name);
1124 d->info.entriesinindex += number;
1126 if ( WriteIniInfo(d) ) {
1128 d->info.entriesinindex -= number;
1129 MesPrint(
"!>File may be corrupted\n");
1134 else if ( d->info.entriesinindex+number <=
1135 NUMOBJECTS*d->info.numberofindexblocks ) {
1136 d->info.entriesinindex += number;
1140 d->info.entriesinindex += number;
1141 newnumofindexblocks = d->info.numberofindexblocks + ((number -
1142 (NUMOBJECTS*d->info.numberofindexblocks - d->info.entriesinindex))
1143 +NUMOBJECTS-1)/NUMOBJECTS;
1145 "index") ) == 0 )
return(-1);
1146 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1147 ib[i] = d->iblocks[i];
1149 for ( i = d->info.numberofindexblocks; i < newnumofindexblocks; i++ ) {
1154 if ( i > 0 ) ib[i]->previousblock = ib[i-1]->position;
1155 else ib[i]->previousblock = -1;
1159 for ( j = 0; j < NUMOBJECTS; j++ ) {
1160 ib[i]->objects[j].date = t;
1161 ib[i]->objects[j].size = 0;
1162 ib[i]->objects[j].position = -1;
1163 ib[i]->objects[j].tablenumber = 0;
1164 ib[i]->objects[j].uncompressed = 0;
1165 ib[i]->objects[j].spare1 = 0;
1166 ib[i]->objects[j].spare2 = 0;
1167 ib[i]->objects[j].spare3 = 0;
1168 for ( jj = 0; jj < ELEMENTSIZE; jj++ ) ib[i]->
objects[j].element[jj] = 0;
1170 fseek(d->handle,0,SEEK_END);
1171 ib[i]->position = ftell(d->handle);
1172 convertblock(ib[i],&scratchblock,TODISK);
1173 if ( minoswrite(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
1175 MesPrint(
"!>Error while writing new index of file %s",d->name);
1181 d->info.lastindexblock = ib[newnumofindexblocks-1]->position;
1182 d->info.firstindexblock = ib[0]->position;
1183 d->info.numberofindexblocks = newnumofindexblocks;
1184 if ( WriteIniInfo(d) ) {
1186 d->info.numberofindexblocks = oldnumofindexblocks;
1187 d->info.entriesinindex -= number;
1188 MesPrint(
"!>File may be corrupted\n");
1193 M_free(d->iblocks,
"AddToIndex");
1204MLONG AddObject(
DBASE *d,MLONG tablenumber,
char *arguments,
char *rhs)
1207 number = d->info.entriesinindex;
1208 if ( AddToIndex(d,1) )
return(-1);
1209 if ( WriteObject(d,tablenumber,arguments,rhs,number) )
return(-1);
1218MLONG FindTableNumber(
DBASE *d,
char *name)
1220 char *s = d->tablenames, *t, *ss;
1222 ss = d->tablenames + d->tablenamefill;
1226 while ( *s == *t && *t ) {
1229 if ( *s == 0 && *t == 0 )
return(num);
1246int WriteObject(
DBASE *d,MLONG tablenumber,
char *arguments,
char *rhs,MLONG number)
1251 uLongf newsize = 0, oldsize = 0;
1255 MLONG i, j, position, size, n;
1257 if ( ( d->mode & INPUTONLY ) == INPUTONLY ) {
1258 MesPrint(
"Not allowed to write to input\n");
1261 if ( number >= d->info.entriesinindex ) {
1262 MesPrint(
"Reference to non-existing object number %ld\n",number+1);
1265 j = number/NUMOBJECTS;
1266 i = number%NUMOBJECTS;
1267 obj = &(d->iblocks[j]->objects[i]);
1270 a++; n = a - arguments;
1271 if ( n > ELEMENTSIZE ) {
1272 MesPrint(
"Table element %s has more than %ld characters.\n",arguments,
1273 (MLONG)ELEMENTSIZE);
1278 while ( *a ) *s++ = *a++;
1280 while ( n < ELEMENTSIZE ) { *s++ = 0; n++; }
1281 obj->spare1 = obj->spare2 = obj->spare3 = 0;
1283 fseek(d->handle,0,SEEK_END);
1284 position = ftell(d->handle);
1290 if ( ( d->mode & NOCOMPRESS ) == 0 ) {
1291 newsize = size + size/1000 + 20;
1292 if ( ( buffer = (
char *)Malloc1(newsize*
sizeof(
char),
"compress buffer") )
1294 MesPrint(
"No compress used for element %s in file %s\n",arguments,d->name);
1303 const int old_isUsingZSTDcompression = ZWRAP_isUsingZSTDcompression();
1304 ZWRAP_useZSTDcompression(0);
1306 if ( ( error = compress((Bytef *)buffer,&newsize,(Bytef *)rhs,ssize) ) != Z_OK ) {
1308 MesPrint(
"!>Due to error no compress used for element %s in file %s\n",arguments,d->name);
1309 MesPrint(
"Error = %d\n",error);
1310 M_free(buffer,
"tb,WriteObject");
1315 ZWRAP_useZSTDcompression(old_isUsingZSTDcompression);
1324 if ( minoswrite(d->handle,rhs,size) ) {
1326 MesPrint(
"!>Error while writing rhs\n");
1330 obj->position = position;
1332 obj->date = (MLONG)(time(0));
1333 obj->tablenumber = tablenumber;
1335 obj->uncompressed = oldsize;
1336 if ( buffer ) M_free(buffer,
"tb,WriteObject");
1338 obj->uncompressed = 0;
1340 return(WriteIndexBlock(d,j));
1350char *ReadObject(
DBASE *d,MLONG tablenumber,
char *arguments)
1354 char *buffer1, *s, *t;
1357 uLongf finallength = 0;
1359 if ( tablenumber > d->topnumber ) {
1360 MesPrint(
"Reference to non-existing table number in tablebase %s: %ld\n",
1361 d->name,tablenumber);
1367 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1368 for ( j = 0; j < NUMOBJECTS; j++ ) {
1369 if ( d->iblocks[i]->objects[j].tablenumber != tablenumber )
continue;
1370 s = arguments; t = d->iblocks[i]->objects[j].element;
1371 while ( *s == *t && *s ) { s++; t++; }
1372 if ( *t == 0 && *s == 0 )
goto foundelement;
1375 s = d->tablenames; i = 1;
1377 if ( i == tablenumber )
break;
1384 MesPrint(
"%s(%s) not found in tablebase %s\n",s,arguments,d->name);
1388 obj = &(d->iblocks[i]->objects[j]);
1389 fseek(d->handle,obj->position,SEEK_SET);
1390 if ( ( buffer1 = (
char *)Malloc1(obj->size,
"reading rhs buffer1") ) == 0 ) {
1394 if ( obj->uncompressed > 0 ) {
1395 if ( ( buffer2 = (
char *)Malloc1(obj->uncompressed,
"reading rhs buffer2") ) == 0 ) {
1401 if ( minosread(d->handle,buffer1,obj->size) ) {
1403 MesPrint(
"!>Could not read rhs %s in file %s\n",arguments,d->name);
1404 M_free(buffer1,
"tb,ReadObject");
1406 if ( buffer2 ) M_free(buffer2,
"tb,ReadObject");
1412 if ( buffer2 == 0 )
return(buffer1);
1413 finallength = obj->uncompressed;
1414 if ( uncompress((Bytef *)buffer2,&finallength,(Bytef *)buffer1,obj->size) != Z_OK ) {
1416 MesPrint(
"!>Cannot uncompress element %s in file %s\n",arguments,d->name);
1417 M_free(buffer1,
"tb,ReadObject"); M_free(buffer2,
"tb,ReadObject");
1421 M_free(buffer1,
"tb,ReadObject");
1435char *ReadijObject(
DBASE *d,MLONG i,MLONG j,
char *arguments)
1441 uLongf finallength = 0;
1443 obj = &(d->iblocks[i]->objects[j]);
1444 fseek(d->handle,obj->position,SEEK_SET);
1445 if ( ( buffer1 = (
char *)Malloc1(obj->size,
"reading rhs buffer1") ) == 0 ) {
1449 if ( obj->uncompressed > 0 ) {
1450 if ( ( buffer2 = (
char *)Malloc1(obj->uncompressed,
"reading rhs buffer2") ) == 0 ) {
1456 if ( minosread(d->handle,buffer1,obj->size) ) {
1458 MesPrint(
"!>Could not read rhs %s in file %s\n",arguments,d->name);
1459 if ( buffer1 ) M_free(buffer1,
"rhs buffer1");
1461 if ( buffer2 ) M_free(buffer2,
"rhs buffer2");
1467 if ( buffer2 == 0 )
return(buffer1);
1468 finallength = obj->uncompressed;
1469 if ( uncompress((Bytef *)buffer2,&finallength,(Bytef *)buffer1,obj->size) != Z_OK ) {
1471 MesPrint(
"!>Cannot uncompress element %s in file %s\n",arguments,d->name);
1472 if ( buffer1 ) M_free(buffer1,
"rhs buffer1");
1473 if ( buffer2 ) M_free(buffer2,
"rhs buffer2");
1477 M_free(buffer1,
"rhs buffer1");
1491int ExistsObject(
DBASE *d,MLONG tablenumber,
char *arguments)
1495 if ( tablenumber > d->topnumber ) {
1496 MesPrint(
"Reference to non-existing table number in tablebase %s: %ld\n",
1497 d->name,tablenumber);
1503 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1504 for ( j = 0; j < NUMOBJECTS; j++ ) {
1505 if ( d->iblocks[i]->objects[j].tablenumber != tablenumber )
continue;
1506 s = arguments; t = d->iblocks[i]->objects[j].element;
1507 while ( *s == *t && *s ) { s++; t++; }
1508 if ( *t == 0 && *s == 0 )
return(1);
1523int DeleteObject(
DBASE *d,MLONG tablenumber,
char *arguments)
1527 if ( tablenumber > d->topnumber ) {
1528 MesPrint(
"Reference to non-existing table number in tablebase %s: %ld\n",
1529 d->name,tablenumber);
1535 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1536 for ( j = 0; j < NUMOBJECTS; j++ ) {
1537 if ( d->iblocks[i]->objects[j].tablenumber != tablenumber )
continue;
1538 s = arguments; t = d->iblocks[i]->objects[j].element;
1539 while ( *s == *t && *s ) { s++; t++; }
1540 if ( *t == 0 && *s == 0 ) {
1541 d->iblocks[i]->objects[j].tablenumber =
1542 -d->iblocks[i]->objects[j].tablenumber - 1;