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