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