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