Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

fLmd.c

Go to the documentation of this file.
00001 //-------------------------------------------------------------
00002 //        Go4 Release Package v3.04-01 (build 30401)
00003 //                      28-November-2008
00004 //---------------------------------------------------------------
00005 //   The GSI Online Offline Object Oriented (Go4) Project
00006 //   Experiment Data Processing at EE department, GSI
00007 //---------------------------------------------------------------
00008 //
00009 //Copyright (C) 2000- Gesellschaft f. Schwerionenforschung, GSI
00010 //                    Planckstr. 1, 64291 Darmstadt, Germany
00011 //Contact:            http://go4.gsi.de
00012 //----------------------------------------------------------------
00013 //This software can be used under the license agreements as stated
00014 //in Go4License.txt file which is part of the distribution.
00015 //----------------------------------------------------------------
00016 #include <stdlib.h>
00017 #include <fcntl.h>
00018 #include <string.h>
00019 #include <memory.h>
00020 #include <time.h>
00021 #include <sys/types.h>
00022 #include <sys/stat.h>
00023 
00024 #ifdef Lynx /* LynxOS */
00025 #include <unistd.h>
00026 #include <pwd.h>
00027 #include <timeb.h>
00028 #endif
00029 
00030 #ifdef Linux /* Linux */
00031 #include <unistd.h>
00032 #include <pwd.h>
00033 #include <sys/timeb.h>
00034 #endif
00035 
00036 #ifdef Solaris /* Solaris */
00037 #include <unistd.h>
00038 #include <pwd.h>
00039 #include <sys/timeb.h>
00040 #endif
00041 
00042 #ifdef WIN32
00043 #include <WTypes.h>
00044 #include <wchar.h>
00045 
00046 #define fgetpos64 fgetpos 
00047 #define fopen64 fopen 
00048 #define fseeko64 fseek
00049 
00050 struct timespec {
00051    long   tv_sec;        /* seconds */
00052    long   tv_nsec;       /* nanoseconds */
00053 };
00054 
00055 #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
00056   #define DELTA_EPOCH_IN_MICROSECS  11644473600000000Ui64
00057 #else
00058   #define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL
00059 #endif
00060 
00061 #define CLOCK_REALTIME 1
00062 
00063 int clock_gettime(int clockid, struct timespec *tp)
00064 {
00065    FILETIME ft;
00066    unsigned __int64 tmpres = 0;
00067 
00068    tp->tv_sec = 0;
00069    tp->tv_nsec = 0;
00070 
00071    GetSystemTimeAsFileTime(&ft);
00072  
00073    tmpres |= ft.dwHighDateTime;
00074    tmpres <<= 32;
00075    tmpres |= ft.dwLowDateTime;
00076  
00077    /*converting file time to unix epoch*/
00078    tmpres /= 10;  /*convert into microseconds*/
00079    tmpres -= DELTA_EPOCH_IN_MICROSECS; 
00080    tp->tv_sec = (long)(tmpres / 1000000UL);
00081    tp->tv_nsec = (long)(tmpres % 1000000UL) * 1000;
00082 
00083    return 0;
00084 }
00085 #endif
00086 
00087 #include "fLmd.h"
00088 
00089 int32_t  fLmdWriteBuffer(sLmdControl *, char *, uint32_t);
00090 uint32_t fLmdCleanup(sLmdControl *);
00091 void     fLmdOffsetResize(sLmdControl *, uint32_t);
00092 uint32_t fLmdOffsetSet(sLmdControl *, uint32_t );
00093 uint32_t fLmdOffsetRead(sLmdControl *);
00094 uint32_t fLmdOffsetWrite(sLmdControl *);
00095 lmdoff_t fLmdOffsetGet(sLmdControl *, uint32_t);
00096 void     fLmdOffsetElements(sLmdControl *, uint32_t, uint32_t *, uint32_t *);
00097 #define OFFSET__ENTRIES 250000
00098 
00099 //===============================================================
00100 uint32_t fLmdPutOpen(
00101 sLmdControl *pLmdControl, 
00102 char    *Filename, 
00103 sMbsFileHeader *pBuffHead, // LMD__STANDARD_HEADER (NULL) or address
00104 uint32_t iBytes,           // LMD__NO_BUFFER (0) or buffer size
00105 uint32_t iOver,            // LMD__[NO_]OVERWRITE
00106 uint32_t iUseOffset,       // LMD__[NO_]INDEX
00107 uint32_t iLargeFile){      // LMD__[NO_]LARGE_FILE
00108 
00109   int32_t iReturn;
00110   struct timespec clock;
00111 
00112   memset(pLmdControl,0,sizeof(sLmdControl));
00113 
00114   // allocate header or take extern
00115   if(pBuffHead == LMD__STANDARD_HEADER){
00116     pLmdControl->pMbsFileHeader= (sMbsFileHeader *)malloc(sizeof(sMbsFileHeader));
00117     memset(pLmdControl->pMbsFileHeader,0,sizeof(sMbsFileHeader));
00118     pLmdControl->iInternHeader=1;
00119   }
00120   else {
00121     pLmdControl->pMbsFileHeader= pBuffHead;
00122     pLmdControl->iInternHeader=0;
00123   }
00124 
00125   clock_gettime(CLOCK_REALTIME,&clock);
00126   pLmdControl->pMbsFileHeader->iTimeSpecSec=clock.tv_sec;
00127   pLmdControl->pMbsFileHeader->iTimeSpecNanoSec=clock.tv_nsec;
00128 
00129   pLmdControl->pMbsFileHeader->iType=LMD__TYPE_FILE_HEADER_101_1;
00130   pLmdControl->pMbsFileHeader->iEndian=1;
00131   strcpy(pLmdControl->cFile,Filename);
00132 
00133   // optionally allocate buffer
00134   if(iBytes > 0){
00135     pLmdControl->pBuffer=(int16_t *)malloc(iBytes);
00136     pLmdControl->iInternBuffer=1;
00137   }
00138   pLmdControl->iBufferWords=iBytes/2;
00139   pLmdControl->iLeftWords=iBytes/2;
00140   // open file
00141   if(iOver == LMD__NO_OVERWRITE){  // do not overwrite
00142   if((pLmdControl->fFile=(FILE *)fopen64(Filename,"r") )!=NULL){
00143     printf("fLmdPutOpen: File exists: %s\n",Filename);
00144     fLmdCleanup(pLmdControl);
00145     fclose(pLmdControl->fFile);
00146     return(PUTLMD__FILE_EXIST);
00147   }}
00148 
00149   if((pLmdControl->fFile=(FILE *)fopen64(Filename,"w+") )== NULL){
00150     printf("fLmdPutOpen: Error open file %s\n",Filename);
00151     fLmdCleanup(pLmdControl);
00152     return(PUTLMD__OPEN_ERR);
00153   }
00154 
00155   if(iLargeFile == LMD__LARGE_FILE)pLmdControl->iOffsetSize=8;
00156   else                             pLmdControl->iOffsetSize=4;
00157   pLmdControl->pMbsFileHeader->iOffsetSize=pLmdControl->iOffsetSize;
00158 
00159   // write header
00160   iReturn=fLmdWriteBuffer(pLmdControl,(char *)pLmdControl->pMbsFileHeader,
00161                     (pLmdControl->pMbsFileHeader->iUsedWords)*2+sizeof(sMbsFileHeader));
00162   pLmdControl->iBytes+=iReturn;
00163 
00164   if(iUseOffset == LMD__INDEX)fLmdOffsetResize(pLmdControl,iReturn/4); // create and set first value
00165   printf("fLmdPutOpen: %s. Bytes:%d over:%d table:%d large:%d.\n",
00166          Filename,iBytes,iOver,iUseOffset,iLargeFile);
00167 return(LMD__SUCCESS);
00168 }
00169 
00170 //===============================================================
00171 uint32_t fLmdPutElement(
00172 sLmdControl *pLmdControl, 
00173 sMbsHeader *pHeader){
00174   uint32_t *ps, *pd, i, elements;
00175   int64_t fileleft,used;
00176   int32_t iReturn;
00177 
00178   // enough space left?
00179   if(pLmdControl->iOffsetEntries && (pLmdControl->iOffsetSize == 4)){
00180     elements=pLmdControl->iElements+2;
00181     used=pLmdControl->iBytes/4;
00182     fileleft=0xffffffff - used - (4+elements); // size of table
00183     if((int64_t)(pHeader->iWords/2+2) > fileleft){
00184       printf("fLmdPutElement: File size exceed\n");
00185       return(PUTLMD__EXCEED);
00186     }
00187   }
00188   // save largest size in header
00189   if((pHeader->iWords+4) > pLmdControl->pMbsFileHeader->iMaxWords) 
00190       pLmdControl->pMbsFileHeader->iMaxWords=pHeader->iWords+4;
00191   // no buffer, write element directly
00192   if(pLmdControl->iBufferWords == 0){
00193     pLmdControl->pMbsHeader=pHeader;
00194     iReturn=fLmdWriteBuffer(pLmdControl,(char *)pHeader,(pHeader->iWords+4)*2);
00195     pLmdControl->iBytes+=iReturn;
00196     if(iReturn != (pHeader->iWords+4)*2){
00197       printf("fLmdPutElement: Write error \n");
00198      return(LMD__FAILURE);
00199     }
00200     pLmdControl->pMbsFileHeader->iElements++;
00201     pLmdControl->iElements++;
00202     if(pLmdControl->iOffsetEntries)fLmdOffsetSet(pLmdControl,iReturn/4);
00203     return(LMD__SUCCESS);
00204 
00205   } // end no buffer
00206   if((pHeader->iWords+4) > pLmdControl->iLeftWords){ // flash buffer to file  
00207     iReturn=fLmdWriteBuffer(pLmdControl, (char *)pLmdControl->pBuffer,
00208                             (pLmdControl->iBufferWords-pLmdControl->iLeftWords)*2);
00209     pLmdControl->iBytes+=iReturn;
00210     if(iReturn != (pLmdControl->iBufferWords-pLmdControl->iLeftWords)*2)return(LMD__FAILURE);
00211     pLmdControl->iLeftWords=pLmdControl->iBufferWords; // buffer free
00212   }
00213   if((pHeader->iWords+4) > pLmdControl->iLeftWords){ // element too big for buffer
00214     printf("fLmdPutElement: Element too big: %d words\n",pHeader->iWords+4);
00215     return(PUTLMD__TOOBIG); 
00216   } 
00217   // copy to buffer
00218   ps=(uint32_t *)pHeader;
00219   pd=(uint32_t *)pLmdControl->pBuffer+(pLmdControl->iBufferWords-pLmdControl->iLeftWords)/2;
00220   iReturn=(pHeader->iWords+4)/2; // here 32b words
00221   for(i=0;i<iReturn;i++) *pd++ = *ps++;
00222   pLmdControl->pMbsFileHeader->iElements++;
00223   pLmdControl->iElements++;
00224   pLmdControl->iLeftWords -= (pHeader->iWords+4);
00225   if(pLmdControl->iOffsetEntries)fLmdOffsetSet(pLmdControl,iReturn);
00226   return(LMD__SUCCESS);
00227 }
00228 
00229 //===============================================================
00230 uint32_t fLmdPutBuffer(
00231 sLmdControl *pLmdControl, 
00232 sMbsHeader *pHeader, 
00233 uint32_t Items){
00234 
00235   sMbsHeader *pH;
00236   uint32_t Bytes=0,TotalBytes=0,i, elements;
00237   int64_t fileleft,used;
00238   int32_t iReturn;
00239 
00240   // check if total buffer fits in file
00241   if(pLmdControl->iOffsetEntries && (pLmdControl->iOffsetSize == 4)){
00242     elements=pLmdControl->iElements+Items+2;
00243     used=pLmdControl->iBytes/4;
00244     fileleft=0xffffffff - used - (4+elements); // size of table
00245     for(i=0;i<Items;i++)
00246       {
00247         Bytes = (4+pH->iWords)*2;
00248         TotalBytes += Bytes;
00249         pH=(sMbsHeader *)((int16_t *)pH+Bytes/2);
00250       }
00251     if((int64_t)TotalBytes/4 > fileleft){
00252       printf("fLmdPutElement: File size exceed\n");
00253       return(PUTLMD__EXCEED);
00254     }
00255     Bytes=0;
00256     TotalBytes=0;
00257   }
00258   pH=pHeader;
00259   for(i=0;i<Items;i++)
00260     {
00261       pLmdControl->iElements++;
00262       Bytes = (4+pH->iWords)*2;
00263       TotalBytes += Bytes;
00264       if(pLmdControl->iOffsetEntries)fLmdOffsetSet(pLmdControl,Bytes/4);
00265       if((pH->iWords+4) > pLmdControl->pMbsFileHeader->iMaxWords) 
00266           pLmdControl->pMbsFileHeader->iMaxWords=pH->iWords+4;
00267       pH=(sMbsHeader *)((int16_t *)pH+Bytes/2);
00268     }
00269   iReturn=fLmdWriteBuffer(pLmdControl,(char *)pHeader,TotalBytes);
00270   pLmdControl->iBytes+=iReturn;
00271   if(iReturn != TotalBytes)return(LMD__FAILURE);
00272   else {
00273     pLmdControl->pMbsFileHeader->iElements += Items;
00274     return(LMD__SUCCESS);
00275   }
00276 }
00277 
00278 //===============================================================
00279 uint32_t fLmdPutClose(
00280 sLmdControl *pLmdControl){
00281   int32_t iReturn,i;
00282   lmdoff_t current,c;
00283 
00284   if(pLmdControl->iBufferWords > pLmdControl->iLeftWords){ // write last buffer
00285     iReturn=fLmdWriteBuffer(pLmdControl, (char *)pLmdControl->pBuffer,
00286                             (pLmdControl->iBufferWords-pLmdControl->iLeftWords)*2);
00287     pLmdControl->iBytes+=iReturn;
00288     if(iReturn != (pLmdControl->iBufferWords-pLmdControl->iLeftWords)*2){
00289       printf("fLmdPutClose: Error writing last buffer. Closing file.\n");
00290       // rewind file and rewrite header
00291       rewind(pLmdControl->fFile);  /* rewind file, rewrite header */
00292       fLmdWriteBuffer(pLmdControl, (char *)pLmdControl->pMbsFileHeader,
00293                       sizeof(sMbsFileHeader));
00294       fLmdCleanup(pLmdControl);
00295       return(LMD__FAILURE);
00296     }
00297   }
00298   if(pLmdControl->iOffsetEntries) 
00299     if(fLmdOffsetWrite(pLmdControl) != LMD__SUCCESS)
00300       pLmdControl->pMbsFileHeader->iTableOffset=0; // table could not be written
00301   
00302   // rewind file and rewrite header
00303   rewind(pLmdControl->fFile);  /* rewind file, rewrite header */
00304   fLmdWriteBuffer(pLmdControl, (char *)pLmdControl->pMbsFileHeader,
00305                   sizeof(sMbsFileHeader));
00306   return(fLmdGetClose(pLmdControl));
00307 }
00308 
00309 #ifndef FILEONLY
00310 //===============================================================
00311 uint32_t fLmdConnectMbs(
00312 sLmdControl *pLmdControl, 
00313 char    *Nodename,
00314 uint32_t iPort,
00315 uint32_t *iBufferBytes){ // LMD__GET_EVENTS (NULL) or address to return buffer size
00316 
00317   int32_t stat;
00318   sMbsTransportInfo sMbs;
00319 
00320   if(iPort == 0) pLmdControl->iPort=PORT__TRANS;
00321   else pLmdControl->iPort=iPort;
00322   memset(pLmdControl,0,sizeof(sLmdControl));
00323   pLmdControl->pTCP=(struct s_tcpcomm *)malloc(sizeof(struct s_tcpcomm));
00324   if(pLmdControl->iPort==PORT__TRANS)
00325   printf("fLmdConnectMbs: Connect to transport server %s port %d\n",Nodename,pLmdControl->iPort);
00326   if(pLmdControl->iPort==PORT__STREAM)
00327   printf("fLmdConnectMbs: Connect to stream server %s port %d\n",Nodename,pLmdControl->iPort);
00328   stat=f_stc_connectserver(Nodename,pLmdControl->iPort,&pLmdControl->iTCP,pLmdControl->pTCP);
00329   if (stat != STC__SUCCESS) {
00330     printf ("fLmdConnectMbs: Error connect to %s \n",Nodename);
00331     fLmdCleanup(pLmdControl);
00332     return(LMD__FAILURE);
00333   }
00334   stat=f_stc_read((int32_t *)&sMbs, sizeof(sMbsTransportInfo),pLmdControl->iTCP,3);
00335   if (stat != STC__SUCCESS) {
00336     printf ("fLmdConnectMbs: Error read info from %s \n",Nodename);
00337     fLmdCleanup(pLmdControl);
00338     return(LMD__FAILURE);
00339   }
00340   if(sMbs.iEndian != 1)pLmdControl->iSwap=1;
00341   if(pLmdControl->iSwap)fLmdSwap4((uint32_t *)&sMbs,sizeof(sMbsTransportInfo)/4);
00342   if(sMbs.iBuffers > 1){
00343     printf("fLmdConnectMbs: Event spanning not supported!\n");
00344     fLmdCleanup(pLmdControl);
00345     return(LMD__FAILURE);
00346   }
00347   if(sMbs.iStreams > 0){
00348     printf("fLmdConnectMbs: MBS not in DABC mode!\n");
00349     fLmdCleanup(pLmdControl);
00350     return(LMD__FAILURE); 
00351   }
00352   strcpy(pLmdControl->cFile,Nodename);
00353   if(iBufferBytes == LMD__GET_EVENTS){ // use internal buffer for fLmdGetMbsEvent
00354     pLmdControl->pBuffer = (int16_t *) malloc(sMbs.iMaxBytes);
00355     pLmdControl->iBufferWords=sMbs.iMaxBytes/2;
00356     pLmdControl->iInternBuffer=1;
00357   } else
00358   *iBufferBytes=sMbs.iMaxBytes;
00359   return(LMD__SUCCESS);
00360 }
00361 //===============================================================
00362 uint32_t fLmdInitMbs(
00363 sLmdControl *pLmdControl, 
00364 char    *Nodename,
00365 uint32_t iMaxBytes,
00366 uint32_t iBuffers,
00367 uint32_t iStreams,
00368 uint32_t iPort,
00369 uint32_t iTimeout){
00370 
00371   int32_t stat;
00372 
00373   if(iBuffers > 1){printf("fLmdInitMbs: Event spanning not supported!\n");return(LMD__FAILURE);}
00374   if(iStreams > 0){printf("fLmdInitMbs: MBS not in DABC mode!\n");return(LMD__FAILURE);}
00375   pLmdControl->iPort=iPort;
00376   strcpy(pLmdControl->cFile,Nodename);
00377   if(pLmdControl->pBuffer == NULL)pLmdControl->pBuffer= (int16_t *) malloc(iMaxBytes);
00378   pLmdControl->iBufferWords=iMaxBytes/2;
00379   pLmdControl->iInternBuffer=1;
00380   pLmdControl->iTCP=pLmdControl->pTCP->socket;
00381   pLmdControl->iTcpTimeout=iTimeout;
00382   return(LMD__SUCCESS);
00383 }
00384 //===============================================================
00385 uint32_t fLmdCloseMbs(sLmdControl *pLmdControl){
00386 
00387   int32_t stat;
00388   const char cClose[12] = "CLOSE";
00389   // send request buffer for stream server
00390   if(pLmdControl->iPort == PORT__STREAM)
00391     stat=f_stc_write(cClose,12,pLmdControl->iTCP);
00392   stat=f_stc_close(pLmdControl->pTCP);
00393   pLmdControl->pMbsFileHeader = NULL; // was reference only
00394   fLmdCleanup(pLmdControl);
00395   return(stat);
00396 }
00397 //===============================================================
00398 uint32_t fLmdGetMbsEvent(sLmdControl *pLmdControl, sMbsHeader** event){
00399   uint32_t stat;
00400   sMbsHeader *pM;
00401   *event=NULL;
00402   if(pLmdControl->iLeftWords == 0){ // get new buffer
00403     stat=fLmdGetMbsBuffer(pLmdControl,NULL,0,NULL,NULL);
00404     if(stat != LMD__SUCCESS){
00405       return(stat);
00406     }
00407     // first event behind header:
00408     pLmdControl->pMbsHeader=(sMbsHeader *)(pLmdControl->pBuffer+sizeof(sMbsBufferHeader)/2);
00409   }
00410   pM=pLmdControl->pMbsHeader; // current to be returned
00411   pLmdControl->iLeftWords -= (pLmdControl->pMbsHeader->iWords+4);
00412   pLmdControl->pMbsHeader = 
00413            (sMbsHeader *)((int16_t *)pLmdControl->pMbsHeader +
00414            pLmdControl->pMbsHeader->iWords+4);
00415   pLmdControl->iElements++;
00416   *event=pM;
00417   return(LMD__SUCCESS);
00418 }
00419 //===============================================================
00420 uint32_t fLmdGetMbsBuffer(
00421 sLmdControl *pLmdControl, 
00422 sMbsBufferHeader *pBuffer, 
00423 uint32_t iBytes, 
00424 uint32_t *iElements, 
00425 uint32_t *iBytesUsed){
00426 
00427   sMbsHeader *pm;
00428   sMbsBufferHeader *pBuf;
00429   uint32_t *ps, *pd, i,ii, elem=0, size=0, usedBytes=0,leftBytes=0;
00430   int32_t iReturn;
00431   const char cRequest[12] = "GETEVT";
00432 
00433   leftBytes=iBytes;
00434   pBuf=pBuffer;
00435   if(pBuf == NULL){
00436     pBuf=(sMbsBufferHeader *)pLmdControl->pBuffer; // internal buffer
00437     leftBytes=pLmdControl->iBufferWords*2; // size of this buffer
00438   }
00439   if(pBuf == NULL){
00440     printf("fLmdGetMbsBuffer: Need buffer to read\n");
00441     return(LMD__FAILURE);
00442   }
00443   if(leftBytes < sizeof(sMbsBufferHeader)){
00444     printf("fLmdGetMbsBuffer: %s buffer size %d too small for %d bytes\n",
00445      pLmdControl->cFile,leftBytes,sizeof(sMbsBufferHeader));
00446     return(LMD__FAILURE);
00447   }
00448   // send request buffer for stream server
00449   if(pLmdControl->iPort == PORT__STREAM)
00450     iReturn=f_stc_write(cRequest,12,pLmdControl->iTCP);
00451   iReturn=f_stc_read((int32_t *)pBuf,sizeof(sMbsBufferHeader),pLmdControl->iTCP,pLmdControl->iTcpTimeout);
00452   if(iReturn == STC__TIMEOUT) return(LMD__TIMEOUT);
00453   if(iReturn != STC__SUCCESS) return(LMD__FAILURE);
00454   if(pLmdControl->iSwap)fLmdSwap4((uint32_t *)pBuf,sizeof(sMbsBufferHeader)/4);
00455   if(leftBytes < (sizeof(sMbsBufferHeader)+2*pBuf->iUsedWords)){
00456     printf("fLmdGetMbsBuffer: %s buffer size %d too small for %d bytes\n",
00457      pLmdControl->cFile,leftBytes,sizeof(sMbsBufferHeader)+2*pBuf->iMaxWords);
00458     return(LMD__FAILURE);
00459   }
00460   usedBytes=pBuf->iUsedWords*2;
00461   if((pBuf->iType&0xffff) == 100)
00462     iReturn=f_stc_read((int32_t *)(pBuf+1),usedBytes,pLmdControl->iTCP,-1);
00463   if(iReturn == STC__TIMEOUT) return(LMD__TIMEOUT);
00464   if(iReturn != STC__SUCCESS) return(LMD__FAILURE);
00465   if(pLmdControl->iSwap)fLmdSwap4((uint32_t *)(pBuf+1),usedBytes/4);
00466   if(iBytesUsed != NULL)*iBytesUsed =usedBytes+sizeof(sMbsBufferHeader);
00467   if(iElements  != NULL)*iElements  =pBuf->iElements;
00468   pLmdControl->iBytes += usedBytes;
00469   pLmdControl->iLeftWords = usedBytes/2; // without header
00470   pLmdControl->pMbsFileHeader = (sMbsFileHeader *)pBuf;
00471   return(LMD__SUCCESS);
00472 }
00473 #endif
00474 // endif FILEONLY
00475 
00476 //===============================================================
00477 uint32_t fLmdGetOpen(
00478 sLmdControl *pLmdControl, 
00479 char    *Filename, 
00480 sMbsFileHeader *pBuffHead, // LMD__INTERNAL_HEADER (NULL) or address of file header
00481 uint32_t iBytes,           // LMD__NO_BUFFER (0) or LMD__MIN_BUFFER or internal buffersize
00482 uint32_t iUseOffset){      // LMD__[NO_]INDEX
00483 
00484   int32_t iReturn;
00485   uint32_t l=0,i,bufferBytes=0,h[12];
00486   lmdoff_t to;
00487 
00488   memset(pLmdControl,0,sizeof(sLmdControl));
00489   if(pBuffHead == LMD__INTERNAL_HEADER){
00490     pLmdControl->pMbsFileHeader= (sMbsFileHeader *)malloc(sizeof(sMbsFileHeader));
00491     pLmdControl->iInternHeader=1;
00492   }
00493   else {
00494     pLmdControl->pMbsFileHeader= pBuffHead;
00495     pLmdControl->iInternHeader=0;
00496   }
00497   memset(pLmdControl->pMbsFileHeader,0,sizeof(sMbsFileHeader));
00498 
00499   // copy file name to control structure
00500   strcpy(pLmdControl->cFile,Filename);
00501   if((pLmdControl->fFile=(FILE *)fopen64(Filename,"r"))== NULL)
00502     {
00503       printf("fLmdGetOpen: File not found: %d\n",Filename);
00504       fLmdCleanup(pLmdControl);
00505       return(GETLMD__NOFILE);
00506     }
00507  /* read header */
00508   iReturn=fLmdReadBuffer(pLmdControl,
00509                     (char *)pLmdControl->pMbsFileHeader,
00510                          sizeof(sMbsFileHeader));
00511     if(iReturn!=sizeof(sMbsFileHeader)) {
00512     printf("fLmdGetOpen: LMD format error: no LMD file: %s\n",Filename);
00513     fLmdGetClose(pLmdControl);
00514     return(GETLMD__NOLMDFILE);
00515   }
00516   // check type and subtype, and endian
00517   if(pLmdControl->pMbsFileHeader->iEndian != 1) pLmdControl->iSwap=1;
00518   if(pLmdControl->iSwap){
00519       printf("do swap !!!\n");
00520     fLmdSwap4((uint32_t *)pLmdControl->pMbsFileHeader,sizeof(sMbsFileHeader)/4);
00521     fLmdSwap8((uint64_t *)&pLmdControl->pMbsFileHeader->iTableOffset,1);
00522   }
00523   if(pLmdControl->pMbsFileHeader->iType != LMD__TYPE_FILE_HEADER_101_1){
00524     printf("fLmdGetOpen: LMD format error: no LMD file: %s, type is %0x\n",
00525         Filename,pLmdControl->pMbsFileHeader->iType);
00526     fLmdGetClose(pLmdControl);
00527     return(GETLMD__NOLMDFILE);
00528   }
00529 
00530   if((iUseOffset == LMD__INDEX)&&(pLmdControl->pMbsFileHeader->iTableOffset > 0)){
00531     // printf("fLmdGetOpen: use table in file: %s\n",Filename);
00532     pLmdControl->iOffsetSize=pLmdControl->pMbsFileHeader->iOffsetSize;
00533     iReturn=fLmdOffsetRead(pLmdControl); // read offset table
00534     if(iReturn != LMD__SUCCESS){
00535     printf("fLmdGetOpen: Index format error: %s\n",Filename);
00536     fLmdGetClose(pLmdControl);
00537       return(iReturn);
00538     }
00539   }
00540 
00541   pLmdControl->iBytes+=iReturn;
00542   // more of header?
00543   if(pLmdControl->pMbsFileHeader->iUsedWords > 0)
00544     {
00545       // Read this additional information without swapping.
00546       // Could be mostly strings. Caller must know.
00547       pLmdControl->cHeader=malloc(pLmdControl->pMbsFileHeader->iUsedWords*2);
00548       iReturn=fLmdReadBuffer(pLmdControl,pLmdControl->cHeader,
00549                              pLmdControl->pMbsFileHeader->iUsedWords*2 );
00550       if(iReturn!=pLmdControl->pMbsFileHeader->iUsedWords*2) {
00551         printf("fLmdGetOpen: LMD format error: no LMD file: %s\n",Filename);
00552         fLmdGetClose(pLmdControl);
00553         return(GETLMD__NOLMDFILE);
00554       }
00555     }
00556 
00557   bufferBytes=iBytes;
00558   if(bufferBytes < pLmdControl->pMbsFileHeader->iMaxWords*2) 
00559     bufferBytes=pLmdControl->pMbsFileHeader->iMaxWords*2;
00560   fLmdPrintFileHeader(1,pLmdControl->pMbsFileHeader);
00561   pLmdControl->pBuffer=(int16_t *)malloc(bufferBytes);
00562   pLmdControl->iBufferWords=bufferBytes/2; // will be increased if necessary
00563 
00564   printf("fLmdGetOpen: %s words %u\n", Filename, pLmdControl->iBufferWords);
00565 
00566   pLmdControl->iLeftWords = 0; // buffer empty, read with first fLmdGetElement
00567   pLmdControl->pMbsHeader = NULL;
00568   return(LMD__SUCCESS);
00569 }
00570 //===============================================================
00571 uint32_t fLmdGetBuffer(
00572 sLmdControl *pLmdControl, 
00573 sMbsHeader *pMbsHeader, 
00574 uint32_t iBytes, 
00575 uint32_t *iElements, 
00576 uint32_t *iBytesUsed){
00577 
00578   sMbsHeader *pm;
00579   uint32_t *ps, *pd, i,ii, elem=0, size=0, leftBytes=0, used, elem_sz;
00580   int32_t iReturn;
00581 
00582   if(iBytes < pLmdControl->pMbsFileHeader->iMaxWords){
00583      printf("fLmdGetBuffer: %s buffer size %d too small for %d bytes\n",
00584      pLmdControl->cFile,iBytes,pLmdControl->pMbsFileHeader->iMaxWords);
00585     return(LMD__FAILURE);
00586   }
00587   if(pMbsHeader == NULL){
00588     printf("fLmdGetBuffer: Need buffer to read\n");
00589     return(LMD__FAILURE);
00590   }
00591   *iBytesUsed=0;
00592   *iElements=0;
00593   if(pLmdControl->iElements == pLmdControl->pMbsFileHeader->iElements) return(GETLMD__EOFILE);
00594 
00595   // Offset table
00596   if(pLmdControl->iOffsetEntries){ // use offsets to read elements fitting in buffer
00597     fLmdOffsetElements(pLmdControl,iBytes, &elem, &used);
00598     //printf("Read %d bytes of %d, elements %d\n",used,iBytes,elem);
00599     iReturn=fLmdReadBuffer(pLmdControl,(char *)pMbsHeader,used);
00600     if(iReturn <= 0){
00601       printf("fLmdGetBuffer: EOF: %s\n",pLmdControl->cFile);
00602       return(GETLMD__EOFILE);
00603     }
00604     if(iReturn!=used) {
00605       printf("fLmdGetBuffer: LMD read error: unexpected EOF: %s %u %u\n",
00606                  pLmdControl->cFile, iReturn, used);
00607       return(GETLMD__NOLMDFILE);
00608     }
00609     *iBytesUsed=used;
00610     *iElements=elem;
00611     if(pLmdControl->iSwap)fLmdSwap4((uint32_t *)pMbsHeader,iReturn/4);
00612     pLmdControl->iBytes+=iReturn;
00613     return(LMD__SUCCESS);
00614   }
00615   // no offset table
00616   // do we have fragment stored?
00617   leftBytes = pLmdControl->iLeftWords*2;
00618   if(leftBytes>0) {
00619       if (leftBytes > iBytes) {
00620          printf("fLmdGetBuffer: stored peace of data (%u) larger than provided buffer (%u)\n",
00621                     leftBytes, iBytes);
00622          return(LMD__FAILURE);
00623       }
00624       
00625       if (pLmdControl->pMbsHeader==0) {
00626          printf("fLmdGetBuffer: Internal error pMbsHeader==0\n");
00627          return(LMD__FAILURE);
00628       }
00629       
00630       memcpy(pMbsHeader, pLmdControl->pMbsHeader, leftBytes);
00631   }
00632   iReturn = fLmdReadBuffer(pLmdControl,(char *)pMbsHeader+leftBytes, iBytes-leftBytes);
00633   if(iReturn <= 0) {
00634     printf("fLmdGetBuffer: EOF: %s\n",pLmdControl->cFile);
00635     if (leftBytes>0) 
00636        printf("fLmdGetBuffer: EOF while we have some rest data (%u)\n", leftBytes);
00637     else
00638        return(GETLMD__EOFILE);
00639   }
00640   
00641   if(iReturn > (iBytes-leftBytes)) {
00642       printf("fLmdGetBuffer: LMD read error %s - too many bytes read %u wants %u",
00643             pLmdControl->cFile, iReturn, iBytes-leftBytes);
00644       return(GETLMD__NOLMDFILE);
00645   }
00646   
00647   if(pLmdControl->iSwap)fLmdSwap4((uint32_t *)pMbsHeader+leftBytes/4,iReturn/4);
00648   pLmdControl->iBytes += iReturn;
00649   leftBytes += iReturn; // thats what is in the buffer
00650   // step through buffer to get number of elements and size
00651   pm=pMbsHeader;
00652   while(leftBytes >=8){
00653      if(pm->iType == LMD__TYPE_FILE_INDEX_101_2) break; // file index is last
00654      elem_sz = (pm->iWords+4)*2;
00655      if(elem_sz > leftBytes) break; // pm valid but incomplete data
00656 
00657      *iBytesUsed += elem_sz;
00658      *iElements += 1;
00659      pLmdControl->iElements++;
00660      pm = (sMbsHeader *)((char*)pm + elem_sz);
00661      leftBytes -= elem_sz;
00662   }
00663   //printf("Read %d bytes of %d, elements %d\n",*iBytesUsed,iBytes,*iElements);
00664   // fragment left? copy to internal buffer
00665   if(leftBytes>0){
00666     if(leftBytes > pLmdControl->iBufferWords*2){
00667       printf("fLmdGetBuffer: ERROR: internal buffer overflow. Needed:%d available:%d\n",
00668              leftBytes,pLmdControl->iBufferWords*2);
00669       return(LMD__FAILURE);
00670     } else {
00671       memcpy(pLmdControl->pBuffer,pm,leftBytes);
00672     }
00673   }
00674   pLmdControl->iLeftWords = leftBytes/2;
00675   if (pLmdControl->iLeftWords>0)
00676      pLmdControl->pMbsHeader = (sMbsHeader*)pLmdControl->pBuffer;
00677   else
00678      pLmdControl->pMbsHeader = 0;
00679   
00680   return(LMD__SUCCESS);
00681 }
00682 //===============================================================
00683 uint32_t fLmdGetElement(sLmdControl *pLmdControl, uint32_t iEvent, sMbsHeader **event){
00684   sMbsHeader *pM;
00685   uint32_t *ps, *pd, i, evsz;
00686   int32_t iReturn;
00687   *event=NULL;
00688 
00689   if(iEvent == LMD__NO_INDEX) {
00690      if(pLmdControl->pBuffer==NULL) return(GETLMD__NOBUFFER); // internal buffer needed
00691      if(pLmdControl->pMbsFileHeader->iElements==0) return(GETLMD__NOMORE);
00692      
00693      // check if we need to read extra data
00694      if ((pLmdControl->iLeftWords < 4) || 
00695          (pLmdControl->pMbsHeader == 0) ||
00696          (pLmdControl->pMbsHeader->iWords+4 > pLmdControl->iLeftWords)) {
00697              // first copy old data, if it exists
00698              if (pLmdControl->iLeftWords > 0) {
00699                 memmove(pLmdControl->pBuffer, pLmdControl->pMbsHeader, pLmdControl->iLeftWords*2);
00700 //                printf("copy to the begin rest %u bytes", pLmdControl->iLeftWords*2);
00701              }
00702                
00703              // second, try to read more bytes  
00704              
00705              iReturn = fLmdReadBuffer(pLmdControl,
00706                     (char *)(pLmdControl->pBuffer+pLmdControl->iLeftWords),
00707                     (pLmdControl->iBufferWords-pLmdControl->iLeftWords)*2);
00708 
00709              if(iReturn <= 0) { printf("fLmdGetElement: EOF\n"); return(GETLMD__EOFILE); }
00710              
00711              if(pLmdControl->iSwap) fLmdSwap4((uint32_t *)(pLmdControl->pBuffer+pLmdControl->iLeftWords),iReturn/4);
00712 
00713              pLmdControl->iBytes += iReturn;
00714              pLmdControl->pMbsHeader=(sMbsHeader *)pLmdControl->pBuffer;
00715              pLmdControl->iLeftWords += iReturn/2;
00716          }
00717          
00718      // check if read buffer enough for event
00719      
00720      evsz = (pLmdControl->pMbsHeader->iWords + 4) * 2;
00721      
00722      if (evsz > pLmdControl->iLeftWords*2) {
00723         printf ("fLmdGetElement: Error, full element %u does not fit in buffer %u",
00724                   evsz, pLmdControl->iLeftWords*2);
00725         return (GETLMD__TOOBIG);  
00726      }
00727          
00728      pLmdControl->pMbsFileHeader->iElements--;
00729      pM = pLmdControl->pMbsHeader;
00730      pLmdControl->pMbsHeader = (sMbsHeader *) ((char*) pM + evsz);
00731      pLmdControl->iLeftWords -= evsz/2;
00732      pLmdControl->iElements++;
00733      *event=pM;
00734      return(LMD__SUCCESS);
00735   }
00736   // get indexed event
00737   if(pLmdControl->iOffsetEntries){
00738     if(iEvent >= pLmdControl->iOffsetEntries)return(GETLMD__OUTOF_RANGE);
00739     fseeko64(pLmdControl->fFile,fLmdOffsetGet(pLmdControl,iEvent-1)*4,SEEK_SET);
00740     i=(fLmdOffsetGet(pLmdControl,iEvent)-fLmdOffsetGet(pLmdControl,iEvent-1));
00741     iReturn=fLmdReadBuffer(pLmdControl,(char *)pLmdControl->pBuffer,i*4);
00742     if(iReturn <= 0) {printf("fLmdGetElement: EOF\n");return(GETLMD__EOFILE);}
00743     if(iReturn!=(i*4)) {
00744       printf("fLmdGetBuffer: LMD read error: unexpected EOF: %s\n",pLmdControl->cFile);
00745       return(GETLMD__EOFILE);
00746     }
00747     if(pLmdControl->iSwap)fLmdSwap4((uint32_t *)pLmdControl->pBuffer,iReturn/4);
00748     pLmdControl->pMbsHeader=(sMbsHeader *)pLmdControl->pBuffer;
00749     if((pLmdControl->pMbsHeader->iWords+4) != i*2){
00750       printf("fLmdGetElement: Error Event %d: size from table is %d, header %d\n",
00751        iEvent,i/2,pLmdControl->pMbsHeader->iWords+4);
00752       return(GETLMD__SIZE_ERROR);
00753     }
00754     pLmdControl->iBytes+=iReturn;
00755     *event=pLmdControl->pMbsHeader;
00756     return(LMD__SUCCESS);
00757   }
00758   else return(GETLMD__NOMORE);
00759   // return zero if no more events
00760 }
00761 //===============================================================
00762 uint32_t fLmdGetClose(sLmdControl *pLmdControl){
00763   fLmdCleanup(pLmdControl); // cleanup except fFile
00764   if(fclose(pLmdControl->fFile)!=0) {
00765       pLmdControl->fFile=NULL;
00766       return(LMD__CLOSE_ERR);
00767   }
00768   pLmdControl->fFile=NULL;
00769   return(LMD__SUCCESS);
00770 }
00771 //===============================================================
00772 int32_t fLmdReadBuffer(sLmdControl *pLmdControl, char *buffer, uint32_t bytes){
00773   int32_t IObytes;
00774   IObytes=(int32_t)fread(buffer,1,bytes,pLmdControl->fFile);
00775   //if(IObytes < bytes) printf("Read %s: request %d bytes, got %d\n",pLmdControl->cFile,bytes,IObytes);
00776   return(IObytes);
00777 }
00778 //===============================================================
00779 int32_t fLmdWriteBuffer(sLmdControl *pLmdControl, char *buffer, uint32_t bytes){
00780   int32_t IObytes;
00781   IObytes=(int32_t)fwrite(buffer,1,bytes,pLmdControl->fFile);
00782   //if(IObytes < bytes) printf("Write %s: request %d bytes, put %d\n",
00783   // pLmdControl->cFile,bytes,IObytes);
00784   return(IObytes);
00785 }
00786 //===============================================================
00787 uint64_t fLmdGetBytesWritten(sLmdControl *pLmdControl){
00788         uint64_t bytes;
00789         bytes=pLmdControl->iBytes;
00790         // add pending data size in current buffer
00791     if(pLmdControl->iBufferWords > pLmdControl->iLeftWords)
00792     bytes += (pLmdControl->iBufferWords - pLmdControl->iLeftWords)*2;
00793         // add table size which will be written at close
00794         if ((pLmdControl->pOffset4!=NULL)||(pLmdControl->pOffset8!=NULL))
00795           bytes += (pLmdControl->iElements+1)*pLmdControl->iOffsetSize;
00796 return(bytes);
00797 }
00798 //===============================================================
00799 uint32_t fLmdCleanup(sLmdControl *pLmdControl){
00800 // do not clean fFile
00801   if(pLmdControl->pTCP     != NULL)free(pLmdControl->pTCP);
00802   if(pLmdControl->cHeader  != NULL)free(pLmdControl->cHeader);
00803   if(pLmdControl->pOffset4 != NULL)free(pLmdControl->pOffset4);
00804   if(pLmdControl->pOffset8 != NULL)free(pLmdControl->pOffset8);
00805   if(pLmdControl->pBuffer  != NULL && pLmdControl->iInternBuffer)
00806                                    free(pLmdControl->pBuffer);
00807   if(pLmdControl->pMbsFileHeader != NULL && pLmdControl->iInternHeader)
00808                                    free(pLmdControl->pMbsFileHeader);
00809   pLmdControl->pTCP=NULL;
00810   pLmdControl->cHeader=NULL;
00811   pLmdControl->pBuffer=NULL;
00812   pLmdControl->pOffset4=NULL;
00813   pLmdControl->pOffset8=NULL;
00814   pLmdControl->pMbsFileHeader=NULL;
00815   pLmdControl->pMbsHeader=NULL;
00816   return (LMD__SUCCESS);
00817 }
00818 //===============================================================
00819 // can be called after GetOpen or ConnectMbs
00820 uint32_t fLmdGetSwap(sLmdControl *pLmdControl){
00821 if(pLmdControl != NULL)
00822         return(pLmdControl->iSwap);
00823         else return(-1);
00824 }
00825 //===============================================================
00826 // can be called after PutOpen or before PutClose
00827 void fLmdSetWrittenEndian(sLmdControl *pLmdControl,uint32_t iE){
00828 if(pLmdControl->pMbsFileHeader != NULL)
00829         pLmdControl->pMbsFileHeader->iWrittenEndian=iE;
00830         else printf("fLmdSetWrittenEndian: No file header allocated!");
00831 }
00832 //===============================================================
00833 // can be called after GetOpen or GetMbsEvent
00834 uint32_t   fLmdGetWrittenEndian(sLmdControl *pLmdControl){
00835 if(pLmdControl->pMbsFileHeader != NULL)
00836         return(pLmdControl->pMbsFileHeader->iWrittenEndian);
00837 else printf("fLmdGetWrittenEndian: No file header allocated!");
00838 return(LMD__ENDIAN_UNKNOWN);
00839 }
00840 //===============================================================
00841 sLmdControl * fLmdAllocateControl(){
00842   sLmdControl *x;
00843   x=(sLmdControl *)malloc(sizeof(sLmdControl));
00844   memset(x,0,sizeof(sLmdControl));
00845   return(x);
00846 }
00847 //===============================================================
00848 void fLmdOffsetElements(sLmdControl *pLmdControl, 
00849 uint32_t bytes, 
00850 uint32_t *elements, 
00851 uint32_t *used){
00852   lmdoff_t *off1,*off2;
00853   uint32_t elem=0,i,*iff1,*iff2;
00854 
00855   if(pLmdControl->iOffsetSize == 4){
00856     iff1=pLmdControl->pOffset4+pLmdControl->iElements;
00857     iff2=iff1;
00858     for(i=pLmdControl->iElements;i<pLmdControl->iOffsetEntries-1;i++){
00859       if((*(iff1+1)-*iff2)>bytes/4) break;
00860       iff1++;
00861       elem++;
00862       pLmdControl->iElements++;
00863     }
00864     *used=(*iff1-*iff2)*4;
00865     *elements=elem;
00866   }
00867   else if(pLmdControl->iOffsetSize == 8){
00868     off1=pLmdControl->pOffset8+pLmdControl->iElements;
00869     off2=off1;
00870     for(i=pLmdControl->iElements;i<pLmdControl->iOffsetEntries-1;i++){
00871       if((*(off1+1)-*off2)>bytes/4) break;
00872       off1++;
00873       elem++;
00874       pLmdControl->iElements++;
00875     }
00876     *used=(*off1-*off2)*4;
00877     *elements=elem;
00878   }
00879 }
00880 //===============================================================
00881 uint32_t fLmdOffsetRead(sLmdControl *pLmdControl)
00882 {
00883   int32_t iReturn;
00884   sMbsHeader *pTableHead;
00885 
00886   pTableHead=(sMbsHeader *)malloc(16); // header with 8 bytes data for future use.
00887   fseeko64(pLmdControl->fFile,(lmdoff_t)pLmdControl->pMbsFileHeader->iTableOffset*4,SEEK_SET);
00888   iReturn=fLmdReadBuffer(pLmdControl, (char *)pTableHead,16);
00889     if(iReturn!=16) {
00890       printf("fLmdGetBuffer: LMD read error: unexpected EOF: %s\n",pLmdControl->cFile);
00891       free(pTableHead);
00892       return(GETLMD__NOLMDFILE);
00893     }
00894     if(pLmdControl->iSwap)fLmdSwap4((uint32_t *)pTableHead,4);
00895   if(pTableHead->iType != LMD__TYPE_FILE_INDEX_101_2){
00896     printf("fLmdOffsetTable: LMD format error: no index table: %s, type %0x\n",
00897            pLmdControl->cFile,pTableHead->iType);
00898     free(pTableHead);
00899     return(GETLMD__NOLMDFILE);
00900   }
00901   //printf("Table: words:%d type:%08x\n",pTableHead->iWords,pTableHead->iType);
00902   free(pTableHead);
00903   pLmdControl->iOffsetEntries=pLmdControl->pMbsFileHeader->iElements+1;
00904   pLmdControl->pOffset8=(lmdoff_t *)malloc(pLmdControl->iOffsetEntries*pLmdControl->iOffsetSize);
00905   iReturn=fLmdReadBuffer(pLmdControl,
00906                          (char *)pLmdControl->pOffset8,
00907                          pLmdControl->iOffsetEntries*pLmdControl->iOffsetSize);
00908   if(iReturn!=pLmdControl->iOffsetEntries*pLmdControl->iOffsetSize) {
00909     printf("fLmdOffsetTable: LMD format error: no index table: %s\n",pLmdControl->cFile);
00910     pLmdControl->iOffsetEntries=0;
00911     free(pTableHead);
00912     return(GETLMD__NOLMDFILE);
00913   }
00914   if(pLmdControl->iSwap){
00915     fLmdSwap4((uint32_t *)pLmdControl->pOffset8,iReturn/4);
00916     if(pLmdControl->iOffsetSize == 8)
00917     fLmdSwap8((uint64_t *)pLmdControl->pOffset8,iReturn/8);
00918   }
00919   // go back behing header
00920   fseeko64(pLmdControl->fFile,(lmdoff_t)sizeof(sMbsFileHeader),SEEK_SET);
00921   // use small table
00922   if(pLmdControl->iOffsetSize == 4){
00923     pLmdControl->pOffset4= (uint32_t *)pLmdControl->pOffset8;
00924     pLmdControl->pOffset8=NULL;
00925   }
00926   return(LMD__SUCCESS);
00927 }
00928 //===============================================================
00929 uint32_t fLmdOffsetWrite(sLmdControl *pLmdControl)
00930 {
00931   int32_t iReturn;
00932   char *pbuf;
00933   lmdoff_t current;
00934   sMbsHeader *pTableHead;
00935   pTableHead=(sMbsHeader *)malloc(16); // header with 8 bytes data for future use.
00936   memset(pTableHead,0,16);
00937   pTableHead->iWords=(pLmdControl->iElements+1)*pLmdControl->iOffsetSize/2+4;
00938   pTableHead->iType=LMD__TYPE_FILE_INDEX_101_2;
00939 /*   printf("Table: words:%d type:%08x offbytes:%d\n", */
00940 /*     pTableHead->iWords,pTableHead->iType,pLmdControl->iOffsetSize); */
00941   iReturn=fgetpos64(pLmdControl->fFile,(fpos64_t *)&current);
00942   iReturn=fLmdWriteBuffer(pLmdControl, (char *)pTableHead,16);
00943   free(pTableHead);
00944   pbuf=(char *)pLmdControl->pOffset4; // try short table
00945   if(pbuf == NULL) pbuf=(char *)pLmdControl->pOffset8;
00946   iReturn=fLmdWriteBuffer(pLmdControl, pbuf,
00947                   (pLmdControl->iElements+1)*pLmdControl->iOffsetSize);
00948   if(pLmdControl->pOffset8)
00949     pLmdControl->pMbsFileHeader->iTableOffset = *(pLmdControl->pOffset8+pLmdControl->iElements);
00950   if(pLmdControl->pOffset4)
00951     pLmdControl->pMbsFileHeader->iTableOffset = *(pLmdControl->pOffset4+pLmdControl->iElements);
00952   if(current/4 != pLmdControl->pMbsFileHeader->iTableOffset){
00953     printf("Table offset mismatch: current:%lld calculated:%lld, cur-cal %lld\n",
00954            current/4,pLmdControl->pMbsFileHeader->iTableOffset,
00955            current/4-pLmdControl->pMbsFileHeader->iTableOffset);
00956     return(LMD__FAILURE);
00957     }
00958   if(iReturn != (pLmdControl->iElements+1)*pLmdControl->iOffsetSize){
00959     printf("Table write error \n");
00960     return(LMD__FAILURE);
00961   }
00962   return(LMD__SUCCESS);
00963 }
00964 //===============================================================
00965 uint32_t fLmdOffsetSet(sLmdControl *pLmdControl, uint32_t lwords)
00966 {
00967   int32_t iReturn;
00968   if(pLmdControl->iElements >= pLmdControl->iOffsetEntries)fLmdOffsetResize(pLmdControl,0);
00969   if(pLmdControl->pOffset8){
00970     *(pLmdControl->pOffset8+pLmdControl->iElements)=
00971     *(pLmdControl->pOffset8+pLmdControl->iElements-1)+(lmdoff_t)lwords;
00972   }
00973   if(pLmdControl->pOffset4){
00974     *(pLmdControl->pOffset4+pLmdControl->iElements)=
00975     *(pLmdControl->pOffset4+pLmdControl->iElements-1)+lwords;
00976   }
00977   return(LMD__SUCCESS);
00978 }
00979 //===============================================================
00980 lmdoff_t fLmdOffsetGet(sLmdControl *pLmdControl, uint32_t index){
00981   if(pLmdControl->pOffset8)
00982     return(*(pLmdControl->pOffset8+index));
00983   if(pLmdControl->pOffset4)
00984     return((lmdoff_t)*(pLmdControl->pOffset4+index));
00985 }
00986 //===============================================================
00987 void fLmdOffsetResize(sLmdControl *pLmdControl, uint32_t firstValue){
00988   lmdoff_t *new;
00989   uint32_t oldEntries,newEntries;
00990 
00991   oldEntries=pLmdControl->iOffsetEntries;
00992   newEntries=oldEntries+OFFSET__ENTRIES;
00993   new=(lmdoff_t *)malloc(newEntries*pLmdControl->iOffsetSize);
00994   memset(new,0,newEntries*pLmdControl->iOffsetSize);
00995   if(oldEntries > 0){ //table was expanded
00996     //printf("Resize table %d to %d entries\n",oldEntries,newEntries);
00997     if(pLmdControl->pOffset8){
00998       memcpy(new,pLmdControl->pOffset8,oldEntries*pLmdControl->iOffsetSize);
00999       free(pLmdControl->pOffset8);
01000       pLmdControl->pOffset8=new;
01001     }
01002     if(pLmdControl->pOffset4){
01003       memcpy(new,pLmdControl->pOffset4,oldEntries*pLmdControl->iOffsetSize);
01004       free(pLmdControl->pOffset4);
01005       pLmdControl->pOffset4=(uint32_t *)new;
01006     }
01007   }
01008   else { // table was new
01009     //printf("Create table %d entries, first offset %d\n",newEntries,firstValue);
01010     if(pLmdControl->iOffsetSize==8){
01011       pLmdControl->pOffset8=new;
01012       *pLmdControl->pOffset8=(lmdoff_t)firstValue;
01013     }
01014     if(pLmdControl->iOffsetSize==4){
01015       pLmdControl->pOffset4=(uint32_t *)new;
01016       *pLmdControl->pOffset4=firstValue;
01017     }
01018   }
01019   pLmdControl->iOffsetEntries=newEntries;
01020 }
01021 //===============================================================
01022 void fLmdPrintBufferHeader(uint32_t iVerbose, sMbsBufferHeader *pMbsBufferHeader)
01023 {
01024   if(iVerbose){
01025     if(pMbsBufferHeader){
01026     printf("BfHd: # %d, DataWords:%d Type:%08x Elements:%d sec:%d.%d MaxWords:%d\n",
01027            pMbsBufferHeader->iBuffer,
01028            pMbsBufferHeader->iUsedWords,
01029            pMbsBufferHeader->iType,
01030            pMbsBufferHeader->iElements,
01031            pMbsBufferHeader->iTimeSpecSec,
01032            pMbsBufferHeader->iTimeSpecNanoSec/1000,
01033            pMbsBufferHeader->iMaxWords);
01034 }}}
01035 //===============================================================
01036 void fLmdPrintFileHeader(uint32_t iVerbose, sMbsFileHeader *pMbsFileHeader)
01037 {
01038   if(iVerbose){
01039     if(pMbsFileHeader){
01040     printf("FiHd: DataWords:%d Type:%d.%d Elements:%d sec:%d.%d MaxWords:%d Index: %llx[%d]\n",
01041            pMbsFileHeader->iUsedWords,
01042            pMbsFileHeader->iType&0xffff,
01043            pMbsFileHeader->iType>>16,
01044            pMbsFileHeader->iElements,
01045            pMbsFileHeader->iTimeSpecSec,
01046            pMbsFileHeader->iTimeSpecNanoSec/1000,
01047            pMbsFileHeader->iMaxWords,
01048            pMbsFileHeader->iTableOffset,
01049            pMbsFileHeader->iOffsetSize);
01050 }}}
01051 //===============================================================
01052 void fLmdPrintHeader(uint32_t iVerbose, sMbsHeader *pMbsHeader)
01053 {
01054   if(iVerbose){
01055     if(pMbsHeader){
01056     printf("ElHd: words:%d type:%08x\n",
01057            pMbsHeader->iWords,
01058            pMbsHeader->iType);
01059 }}}
01060 //===============================================================
01061 void fLmdPrintEvent(uint32_t iVerbose, sMbsEventHeader *pMbsEventHeader)
01062 {
01063   if(iVerbose){
01064     if(pMbsEventHeader){
01065     printf("EvHd: words:%6d type:%08x trigger:%2d #:%4d\n",
01066            pMbsEventHeader->iWords,
01067            pMbsEventHeader->iType,
01068            pMbsEventHeader->iTrigger>>16,
01069            pMbsEventHeader->iEventNumber);
01070 }}}
01071 //===============================================================
01072 void fLmdPrintControl(uint32_t iVerbose, sLmdControl *pLmdControl)
01073 {
01074   if(iVerbose){
01075     printf("Ctrl: file:%s words:%d left:%d bytes read:%lld elements:%d\n",
01076            pLmdControl->cFile,
01077            pLmdControl->iBufferWords,
01078            pLmdControl->iLeftWords,
01079            pLmdControl->iBytes,
01080            pLmdControl->iElements
01081     );
01082     fLmdPrintFileHeader(iVerbose,pLmdControl->pMbsFileHeader);
01083     fLmdPrintEvent(iVerbose,(sMbsEventHeader *)pLmdControl->pMbsHeader);
01084 }}
01085 //===============================================================
01086 void fLmdSwap4(uint32_t *array, uint32_t items){
01087   uint32_t i, *pp;
01088   pp=array;
01089   for(i=0;i<items;i++){
01090     //printf("Swap 4 %08x ",*pp);
01091      *pp = 
01092      (*pp >> 24) + 
01093     ((*pp >>  8)&0x0000ff00) +
01094     ((*pp <<  8)&0x00ff0000) +  
01095      (*pp << 24);
01096      //printf("to %08x \n",*pp);
01097      pp++;
01098   }}
01099 //===============================================================
01100 void fLmdSwap8(uint64_t *array, uint32_t items){
01101   uint64_t *pp;
01102   uint32_t i,x;
01103   pp=array;
01104   for(i=0;i<items;i++){
01105     //printf("Swap 8 %016llx ",*pp);
01106     *pp = (*pp << 32) + (*pp >> 32);
01107     //printf("to %016llx\n",*pp,*(pp+1));
01108      pp++;
01109   }}
01110 
01111 
01112 //----------------------------END OF GO4 SOURCE FILE ---------------------

Generated on Fri Nov 28 12:59:32 2008 for Go4-v3.04-1 by  doxygen 1.4.2