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);
66 int minosread(FILE *f,
char *buffer,MLONG size)
70 x = fread(buffer,
sizeof(
char),size,f);
71 if ( x <= 0 )
return(-1);
83 int 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);
101 char *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-- ) {
225 FILE *LocateBase(
char **name,
char **newname)
229 UBYTE *s, *to, *u1, *u2, *indir;
230 if ( ( handle = fopen(*name,
"r+b") ) != 0 ) {
231 *newname = (
char *)strDup1((UBYTE *)(*name),
"LocateBase");
234 namesize = 2; s = (UBYTE *)(*name);
235 while ( *s ) { s++; namesize++; }
239 while ( *s ) { s++; i++; }
240 *newname = (
char *)Malloc1(namesize+i,
"LocateBase");
241 s = indir; to = (UBYTE *)(*newname);
242 while ( *s ) *to++ = *s++;
243 if ( to > (UBYTE *)(*newname) && to[-1] != SEPARATOR ) *to++ = SEPARATOR;
244 s = (UBYTE *)(*name);
245 while ( *s ) *to++ = *s++;
247 if ( ( handle = fopen(*newname,
"r+b") ) != 0 ) {
250 M_free(*newname,
"LocateBase, incdir/file");
256 while ( *u1 && *u1 !=
':' ) {
257 if ( *u1 ==
'\\' ) u1++;
260 *newname = (
char *)Malloc1(namesize+i,
"LocateBase");
261 s = u2; to = (UBYTE *)(*newname);
263 if ( *s ==
'\\' ) s++;
266 if ( to > (UBYTE *)(*newname) && to[-1] != SEPARATOR ) *to++ = SEPARATOR;
267 s = (UBYTE *)(*name);
268 while ( *s ) *to++ = *s++;
270 if ( ( handle = fopen(*newname,
"r+b") ) != 0 ) {
273 M_free(*newname,
"LocateBase Path/file");
287 int ReadIndex(
DBASE *d)
292 MLONG position, size;
296 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);
304 size =
sizeof(
INDEXBLOCK *)*d->info.numberofindexblocks;
305 if ( ( ib = (
INDEXBLOCK **)Malloc1(size,
"tb,index") ) == 0 )
return(-1);
306 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
308 for ( --i; i >= 0; i-- ) M_free(ib[i],
"tb,indexblock");
309 M_free(ib,
"tb,index");
313 size =
sizeof(
NAMESBLOCK *)*d->info.numberofnamesblocks;
314 if ( ( ina = (
NAMESBLOCK **)Malloc1(size,
"tb,indexnames") ) == 0 )
return(-1);
315 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
317 for ( --i; i >= 0; i-- ) M_free(ina[i],
"index names block");
318 M_free(ina,
"tb,indexnames");
319 for ( i = 0; i < d->info.numberofindexblocks; i++ ) M_free(ib[i],
"tb,indexblock");
320 M_free(ib,
"tb,index");
328 position = d->info.lastindexblock;
329 for ( i = d->info.numberofindexblocks - 1; i >= 0; i-- ) {
330 fseek(d->handle,position,SEEK_SET);
331 if ( minosread(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
332 MesPrint(
"Error while reading file %s\n",d->name);
334 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) M_free(ina[i],
"index names block");
335 M_free(ina,
"tb,indexnames");
336 for ( i = 0; i < d->info.numberofindexblocks; i++ ) M_free(ib[i],
"tb,indexblock");
337 M_free(ib,
"tb,index");
340 convertblock(&scratchblock,ib[i],FROMDISK);
341 if ( ib[i]->position != position ||
342 ( ib[i]->previousblock <= 0 && i > 0 ) ) {
343 MesPrint(
"File %s has inconsistent contents\n",d->name);
346 position = ib[i]->previousblock;
348 d->info.firstindexblock = ib[0]->position;
349 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
350 ib[i]->flags &= MCLEANFLAG;
356 position = d->info.lastnameblock;
357 for ( i = d->info.numberofnamesblocks - 1; i >= 0; i-- ) {
358 fseek(d->handle,position,SEEK_SET);
359 if ( minosread(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
360 MesPrint(
"Error while reading file %s\n",d->name);
363 convertnamesblock(&scratchnamesblock,ina[i],FROMDISK);
364 if ( ina[i]->position != position ||
365 ( ina[i]->previousblock <= 0 && i > 0 ) ) {
366 MesPrint(
"File %s has inconsistent contents\n",d->name);
369 position = ina[i]->previousblock;
371 d->info.firstnameblock = ina[0]->position;
376 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
377 if ( d->iblocks[i] ) M_free(d->iblocks[i],
"d->iblocks[i]");
379 M_free(d->iblocks,
"d->iblocks");
382 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
383 if ( d->nblocks[i] ) M_free(d->nblocks[i],
"d->nblocks[i]");
385 M_free(d->nblocks,
"d->nblocks");
400 int WriteIndexBlock(
DBASE *d,MLONG num)
402 if ( num >= d->info.numberofindexblocks ) {
403 MesPrint(
"Illegal number specified for number of index blocks\n");
406 fseek(d->handle,d->iblocks[num]->position,SEEK_SET);
407 convertblock(d->iblocks[num],&scratchblock,TODISK);
408 if ( minoswrite(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
409 MesPrint(
"Error while writing an index block in file %s\n",d->name);
410 MesPrint(
"File may be unreliable now\n");
421 int WriteNamesBlock(
DBASE *d,MLONG num)
423 if ( num >= d->info.numberofnamesblocks ) {
424 MesPrint(
"Illegal number specified for number of names blocks\n");
427 fseek(d->handle,d->nblocks[num]->position,SEEK_SET);
428 convertnamesblock(d->nblocks[num],&scratchnamesblock,TODISK);
429 if ( minoswrite(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
430 MesPrint(
"Error while writing a names block in file %s\n",d->name);
431 MesPrint(
"File may be unreliable now\n");
444 int WriteIndex(
DBASE *d)
447 if ( d->iblocks == 0 )
return(0);
448 if ( d->nblocks == 0 )
return(0);
449 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
450 if ( d->iblocks[i] == 0 ) {
451 MesPrint(
"Error: unassigned index blocks. Cannot write\n");
455 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
456 if ( d->nblocks[i] == 0 ) {
457 MesPrint(
"Error: unassigned names blocks. Cannot write\n");
461 d->info.lastindexblock = -1;
462 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
463 position = d->iblocks[i]->position;
464 if ( position <= 0 ) {
465 fseek(d->handle,0,SEEK_END);
466 position = ftell(d->handle);
467 d->iblocks[i]->position = position;
468 if ( i <= 0 ) d->iblocks[i]->previousblock = -1;
469 else d->iblocks[i]->previousblock = d->iblocks[i-1]->position;
471 else fseek(d->handle,position,SEEK_SET);
472 convertblock(d->iblocks[i],&scratchblock,TODISK);
473 if ( minoswrite(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
474 MesPrint(
"Error while writing index of file %s",d->name);
475 d->iblocks[i]->position = -1;
478 d->info.lastindexblock = position;
480 d->info.lastnameblock = -1;
481 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
482 position = d->nblocks[i]->position;
483 if ( position <= 0 ) {
484 fseek(d->handle,0,SEEK_END);
485 position = ftell(d->handle);
486 d->nblocks[i]->position = position;
487 if ( i <= 0 ) d->nblocks[i]->previousblock = -1;
488 else d->nblocks[i]->previousblock = d->nblocks[i-1]->position;
490 else fseek(d->handle,position,SEEK_SET);
491 convertnamesblock(d->nblocks[i],&scratchnamesblock,TODISK);
492 if ( minoswrite(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
493 MesPrint(
"Error while writing index of file %s",d->name);
494 d->nblocks[i]->position = -1;
497 d->info.lastnameblock = position;
507 int WriteIniInfo(
DBASE *d)
510 fseek(d->handle,0,SEEK_SET);
511 convertiniinfo(&(d->info),&inf,TODISK);
512 if ( minoswrite(d->handle,(
char *)(&inf),
sizeof(
INIINFO)) ) {
513 MesPrint(
"Error while writing masterindex of file %s",d->name);
524 int ReadIniInfo(
DBASE *d)
527 fseek(d->handle,0,SEEK_SET);
528 if ( minosread(d->handle,(
char *)(&inf),
sizeof(
INIINFO)) ) {
529 MesPrint(
"Error while reading masterindex of file %s",d->name);
532 convertiniinfo(&inf,&(d->info),FROMDISK);
533 if ( d->info.entriesinindex < 0
534 || d->info.numberofindexblocks < 0
535 || d->info.lastindexblock < 0 ) {
536 MesPrint(
"The file %s is not a proper database\n",d->name);
547 DBASE *GetDbase(
char *filename)
552 if ( ( f = LocateBase(&filename,&newname) ) == 0 ) {
554 return(NewDbase(filename,0));
557 d = (
DBASE *)From0List(&(AC.TableBaseList));
559 d->tablenamessize = 0;
561 d->tablenamefill = 0;
566 d->info.entriesinindex = 0;
567 d->info.numberofindexblocks = 0;
568 d->info.firstindexblock = 0;
569 d->info.lastindexblock = 0;
570 d->info.numberoftables = 0;
571 d->info.numberofnamesblocks = 0;
572 d->info.firstnameblock = 0;
573 d->info.lastnameblock = 0;
575 d->name = str_dup(filename);
577 if ( ReadIniInfo(d) || ReadIndex(d) ) { M_free(d,
"index-d"); fclose(f);
return(0); }
578 if ( ComposeTableNames(d) < 0 ) { FreeTableBase(d); fclose(f);
return(0); }
579 d->name = str_dup(filename);
580 d->fullname = newname;
591 DBASE *NewDbase(
char *name,MLONG number)
595 MLONG numblocks, numnameblocks, i;
599 MLONG t = (MLONG)(time(0));
601 if ( number < 0 ) number = 0;
602 if ( ( f = fopen(name,
"w+b") ) == 0 ) {
603 MesPrint(
"Could not create a new file with name %s\n",name);
606 numblocks = (number+NUMOBJECTS-1)/NUMOBJECTS;
608 if ( numblocks <= 0 ) numblocks = 1;
609 if ( numnameblocks <= 0 ) numnameblocks = 1;
610 d = (
DBASE *)From0List(&(AC.TableBaseList));
612 "new database") ) == 0 ) {
617 d->tablenamessize = 0;
619 d->tablenamefill = 0;
623 "new database") ) == 0 ) {
624 M_free(d->iblocks,
"new database");
628 if ( ( f = fopen(name,
"w+b") ) == 0 ) {
629 MesPrint(
"Could not create new file %s\n",name);
634 d->name = str_dup(name);
635 d->fullname = str_dup(name);
638 d->info.entriesinindex = number;
639 d->info.numberofindexblocks = numblocks;
640 d->info.numberofnamesblocks = numnameblocks;
641 d->info.firstindexblock = 0;
642 d->info.lastindexblock = 0;
643 d->info.numberoftables = 0;
644 d->info.firstnameblock = 0;
645 d->info.lastnameblock = 0;
647 if ( WriteIniInfo(d) ) {
651 if ( d->name ) { M_free(d->name,
"name tablebase"); d->name = 0; }
652 if ( d->fullname ) { M_free(d->fullname,
"fullname tablebase"); d->fullname = 0; }
653 M_free(d->nblocks,
"new database");
654 M_free(d->iblocks,
"new database");
658 for ( i = 0; i < numblocks; i++ ) {
660 "index blocks of new database") ) == 0 ) {
661 while ( --i >= 0 ) M_free(d->iblocks[i],
"index blocks of new database");
664 if ( i > 0 ) d->iblocks[i]->previousblock = d->iblocks[i-1]->position;
665 else d->iblocks[i]->previousblock = -1;
666 d->iblocks[i]->position = ftell(f);
671 for ( j = 0; j < NUMOBJECTS; j++ ) {
672 d->iblocks[i]->objects[j].date = t;
673 d->iblocks[i]->objects[j].size = 0;
674 d->iblocks[i]->objects[j].position = -1;
675 d->iblocks[i]->objects[j].tablenumber = 0;
676 d->iblocks[i]->objects[j].uncompressed = 0;
677 d->iblocks[i]->objects[j].spare1 = 0;
678 d->iblocks[i]->objects[j].spare2 = 0;
679 d->iblocks[i]->objects[j].spare3 = 0;
680 for ( jj = 0; jj < ELEMENTSIZE; jj++ ) d->iblocks[i]->objects[j].element[jj] = 0;
682 convertblock(d->iblocks[i],&scratchblock,TODISK);
683 if ( minoswrite(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
684 MesPrint(
"Error while writing new index blocks\n");
688 for ( i = 0; i < numnameblocks; i++ ) {
690 "names blocks of new database") ) == 0 ) {
691 while ( --i >= 0 ) { M_free(d->nblocks[i],
"names blocks of new database"); }
692 for ( i = 0; i < numblocks; i++ ) M_free(d->iblocks[i],
"index blocks of new database");
695 if ( i > 0 ) d->nblocks[i]->previousblock = d->nblocks[i-1]->position;
696 else d->nblocks[i]->previousblock = -1;
697 d->nblocks[i]->position = ftell(f);
698 s = d->nblocks[i]->names;
699 for ( j = 0; j < NAMETABLESIZE; j++ ) *s++ = 0;
700 convertnamesblock(d->nblocks[i],&scratchnamesblock,TODISK);
701 if ( minoswrite(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
702 MesPrint(
"Error while writing new names blocks\n");
703 for ( i = 0; i < numnameblocks; i++ ) M_free(d->nblocks[i],
"names blocks of new database");
704 for ( i = 0; i < numblocks; i++ ) M_free(d->iblocks[i],
"index blocks of new database");
708 d->info.firstindexblock = d->iblocks[0]->position;
709 d->info.lastindexblock = d->iblocks[numblocks-1]->position;
710 d->info.firstnameblock = d->nblocks[0]->position;
711 d->info.lastnameblock = d->nblocks[numnameblocks-1]->position;
712 if ( WriteIniInfo(d) ) {
713 for ( i = 0; i < numnameblocks; i++ ) M_free(d->nblocks[i],
"names blocks of new database");
714 for ( i = 0; i < numblocks; i++ ) M_free(d->iblocks[i],
"index blocks of new database");
725 void FreeTableBase(
DBASE *d)
727 int i, j, *old, *newL;
729 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) M_free(d->nblocks[i],
"nblocks[i]");
730 for ( i = 0; i < d->info.numberofindexblocks; i++ ) M_free(d->iblocks[i],
"iblocks[i]");
731 M_free(d->nblocks,
"nblocks");
732 M_free(d->iblocks,
"iblocks");
733 if ( d->tablenames ) M_free(d->tablenames,
"d->tablenames");
734 if ( d->name ) M_free(d->name,
"d->name");
735 if ( d->fullname ) M_free(d->fullname,
"d->fullname");
737 if ( i < ( NumTableBases - 1 ) ) {
738 L = &(AC.TableBaseList);
739 j = ( ( NumTableBases - i - 1 ) * L->
size ) /
sizeof(int);
740 old = (
int *)d; newL = (
int *)(d+1);
741 while ( --j >= 0 ) *newL++ = *old++;
742 j = L->
size /
sizeof(int);
743 while ( --j >= 0 ) *newL++ = 0;
757 int ComposeTableNames(
DBASE *d)
763 i = 0; s = d->nblocks[i]->names; j = NAMETABLESIZE;
765 if ( *s ) d->topnumber++;
766 for ( k = 0; k < 2; k++ ) {
770 i++;
if ( i >= d->info.numberofnamesblocks )
goto gotall;
771 s = d->nblocks[i]->names; j = NAMETABLESIZE;
777 i++;
if ( i >= d->info.numberofnamesblocks )
goto gotall;
778 s = d->nblocks[i]->names; j = NAMETABLESIZE;
784 nsize = (d->info.numberofnamesblocks-1)*NAMETABLESIZE +
785 (s-d->nblocks[i]->names)+1;
786 if ( ( d->tablenames = (
char *)Malloc1((2*nsize+30)*
sizeof(
char),
"tablenames") )
787 == 0 ) {
return(-1); }
789 d->tablenamessize = 2*nsize+30;
790 d->tablenamefill = nsize-1;
791 for ( k = 0; k < i; k++ ) {
792 ss = d->nblocks[k]->names;
793 for ( j = 0; j < NAMETABLESIZE; j++ ) *t++ = *ss++;
795 ss = d->nblocks[i]->names;
796 while ( ss < s ) *t++ = *ss++;
806 DBASE *OpenDbase(
char *filename)
811 if ( ( f = LocateBase(&filename,&newname) ) == 0 ) {
812 MesPrint(
"Cannot open file %s\n",filename);
816 d = (
DBASE *)From0List(&(AC.TableBaseList));
819 if ( ReadIniInfo(d) || ReadIndex(d) ) { M_free(d,
"OpenDbase"); fclose(f);
return(0); }
820 if ( ComposeTableNames(d) ) {
825 d->name = str_dup(filename);
826 d->fullname = newname;
843 int namesize, tailsize;
844 MLONG newsize, i, num;
848 if ( d->tablenames ) {
854 while ( ( *s == *t ) && *t ) { s++; t++; }
855 if ( *s == *t ) {
return(-num); }
865 MesPrint(
"We add the name %s\n",name);
867 while ( *t ) { t++; }
869 if ( ( t = (
char *)(T->
argtail) ) != 0 ) {
870 while ( *t ) { t++; }
871 tailsize = t - (
char *)(T->
argtail);
873 else { tailsize = 0; }
874 if ( d->tablenames == 0 ) {
875 if ( ComposeTableNames(d) ) {
877 M_free(d,
"AddTableName");
881 d->info.numberoftables++;
882 while ( ( d->tablenamefill+namesize+tailsize+3 > d->tablenamessize )
883 || ( d->tablenames == 0 ) ) {
884 newsize = 2*d->tablenamessize + 2*namesize + 2*tailsize + 6;
885 if ( ( t = (
char *)Malloc1(newsize*
sizeof(
char),
"AddTableName") ) == 0 )
888 if ( d->tablenames ) {
890 for ( i = 0; i < d->tablenamefill; i++ ) *t++ = *s++;
892 M_free(d->tablenames,
"d->tablenames");
895 d->tablenamessize = newsize;
897 s = d->tablenames + d->tablenamefill;
899 while ( *t ) *s++ = *t++;
902 while ( *t ) *s++ = *t++;
905 d->tablenamefill = s - d->tablenames;
910 if ( PutTableNames(d) )
return(0);
911 return(d->topnumber);
923 MLONG GetTableName(
DBASE *d,
char *name)
930 if ( d->tablenames ) {
936 while ( ( *s == *t ) && *t ) { s++; t++; }
937 if ( *s == *t ) {
return(num); }
955 int PutTableNames(
DBASE *d)
964 MLONG numblocks = d->tablenamefill/NAMETABLESIZE + 1;
965 if ( d->info.numberofnamesblocks < numblocks ) {
970 "new names block") ) == 0 ) {
973 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
974 nnew[i] = d->nblocks[i];
976 for ( ; i < numblocks; i++ ) {
978 "additional names blocks ") ) == 0 ) {
982 d->nblocks[i]->previousblock = -1;
983 d->nblocks[i]->position = -1;
984 s = d->nblocks[i]->names;
985 for ( j = 0; j < NAMETABLESIZE; j++ ) *s++ = 0;
987 d->info.numberofnamesblocks = numblocks;
993 i = 0; t = d->nblocks[i]->names; j = 0; s = d->tablenames;
994 for ( m = 0; m < d->tablenamefill; m++ ) {
997 if ( j >= NAMETABLESIZE ) {
999 t = d->nblocks[i]->names;
1005 for ( ; m < d->tablenamefill; m++ ) {
1008 if ( j >= NAMETABLESIZE ) {
1010 t = d->nblocks[i]->names;
1017 for ( i = 0; i < d->info.numberofnamesblocks; i++ ) {
1018 if ( i == firstdif )
break;
1019 if ( d->nblocks[i]->position < 0 ) { firstdif = i;
break; }
1024 for ( i = firstdif; i < d->info.numberofnamesblocks; i++ ) {
1025 if ( i > 0 ) d->nblocks[i]->previousblock = d->nblocks[i-1]->position;
1026 else d->nblocks[i]->previousblock = -1;
1027 if ( d->nblocks[i]->position < 0 ) {
1028 fseek(d->handle,0,SEEK_END);
1029 d->nblocks[i]->position = ftell(d->handle);
1031 else fseek(d->handle,d->nblocks[i]->position,SEEK_SET);
1032 convertnamesblock(d->nblocks[i],&scratchnamesblock,TODISK);
1033 if ( minoswrite(d->handle,(
char *)(&scratchnamesblock),
sizeof(
NAMESBLOCK)) ) {
1034 MesPrint(
"Error while writing names blocks\n");
1039 d->info.lastnameblock = d->nblocks[d->info.numberofnamesblocks-1]->position;
1040 d->info.firstnameblock = d->nblocks[0]->position;
1041 return(WriteIniInfo(d));
1049 int AddToIndex(
DBASE *d,MLONG number)
1051 MLONG i, oldnumofindexblocks = d->info.numberofindexblocks;
1052 MLONG j, newnumofindexblocks, jj;
1054 MLONG t = (MLONG)(time(0));
1055 if ( number == 0 )
return(0);
1056 else if ( number < 0 ) {
1057 if ( d->info.entriesinindex < -number ) {
1058 MesPrint(
"There are only %ld entries in the index of file %s\n",
1059 d->info.entriesinindex,d->name);
1062 d->info.entriesinindex += number;
1064 if ( WriteIniInfo(d) ) {
1065 d->info.entriesinindex -= number;
1066 MesPrint(
"File may be corrupted\n");
1070 else if ( d->info.entriesinindex+number <=
1071 NUMOBJECTS*d->info.numberofindexblocks ) {
1072 d->info.entriesinindex += number;
1076 d->info.entriesinindex += number;
1077 newnumofindexblocks = d->info.numberofindexblocks + ((number -
1078 (NUMOBJECTS*d->info.numberofindexblocks - d->info.entriesinindex))
1079 +NUMOBJECTS-1)/NUMOBJECTS;
1081 "index") ) == 0 )
return(-1);
1082 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1083 ib[i] = d->iblocks[i];
1085 for ( i = d->info.numberofindexblocks; i < newnumofindexblocks; i++ ) {
1090 if ( i > 0 ) ib[i]->previousblock = ib[i-1]->position;
1091 else ib[i]->previousblock = -1;
1095 for ( j = 0; j < NUMOBJECTS; j++ ) {
1096 ib[i]->objects[j].date = t;
1097 ib[i]->objects[j].size = 0;
1098 ib[i]->objects[j].position = -1;
1099 ib[i]->objects[j].tablenumber = 0;
1100 ib[i]->objects[j].uncompressed = 0;
1101 ib[i]->objects[j].spare1 = 0;
1102 ib[i]->objects[j].spare2 = 0;
1103 ib[i]->objects[j].spare3 = 0;
1104 for ( jj = 0; jj < ELEMENTSIZE; jj++ ) ib[i]->objects[j].element[jj] = 0;
1106 fseek(d->handle,0,SEEK_END);
1107 ib[i]->position = ftell(d->handle);
1108 convertblock(ib[i],&scratchblock,TODISK);
1109 if ( minoswrite(d->handle,(
char *)(&scratchblock),
sizeof(
INDEXBLOCK)) ) {
1110 MesPrint(
"Error while writing new index of file %s",d->name);
1115 d->info.lastindexblock = ib[newnumofindexblocks-1]->position;
1116 d->info.firstindexblock = ib[0]->position;
1117 d->info.numberofindexblocks = newnumofindexblocks;
1118 if ( WriteIniInfo(d) ) {
1119 d->info.numberofindexblocks = oldnumofindexblocks;
1120 d->info.entriesinindex -= number;
1121 MesPrint(
"File may be corrupted\n");
1125 M_free(d->iblocks,
"AddToIndex");
1136 MLONG AddObject(
DBASE *d,MLONG tablenumber,
char *arguments,
char *rhs)
1139 number = d->info.entriesinindex;
1140 if ( AddToIndex(d,1) )
return(-1);
1141 if ( WriteObject(d,tablenumber,arguments,rhs,number) )
return(-1);
1150 MLONG FindTableNumber(
DBASE *d,
char *name)
1152 char *s = d->tablenames, *t, *ss;
1154 ss = d->tablenames + d->tablenamefill;
1158 while ( *s == *t && *t ) {
1161 if ( *s == 0 && *t == 0 )
return(num);
1178 int WriteObject(
DBASE *d,MLONG tablenumber,
char *arguments,
char *rhs,MLONG number)
1183 uLongf newsize = 0, oldsize = 0;
1187 MLONG i, j, position, size, n;
1189 if ( ( d->mode & INPUTONLY ) == INPUTONLY ) {
1190 MesPrint(
"Not allowed to write to input\n");
1193 if ( number >= d->info.entriesinindex ) {
1194 MesPrint(
"Reference to non-existing object number %ld\n",number+1);
1197 j = number/NUMOBJECTS;
1198 i = number%NUMOBJECTS;
1199 obj = &(d->iblocks[j]->objects[i]);
1202 a++; n = a - arguments;
1203 if ( n > ELEMENTSIZE ) {
1204 MesPrint(
"Table element %s has more than %ld characters.\n",arguments,
1205 (MLONG)ELEMENTSIZE);
1210 while ( *a ) *s++ = *a++;
1212 while ( n < ELEMENTSIZE ) { *s++ = 0; n++; }
1213 obj->spare1 = obj->spare2 = obj->spare3 = 0;
1215 fseek(d->handle,0,SEEK_END);
1216 position = ftell(d->handle);
1222 if ( ( d->mode & NOCOMPRESS ) == 0 ) {
1223 newsize = size + size/1000 + 20;
1224 if ( ( buffer = (
char *)Malloc1(newsize*
sizeof(
char),
"compress buffer") )
1226 MesPrint(
"No compress used for element %s in file %s\n",arguments,d->name);
1232 if ( ( error = compress((Bytef *)buffer,&newsize,(Bytef *)rhs,ssize) ) != Z_OK ) {
1233 MesPrint(
"Error = %d\n",error);
1234 MesPrint(
"Due to error no compress used for element %s in file %s\n",arguments,d->name);
1235 M_free(buffer,
"tb,WriteObject");
1245 if ( minoswrite(d->handle,rhs,size) ) {
1246 MesPrint(
"Error while writing rhs\n");
1249 obj->position = position;
1251 obj->date = (MLONG)(time(0));
1252 obj->tablenumber = tablenumber;
1254 obj->uncompressed = oldsize;
1255 if ( buffer ) M_free(buffer,
"tb,WriteObject");
1257 obj->uncompressed = 0;
1259 return(WriteIndexBlock(d,j));
1269 char *ReadObject(
DBASE *d,MLONG tablenumber,
char *arguments)
1273 char *buffer1, *s, *t;
1276 uLongf finallength = 0;
1278 if ( tablenumber > d->topnumber ) {
1279 MesPrint(
"Reference to non-existing table number in tablebase %s: %ld\n",
1280 d->name,tablenumber);
1286 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1287 for ( j = 0; j < NUMOBJECTS; j++ ) {
1288 if ( d->iblocks[i]->objects[j].tablenumber != tablenumber )
continue;
1289 s = arguments; t = d->iblocks[i]->objects[j].element;
1290 while ( *s == *t && *s ) { s++; t++; }
1291 if ( *t == 0 && *s == 0 )
goto foundelement;
1294 s = d->tablenames; i = 1;
1296 if ( i == tablenumber )
break;
1303 MesPrint(
"%s(%s) not found in tablebase %s\n",s,arguments,d->name);
1307 obj = &(d->iblocks[i]->objects[j]);
1308 fseek(d->handle,obj->position,SEEK_SET);
1309 if ( ( buffer1 = (
char *)Malloc1(obj->size,
"reading rhs buffer1") ) == 0 ) {
1313 if ( obj->uncompressed > 0 ) {
1314 if ( ( buffer2 = (
char *)Malloc1(obj->uncompressed,
"reading rhs buffer2") ) == 0 ) {
1320 if ( minosread(d->handle,buffer1,obj->size) ) {
1321 MesPrint(
"Could not read rhs %s in file %s\n",arguments,d->name);
1322 M_free(buffer1,
"tb,ReadObject");
1324 if ( buffer2 ) M_free(buffer2,
"tb,ReadObject");
1329 if ( buffer2 == 0 )
return(buffer1);
1330 finallength = obj->uncompressed;
1331 if ( uncompress((Bytef *)buffer2,&finallength,(Bytef *)buffer1,obj->size) != Z_OK ) {
1332 MesPrint(
"Cannot uncompress element %s in file %s\n",arguments,d->name);
1333 M_free(buffer1,
"tb,ReadObject"); M_free(buffer2,
"tb,ReadObject");
1336 M_free(buffer1,
"tb,ReadObject");
1350 char *ReadijObject(
DBASE *d,MLONG i,MLONG j,
char *arguments)
1356 uLongf finallength = 0;
1358 obj = &(d->iblocks[i]->objects[j]);
1359 fseek(d->handle,obj->position,SEEK_SET);
1360 if ( ( buffer1 = (
char *)Malloc1(obj->size,
"reading rhs buffer1") ) == 0 ) {
1364 if ( obj->uncompressed > 0 ) {
1365 if ( ( buffer2 = (
char *)Malloc1(obj->uncompressed,
"reading rhs buffer2") ) == 0 ) {
1371 if ( minosread(d->handle,buffer1,obj->size) ) {
1372 MesPrint(
"Could not read rhs %s in file %s\n",arguments,d->name);
1373 if ( buffer1 ) M_free(buffer1,
"rhs buffer1");
1375 if ( buffer2 ) M_free(buffer2,
"rhs buffer2");
1380 if ( buffer2 == 0 )
return(buffer1);
1381 finallength = obj->uncompressed;
1382 if ( uncompress((Bytef *)buffer2,&finallength,(Bytef *)buffer1,obj->size) != Z_OK ) {
1383 MesPrint(
"Cannot uncompress element %s in file %s\n",arguments,d->name);
1384 if ( buffer1 ) M_free(buffer1,
"rhs buffer1");
1385 if ( buffer2 ) M_free(buffer2,
"rhs buffer2");
1388 M_free(buffer1,
"rhs buffer1");
1402 int ExistsObject(
DBASE *d,MLONG tablenumber,
char *arguments)
1406 if ( tablenumber > d->topnumber ) {
1407 MesPrint(
"Reference to non-existing table number in tablebase %s: %ld\n",
1408 d->name,tablenumber);
1414 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1415 for ( j = 0; j < NUMOBJECTS; j++ ) {
1416 if ( d->iblocks[i]->objects[j].tablenumber != tablenumber )
continue;
1417 s = arguments; t = d->iblocks[i]->objects[j].element;
1418 while ( *s == *t && *s ) { s++; t++; }
1419 if ( *t == 0 && *s == 0 )
return(1);
1434 int DeleteObject(
DBASE *d,MLONG tablenumber,
char *arguments)
1438 if ( tablenumber > d->topnumber ) {
1439 MesPrint(
"Reference to non-existing table number in tablebase %s: %ld\n",
1440 d->name,tablenumber);
1446 for ( i = 0; i < d->info.numberofindexblocks; i++ ) {
1447 for ( j = 0; j < NUMOBJECTS; j++ ) {
1448 if ( d->iblocks[i]->objects[j].tablenumber != tablenumber )
continue;
1449 s = arguments; t = d->iblocks[i]->objects[j].element;
1450 while ( *s == *t && *s ) { s++; t++; }
1451 if ( *t == 0 && *s == 0 ) {
1452 d->iblocks[i]->objects[j].tablenumber =
1453 -d->iblocks[i]->objects[j].tablenumber - 1;