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 d->iblocks[num]->flags &= MCLEANFLAG;
419 convertblock(d->iblocks[num],&scratchblock,TODISK);
420 if ( minoswrite(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
422 d->iblocks[num]->flags |= MDIRTYFLAG;
423 MesPrint(
"!>Error while writing an index block in file %s\n",d->name);
424 MesPrint(
"File may be unreliable now\n");
436int FlushDirtyIndexBlocks(
DBASE *d)
439 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
440 if ( ( d->iblocks[i]->flags & MDIRTYFLAG ) != 0 ) {
441 if ( WriteIndexBlock(d,i) )
return(-1);
452int WriteNamesBlock(
DBASE *d,MLONG num)
454 if ( num >= d->info.numberofnamesblocks ) {
456 MesPrint(
"!>Illegal number specified for number of names blocks\n");
460 fseek(d->handle,d->nblocks[num]->position,SEEK_SET);
461 convertnamesblock(d->nblocks[num],&scratchnamesblock,TODISK);
462 if ( minoswrite(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
464 MesPrint(
"!>Error while writing a names block in file %s\n",d->name);
465 MesPrint(
"File may be unreliable now\n");
479int WriteIndex(
DBASE *d)
482 if ( d->iblocks == 0 )
return(0);
483 if ( d->nblocks == 0 )
return(0);
484 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
485 if ( d->iblocks[i] == 0 ) {
487 MesPrint(
"!>Error: unassigned index blocks. Cannot write\n");
492 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
493 if ( d->nblocks[i] == 0 ) {
495 MesPrint(
"!>Error: unassigned names blocks. Cannot write\n");
500 d->info.lastindexblock = -1;
501 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
502 position = d->iblocks[i]->position;
503 if ( position <= 0 ) {
504 fseek(d->handle,0,SEEK_END);
505 position = ftell(d->handle);
506 d->iblocks[i]->position = position;
507 if ( i <= 0 ) d->iblocks[i]->previousblock = -1;
508 else d->iblocks[i]->previousblock = d->iblocks[i-1]->position;
510 else fseek(d->handle,position,SEEK_SET);
511 convertblock(d->iblocks[i],&scratchblock,TODISK);
512 if ( minoswrite(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
514 MesPrint(
"!>Error while writing index of file %s",d->name);
515 d->iblocks[i]->position = -1;
519 d->info.lastindexblock = position;
521 d->info.lastnameblock = -1;
522 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
523 position = d->nblocks[i]->position;
524 if ( position <= 0 ) {
525 fseek(d->handle,0,SEEK_END);
526 position = ftell(d->handle);
527 d->nblocks[i]->position = position;
528 if ( i <= 0 ) d->nblocks[i]->previousblock = -1;
529 else d->nblocks[i]->previousblock = d->nblocks[i-1]->position;
531 else fseek(d->handle,position,SEEK_SET);
532 convertnamesblock(d->nblocks[i],&scratchnamesblock,TODISK);
533 if ( minoswrite(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
535 MesPrint(
"!>Error while writing index of file %s",d->name);
536 d->nblocks[i]->position = -1;
540 d->info.lastnameblock = position;
550int WriteIniInfo(
DBASE *d)
553 fseek(d->handle,0,SEEK_SET);
554 convertiniinfo(&(d->info),&inf,TODISK);
555 if ( minoswrite(d->handle,(
char *)(&inf),
sizeof(
INIINFO)) ) {
557 MesPrint(
"!>Error while writing masterindex of file %s",d->name);
569int ReadIniInfo(
DBASE *d)
572 fseek(d->handle,0,SEEK_SET);
573 if ( minosread(d->handle,(
char *)(&inf),
sizeof(
INIINFO)) ) {
575 MesPrint(
"!>Error while reading masterindex of file %s",d->name);
579 convertiniinfo(&inf,&(d->info),FROMDISK);
580 if ( d->info.entriesinindex < 0
581 || d->info.numberofindexblocks < 0
582 || d->info.lastindexblock < 0 ) {
584 MesPrint(
"!>The file %s is not a proper database\n",d->name);
596DBASE *GetDbase(
char *filename, MLONG rwmode)
602 if ( ( f = LocateBase(&filename,&newname,
"rb") ) == 0 ) {
604 MesPrint(
"&Trying to open non-existent TableBase in readonly mode: %s", filename);
608 if ( ( f = LocateBase(&filename,&newname,
"r+b") ) == 0 ) {
610 return(NewDbase(filename,0));
615 d = (
DBASE *)From0List(&(AC.TableBaseList));
617 d->tablenamessize = 0;
619 d->tablenamefill = 0;
625 d->info.entriesinindex = 0;
626 d->info.numberofindexblocks = 0;
627 d->info.firstindexblock = 0;
628 d->info.lastindexblock = 0;
629 d->info.numberoftables = 0;
630 d->info.numberofnamesblocks = 0;
631 d->info.firstnameblock = 0;
632 d->info.lastnameblock = 0;
634 d->name = str_dup(filename);
636 if ( ReadIniInfo(d) || ReadIndex(d) ) { M_free(d,
"index-d"); fclose(f);
return(0); }
637 if ( ComposeTableNames(d) < 0 ) { FreeTableBase(d); fclose(f);
return(0); }
639 M_free(d->name,
"from str_dup");
640 d->name = str_dup(filename);
641 d->fullname = newname;
652DBASE *NewDbase(
char *name,MLONG number)
656 MLONG numblocks, numnameblocks, i;
660 MLONG t = (MLONG)(time(0));
662 if ( number < 0 ) number = 0;
663 if ( ( f = fopen(name,
"w+b") ) == 0 ) {
664 MesPrint(
"Could not create a new file with name %s\n",name);
667 numblocks = (number+NUMOBJECTS-1)/NUMOBJECTS;
669 if ( numblocks <= 0 ) numblocks = 1;
670 if ( numnameblocks <= 0 ) numnameblocks = 1;
671 d = (
DBASE *)From0List(&(AC.TableBaseList));
673 "new database") ) == 0 ) {
679 d->tablenamessize = 0;
681 d->tablenamefill = 0;
686 "new database") ) == 0 ) {
687 M_free(d->iblocks,
"new database");
692 if ( ( f = fopen(name,
"w+b") ) == 0 ) {
693 MesPrint(
"Could not create new file %s\n",name);
698 d->name = str_dup(name);
699 d->fullname = str_dup(name);
702 d->info.entriesinindex = number;
703 d->info.numberofindexblocks = numblocks;
704 d->info.numberofnamesblocks = numnameblocks;
705 d->info.firstindexblock = 0;
706 d->info.lastindexblock = 0;
707 d->info.numberoftables = 0;
708 d->info.firstnameblock = 0;
709 d->info.lastnameblock = 0;
711 if ( WriteIniInfo(d) ) {
716 if ( d->name ) { M_free(d->name,
"name tablebase"); d->name = 0; }
717 if ( d->fullname ) { M_free(d->fullname,
"fullname tablebase"); d->fullname = 0; }
718 M_free(d->nblocks,
"new database");
719 M_free(d->iblocks,
"new database");
724 for ( i = 0; i < numblocks; i++ ) {
726 "index blocks of new database") ) == 0 ) {
728 while ( --i >= 0 ) M_free(d->iblocks[i],
"index blocks of new database");
732 if ( i > 0 ) d->iblocks[i]->previousblock = d->iblocks[i-1]->position;
733 else d->iblocks[i]->previousblock = -1;
734 d->iblocks[i]->position = ftell(f);
736 d->iblocks[i]->flags = 0;
741 for ( j = 0; j < NUMOBJECTS; j++ ) {
742 d->iblocks[i]->objects[j].date = t;
743 d->iblocks[i]->objects[j].size = 0;
744 d->iblocks[i]->objects[j].position = -1;
745 d->iblocks[i]->objects[j].tablenumber = 0;
746 d->iblocks[i]->objects[j].uncompressed = 0;
747 d->iblocks[i]->objects[j].spare1 = 0;
748 d->iblocks[i]->objects[j].spare2 = 0;
749 d->iblocks[i]->objects[j].spare3 = 0;
750 for ( jj = 0; jj < ELEMENTSIZE; jj++ ) d->iblocks[i]->objects[j].element[jj] = 0;
752 convertblock(d->iblocks[i],&scratchblock,TODISK);
753 if ( minoswrite(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
755 MesPrint(
"!>Error while writing new index blocks\n");
760 for ( i = 0; i < numnameblocks; i++ ) {
762 "names blocks of new database") ) == 0 ) {
763 while ( --i >= 0 ) { M_free(d->nblocks[i],
"names blocks of new database"); }
764 for ( i = 0; i < numblocks; i++ ) M_free(d->iblocks[i],
"index blocks of new database");
767 if ( i > 0 ) d->nblocks[i]->previousblock = d->nblocks[i-1]->position;
768 else d->nblocks[i]->previousblock = -1;
769 d->nblocks[i]->position = ftell(f);
770 s = d->nblocks[i]->names;
771 for ( j = 0; j < NAMETABLESIZE; j++ ) *s++ = 0;
772 convertnamesblock(d->nblocks[i],&scratchnamesblock,TODISK);
773 if ( minoswrite(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
775 MesPrint(
"!>Error while writing new names blocks\n");
776 for ( i = 0; i < numnameblocks; i++ ) M_free(d->nblocks[i],
"names blocks of new database");
777 for ( i = 0; i < numblocks; i++ ) M_free(d->iblocks[i],
"index blocks of new database");
782 d->info.firstindexblock = d->iblocks[0]->position;
783 d->info.lastindexblock = d->iblocks[numblocks-1]->position;
784 d->info.firstnameblock = d->nblocks[0]->position;
785 d->info.lastnameblock = d->nblocks[numnameblocks-1]->position;
786 if ( WriteIniInfo(d) ) {
787 for ( i = 0; i < numnameblocks; i++ ) M_free(d->nblocks[i],
"names blocks of new database");
788 for ( i = 0; i < numblocks; i++ ) M_free(d->iblocks[i],
"index blocks of new database");
799void FreeTableBase(
DBASE *d)
801 int i, j, *old, *newL;
803 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) M_free(d->nblocks[i],
"nblocks[i]");
804 for ( i = 0; i < d->info.numberofindexblocks; i++ ) M_free(d->iblocks[i],
"iblocks[i]");
805 M_free(d->nblocks,
"nblocks");
806 M_free(d->iblocks,
"iblocks");
807 if ( d->tablenames ) M_free(d->tablenames,
"d->tablenames");
808 if ( d->name ) M_free(d->name,
"d->name");
809 if ( d->fullname ) M_free(d->fullname,
"d->fullname");
811 if ( i < ( NumTableBases - 1 ) ) {
812 L = &(AC.TableBaseList);
813 j = ( ( NumTableBases - i - 1 ) * L->
size ) /
sizeof(int);
814 old = (
int *)d; newL = (
int *)(d+1);
815 while ( --j >= 0 ) *newL++ = *old++;
816 j = L->
size /
sizeof(int);
817 while ( --j >= 0 ) *newL++ = 0;
831int ComposeTableNames(
DBASE *d)
837 i = 0; s = d->nblocks[i]->names; j = NAMETABLESIZE;
839 if ( *s ) d->topnumber++;
840 for ( k = 0; k < 2; k++ ) {
844 i++;
if ( i >= d->info.numberofnamesblocks )
goto gotall;
845 s = d->nblocks[i]->names; j = NAMETABLESIZE;
851 i++;
if ( i >= d->info.numberofnamesblocks )
goto gotall;
852 s = d->nblocks[i]->names; j = NAMETABLESIZE;
858 nsize = (d->info.numberofnamesblocks-1)*NAMETABLESIZE +
859 (s-d->nblocks[i]->names)+1;
860 if ( ( d->tablenames = (
char *)Malloc1((2*nsize+30)*
sizeof(
char),
"tablenames") )
861 == 0 ) {
return(-1); }
863 d->tablenamessize = 2*nsize+30;
864 d->tablenamefill = nsize-1;
865 for ( k = 0; k < i; k++ ) {
866 ss = d->nblocks[k]->names;
867 for ( j = 0; j < NAMETABLESIZE; j++ ) *t++ = *ss++;
869 ss = d->nblocks[i]->names;
870 while ( ss < s ) *t++ = *ss++;
880DBASE *OpenDbase(
char *filename)
885 if ( ( f = LocateBase(&filename,&newname,
"r+b") ) == 0 ) {
886 MesPrint(
"Cannot open file %s\n",filename);
890 d = (
DBASE *)From0List(&(AC.TableBaseList));
893 if ( ReadIniInfo(d) || ReadIndex(d) ) { M_free(d,
"OpenDbase"); fclose(f);
return(0); }
894 if ( ComposeTableNames(d) ) {
899 d->name = str_dup(filename);
900 d->fullname = newname;
917 int namesize, tailsize;
918 MLONG newsize, i, num;
922 if ( d->tablenames ) {
928 while ( ( *s == *t ) && *t ) { s++; t++; }
929 if ( *s == *t ) {
return(-num); }
939 MesPrint(
"We add the name %s\n",name);
941 while ( *t ) { t++; }
943 if ( ( t = (
char *)(T->
argtail) ) != 0 ) {
944 while ( *t ) { t++; }
945 tailsize = t - (
char *)(T->
argtail);
947 else { tailsize = 0; }
948 if ( d->tablenames == 0 ) {
949 if ( ComposeTableNames(d) ) {
951 M_free(d,
"AddTableName");
955 d->info.numberoftables++;
956 while ( ( d->tablenamefill+namesize+tailsize+3 > d->tablenamessize )
957 || ( d->tablenames == 0 ) ) {
958 newsize = 2*d->tablenamessize + 2*namesize + 2*tailsize + 6;
959 if ( ( t = (
char *)Malloc1(newsize*
sizeof(
char),
"AddTableName") ) == 0 )
962 if ( d->tablenames ) {
964 for ( i = 0; i < d->tablenamefill; i++ ) *t++ = *s++;
966 M_free(d->tablenames,
"d->tablenames");
969 d->tablenamessize = newsize;
971 s = d->tablenames + d->tablenamefill;
973 while ( *t ) *s++ = *t++;
976 while ( *t ) *s++ = *t++;
979 d->tablenamefill = s - d->tablenames;
984 if ( PutTableNames(d) )
return(0);
985 return(d->topnumber);
997MLONG GetTableName(
DBASE *d,
char *name)
1004 if ( d->tablenames ) {
1010 while ( ( *s == *t ) && *t ) { s++; t++; }
1011 if ( *s == *t ) {
return(num); }
1029int PutTableNames(
DBASE *d)
1038 MLONG numblocks = d->tablenamefill/NAMETABLESIZE + 1;
1039 if ( d->info.numberofnamesblocks < numblocks ) {
1044 "new names block") ) == 0 ) {
1047 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
1048 nnew[i] = d->nblocks[i];
1052 for ( ; i < numblocks; i++ ) {
1054 "additional names blocks ") ) == 0 ) {
1058 d->nblocks[i]->previousblock = -1;
1059 d->nblocks[i]->position = -1;
1060 s = d->nblocks[i]->names;
1061 for ( j = 0; j < NAMETABLESIZE; j++ ) *s++ = 0;
1063 d->info.numberofnamesblocks = numblocks;
1069 i = 0; t = d->nblocks[i]->names; j = 0; s = d->tablenames;
1070 for ( m = 0; m < d->tablenamefill; m++ ) {
1073 if ( j >= NAMETABLESIZE ) {
1075 t = d->nblocks[i]->names;
1081 for ( ; m < d->tablenamefill; m++ ) {
1083 if ( j >= NAMETABLESIZE ) {
1085 t = d->nblocks[i]->names;
1093 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
1094 if ( i == firstdif )
break;
1095 if ( d->nblocks[i]->position < 0 ) { firstdif = i;
break; }
1100 for ( i = firstdif; i < d->info.numberofnamesblocks; i++ ) {
1101 if ( i > 0 ) d->nblocks[i]->previousblock = d->nblocks[i-1]->position;
1102 else d->nblocks[i]->previousblock = -1;
1103 if ( d->nblocks[i]->position < 0 ) {
1104 fseek(d->handle,0,SEEK_END);
1105 d->nblocks[i]->position = ftell(d->handle);
1107 else fseek(d->handle,d->nblocks[i]->position,SEEK_SET);
1108 convertnamesblock(d->nblocks[i],&scratchnamesblock,TODISK);
1109 if ( minoswrite(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
1111 MesPrint(
"!>Error while writing names blocks\n");
1117 d->info.lastnameblock = d->nblocks[d->info.numberofnamesblocks-1]->position;
1118 d->info.firstnameblock = d->nblocks[0]->position;
1119 return(WriteIniInfo(d));
1127int AddToIndex(
DBASE *d,MLONG number)
1129 MLONG i, oldnumofindexblocks = d->info.numberofindexblocks;
1130 MLONG j, newnumofindexblocks, jj;
1132 MLONG t = (MLONG)(time(0));
1133 if ( number == 0 )
return(0);
1134 else if ( number < 0 ) {
1135 if ( d->info.entriesinindex < -number ) {
1137 MesPrint(
"!>There are only %ld entries in the index of file %s\n",
1138 d->info.entriesinindex,d->name);
1142 d->info.entriesinindex += number;
1144 if ( WriteIniInfo(d) ) {
1146 d->info.entriesinindex -= number;
1147 MesPrint(
"!>File may be corrupted\n");
1152 else if ( d->info.entriesinindex+number <=
1153 NUMOBJECTS*d->info.numberofindexblocks ) {
1154 d->info.entriesinindex += number;
1158 d->info.entriesinindex += number;
1159 newnumofindexblocks = d->info.numberofindexblocks + ((number -
1160 (NUMOBJECTS*d->info.numberofindexblocks - d->info.entriesinindex))
1161 +NUMOBJECTS-1)/NUMOBJECTS;
1163 "index") ) == 0 )
return(-1);
1164 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1165 ib[i] = d->iblocks[i];
1167 for ( i = d->info.numberofindexblocks; i < newnumofindexblocks; i++ ) {
1172 if ( i > 0 ) ib[i]->previousblock = ib[i-1]->position;
1173 else ib[i]->previousblock = -1;
1178 for ( j = 0; j < NUMOBJECTS; j++ ) {
1179 ib[i]->objects[j].date = t;
1180 ib[i]->objects[j].size = 0;
1181 ib[i]->objects[j].position = -1;
1182 ib[i]->objects[j].tablenumber = 0;
1183 ib[i]->objects[j].uncompressed = 0;
1184 ib[i]->objects[j].spare1 = 0;
1185 ib[i]->objects[j].spare2 = 0;
1186 ib[i]->objects[j].spare3 = 0;
1187 for ( jj = 0; jj < ELEMENTSIZE; jj++ ) ib[i]->
objects[j].element[jj] = 0;
1189 fseek(d->handle,0,SEEK_END);
1190 ib[i]->position = ftell(d->handle);
1191 convertblock(ib[i],&scratchblock,TODISK);
1192 if ( minoswrite(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
1194 MesPrint(
"!>Error while writing new index of file %s",d->name);
1200 d->info.lastindexblock = ib[newnumofindexblocks-1]->position;
1201 d->info.firstindexblock = ib[0]->position;
1202 d->info.numberofindexblocks = newnumofindexblocks;
1203 if ( WriteIniInfo(d) ) {
1205 d->info.numberofindexblocks = oldnumofindexblocks;
1206 d->info.entriesinindex -= number;
1207 MesPrint(
"!>File may be corrupted\n");
1212 M_free(d->iblocks,
"AddToIndex");
1223MLONG AddObject(
DBASE *d,MLONG tablenumber,
char *arguments,
char *rhs)
1226 number = d->info.entriesinindex;
1227 if ( AddToIndex(d,1) )
return(-1);
1228 if ( WriteObject(d,tablenumber,arguments,rhs,number) )
return(-1);
1237MLONG FindTableNumber(
DBASE *d,
char *name)
1239 char *s = d->tablenames, *t, *ss;
1241 ss = d->tablenames + d->tablenamefill;
1245 while ( *s == *t && *t ) {
1248 if ( *s == 0 && *t == 0 )
return(num);
1265int WriteObject(
DBASE *d,MLONG tablenumber,
char *arguments,
char *rhs,MLONG number)
1270 uLongf newsize = 0, oldsize = 0;
1274 MLONG i, j, position, size, n;
1276 if ( ( d->mode & INPUTONLY ) == INPUTONLY ) {
1277 MesPrint(
"Not allowed to write to input\n");
1280 if ( number >= d->info.entriesinindex ) {
1281 MesPrint(
"Reference to non-existing object number %ld\n",number+1);
1284 j = number/NUMOBJECTS;
1285 i = number%NUMOBJECTS;
1286 obj = &(d->iblocks[j]->objects[i]);
1289 a++; n = a - arguments;
1290 if ( n > ELEMENTSIZE ) {
1291 MesPrint(
"Table element %s has more than %ld characters.\n",arguments,
1292 (MLONG)ELEMENTSIZE);
1297 while ( *a ) *s++ = *a++;
1299 while ( n < ELEMENTSIZE ) { *s++ = 0; n++; }
1300 obj->spare1 = obj->spare2 = obj->spare3 = 0;
1302 fseek(d->handle,0,SEEK_END);
1303 position = ftell(d->handle);
1309 if ( ( d->mode & NOCOMPRESS ) == 0 ) {
1310 newsize = size + size/1000 + 20;
1311 if ( ( buffer = (
char *)Malloc1(newsize*
sizeof(
char),
"compress buffer") )
1313 MesPrint(
"No compress used for element %s in file %s\n",arguments,d->name);
1322 const int old_isUsingZSTDcompression = ZWRAP_isUsingZSTDcompression();
1323 ZWRAP_useZSTDcompression(0);
1325 if ( ( error = compress((Bytef *)buffer,&newsize,(Bytef *)rhs,ssize) ) != Z_OK ) {
1327 MesPrint(
"!>Due to error no compress used for element %s in file %s\n",arguments,d->name);
1328 MesPrint(
"Error = %d\n",error);
1329 M_free(buffer,
"tb,WriteObject");
1334 ZWRAP_useZSTDcompression(old_isUsingZSTDcompression);
1343 if ( minoswrite(d->handle,rhs,size) ) {
1345 MesPrint(
"!>Error while writing rhs\n");
1349 obj->position = position;
1351 obj->date = (MLONG)(time(0));
1352 obj->tablenumber = tablenumber;
1354 obj->uncompressed = oldsize;
1355 if ( buffer ) M_free(buffer,
"tb,WriteObject");
1357 obj->uncompressed = 0;
1359 d->iblocks[j]->flags |= MDIRTYFLAG;
1370char *ReadObject(
DBASE *d,MLONG tablenumber,
char *arguments)
1374 char *buffer1, *s, *t;
1377 uLongf finallength = 0;
1379 if ( tablenumber > d->topnumber ) {
1380 MesPrint(
"Reference to non-existing table number in tablebase %s: %ld\n",
1381 d->name,tablenumber);
1387 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1388 for ( j = 0; j < NUMOBJECTS; j++ ) {
1389 if ( d->iblocks[i]->objects[j].tablenumber != tablenumber )
continue;
1390 s = arguments; t = d->iblocks[i]->objects[j].element;
1391 while ( *s == *t && *s ) { s++; t++; }
1392 if ( *t == 0 && *s == 0 )
goto foundelement;
1395 s = d->tablenames; i = 1;
1397 if ( i == tablenumber )
break;
1404 MesPrint(
"%s(%s) not found in tablebase %s\n",s,arguments,d->name);
1408 obj = &(d->iblocks[i]->objects[j]);
1409 fseek(d->handle,obj->position,SEEK_SET);
1410 if ( ( buffer1 = (
char *)Malloc1(obj->size,
"reading rhs buffer1") ) == 0 ) {
1414 if ( obj->uncompressed > 0 ) {
1415 if ( ( buffer2 = (
char *)Malloc1(obj->uncompressed,
"reading rhs buffer2") ) == 0 ) {
1421 if ( minosread(d->handle,buffer1,obj->size) ) {
1423 MesPrint(
"!>Could not read rhs %s in file %s\n",arguments,d->name);
1424 M_free(buffer1,
"tb,ReadObject");
1426 if ( buffer2 ) M_free(buffer2,
"tb,ReadObject");
1432 if ( buffer2 == 0 )
return(buffer1);
1433 finallength = obj->uncompressed;
1434 if ( uncompress((Bytef *)buffer2,&finallength,(Bytef *)buffer1,obj->size) != Z_OK ) {
1436 MesPrint(
"!>Cannot uncompress element %s in file %s\n",arguments,d->name);
1437 M_free(buffer1,
"tb,ReadObject"); M_free(buffer2,
"tb,ReadObject");
1441 M_free(buffer1,
"tb,ReadObject");
1455char *ReadijObject(
DBASE *d,MLONG i,MLONG j,
char *arguments)
1461 uLongf finallength = 0;
1463 obj = &(d->iblocks[i]->objects[j]);
1464 fseek(d->handle,obj->position,SEEK_SET);
1465 if ( ( buffer1 = (
char *)Malloc1(obj->size,
"reading rhs buffer1") ) == 0 ) {
1469 if ( obj->uncompressed > 0 ) {
1470 if ( ( buffer2 = (
char *)Malloc1(obj->uncompressed,
"reading rhs buffer2") ) == 0 ) {
1476 if ( minosread(d->handle,buffer1,obj->size) ) {
1478 MesPrint(
"!>Could not read rhs %s in file %s\n",arguments,d->name);
1479 if ( buffer1 ) M_free(buffer1,
"rhs buffer1");
1481 if ( buffer2 ) M_free(buffer2,
"rhs buffer2");
1487 if ( buffer2 == 0 )
return(buffer1);
1488 finallength = obj->uncompressed;
1489 if ( uncompress((Bytef *)buffer2,&finallength,(Bytef *)buffer1,obj->size) != Z_OK ) {
1491 MesPrint(
"!>Cannot uncompress element %s in file %s\n",arguments,d->name);
1492 if ( buffer1 ) M_free(buffer1,
"rhs buffer1");
1493 if ( buffer2 ) M_free(buffer2,
"rhs buffer2");
1497 M_free(buffer1,
"rhs buffer1");
1511int ExistsObject(
DBASE *d,MLONG tablenumber,
char *arguments)
1515 if ( tablenumber > d->topnumber ) {
1516 MesPrint(
"Reference to non-existing table number in tablebase %s: %ld\n",
1517 d->name,tablenumber);
1523 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1524 for ( j = 0; j < NUMOBJECTS; j++ ) {
1525 if ( d->iblocks[i]->objects[j].tablenumber != tablenumber )
continue;
1526 s = arguments; t = d->iblocks[i]->objects[j].element;
1527 while ( *s == *t && *s ) { s++; t++; }
1528 if ( *t == 0 && *s == 0 )
return(1);
1543int DeleteObject(
DBASE *d,MLONG tablenumber,
char *arguments)
1547 if ( tablenumber > d->topnumber ) {
1548 MesPrint(
"Reference to non-existing table number in tablebase %s: %ld\n",
1549 d->name,tablenumber);
1555 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1556 for ( j = 0; j < NUMOBJECTS; j++ ) {
1557 if ( d->iblocks[i]->objects[j].tablenumber != tablenumber )
continue;
1558 s = arguments; t = d->iblocks[i]->objects[j].element;
1559 while ( *s == *t && *s ) { s++; t++; }
1560 if ( *t == 0 && *s == 0 ) {
1561 d->iblocks[i]->objects[j].tablenumber =
1562 -d->iblocks[i]->objects[j].tablenumber - 1;