/*******************************************************/ /* */ /* File : cybos.c */ /* Description : (simpilified) c interface to YBOS */ /* */ /* Author: Sfiligoi Igor */ /* */ /* Created : 07.09.1998 */ /* Last modified: 10.09.1998 */ /* */ /*******************************************************/ #include <Error.h> #include "cybos.h" #include <byteorder.h> #if BYTE_ORDER == BIG_ENDIAN #include <Swap.h> #endif /* BYTEORDER */ /**************************************************************************/ /* implemented below */ pcybos cybos_newid(); void cybos_freeid(pcybos ybos_id); int cybos_read_physic(pcybos ybos_id, int record_nr); int cybos_seekread(pcybos ybos_id, int *lrec, int maxsize); int cybos_lrec_swap(int *lrec, int lrec_size); /**************************************************************************/ pcybos cybos_open(char *filename) { pcybos ybos_id; int errnr; ybos_id = cybos_newid(); /* open the ybos file */ ybos_id->ybfile = fopen(filename,"r"); if (ybos_id->ybfile==NULL) { /* error opening file */ cybos_freeid(ybos_id); ErrorSetF(0,"cybos_open","error opening file. file:%s",filename); return NULL; } /* Read the record size of the first physical record */ /* Should be the same for all the physical records in the file */ { int count; count = fread(&ybos_id->record_size,sizeof(int),1,ybos_id->ybfile); if (count<1) { cybos_freeid(ybos_id); ErrorSetF(0,"cybos_open","error reading record size. file:%s",filename); return NULL; } } #if BYTE_ORDER == BIG_ENDIAN swap4mv((unsigned int *) &ybos_id->record_size,1); #endif /* BYTEORDER */ ybos_id->record_size++; /* Allocate the buffer for the physical records */ ybos_id->record_buffer = (tcybos_record *) malloc(ybos_id->record_size*sizeof(int)); /* Read the first physical record, filling the record_buffer, curr_record */ errnr = cybos_read_physic(ybos_id,0); if (errnr!=0) { /* error reading first physical record */ fclose(ybos_id->ybfile); cybos_freeid(ybos_id); ErrorSetF(0,"cybos_open","error reading first physical record. file:%s",filename); return NULL; } /* Set various curr_ values */ ybos_id->curr_pointer = 0; ybos_id->curr_lrec = 0; return ybos_id; } void cybos_close(pcybos ybos_id) { fclose(ybos_id->ybfile); cybos_freeid(ybos_id); } int cybos_seek(pcybos ybos_id, int nr_lrecs) { int i; if (nr_lrecs==0) return ybos_id->curr_lrec; /* nothing to do */ if (nr_lrecs<0) return cybos_seek(ybos_id,ybos_id->curr_lrec+nr_lrecs); /* don't know how to do it else */ for (i=0; i<nr_lrecs; i++) cybos_seekread(ybos_id,NULL,-1); return ybos_id->curr_lrec; } int cybos_seek_abs(pcybos ybos_id, int lrec_nr) { if (lrec_nr<0) lrec_nr = 0; if (lrec_nr==ybos_id->curr_lrec) return ybos_id->curr_lrec; /* nothing to do */ if (lrec_nr>ybos_id->curr_lrec) return cybos_seek(ybos_id,lrec_nr-ybos_id->curr_lrec); /* faster */ cybos_read_physic(ybos_id,0); ybos_id->curr_pointer = 0; ybos_id->curr_lrec = 0; for (;ybos_id->curr_lrec<lrec_nr;) cybos_seekread(ybos_id,NULL,-1); return ybos_id->curr_lrec; } int cybos_read(pcybos ybos_id, int *lrec, int maxsize) { int count; if (maxsize<0) { ErrorSetF(0,"cybos_read","maxsize(%i) invalid.",maxsize); return -10; /* must be at least an int */ } count = cybos_seekread(ybos_id,lrec,maxsize); #if BYTE_ORDER == BIG_ENDIAN if ((count>0) && (count<=maxsize)) cybos_lrec_swap(lrec,count); #endif return count; } /********************************************************************/ /* allocate a new ybos_id */ pcybos cybos_newid() { pcybos ybos_id; ybos_id = (tcybos *) malloc(sizeof(tcybos)); ybos_id->record_size = 0; ybos_id->record_buffer = NULL; ybos_id->curr_pointer = 0; ybos_id->curr_lrec = 0; return ybos_id; } /* deallocate an initialized ybos_id */ void cybos_freeid(pcybos ybos_id) { if (ybos_id->record_buffer!=NULL) free(ybos_id->record_buffer); free(ybos_id); } /* Read a physical record */ int cybos_read_physic(pcybos ybos_id, int record_nr) { int count; /* Fill the buffer with the first record */ ybos_id->curr_record = record_nr; fseek(ybos_id->ybfile,record_nr*ybos_id->record_size*sizeof(int),SEEK_SET); count = fread(ybos_id->record_buffer,sizeof(int),ybos_id->record_size,ybos_id->ybfile); if (count!=ybos_id->record_size) { ErrorSetF(0,"cybos_read_physic","error reading file."); return -1; /* error reading file */ } #if BYTE_ORDER == BIG_ENDIAN swap4mv((unsigned int *) ybos_id->record_buffer,ybos_id->record_size); #endif /* BYTEORDER */ if ((ybos_id->record_buffer->rec_size+1) != ybos_id->record_size) { ErrorSetF(0,"cybos_read_physic","Record size changed (%i,%i).",ybos_id->record_buffer->rec_size+1,ybos_id->record_size); return -2; /* Cannot manage this case */ } if (ybos_id->record_buffer->header_size != 4) { ErrorSetF(0,"cybos_read_physic","invalid header size. (%i,4)",ybos_id->record_buffer->header_size); return -3; /* Cannot manage this case */ } if (ybos_id->record_buffer->ph_rec_nr != record_nr) { ErrorSetF(0,"cybos_read_physic","Invalid record number. (%i,%i)",ybos_id->record_buffer->ph_rec_nr,record_nr); return -4; /* ??? maybe corrupted file ??? */ } return 0; } /* same as read if maxsize>0, else the lrec is not filled */ int cybos_seekread(pcybos ybos_id, int *lrec, int maxsize) { int lrec_size; lrec_size = ybos_id->record_buffer->data[ybos_id->curr_pointer]; while (lrec_size==-1) { /* lrec should be in the next record */ int errnr; errnr = cybos_read_physic(ybos_id,ybos_id->curr_record+1); ybos_id->curr_pointer = 0; if (errnr!=0) return errnr; lrec_size = ybos_id->record_buffer->data[ybos_id->curr_pointer]; } if (lrec_size==0) { /* treat as an error for the moment */ ErrorSetF(0,"cybos_seekread","unsupported case 1."); return -20; } if ((maxsize>=0) && ((lrec_size+1)>maxsize)) return (lrec_size+1); { int lrec_read; /* nr of ints already read, excluding the lrec_size */ lrec[0] = lrec_size; lrec_read = 0; ybos_id->curr_pointer++; while (lrec_read<lrec_size) { int curr_avail; int curr_to_read; curr_avail = ybos_id->record_buffer->rec_size-ybos_id->curr_pointer-ybos_id->record_buffer->header_size; curr_to_read = lrec_size-lrec_read; if (curr_avail>=curr_to_read) { if (maxsize>0) memcpy(&(lrec[lrec_read+1]), &(ybos_id->record_buffer->data[ybos_id->curr_pointer]), curr_to_read*sizeof(int)); ybos_id->curr_pointer+=curr_to_read; lrec_read+=curr_to_read; } else { int errnr; if (maxsize>0) memcpy(&(lrec[lrec_read+1]), &(ybos_id->record_buffer->data[ybos_id->curr_pointer]), curr_avail*sizeof(int)); lrec_read+=curr_avail; errnr = cybos_read_physic(ybos_id,ybos_id->curr_record+1); ybos_id->curr_pointer = 0; if (errnr!=0) return errnr; } } /* while */ } ybos_id->curr_lrec++; /* Pointer moved to the next logical record */ return (lrec_size+1); } #define YBHEADLEN 5 /* Reswap the names of the banks */ int cybos_lrec_swap(int *lrec, int lrec_size) { int record_datasize,datasize; int runsize,ybhead,ybnext,ybstart; int bnum; if( lrec==NULL) { printf("cybos_lrec_swap: lrec pointer not initialized"); return -1; } record_datasize = *lrec; if( record_datasize > 0 ) { runsize = 0; /*First word of Logical Record is Buff Datasize*/ ybhead = 1; /* skip one word to jump to LRID header*/ ybnext = 0; /* at the beginning assume no NEXT banks */ ybstart = ybhead; /* we WILL start from LRID header */ for (bnum=0; runsize<record_datasize; bnum++) { int *head; head = &(lrec[ybhead]); datasize = head[3]-1; /* Num Words of data*/ runsize += (datasize+YBHEADLEN); /* running size*/ /*printf("Record datasize %i datasize %i runsize %i\n", record_datasize,datasize,runsize);*/ swap4mv((unsigned int *) head, 1); /* swap just the bname*/ if( runsize <= record_datasize ) { int i; ybstart = ybhead +YBHEADLEN; /* running datastart */ ybhead = ybstart+datasize; /* beginning of next YBHEADER if any */ ybnext = ybhead+YBHEADLEN; if( runsize == record_datasize) break; } else { printf(" cybos_lrec_swap FATAL: exceeding RecordSIze \n"); } } } return 0; }