GSI Object Oriented Online Offline (Go4)  GO4-6.3.0
fLmd.c
Go to the documentation of this file.
1 // $Id$
2 //-----------------------------------------------------------------------
3 // The GSI Online Offline Object Oriented (Go4) Project
4 // Experiment Data Processing at EE department, GSI
5 //-----------------------------------------------------------------------
6 // Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
7 // Planckstr. 1, 64291 Darmstadt, Germany
8 // Contact: http://go4.gsi.de
9 //-----------------------------------------------------------------------
10 // This software can be used under the license agreements as stated
11 // in Go4License.txt file which is part of the distribution.
12 //-----------------------------------------------------------------------
13 
14 #include <stdlib.h>
15 #include <fcntl.h>
16 #include <string.h>
17 #include <memory.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 
21 #ifdef Lynx /* LynxOS */
22 #include <unistd.h>
23 #include <pwd.h>
24 #include <timeb.h>
25 #endif
26 
27 #ifdef Linux /* Linux */
28 #include <unistd.h>
29 #include <pwd.h>
30 #endif
31 
32 #ifdef Solaris /* Solaris */
33 #include <unistd.h>
34 #include <pwd.h>
35 #endif
36 
37 #ifdef Darwin /* Max OS X */
38 #include <unistd.h>
39 #include <pwd.h>
40 #define fgetpos64 fgetpos
41 #define fopen64 fopen
42 #define fseeko64 fseek
43 #define fpos64_t fpos_t
44 #endif
45 
46 #ifdef _MSC_VER
47 #include <WTypes.h>
48 #include <wchar.h>
49 
50 #define fgetpos64 fgetpos
51 #define fopen64 fopen
52 #define fseeko64 fseek
53 #define fpos64_t fpos_t
54 #endif
55 
56 #include "fLmd.h"
57 #include "f_ut_time.h"
58 
59 
60 int32_t fLmdWriteBuffer(sLmdControl *, char *, uint32_t);
61 uint32_t fLmdCleanup(sLmdControl *);
62 void fLmdOffsetResize(sLmdControl *, uint32_t);
63 uint32_t fLmdOffsetSet(sLmdControl *, uint32_t );
64 uint32_t fLmdOffsetRead(sLmdControl *);
65 uint32_t fLmdOffsetWrite(sLmdControl *);
67 void fLmdOffsetElements(sLmdControl *, uint32_t, uint32_t *, uint32_t *);
68 #define OFFSET__ENTRIES 250000
69 
70 //===============================================================
71 uint32_t fLmdPutOpen(sLmdControl *pLmdControl,
72  char *Filename,
73  sMbsFileHeader *pBuffHead, // LMD__STANDARD_HEADER (NULL) or address
74  uint32_t iBytes, // LMD__NO_BUFFER (0) or buffer size
75  uint32_t iOver, // LMD__[NO_]OVERWRITE
76  uint32_t iUseOffset, // LMD__[NO_]INDEX
77  uint32_t iLargeFile) // LMD__[NO_]LARGE_FILE
78 {
79  int32_t iReturn;
80  struct timespec clock;
81 
82  memset(pLmdControl,0,sizeof(sLmdControl));
83 
84  // allocate header or take extern
85  if(pBuffHead == LMD__STANDARD_HEADER){
86  pLmdControl->pMbsFileHeader = (sMbsFileHeader *)malloc(sizeof(sMbsFileHeader));
87  if (!pLmdControl->pMbsFileHeader) {
88  printf("fLmdPutOpen: memory allocation error\n");
89  return(LMD__FAILURE);
90  }
91  memset(pLmdControl->pMbsFileHeader,0,sizeof(sMbsFileHeader));
92  pLmdControl->iInternHeader=1;
93  } else {
94  pLmdControl->pMbsFileHeader= pBuffHead;
95  pLmdControl->iInternHeader=0;
96  }
97 
98  clock_gettime(CLOCK_REALTIME,&clock);
99  pLmdControl->pMbsFileHeader->iTimeSpecSec=clock.tv_sec;
100  pLmdControl->pMbsFileHeader->iTimeSpecNanoSec=clock.tv_nsec;
101 
103  pLmdControl->pMbsFileHeader->iEndian=1;
104  strcpy(pLmdControl->cFile,Filename);
105 
106  // optionally allocate buffer
107  if(iBytes > 0){
108  pLmdControl->pBuffer = (int16_t*) malloc(iBytes);
109  pLmdControl->iInternBuffer = 1;
110  }
111  pLmdControl->iBufferWords=iBytes/2;
112  pLmdControl->iLeftWords=iBytes/2;
113  // open file
114  if(iOver == LMD__NO_OVERWRITE){ // do not overwrite
115  if((pLmdControl->fFile=(FILE *)fopen64(Filename,"r") )!=NULL){
116  printf("fLmdPutOpen: File exists: %s\n",Filename);
117  fLmdCleanup(pLmdControl);
118  fclose(pLmdControl->fFile);
119  return(PUTLMD__FILE_EXIST);
120  }
121  }
122 
123  if((pLmdControl->fFile=(FILE *)fopen64(Filename,"w+") )== NULL){
124  printf("fLmdPutOpen: Error open file %s\n",Filename);
125  fLmdCleanup(pLmdControl);
126  return(PUTLMD__OPEN_ERR);
127  }
128 
129  if(iLargeFile == LMD__LARGE_FILE)pLmdControl->iOffsetSize=8;
130  else pLmdControl->iOffsetSize=4;
131  pLmdControl->pMbsFileHeader->iOffsetSize=pLmdControl->iOffsetSize;
132 
133  // write header
134  iReturn=fLmdWriteBuffer(pLmdControl,(char *)pLmdControl->pMbsFileHeader,
135  (pLmdControl->pMbsFileHeader->iUsedWords)*2+sizeof(sMbsFileHeader));
136  pLmdControl->iBytes+=iReturn;
137 
138  if(iUseOffset == LMD__INDEX)fLmdOffsetResize(pLmdControl,iReturn/4); // create and set first value
139  printf("fLmdPutOpen: %s. Bytes:%d over:%d table:%d large:%d.\n",
140  Filename,iBytes,iOver,iUseOffset,iLargeFile);
141  return(LMD__SUCCESS);
142 }
143 
144 //===============================================================
145 uint32_t fLmdPutElement(sLmdControl *pLmdControl,sMbsHeader *pHeader)
146 {
147  uint32_t *ps, *pd, i, elements;
148  int64_t fileleft,used;
149  int32_t iReturn;
150 
151  // enough space left?
152  if(pLmdControl->iOffsetEntries && (pLmdControl->iOffsetSize == 4)){
153  elements=pLmdControl->iElements+2;
154  used=pLmdControl->iBytes/4;
155  fileleft=0xffffffff - used - (4+elements); // size of table
156  if((int64_t)(pHeader->iWords/2+2) > fileleft){
157  printf("fLmdPutElement: File size exceed\n");
158  return(PUTLMD__EXCEED);
159  }
160  }
161  // save largest size in header
162  if((pHeader->iWords+4) > pLmdControl->pMbsFileHeader->iMaxWords)
163  pLmdControl->pMbsFileHeader->iMaxWords=pHeader->iWords+4;
164  // no buffer, write element directly
165  if(pLmdControl->iBufferWords == 0){
166  pLmdControl->pMbsHeader=pHeader;
167  iReturn=fLmdWriteBuffer(pLmdControl,(char *)pHeader,(pHeader->iWords+4)*2);
168  pLmdControl->iBytes+=iReturn;
169  if((uint32_t) iReturn != (pHeader->iWords+4)*2){
170  printf("fLmdPutElement: Write error \n");
171  return LMD__FAILURE;
172  }
173  pLmdControl->pMbsFileHeader->iElements++;
174  pLmdControl->iElements++;
175  if(pLmdControl->iOffsetEntries)fLmdOffsetSet(pLmdControl,iReturn/4);
176  return(LMD__SUCCESS);
177 
178  } // end no buffer
179  if((pHeader->iWords+4) > pLmdControl->iLeftWords){ // flash buffer to file
180  iReturn = fLmdWriteBuffer(pLmdControl, (char *)pLmdControl->pBuffer,
181  (pLmdControl->iBufferWords-pLmdControl->iLeftWords)*2);
182  pLmdControl->iBytes+=iReturn;
183  if((uint32_t) iReturn != (pLmdControl->iBufferWords-pLmdControl->iLeftWords)*2)
184  return LMD__FAILURE;
185  pLmdControl->iLeftWords=pLmdControl->iBufferWords; // buffer free
186  }
187  if((pHeader->iWords+4) > pLmdControl->iLeftWords){ // element too big for buffer
188  printf("fLmdPutElement: Element too big: %d words\n",pHeader->iWords+4);
189  return(PUTLMD__TOOBIG);
190  }
191  // copy to buffer
192  ps=(uint32_t *)pHeader;
193  pd=(uint32_t *)pLmdControl->pBuffer+(pLmdControl->iBufferWords-pLmdControl->iLeftWords)/2;
194  iReturn=(pHeader->iWords+4)/2; // here 32b words
195  for(i=0;i<iReturn;i++) *pd++ = *ps++;
196  pLmdControl->pMbsFileHeader->iElements++;
197  pLmdControl->iElements++;
198  pLmdControl->iLeftWords -= (pHeader->iWords+4);
199  if(pLmdControl->iOffsetEntries)
200  fLmdOffsetSet(pLmdControl,iReturn);
201  return (LMD__SUCCESS);
202 }
203 
204 //===============================================================
205 uint32_t fLmdPutBuffer(sLmdControl *pLmdControl, sMbsHeader *pHeader, uint32_t Items)
206 {
207  sMbsHeader *pH;
208  uint32_t Bytes=0,TotalBytes=0,i, elements;
209  int64_t fileleft,used;
210  int32_t iReturn;
211 
212  // check if total buffer fits in file
213  if(pLmdControl->iOffsetEntries && (pLmdControl->iOffsetSize == 4)){
214  pH=pHeader; // SL 16.11.2009 - pH was not initialized in this branch
215  elements=pLmdControl->iElements+Items+2;
216  used=pLmdControl->iBytes/4;
217  fileleft=0xffffffff - used - (4+elements); // size of table
218  for(i=0;i<Items;i++) {
219  Bytes = (4+pH->iWords)*2;
220  TotalBytes += Bytes;
221  pH=(sMbsHeader *)((int16_t*)pH + Bytes/2);
222  }
223  if((int64_t)TotalBytes/4 > fileleft){
224  printf("fLmdPutElement: File size exceed\n");
225  return(PUTLMD__EXCEED);
226  }
227  Bytes=0;
228  TotalBytes=0;
229  }
230  pH = pHeader;
231  for(i=0;i<Items;i++)
232  {
233  pLmdControl->iElements++;
234  Bytes = (4+pH->iWords)*2;
235  TotalBytes += Bytes;
236  if(pLmdControl->iOffsetEntries)fLmdOffsetSet(pLmdControl,Bytes/4);
237  if((pH->iWords+4) > pLmdControl->pMbsFileHeader->iMaxWords)
238  pLmdControl->pMbsFileHeader->iMaxWords=pH->iWords+4;
239  pH=(sMbsHeader *)((int16_t *)pH+Bytes/2);
240  }
241  iReturn = fLmdWriteBuffer(pLmdControl,(char *)pHeader,TotalBytes);
242  pLmdControl->iBytes+=iReturn;
243  if((uint32_t) iReturn != TotalBytes)
244  return LMD__FAILURE;
245 
246  pLmdControl->pMbsFileHeader->iElements += Items;
247  return(LMD__SUCCESS);
248 }
249 
250 //===============================================================
251 uint32_t fLmdPutClose(sLmdControl *pLmdControl)
252 {
253  int32_t iReturn;
254 
255  if(pLmdControl->iBufferWords > pLmdControl->iLeftWords){ // write last buffer
256  iReturn = fLmdWriteBuffer(pLmdControl, (char *)pLmdControl->pBuffer,
257  (pLmdControl->iBufferWords-pLmdControl->iLeftWords)*2);
258  pLmdControl->iBytes+=iReturn;
259  if((uint32_t)iReturn != (pLmdControl->iBufferWords-pLmdControl->iLeftWords)*2) {
260  printf("fLmdPutClose: Error writing last buffer. Closing file.\n");
261  // rewind file and rewrite header
262  rewind(pLmdControl->fFile); /* rewind file, rewrite header */
263  fLmdWriteBuffer(pLmdControl, (char *)pLmdControl->pMbsFileHeader,
264  sizeof(sMbsFileHeader));
265  fLmdCleanup(pLmdControl);
266  return(LMD__FAILURE);
267  }
268  }
269  if(pLmdControl->iOffsetEntries)
270  if(fLmdOffsetWrite(pLmdControl) != LMD__SUCCESS)
271  pLmdControl->pMbsFileHeader->iTableOffset=0; // table could not be written
272 
273  // rewind file and rewrite header
274  rewind(pLmdControl->fFile); /* rewind file, rewrite header */
275  fLmdWriteBuffer(pLmdControl, (char *)pLmdControl->pMbsFileHeader,
276  sizeof(sMbsFileHeader));
277  return(fLmdGetClose(pLmdControl));
278 }
279 
280 #ifndef FILEONLY
281 //===============================================================
282 uint32_t fLmdInitMbs(sLmdControl *pLmdControl,
283  char *Nodename,
284  uint32_t iMaxBytes,
285  uint32_t iBuffers,
286  uint32_t iStreams,
287  uint32_t iPort,
288  uint32_t iTimeout)
289 {
290  if(iBuffers > 1){printf("fLmdInitMbs: Event spanning not supported!\n");return(LMD__FAILURE);}
291  if(iStreams > 0){printf("fLmdInitMbs: MBS not in DABC mode!\n");return(LMD__FAILURE);}
292  pLmdControl->iPort=iPort;
293  strcpy(pLmdControl->cFile,Nodename);
294  if(pLmdControl->pBuffer == NULL) pLmdControl->pBuffer = (int16_t*) malloc(iMaxBytes);
295  pLmdControl->iBufferWords=iMaxBytes/2;
296  pLmdControl->iInternBuffer=1;
297  pLmdControl->iTCP=pLmdControl->pTCP->socket;
298  pLmdControl->iTcpTimeout=iTimeout;
299  pLmdControl->iTCPowner=0;
300  return(LMD__SUCCESS);
301 }
302 //===============================================================
303 uint32_t fLmdCloseMbs(sLmdControl *pLmdControl)
304 {
305 
306  int32_t stat;
307  char cClose[12];
308  // send request buffer for stream server
309  if(pLmdControl->iPort == PORT__STREAM) {
310  memset(cClose,0,sizeof(cClose));
311  strcpy(cClose, "CLOSE");
312  stat=f_stc_write(cClose,12,pLmdControl->iTCP);
313  }
314  stat=f_stc_close(pLmdControl->pTCP);
315  pLmdControl->pMbsFileHeader = NULL; // was reference only
316  if(pLmdControl->iTCPowner == 0) pLmdControl->pTCP=NULL; // was reference only
317  fLmdCleanup(pLmdControl);
318  return(stat);
319 }
320 //===============================================================
321 uint32_t fLmdGetMbsEvent(sLmdControl *pLmdControl, sMbsHeader** event)
322 {
323  uint32_t stat;
324  sMbsHeader *pM;
325  *event=NULL;
326  if(pLmdControl->iLeftWords == 0){ // get new buffer
327  stat=fLmdGetMbsBuffer(pLmdControl,NULL,0,NULL,NULL);
328  if(stat != LMD__SUCCESS){
329  return(stat);
330  }
331  // first event behind header:
332  pLmdControl->pMbsHeader=(sMbsHeader *)(pLmdControl->pBuffer+sizeof(sMbsBufferHeader)/2);
333  }
334  pM=pLmdControl->pMbsHeader; // current to be returned
335  pLmdControl->iLeftWords -= (pLmdControl->pMbsHeader->iWords+4);
336  pLmdControl->pMbsHeader =
337  (sMbsHeader *)((int16_t *)pLmdControl->pMbsHeader +
338  pLmdControl->pMbsHeader->iWords+4);
339  pLmdControl->iElements++;
340  *event=pM;
341  return(LMD__SUCCESS);
342 }
343 //===============================================================
344 uint32_t fLmdGetMbsBuffer(sLmdControl *pLmdControl, sMbsBufferHeader *pBuffer, uint32_t iBytes, uint32_t *iElements, uint32_t *iBytesUsed)
345 {
346 
347  sMbsBufferHeader *pBuf;
348  uint32_t usedBytes = 0, leftBytes = 0;
349  int32_t iReturn;
350  char cRequest[12];
351 
352  leftBytes = iBytes;
353  pBuf = pBuffer;
354  if(pBuf == NULL){
355  pBuf = (sMbsBufferHeader *)pLmdControl->pBuffer; // internal buffer
356  leftBytes = pLmdControl->iBufferWords*2; // size of this buffer
357  }
358  if(pBuf == NULL){
359  printf("fLmdGetMbsBuffer: Need buffer to read\n");
360  return(LMD__FAILURE);
361  }
362  if (leftBytes < sizeof(sMbsBufferHeader)) {
363  printf("fLmdGetMbsBuffer: %s buffer size %d too small for %d bytes\n", pLmdControl->cFile, leftBytes,
364  (int)sizeof(sMbsBufferHeader));
365  return (LMD__FAILURE);
366  }
367  // send request buffer for stream server
368  if(pLmdControl->iPort == PORT__STREAM) {
369  memset(cRequest,0,sizeof(cRequest));
370  strcpy(cRequest, "GETEVT");
371  iReturn=f_stc_write(cRequest,12,pLmdControl->iTCP);
372  }
373  iReturn=f_stc_read((int32_t *)pBuf,sizeof(sMbsBufferHeader),pLmdControl->iTCP,pLmdControl->iTcpTimeout);
374  if(iReturn == STC__TIMEOUT) return(LMD__TIMEOUT);
375  if(iReturn != STC__SUCCESS) return(LMD__FAILURE);
376  if(pLmdControl->iSwap)fLmdSwap4((uint32_t *)pBuf,sizeof(sMbsBufferHeader)/4);
377  if(leftBytes < (sizeof(sMbsBufferHeader)+2*pBuf->iUsedWords)){
378  printf("fLmdGetMbsBuffer: %s buffer size %d too small for %lu bytes\n",
379  pLmdControl->cFile,leftBytes,(long unsigned) (sizeof(sMbsBufferHeader)+2*pBuf->iMaxWords));
380  return(LMD__FAILURE);
381  }
382  usedBytes = pBuf->iUsedWords*2;
383  if((pBuf->iType & 0xffff) == 100)
384  iReturn=f_stc_read((int32_t *)(pBuf+1),usedBytes,pLmdControl->iTCP,-1);
385  if(iReturn == STC__TIMEOUT) return(LMD__TIMEOUT);
386  if(iReturn != STC__SUCCESS) return(LMD__FAILURE);
387  if(pLmdControl->iSwap)fLmdSwap4((uint32_t *)(pBuf+1),usedBytes/4);
388  if(iBytesUsed != NULL)*iBytesUsed =usedBytes+sizeof(sMbsBufferHeader);
389  if(iElements != NULL)*iElements =pBuf->iElements;
390  pLmdControl->iBytes += usedBytes;
391  pLmdControl->iLeftWords = usedBytes/2; // without header
392  pLmdControl->pMbsFileHeader = (sMbsFileHeader *)pBuf;
393  return(LMD__SUCCESS);
394 }
395 #endif // FILEONLY
396 
397 //===============================================================
398 uint32_t fLmdGetOpen(sLmdControl *pLmdControl,
399  char *Filename,
400  sMbsFileHeader *pBuffHead, // LMD__INTERNAL_HEADER (NULL) or address of file header
401  uint32_t iBytes, // LMD__NO_BUFFER (0) or LMD__MIN_BUFFER or internal buffersize
402  uint32_t iUseOffset) // LMD__[NO_]INDEX
403 {
404  int32_t iReturn;
405  uint32_t bufferBytes=0;
406 
407  memset(pLmdControl,0,sizeof(sLmdControl));
408  if(pBuffHead == LMD__INTERNAL_HEADER){
409  pLmdControl->pMbsFileHeader = (sMbsFileHeader *)malloc(sizeof(sMbsFileHeader));
410  pLmdControl->iInternHeader=1;
411  } else {
412  pLmdControl->pMbsFileHeader = pBuffHead;
413  pLmdControl->iInternHeader=0;
414  }
415  memset(pLmdControl->pMbsFileHeader,0,sizeof(sMbsFileHeader));
416 
417  // copy file name to control structure
418  strcpy(pLmdControl->cFile,Filename);
419  if((pLmdControl->fFile=(FILE *)fopen64(Filename,"r"))== NULL)
420  {
421  printf("fLmdGetOpen: File not found: %s\n",Filename);
422  fLmdCleanup(pLmdControl);
423  return(GETLMD__NOFILE);
424  }
425  /* read header */
426  iReturn=fLmdReadBuffer(pLmdControl,
427  (char *)pLmdControl->pMbsFileHeader,
428  sizeof(sMbsFileHeader));
429  if(iReturn!=sizeof(sMbsFileHeader)) {
430  printf("fLmdGetOpen: LMD format error: no LMD file: %s\n",Filename);
431  fLmdGetClose(pLmdControl);
432  return(GETLMD__NOLMDFILE);
433  }
434  // check type and subtype, and endian
435  if(pLmdControl->pMbsFileHeader->iEndian != 1) pLmdControl->iSwap=1;
436  if(pLmdControl->iSwap){
437  printf("do swap !!!\n");
438  fLmdSwap4((uint32_t *)pLmdControl->pMbsFileHeader,sizeof(sMbsFileHeader)/4);
439  fLmdSwap8((uint64_t *)&pLmdControl->pMbsFileHeader->iTableOffset,1);
440  }
441  if(pLmdControl->pMbsFileHeader->iType != LMD__TYPE_FILE_HEADER_101_1){
442  printf("fLmdGetOpen: LMD format error: no LMD file: %s, type is %0x\n",
443  Filename,pLmdControl->pMbsFileHeader->iType);
444  fLmdGetClose(pLmdControl);
445  return(GETLMD__NOLMDFILE);
446  }
447 
448  if((iUseOffset == LMD__INDEX)&&(pLmdControl->pMbsFileHeader->iTableOffset > 0)){
449  // printf("fLmdGetOpen: use table in file: %s\n",Filename);
450  pLmdControl->iOffsetSize=pLmdControl->pMbsFileHeader->iOffsetSize;
451  iReturn=fLmdOffsetRead(pLmdControl); // read offset table
452  if(iReturn != LMD__SUCCESS){
453  printf("fLmdGetOpen: Index format error: %s\n",Filename);
454  fLmdGetClose(pLmdControl);
455  return(iReturn);
456  }
457  }
458 
459  pLmdControl->iBytes+=iReturn;
460  // more of header?
461  if(pLmdControl->pMbsFileHeader->iUsedWords > 0)
462  {
463  // Read this additional information without swapping.
464  // Could be mostly strings. Caller must know.
465  pLmdControl->cHeader = malloc(pLmdControl->pMbsFileHeader->iUsedWords*2);
466  iReturn = fLmdReadBuffer(pLmdControl,pLmdControl->cHeader,
467  pLmdControl->pMbsFileHeader->iUsedWords*2 );
468  if((uint32_t) iReturn != pLmdControl->pMbsFileHeader->iUsedWords*2) {
469  printf("fLmdGetOpen: LMD format error: no LMD file: %s\n",Filename);
470  fLmdGetClose(pLmdControl);
471  return(GETLMD__NOLMDFILE);
472  }
473  }
474 
475  bufferBytes = iBytes;
476  if(bufferBytes < pLmdControl->pMbsFileHeader->iMaxWords*2)
477  bufferBytes = pLmdControl->pMbsFileHeader->iMaxWords*2;
478  fLmdPrintFileHeader(1,pLmdControl->pMbsFileHeader);
479  pLmdControl->pBuffer = (int16_t *)malloc(bufferBytes);
480  pLmdControl->iInternBuffer = 1;
481  pLmdControl->iBufferWords=bufferBytes/2; // will be increased if necessary
482 
483  printf("fLmdGetOpen: %s words %u\n", Filename, pLmdControl->iBufferWords);
484 
485  pLmdControl->iLeftWords = 0; // buffer empty, read with first fLmdGetElement
486  pLmdControl->pMbsHeader = NULL;
487  return(LMD__SUCCESS);
488 }
489 
490 //===============================================================
491 uint32_t fLmdGetBuffer(sLmdControl *pLmdControl, sMbsHeader *pMbsHeader, uint32_t iBytes, uint32_t *iElements,
492  uint32_t *iBytesUsed)
493 {
494 
495  sMbsHeader *pm;
496  uint32_t elem = 0, leftBytes = 0, used, elem_sz;
497  int32_t iReturn;
498 
499  if (iBytes < pLmdControl->pMbsFileHeader->iMaxWords) {
500  printf("fLmdGetBuffer: %s buffer size %d too small for %d bytes\n", pLmdControl->cFile, iBytes,
501  pLmdControl->pMbsFileHeader->iMaxWords);
502  return (LMD__FAILURE);
503  }
504  if (pMbsHeader == NULL) {
505  printf("fLmdGetBuffer: Need buffer to read\n");
506  return (LMD__FAILURE);
507  }
508  *iBytesUsed = 0;
509  *iElements = 0;
510  if (pLmdControl->iElements == pLmdControl->pMbsFileHeader->iElements)
511  return (GETLMD__EOFILE);
512 
513  // Offset table
514  if (pLmdControl->iOffsetEntries) { // use offsets to read elements fitting in buffer
515  fLmdOffsetElements(pLmdControl, iBytes, &elem, &used);
516  // printf("Read %d bytes of %d, elements %d\n",used,iBytes,elem);
517  iReturn = fLmdReadBuffer(pLmdControl, (char *)pMbsHeader, used);
518  if (iReturn <= 0) {
519  printf("fLmdGetBuffer: EOF: %s\n", pLmdControl->cFile);
520  return (GETLMD__EOFILE);
521  }
522  if ((uint32_t) iReturn != used) {
523  printf("fLmdGetBuffer: LMD read error: unexpected EOF: %s %u %u\n", pLmdControl->cFile, iReturn, used);
524  return (GETLMD__NOLMDFILE);
525  }
526  *iBytesUsed = used;
527  *iElements = elem;
528  if (pLmdControl->iSwap)
529  fLmdSwap4((uint32_t *)pMbsHeader, iReturn / 4);
530  pLmdControl->iBytes += iReturn;
531  return (LMD__SUCCESS);
532  }
533  // no offset table
534  // do we have fragment stored?
535  leftBytes = pLmdControl->iLeftWords * 2;
536  if (leftBytes > 0) {
537  if (leftBytes > iBytes) {
538  printf("fLmdGetBuffer: stored piece of data (%u) larger than provided buffer (%u)\n",
539  leftBytes, iBytes);
540  return(LMD__FAILURE);
541  }
542 
543  if (pLmdControl->pMbsHeader == 0) {
544  printf("fLmdGetBuffer: Internal error pMbsHeader==0\n");
545  return(LMD__FAILURE);
546  }
547 
548  memcpy(pMbsHeader, pLmdControl->pMbsHeader, leftBytes);
549  }
550  iReturn = fLmdReadBuffer(pLmdControl,(char *)pMbsHeader+leftBytes, iBytes-leftBytes);
551  if(iReturn <= 0) {
552  printf("fLmdGetBuffer: EOF: %s\n",pLmdControl->cFile);
553  if (leftBytes>0)
554  printf("fLmdGetBuffer: EOF while we have some rest data (%u)\n", leftBytes);
555  else
556  return(GETLMD__EOFILE);
557  }
558 
559  if(iReturn > (iBytes-leftBytes)) {
560  printf("fLmdGetBuffer: LMD read error %s - too many bytes read %u wants %u",
561  pLmdControl->cFile, iReturn, iBytes-leftBytes);
562  return(GETLMD__NOLMDFILE);
563  }
564 
565  if(pLmdControl->iSwap)fLmdSwap4((uint32_t *)pMbsHeader+leftBytes/4,iReturn/4);
566  pLmdControl->iBytes += iReturn;
567  leftBytes += iReturn; // thats what is in the buffer
568  // step through buffer to get number of elements and size
569  pm=pMbsHeader;
570  while(leftBytes >=8){
571  if(pm->iType == LMD__TYPE_FILE_INDEX_101_2) break; // file index is last
572  elem_sz = (pm->iWords+4)*2;
573  if(elem_sz > leftBytes) break; // pm valid but incomplete data
574 
575  *iBytesUsed += elem_sz;
576  *iElements += 1;
577  pLmdControl->iElements++;
578  pm = (sMbsHeader *)((char*)pm + elem_sz);
579  leftBytes -= elem_sz;
580  }
581  //printf("Read %d bytes of %d, elements %d\n",*iBytesUsed,iBytes,*iElements);
582  // fragment left? copy to internal buffer
583  if(leftBytes>0){
584  if(leftBytes > pLmdControl->iBufferWords*2){
585  printf("fLmdGetBuffer: ERROR: internal buffer overflow. Needed:%d available:%d\n",
586  leftBytes,pLmdControl->iBufferWords*2);
587  return(LMD__FAILURE);
588  } else {
589  memcpy(pLmdControl->pBuffer,pm,leftBytes);
590  }
591  }
592  pLmdControl->iLeftWords = leftBytes/2;
593  if (pLmdControl->iLeftWords>0)
594  pLmdControl->pMbsHeader = (sMbsHeader*)pLmdControl->pBuffer;
595  else
596  pLmdControl->pMbsHeader = 0;
597 
598  return(LMD__SUCCESS);
599 }
600 //===============================================================
601 uint32_t fLmdGetElement(sLmdControl *pLmdControl, uint32_t iEvent, sMbsHeader **event)
602 {
603  sMbsHeader *pM;
604  uint32_t i, evsz;
605  int32_t iReturn;
606  *event=NULL;
607 
608  if(iEvent == LMD__NO_INDEX) {
609  if(pLmdControl->pBuffer==NULL) return(GETLMD__NOBUFFER); // internal buffer needed
610  if(pLmdControl->pMbsFileHeader->iElements == 0) return(GETLMD__NOMORE);
611 
612  // check if we need to read extra data
613  if ((pLmdControl->iLeftWords < 4) ||
614  (pLmdControl->pMbsHeader == 0) ||
615  (pLmdControl->pMbsHeader->iWords+4 > pLmdControl->iLeftWords)) {
616  // first copy old data, if it exists
617  if (pLmdControl->iLeftWords > 0) {
618  memmove(pLmdControl->pBuffer, pLmdControl->pMbsHeader, pLmdControl->iLeftWords*2);
619 // printf("copy to the begin rest %u bytes", pLmdControl->iLeftWords*2);
620  }
621 
622  // second, try to read more bytes
623 
624  iReturn = fLmdReadBuffer(pLmdControl,
625  (char *)(pLmdControl->pBuffer+pLmdControl->iLeftWords),
626  (pLmdControl->iBufferWords-pLmdControl->iLeftWords)*2);
627 
628  if(iReturn <= 0) { printf("fLmdGetElement: EOF\n"); return(GETLMD__EOFILE); }
629 
630  if(pLmdControl->iSwap) fLmdSwap4((uint32_t *)(pLmdControl->pBuffer+pLmdControl->iLeftWords),iReturn/4);
631 
632  pLmdControl->iBytes += iReturn;
633  pLmdControl->pMbsHeader=(sMbsHeader *)pLmdControl->pBuffer;
634  pLmdControl->iLeftWords += iReturn/2;
635  }
636 
637  // check if read buffer enough for event
638 
639  evsz = (pLmdControl->pMbsHeader->iWords + 4) * 2;
640 
641  if (evsz > pLmdControl->iLeftWords*2) {
642  printf ("fLmdGetElement: Error, full element %u does not fit in buffer %u",
643  evsz, pLmdControl->iLeftWords*2);
644  return (GETLMD__TOOBIG);
645  }
646 
647  pLmdControl->pMbsFileHeader->iElements--;
648  pM = pLmdControl->pMbsHeader;
649  pLmdControl->pMbsHeader = (sMbsHeader *) ((char*) pM + evsz);
650  pLmdControl->iLeftWords -= evsz/2;
651  pLmdControl->iElements++;
652  *event=pM;
653  return(LMD__SUCCESS);
654  }
655  // get indexed event
656  if(pLmdControl->iOffsetEntries){
657  if(iEvent >= pLmdControl->iOffsetEntries)return(GETLMD__OUTOF_RANGE);
658  fseeko64(pLmdControl->fFile,fLmdOffsetGet(pLmdControl,iEvent-1)*4,SEEK_SET);
659  i=(fLmdOffsetGet(pLmdControl,iEvent)-fLmdOffsetGet(pLmdControl,iEvent-1));
660  iReturn = fLmdReadBuffer(pLmdControl,(char *)pLmdControl->pBuffer,i*4);
661  if(iReturn <= 0) {
662  printf("fLmdGetElement: EOF\n");
663  return(GETLMD__EOFILE);
664  }
665  if((uint32_t) iReturn != (i*4)) {
666  printf("fLmdGetBuffer: LMD read error: unexpected EOF: %s\n",pLmdControl->cFile);
667  return(GETLMD__EOFILE);
668  }
669  if(pLmdControl->iSwap)fLmdSwap4((uint32_t *)pLmdControl->pBuffer,iReturn/4);
670  pLmdControl->pMbsHeader=(sMbsHeader *)pLmdControl->pBuffer;
671  if((pLmdControl->pMbsHeader->iWords+4) != i*2){
672  printf("fLmdGetElement: Error Event %d: size from table is %d, header %d\n",
673  iEvent,i/2,pLmdControl->pMbsHeader->iWords+4);
674  return(GETLMD__SIZE_ERROR);
675  }
676  pLmdControl->iBytes+=iReturn;
677  *event=pLmdControl->pMbsHeader;
678  return(LMD__SUCCESS);
679  }
680  else return(GETLMD__NOMORE);
681  // return zero if no more events
682 }
683 //===============================================================
684 uint32_t fLmdGetClose(sLmdControl *pLmdControl)
685 {
686  fLmdCleanup(pLmdControl); // cleanup except fFile
687  if(fclose(pLmdControl->fFile) != 0) {
688  pLmdControl->fFile=NULL;
689  return(LMD__CLOSE_ERR);
690  }
691  pLmdControl->fFile=NULL;
692  return(LMD__SUCCESS);
693 }
694 //===============================================================
695 int32_t fLmdReadBuffer(sLmdControl *pLmdControl, char *buffer, uint32_t bytes){
696  int32_t IObytes;
697  IObytes=(int32_t)fread(buffer,1,bytes,pLmdControl->fFile);
698  //if(IObytes < bytes) printf("Read %s: request %d bytes, got %d\n",pLmdControl->cFile,bytes,IObytes);
699  return(IObytes);
700 }
701 //===============================================================
702 int32_t fLmdWriteBuffer(sLmdControl *pLmdControl, char *buffer, uint32_t bytes){
703  int32_t IObytes;
704  IObytes=(int32_t)fwrite(buffer,1,bytes,pLmdControl->fFile);
705  //if(IObytes < bytes) printf("Write %s: request %d bytes, put %d\n",
706  // pLmdControl->cFile,bytes,IObytes);
707  return(IObytes);
708 }
709 //===============================================================
710 uint64_t fLmdGetBytesWritten(sLmdControl *pLmdControl)
711 {
712  uint64_t bytes;
713  bytes=pLmdControl->iBytes;
714  // add pending data size in current buffer
715  if(pLmdControl->iBufferWords > pLmdControl->iLeftWords)
716  bytes += (pLmdControl->iBufferWords - pLmdControl->iLeftWords)*2;
717  // add table size which will be written at close
718  if ((pLmdControl->pOffset4!=NULL)||(pLmdControl->pOffset8!=NULL))
719  bytes += (pLmdControl->iElements+1)*pLmdControl->iOffsetSize;
720  return bytes;
721 }
722 //===============================================================
723 uint32_t fLmdCleanup(sLmdControl *pLmdControl)
724 {
725  // do not clean fFile
726  if(pLmdControl->pTCP != NULL)free(pLmdControl->pTCP);
727  if(pLmdControl->cHeader != NULL)free(pLmdControl->cHeader);
728  if(pLmdControl->pOffset4 != NULL)free(pLmdControl->pOffset4);
729  if(pLmdControl->pOffset8 != NULL)free(pLmdControl->pOffset8);
730  if((pLmdControl->pBuffer != NULL) && (pLmdControl->iInternBuffer>0))
731  free(pLmdControl->pBuffer);
732  if((pLmdControl->pMbsFileHeader != NULL) && (pLmdControl->iInternHeader>0))
733  free(pLmdControl->pMbsFileHeader);
734  pLmdControl->pTCP=NULL;
735  pLmdControl->cHeader=NULL;
736  pLmdControl->pBuffer=NULL;
737  pLmdControl->iInternBuffer=0;
738  pLmdControl->pOffset4=NULL;
739  pLmdControl->pOffset8=NULL;
740  pLmdControl->pMbsFileHeader=NULL;
741  pLmdControl->iInternHeader=0;
742  pLmdControl->pMbsHeader=NULL;
743  return (LMD__SUCCESS);
744 }
745 //===============================================================
746 // can be called after GetOpen or ConnectMbs
747 uint32_t fLmdGetSwap(sLmdControl *pLmdControl)
748 {
749  if(pLmdControl != NULL)
750  return pLmdControl->iSwap;
751  return (uint32_t) -1;
752 }
753 //===============================================================
754 // can be called after PutOpen or before PutClose
755 void fLmdSetWrittenEndian(sLmdControl *pLmdControl,uint32_t iE)
756 {
757  if(pLmdControl->pMbsFileHeader != NULL)
758  pLmdControl->pMbsFileHeader->iWrittenEndian=iE;
759  else
760  printf("fLmdSetWrittenEndian: No file header allocated!\n");
761 }
762 //===============================================================
763 // can be called after GetOpen or GetMbsEvent
764 uint32_t fLmdGetWrittenEndian(sLmdControl *pLmdControl)
765 {
766  if(pLmdControl->pMbsFileHeader != NULL)
767  return(pLmdControl->pMbsFileHeader->iWrittenEndian);
768 
769  printf("fLmdGetWrittenEndian: No file header allocated!\n");
770  return(LMD__ENDIAN_UNKNOWN);
771 }
772 //===============================================================
774 {
775  sLmdControl *x;
776  x = (sLmdControl *)malloc(sizeof(sLmdControl));
777  if (x) memset(x,0,sizeof(sLmdControl));
778  return x;
779 }
780 //===============================================================
781 void fLmdOffsetElements(sLmdControl *pLmdControl, uint32_t bytes, uint32_t *elements, uint32_t *used)
782 {
783  lmdoff_t *off1,*off2;
784  uint32_t elem=0,i,*iff1,*iff2;
785 
786  if(pLmdControl->iOffsetSize == 4){
787  iff1=pLmdControl->pOffset4+pLmdControl->iElements;
788  iff2=iff1;
789  for(i=pLmdControl->iElements;i<pLmdControl->iOffsetEntries-1;i++){
790  if((*(iff1+1)-*iff2)>bytes/4) break;
791  iff1++;
792  elem++;
793  pLmdControl->iElements++;
794  }
795  *used=(*iff1-*iff2)*4;
796  *elements=elem;
797  }
798  else if(pLmdControl->iOffsetSize == 8){
799  off1=pLmdControl->pOffset8+pLmdControl->iElements;
800  off2=off1;
801  for(i=pLmdControl->iElements;i<pLmdControl->iOffsetEntries-1;i++){
802  if((*(off1+1)-*off2)>bytes/4) break;
803  off1++;
804  elem++;
805  pLmdControl->iElements++;
806  }
807  *used=(*off1-*off2)*4;
808  *elements=elem;
809  }
810 }
811 //===============================================================
812 uint32_t fLmdOffsetRead(sLmdControl *pLmdControl)
813 {
814  int32_t iReturn;
815  sMbsHeader *pTableHead;
816 
817  pTableHead=(sMbsHeader *)malloc(16); // header with 8 bytes data for future use.
818  fseeko64(pLmdControl->fFile,(lmdoff_t)pLmdControl->pMbsFileHeader->iTableOffset*4,SEEK_SET);
819  iReturn = fLmdReadBuffer(pLmdControl, (char *)pTableHead,16);
820  if(iReturn!=16) {
821  printf("fLmdGetBuffer: LMD read error: unexpected EOF: %s\n",pLmdControl->cFile);
822  free(pTableHead);
823  return(GETLMD__NOLMDFILE);
824  }
825  if(pLmdControl->iSwap)fLmdSwap4((uint32_t *)pTableHead,4);
826  if(pTableHead->iType != LMD__TYPE_FILE_INDEX_101_2){
827  printf("fLmdOffsetTable: LMD format error: no index table: %s, type %0x\n",
828  pLmdControl->cFile,pTableHead->iType);
829  free(pTableHead);
830  return(GETLMD__NOLMDFILE);
831  }
832  //printf("Table: words:%d type:%08x\n",pTableHead->iWords,pTableHead->iType);
833  free(pTableHead);
834  pLmdControl->iOffsetEntries=pLmdControl->pMbsFileHeader->iElements+1;
835  pLmdControl->pOffset8=(lmdoff_t *)malloc(pLmdControl->iOffsetEntries*pLmdControl->iOffsetSize);
836  iReturn = fLmdReadBuffer(pLmdControl,
837  (char *)pLmdControl->pOffset8,
838  pLmdControl->iOffsetEntries*pLmdControl->iOffsetSize);
839  if((uint32_t) iReturn != pLmdControl->iOffsetEntries*pLmdControl->iOffsetSize) {
840  printf("fLmdOffsetTable: LMD format error: no index table: %s\n",pLmdControl->cFile);
841  pLmdControl->iOffsetEntries = 0;
842  return(GETLMD__NOLMDFILE);
843  }
844  if(pLmdControl->iSwap){
845  fLmdSwap4((uint32_t *)pLmdControl->pOffset8,iReturn/4);
846  if(pLmdControl->iOffsetSize == 8)
847  fLmdSwap8((uint64_t *)pLmdControl->pOffset8,iReturn/8);
848  }
849  // go back behing header
850  fseeko64(pLmdControl->fFile,(lmdoff_t)sizeof(sMbsFileHeader),SEEK_SET);
851  // use small table
852  if(pLmdControl->iOffsetSize == 4){
853  pLmdControl->pOffset4= (uint32_t *)pLmdControl->pOffset8;
854  pLmdControl->pOffset8=NULL;
855  }
856  return(LMD__SUCCESS);
857 }
858 //===============================================================
859 uint32_t fLmdOffsetWrite(sLmdControl *pLmdControl)
860 {
861  int32_t iReturn;
862  char *pbuf;
863  lmdoff_t current;
864  sMbsHeader *pTableHead;
865  pTableHead = (sMbsHeader *)malloc(16); // header with 8 bytes data for future use.
866  if (!pTableHead) {
867  printf("fLmdOffsetWrite: memory allocation error\n");
868  return (LMD__FAILURE);
869  }
870  memset(pTableHead,0,16);
871  pTableHead->iWords=(pLmdControl->iElements+1)*pLmdControl->iOffsetSize/2+4;
872  pTableHead->iType=LMD__TYPE_FILE_INDEX_101_2;
873 /* printf("Table: words:%d type:%08x offbytes:%d\n", */
874 /* pTableHead->iWords,pTableHead->iType,pLmdControl->iOffsetSize); */
875  iReturn = fgetpos64(pLmdControl->fFile,(fpos64_t *) &current);
876  iReturn = fLmdWriteBuffer(pLmdControl, (char *)pTableHead,16);
877  free(pTableHead);
878  pbuf=(char *)pLmdControl->pOffset4; // try short table
879  if(pbuf == NULL) pbuf=(char *)pLmdControl->pOffset8;
880  iReturn = fLmdWriteBuffer(pLmdControl, pbuf,
881  (pLmdControl->iElements+1)*pLmdControl->iOffsetSize);
882  if(pLmdControl->pOffset8)
883  pLmdControl->pMbsFileHeader->iTableOffset = *(pLmdControl->pOffset8+pLmdControl->iElements);
884  if(pLmdControl->pOffset4)
885  pLmdControl->pMbsFileHeader->iTableOffset = *(pLmdControl->pOffset4 + pLmdControl->iElements);
886  if (current / 4 != pLmdControl->pMbsFileHeader->iTableOffset) {
887  printf("Table offset mismatch: current:%llu calculated:%llu, cur-cal %llu\n", (long long unsigned)current / 4,
888  (long long unsigned)pLmdControl->pMbsFileHeader->iTableOffset,
889  (long long unsigned)(current / 4 - pLmdControl->pMbsFileHeader->iTableOffset));
890  return (LMD__FAILURE);
891  }
892  if((uint32_t) iReturn != (pLmdControl->iElements+1)*pLmdControl->iOffsetSize){
893  printf("Table write error \n");
894  return(LMD__FAILURE);
895  }
896  return(LMD__SUCCESS);
897 }
898 //===============================================================
899 uint32_t fLmdOffsetSet(sLmdControl *pLmdControl, uint32_t lwords)
900 {
901  if(pLmdControl->iElements >= pLmdControl->iOffsetEntries)fLmdOffsetResize(pLmdControl,0);
902  if(pLmdControl->pOffset8){
903  *(pLmdControl->pOffset8+pLmdControl->iElements)=
904  *(pLmdControl->pOffset8+pLmdControl->iElements-1)+(lmdoff_t)lwords;
905  }
906  if(pLmdControl->pOffset4){
907  *(pLmdControl->pOffset4+pLmdControl->iElements)=
908  *(pLmdControl->pOffset4+pLmdControl->iElements-1)+lwords;
909  }
910  return(LMD__SUCCESS);
911 }
912 //===============================================================
913 lmdoff_t fLmdOffsetGet(sLmdControl *pLmdControl, uint32_t index)
914 {
915  if (pLmdControl->pOffset8)
916  return (*(pLmdControl->pOffset8 + index));
917  if (pLmdControl->pOffset4)
918  return ((lmdoff_t) * (pLmdControl->pOffset4 + index));
919  return 0;
920 }
921 //===============================================================
922 void fLmdOffsetResize(sLmdControl *pLmdControl, uint32_t firstValue){
923  lmdoff_t *newOffset;
924  uint32_t oldEntries,newEntries;
925 
926  oldEntries=pLmdControl->iOffsetEntries;
927  newEntries=oldEntries+OFFSET__ENTRIES;
928  newOffset = (lmdoff_t *)malloc(newEntries*pLmdControl->iOffsetSize);
929  memset(newOffset,0,newEntries*pLmdControl->iOffsetSize);
930  if(oldEntries > 0){ //table was expanded
931  //printf("Resize table %d to %d entries\n",oldEntries,newEntries);
932  if(pLmdControl->pOffset8){
933  memcpy(newOffset,pLmdControl->pOffset8,oldEntries*pLmdControl->iOffsetSize);
934  free(pLmdControl->pOffset8);
935  pLmdControl->pOffset8 = newOffset;
936  }
937  if(pLmdControl->pOffset4){
938  memcpy(newOffset,pLmdControl->pOffset4,oldEntries*pLmdControl->iOffsetSize);
939  free(pLmdControl->pOffset4);
940  pLmdControl->pOffset4 = (uint32_t *)newOffset;
941  }
942  }
943  else { // table was new
944  //printf("Create table %d entries, first offset %d\n",newEntries,firstValue);
945  if(pLmdControl->iOffsetSize==8){
946  pLmdControl->pOffset8 = newOffset;
947  *pLmdControl->pOffset8 = (lmdoff_t)firstValue;
948  }
949  if(pLmdControl->iOffsetSize==4){
950  pLmdControl->pOffset4 = (uint32_t *)newOffset;
951  *pLmdControl->pOffset4 = firstValue;
952  }
953  }
954  pLmdControl->iOffsetEntries = newEntries;
955 }
956 //===============================================================
957 void fLmdPrintBufferHeader(uint32_t iVerbose, sMbsBufferHeader *pMbsBufferHeader)
958 {
959  if (iVerbose) {
960  if (pMbsBufferHeader) {
961  printf("BfHd: # %d, DataWords:%d Type:%08x Elements:%d sec:%d.%d MaxWords:%d\n", pMbsBufferHeader->iBuffer,
962  pMbsBufferHeader->iUsedWords, pMbsBufferHeader->iType, pMbsBufferHeader->iElements,
963  pMbsBufferHeader->iTimeSpecSec, pMbsBufferHeader->iTimeSpecNanoSec / 1000, pMbsBufferHeader->iMaxWords);
964  }
965  }
966 }
967 //===============================================================
968 void fLmdPrintFileHeader(uint32_t iVerbose, sMbsFileHeader *pMbsFileHeader)
969 {
970  if (iVerbose) {
971  if (pMbsFileHeader) {
972  printf("FiHd: DataWords:%d Type:%d.%d Elements:%d sec:%d.%d MaxWords:%d Index: %llx[%d]\n",
973  pMbsFileHeader->iUsedWords, pMbsFileHeader->iType & 0xffff, pMbsFileHeader->iType >> 16,
974  pMbsFileHeader->iElements, pMbsFileHeader->iTimeSpecSec, pMbsFileHeader->iTimeSpecNanoSec / 1000,
975  pMbsFileHeader->iMaxWords, (long long unsigned) pMbsFileHeader->iTableOffset, pMbsFileHeader->iOffsetSize);
976  }
977  }
978 }
979 //===============================================================
980 void fLmdPrintHeader(uint32_t iVerbose, sMbsHeader *pMbsHeader)
981 {
982  if (iVerbose) {
983  if (pMbsHeader) {
984  printf("ElHd: words:%d type:%08x\n", pMbsHeader->iWords, pMbsHeader->iType);
985  }
986  }
987 }
988 //===============================================================
989 void fLmdPrintEvent(uint32_t iVerbose, sMbsEventHeader *pMbsEventHeader)
990 {
991  if (iVerbose) {
992  if (pMbsEventHeader) {
993  printf("EvHd: words:%6d type:%08x trigger:%2d #:%4d\n", pMbsEventHeader->iWords, pMbsEventHeader->iType,
994  pMbsEventHeader->iTrigger >> 16, pMbsEventHeader->iEventNumber);
995  }
996  }
997 }
998 //===============================================================
999 void fLmdPrintControl(uint32_t iVerbose, sLmdControl *pLmdControl)
1000 {
1001  if (iVerbose) {
1002  printf("Ctrl: file:%s words:%d left:%d bytes read:%llu elements:%d\n", pLmdControl->cFile,
1003  pLmdControl->iBufferWords, pLmdControl->iLeftWords, (long long unsigned) pLmdControl->iBytes, pLmdControl->iElements);
1004  fLmdPrintFileHeader(iVerbose, pLmdControl->pMbsFileHeader);
1005  fLmdPrintEvent(iVerbose, (sMbsEventHeader *)pLmdControl->pMbsHeader);
1006  }
1007 }
1008 //===============================================================
1009 void fLmdSwap4(uint32_t *array, uint32_t items)
1010 {
1011  uint32_t i, *pp;
1012  pp = array;
1013  for (i = 0; i < items; i++) {
1014  *pp = (*pp >> 24) + ((*pp >> 8) & 0x0000ff00) + ((*pp << 8) & 0x00ff0000) + (*pp << 24);
1015  pp++;
1016  }
1017 }
1018 //===============================================================
1019 void fLmdSwap8(uint64_t *array, uint32_t items)
1020 {
1021  uint64_t *pp;
1022  uint32_t i;
1023  pp = array;
1024  for (i = 0; i < items; i++) {
1025  *pp = (*pp << 32) + (*pp >> 32);
1026  pp++;
1027  }
1028 }
uint32_t fLmdOffsetWrite(sLmdControl *)
Definition: fLmd.c:859
#define LMD__SUCCESS
Definition: fLmd.h:25
#define LMD__STANDARD_HEADER
Definition: sMbs.h:24
INTS4 socket
Definition: f_stccomm.h:305
INTS4 f_stc_close(struct s_tcpcomm *ps_tcp)
Definition: f_stccomm.c:1089
#define GETLMD__EOFILE
Definition: fLmd.h:30
uint32_t iTrigger
Definition: sMbs.h:116
#define LMD__INDEX
Definition: sMbs.h:26
INTS4 f_stc_read(void *p_buffer, INTS4 i_buflen, INTS4 i_channel, INTS4 i_timeout)
Definition: f_stccomm.c:134
uint32_t iElements
Definition: sMbs.h:68
int32_t fLmdWriteBuffer(sLmdControl *, char *, uint32_t)
Definition: fLmd.c:702
#define PORT__STREAM
Definition: fLmd.h:42
#define LMD__LARGE_FILE
Definition: sMbs.h:28
uint32_t iTimeSpecSec
Definition: sMbs.h:70
#define LMD__ENDIAN_UNKNOWN
Definition: sMbs.h:41
#define GETLMD__NOMORE
Definition: fLmd.h:31
sMbsHeader * pMbsHeader
Definition: fLmd.h:64
#define LMD__NO_OVERWRITE
Definition: sMbs.h:35
uint32_t iType
Definition: sMbs.h:83
INTS4 f_stc_write(void *p_buffer, INTS4 i_buflen, INTS4 i_channel)
Definition: f_stccomm.c:339
#define LMD__NO_INDEX
Definition: sMbs.h:34
#define PUTLMD__FILE_EXIST
Definition: fLmd.h:37
uint32_t fLmdOffsetSet(sLmdControl *, uint32_t)
Definition: fLmd.c:899
uint32_t iMaxWords
Definition: sMbs.h:64
uint32_t fLmdCleanup(sLmdControl *)
Definition: fLmd.c:723
uint32_t iBuffer
Definition: sMbs.h:67
int16_t * pBuffer
Definition: fLmd.h:47
lmdoff_t iTableOffset
Definition: sMbs.h:84
void fLmdOffsetElements(sLmdControl *, uint32_t, uint32_t *, uint32_t *)
Definition: fLmd.c:781
uint64_t iBytes
Definition: fLmd.h:53
uint32_t iWords
Definition: sMbs.h:107
uint32_t iTimeSpecSec
Definition: sMbs.h:87
void fLmdPrintFileHeader(uint32_t iVerbose, sMbsFileHeader *pMbsFileHeader)
Definition: fLmd.c:968
uint32_t iType
Definition: sMbs.h:65
#define OFFSET__ENTRIES
Definition: fLmd.c:68
uint32_t fLmdGetMbsEvent(sLmdControl *pLmdControl, sMbsHeader **event)
Definition: fLmd.c:321
uint32_t iTCP
Definition: fLmd.h:66
uint32_t iType
Definition: sMbs.h:115
uint32_t iInternBuffer
Definition: fLmd.h:51
uint32_t fLmdGetElement(sLmdControl *pLmdControl, uint32_t iEvent, sMbsHeader **event)
Definition: fLmd.c:601
uint32_t iTimeSpecNanoSec
Definition: sMbs.h:88
uint32_t iElements
Definition: fLmd.h:52
uint64_t lmdoff_t
Definition: sMbs.h:45
uint32_t * pOffset4
Definition: fLmd.h:58
uint32_t iMaxWords
Definition: sMbs.h:82
#define STC__TIMEOUT
Definition: f_stccomm.h:374
#define PUTLMD__OPEN_ERR
Definition: fLmd.h:39
uint32_t fLmdInitMbs(sLmdControl *pLmdControl, char *Nodename, uint32_t iMaxBytes, uint32_t iBuffers, uint32_t iStreams, uint32_t iPort, uint32_t iTimeout)
Definition: fLmd.c:282
uint32_t fLmdPutClose(sLmdControl *pLmdControl)
Definition: fLmd.c:251
uint32_t fLmdGetClose(sLmdControl *pLmdControl)
Definition: fLmd.c:684
uint32_t iPort
Definition: fLmd.h:67
#define LMD__TYPE_FILE_INDEX_101_2
Definition: sMbs.h:19
#define STC__SUCCESS
Definition: f_stccomm.h:369
uint32_t iElements
Definition: sMbs.h:85
void fLmdSwap4(uint32_t *array, uint32_t items)
Definition: fLmd.c:1009
uint32_t iOffsetSize
Definition: fLmd.h:61
#define LMD__TIMEOUT
Definition: fLmd.h:36
uint64_t fLmdGetBytesWritten(sLmdControl *pLmdControl)
Definition: fLmd.c:710
#define GETLMD__OUTOF_RANGE
Definition: fLmd.h:34
void fLmdSetWrittenEndian(sLmdControl *pLmdControl, uint32_t iE)
Definition: fLmd.c:755
uint32_t iType
Definition: sMbs.h:108
uint32_t fLmdGetBuffer(sLmdControl *pLmdControl, sMbsHeader *pMbsHeader, uint32_t iBytes, uint32_t *iElements, uint32_t *iBytesUsed)
Definition: fLmd.c:491
#define PUTLMD__EXCEED
Definition: fLmd.h:40
#define GETLMD__TOOBIG
Definition: fLmd.h:33
uint32_t iOffsetEntries
Definition: fLmd.h:62
uint32_t iTimeSpecNanoSec
Definition: sMbs.h:71
#define GETLMD__SIZE_ERROR
Definition: fLmd.h:35
uint32_t iTCPowner
Definition: fLmd.h:69
#define GETLMD__NOFILE
Definition: fLmd.h:28
uint32_t fLmdGetWrittenEndian(sLmdControl *pLmdControl)
Definition: fLmd.c:764
uint32_t iUsedWords
Definition: sMbs.h:75
uint32_t iEventNumber
Definition: sMbs.h:117
void fLmdPrintEvent(uint32_t iVerbose, sMbsEventHeader *pMbsEventHeader)
Definition: fLmd.c:989
uint32_t fLmdGetOpen(sLmdControl *pLmdControl, char *Filename, sMbsFileHeader *pBuffHead, uint32_t iBytes, uint32_t iUseOffset)
Definition: fLmd.c:398
void fLmdPrintHeader(uint32_t iVerbose, sMbsHeader *pMbsHeader)
Definition: fLmd.c:980
int32_t fLmdReadBuffer(sLmdControl *pLmdControl, char *buffer, uint32_t bytes)
Definition: fLmd.c:695
uint32_t fLmdCloseMbs(sLmdControl *pLmdControl)
Definition: fLmd.c:303
#define GETLMD__NOLMDFILE
Definition: fLmd.h:29
void fLmdPrintControl(uint32_t iVerbose, sLmdControl *pLmdControl)
Definition: fLmd.c:999
uint32_t iOffsetSize
Definition: sMbs.h:86
lmdoff_t fLmdOffsetGet(sLmdControl *, uint32_t)
Definition: fLmd.c:913
uint32_t iLeftWords
Definition: fLmd.h:49
uint32_t fLmdOffsetRead(sLmdControl *)
Definition: fLmd.c:812
void fLmdOffsetResize(sLmdControl *, uint32_t)
Definition: fLmd.c:922
FILE * fFile
Definition: fLmd.h:46
uint32_t iUsedWords
Definition: sMbs.h:92
lmdoff_t * pOffset8
Definition: fLmd.h:59
uint32_t iInternHeader
Definition: fLmd.h:50
uint32_t fLmdPutElement(sLmdControl *pLmdControl, sMbsHeader *pHeader)
Definition: fLmd.c:145
#define LMD__TYPE_FILE_HEADER_101_1
Definition: sMbs.h:17
#define PUTLMD__TOOBIG
Definition: fLmd.h:38
char cFile[512]
Definition: fLmd.h:54
uint32_t fLmdGetMbsBuffer(sLmdControl *pLmdControl, sMbsBufferHeader *pBuffer, uint32_t iBytes, uint32_t *iElements, uint32_t *iBytesUsed)
Definition: fLmd.c:344
uint32_t iSwap
Definition: fLmd.h:55
uint32_t iWords
Definition: sMbs.h:114
uint32_t fLmdPutOpen(sLmdControl *pLmdControl, char *Filename, sMbsFileHeader *pBuffHead, uint32_t iBytes, uint32_t iOver, uint32_t iUseOffset, uint32_t iLargeFile)
Definition: fLmd.c:71
struct s_tcpcomm * pTCP
Definition: fLmd.h:65
#define GETLMD__NOBUFFER
Definition: fLmd.h:32
uint32_t fLmdGetSwap(sLmdControl *pLmdControl)
Definition: fLmd.c:747
uint32_t iEndian
Definition: sMbs.h:90
uint32_t iTcpTimeout
Definition: fLmd.h:68
sLmdControl * fLmdAllocateControl(void)
Definition: fLmd.c:773
char * cHeader
Definition: fLmd.h:57
#define LMD__FAILURE
Definition: fLmd.h:26
sMbsFileHeader * pMbsFileHeader
Definition: fLmd.h:63
#define LMD__INTERNAL_HEADER
Definition: sMbs.h:25
uint32_t fLmdPutBuffer(sLmdControl *pLmdControl, sMbsHeader *pHeader, uint32_t Items)
Definition: fLmd.c:205
#define LMD__CLOSE_ERR
Definition: fLmd.h:27
uint32_t iBufferWords
Definition: fLmd.h:48
void fLmdPrintBufferHeader(uint32_t iVerbose, sMbsBufferHeader *pMbsBufferHeader)
Definition: fLmd.c:957
void fLmdSwap8(uint64_t *array, uint32_t items)
Definition: fLmd.c:1019
uint32_t iWrittenEndian
Definition: sMbs.h:91