evio  6.0
All Data Structures Files Functions Variables Typedefs Macros Modules
evio.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <pthread.h>
#include <assert.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <inttypes.h>
#include "evio.h"

Macros

#define _GNU_SOURCE
 Enable GNU extensions to C lib such as strdup, strndup, asprintf, pid_t. More...
 
#define EV_READFILE   0
 Read from a file. More...
 
#define EV_READPIPE   1
 Read from a pipe. More...
 
#define EV_READSOCK   2
 Read from a socket. More...
 
#define EV_READBUF   3
 Read from a buffer. More...
 
#define EV_WRITEFILE   4
 Write to a file. More...
 
#define EV_WRITEPIPE   5
 Write to a pipe. More...
 
#define EV_WRITESOCK   6
 Write to a socket. More...
 
#define EV_WRITEBUF   7
 Write to a buffer. More...
 
#define EV_MAGIC   0xc0da0100
 Number used to determine data endian. More...
 
#define EV_BLOCKSIZE_V3   8192
 Version 3's fixed block size in 32 bit words. More...
 
#define EV_BLOCKSIZE   150
 Version 4&6's target block size in 32 bit words (16MB). More...
 
#define EV_BLOCKSIZE_MIN   1000000
 Minimum block size in 32 bit words allowed if size reset (4MB) More...
 
#define EV_BLOCKSIZE_MAX   33554432
 The upper limit of maximum size for a single block used for writing is 2^25 ints or words. More...
 
#define EV_VERSION_MASK   0xFF
 In version 4 & 6, lowest 8 bits are version, rest is bit info. More...
 
#define EV_DICTIONARY_MASK   0x100
 In version 4 & 6, dictionary presence is 9th bit in version/info word. More...
 
#define EV_LASTBLOCK_MASK   0x200
 In version 4 & 6, "last block" is 10th bit in version/info word. More...
 
#define EV_FIRSTEVENT_MASK   0x4000
 In version 4 & 6, "first event" is 15th bit in version/info word. More...
 
#define EV_COMPRESSED_SHIFT   28
 In version 6, number of bits to shift compression word right to get type of compression. More...
 
#define EV_COMPRESSED_MASK   0xf
 In version 6, # of bits in record's compression word that specifies type of compression after shift right. More...
 
#define EV_EVENTS_MAX   100000
 In versions 4 & 6, upper limit on maximum max number of events per block. More...
 
#define EV_EVENTS_MAX_DEF   10000
 In versions 4 & 6, default max number of events per block. More...
 
#define EV_SPLIT_SIZE   2000000000L
 In versions 4 & 6, if splitting file, default split size in bytes (2GB) More...
 
#define EV_READ_BYTES_V3   16384000
 In versions 1-3, default size for a single file read in bytes. More...
 
#define EV_FILE_TYPE   0x4556494F
 In version 6, the file header's file type. More...
 
#define EV_HD_BLKSIZ   0
 Position of blk hdr word for size of block in 32-bit words (v 1-6). More...
 
#define EV_HD_BLKNUM   1
 Position of blk hdr word for block number, starting at 0 (v 1-6). More...
 
#define EV_HD_HDSIZ   2
 Position of blk hdr word for size of header in 32-bit words (v 1-4, =8) (v 6 =14). More...
 
#define EV_HD_COUNT   3
 Position of blk hdr word for number of events in block (version 4,6). More...
 
#define EV_HD_START   3
 Position of blk hdr word for first start of event in this block (ver 1-3). More...
 
#define EV_HD_USED   4
 Position of blk hdr word for number of words used in block (<= BLKSIZ) (ver 1-3). More...
 
#define EV_HD_RESVD1   4
 Position of blk hdr word for reserved (v 1-4). More...
 
#define EV_HD_VER   5
 Position of blk hdr word for version of file format (+ bit info in ver 4,6). More...
 
#define EV_HD_RESVD2   6
 Position of blk hdr word for reserved (v 1-4). More...
 
#define EV_HD_MAGIC   7
 Position of blk hdr word for magic number for endianness tracking (v 4,6). More...
 
#define EV_HD_INDEXARRAYLEN   4
 Position of file & blk hdr word for index array length (v 6). More...
 
#define EV_HD_USERHDRLEN   6
 Position of file & blk hdr word for user header length (v 6). More...
 
#define EV_HD_UNCOMPDATALEN   8
 Position of blk hdr word for uncompressed data length (v 6). More...
 
#define EV_HD_COMPDATALEN   9
 Position of blk hdr word for compressed data length (v 6). More...
 
#define EV_HD_TRAILERPOS   10
 Position of file hdr word for trailer position (v 6). More...
 
#define EV_HD_USERREG1   10
 Position of blk hdr word for user register 1 (v 6). More...
 
#define EV_HD_USERREG2   12
 Position of blk hdr word for user register 2 (v 6). More...
 
#define EV_HD_USERREGFILE   8
 Position of file hdr word for user register (v 6). More...
 
#define setDictionaryBit(a)   ((a)[EV_HD_VER] |= EV_DICTIONARY_MASK)
 Turn on 9th bit to indicate dictionary included in block. More...
 
#define clearDictionaryBit(a)   ((a)[EV_HD_VER] &= ~EV_DICTIONARY_MASK)
 Turn off 9th bit to indicate dictionary included in block. More...
 
#define hasDictionary(a)   (((a)[EV_HD_VER] & EV_DICTIONARY_MASK) > 0 ? 1 : 0)
 Is there a dictionary in this block? More...
 
#define hasDictionaryInt(i)   ((i & EV_DICTIONARY_MASK) > 0 ? 1 : 0)
 Is there a dictionary in this block? More...
 
#define setLastBlockBit(a)   ((a)[EV_HD_VER] |= EV_LASTBLOCK_MASK)
 Turn on bit to indicate last block of file/transmission. More...
 
#define clearLastBlockBit(a)   ((a)[EV_HD_VER] &= ~EV_LASTBLOCK_MASK)
 Turn off bit to indicate last block of file/transmission. More...
 
#define clearLastBlockBitInt(i)   (i &= ~EV_LASTBLOCK_MASK)
 Turn off bit to indicate last block of file/transmission. More...
 
#define isLastBlock(a)   (((a)[EV_HD_VER] & EV_LASTBLOCK_MASK) > 0 ? 1 : 0)
 Is this the last block of file/transmission? More...
 
#define isLastBlockInt(i)   ((i & EV_LASTBLOCK_MASK) > 0 ? 1 : 0)
 Is this the last block of file/transmission? More...
 
#define isCompressed(i)   (((i >> 28) && 0xf) == 0 ? 0 : 1)
 Is the record data compressed (version 6, 10th header word)? More...
 
#define getPad1(i)   (((int)i >> 20) & 0x3)
 Get padding #1 from bitinfo word (v6). More...
 
#define getPad2(i)   (((int)i >> 22) & 0x3)
 Get padding #2 from bitinfo word (v6). More...
 
#define getPad3(i)   (((int)i >> 24) & 0x3)
 Get padding #3 from bitinfo word (v6). More...
 
#define initBlockHeader(a)
 ‍** Initialize a record header *‍/ More...
 
#define initBlockHeader2(a, b)
 Initialize a record header. More...
 
#define initFileHeader(a)
 Initialize a file header, with split# = 1, record count = 0 (4th word). More...
 

Functions

int evopen_ (char *filename, char *flags, int *handle, int fnlen, int flen)
 Fortran interface to evOpen. More...
 
int evread_ (int *handle, uint32_t *buffer, uint32_t *buflen)
 Fortran interface to evRead. More...
 
int evwrite_ (int *handle, const uint32_t *buffer)
 Fortran interface to evWrite. More...
 
int evclose_ (int *handle)
 Fortran interface to evClose. More...
 
int evioctl_ (int *handle, char *request, void *argp, int reqlen)
 Fortran interface to evIoctl. More...
 
int evIsLastBlock (uint32_t sixthWord)
 Routine to take the 6th word of a block header and tell whether it's the last block or not. More...
 
void evPrintBuffer (uint32_t *p, uint32_t len, int swap)
 Routine to print the contents of a buffer. More...
 
void evFileStructInit (EVFILE *a)
 Routine to intialize an EVFILE structure for writing. More...
 
char * evStrReplace (char *orig, const char *replace, const char *with)
 This routine substitutes a given string for a specified substring. More...
 
char * evStrReplaceEnvVar (const char *orig)
 This routine finds constructs of the form and replaces it with the value of the ENV environmental variable if it exists or with nothing if it doesn't. More...
 
char * evStrFindSpecifiers (const char *orig, int *specifierCount)
 This routine checks a string for C-style printing integer format specifiers. More...
 
char * evStrRemoveSpecifiers (const char *orig, int skip)
 This routine checks a string for C-style printing integer format specifiers. More...
 
int evGenerateBaseFileName (const char *origName, char **baseName, int *count)
 
char * evGenerateFileNameOld (EVFILE *a, int specifierCount, int runNumber, int splitting, int splitNumber, char *runType, uint32_t streamId)
 
int evStrInsertBeforeSpecifier (char *str, uint32_t n, const char *insert, char *result, size_t result_size)
 Inserts a string just before the first occurrence of a format specifier that starts with '' and ends with a conversion specifier of 'd' or 'x'. More...
 
char * evGenerateFileName (EVFILE *a, int specifierCount, uint32_t runNumber, int splitting, uint32_t splitNumber, char *runType, uint32_t streamId, uint32_t streamCount, int debug)
 
int evOpen (char *filename, char *flags, int *handle)
 This function opens a file for either reading or writing evio format data. More...
 
int evOpenBuffer (char *buffer, uint32_t bufLen, char *flags, int *handle)
 This function allows for either reading or writing evio format data from a buffer. More...
 
int evOpenSocket (int sockFd, char *flags, int *handle)
 This function allows for either reading or writing evio format data from a TCP socket. More...
 
int evOpenFake (char *filename, char *flags, int *handle, char **evf)
 For test purposes only ... More...
 
int evRead (int handle, uint32_t *buffer, uint32_t buflen)
 This routine reads from an evio format file/socket/buffer opened with routines evOpen, evOpenBuffer, or evOpenSocket and returns the next event in the buffer arg. More...
 
int evReadAlloc (int handle, uint32_t **buffer, uint32_t *buflen)
 This routine reads an evio bank from an evio format file/socket/buffer opened with routines evOpen, evOpenBuffer, or evOpenSocket, allocates a buffer and fills it with the bank. More...
 
int evReadNoCopy (int handle, const uint32_t **buffer, uint32_t *buflen)
 This routine reads from an evio format file/buffer/socket opened with routines evOpen, evOpenBuffer, or evOpenSocket and returns a pointer to the next event residing in an internal buffer. More...
 
int evReadRandom (int handle, const uint32_t **pEvent, uint32_t *buflen, uint32_t eventNumber)
 This routine does a random access read from an evio format file/buffer opened with routines evOpen or evOpenBuffer. More...
 
int evWrite (int handle, const uint32_t *buffer)
 This routine writes an evio event to an internal buffer containing evio data. More...
 
int evFlush (int handle)
 This function flushes any remaining internally buffered data to file/socket. More...
 
int evClose (int handle)
 This routine flushes any existing evio format data in an internal buffer (written to with evWrite) to the final destination file/socket/buffer opened with routines evOpen, evOpenBuffer, or evOpenSocket. More...
 
int evGetFileName (int handle, char *name, size_t maxLength)
 This routine gets the name of the file currently being written to and opened with evOpen, Returned string may NOT be written into. More...
 
int evGetBufferLength (int handle, uint32_t *length)
 This routine returns the number of bytes written into a buffer so far when given a handle provided by calling evOpenBuffer. More...
 
int evIoctl (int handle, char *request, void *argp)
 This routine changes various evio parameters used in reading and writing. More...
 
int evGetRandomAccessTable (int handle, uint32_t ***const table, uint32_t *len)
 This routine gets an array of event pointers if the handle was opened in random access mode. More...
 
int evGetDictionary (int handle, char **dictionary, uint32_t *len)
 This routine gets the dictionary associated with this handle if there is any. More...
 
int evStringsToBuf (uint32_t *buffer, int bufLen, char **strings, int stringCount, int *dataLen)
 This routine writes an array of strings, in evio format, into the given buffer. More...
 
int evBufToStrings (char *buffer, int bufLen, char ***pStrArray, int *strCount)
 This routine unpacks/parses an evio format buffer containing strings into an array of strings. More...
 
const char * evGetTypename (int type)
 This routine returns a string representation of an evio type. More...
 
int evIsContainer (int type)
 This routine return true (1) if given type is a container, else returns false (0). More...
 
char * evPerror (int error)
 This routine returns a string describing the given error value. More...
 

Variables

EVFILE ** handleList = NULL
 Array that holds all pointers to structures created with evOpen(). More...
 

Detailed Description


Let's take a look at an evio block header also
known as a physical record header.

In versions 1, 2 & 3, evio files impose an anachronistic
block structure. The complication that arises is that logical records
(events) will sometimes cross physical record boundaries.

####################################
Evio block header, versions 1,2 & 3:
####################################

MSB(31)                          LSB(0)
<---  32 bits ------------------------>
+-------------------------------------+
+             Block Size              +
+-------------------------------------+
+            Block Number             +
+-------------------------------------+
+           Header Size = 8           +
+-------------------------------------+
+               Start                 +
+-------------------------------------+
+                Used                 +
+-------------------------------------+
+              Version                +
+-------------------------------------+
+              Reserved               +
+-------------------------------------+
+              Magic #                +
+-------------------------------------+


     Block Size    = number of 32 bit ints in block (including this one).
                     This is fixed for versions 1-3, generally at 8192 (32768 bytes)
     Block Number  = id number (starting at 1)
     Header Size   = number of 32 bit nts in this header (always 8)
     Start         = offset to first event header in block relative to start of block
     Used          = # of used/valid words (header + data) in block,
                     (normally = block size, but in last block may be smaller)
     Version       = evio format version
     Reserved      = reserved
     Magic #       = magic number (0xc0da0100) used to check endianness



In version 4, only an integral number of complete
events will be contained in a single block.

################################
Evio block header, version 4:
################################

MSB(31)                          LSB(0)
<---  32 bits ------------------------>
+-------------------------------------+
+             Block Size              +
+-------------------------------------+
+            Block Number             +
+-------------------------------------+
+          Header Length = 8          +
+-------------------------------------+
+             Event Count             +
+-------------------------------------+
+              Reserved               +
+-------------------------------------+
+          Bit info         + Version +
+-------------------------------------+
+              Reserved               +
+-------------------------------------+
+            Magic Number             +
+-------------------------------------+


     Block Size         = number of ints in block (including this one).
     Block Number       = id number (starting at 1)
     Header Length      = number of ints in this header (EV_HDSIZ which is currently 8)
     Event Count        = number of events in this block (always an integral #).
                          NOTE: this value should not be used to parse the following
                          events since the first block may have a dictionary whose
                          presence is not included in this count.
     Bit info & Version = Lowest 8 bits are the version number (4).
                          Upper 24 bits contain bit info.
                          If a dictionary is included as the first event, bit #9 is set (=1)
     Magic #            = magic number (0xc0da0100) used to check endianness


     Bit info (24 bits) has the following bits defined (starting at 1):

        Bit  9     = true if dictionary is included (relevant for first block only)
        Bit  10    = true if this block is the last block in file or network transmission
        Bits 11-14 = type of events following (ROC Raw = 0, Physics = 1, PartialPhysics = 2,
                     DisentangledPhysics = 3, User = 4, Control = 5, Prestart = 6, Go = 7,
                     Pause = 8, End = 9, Other = 15)
        Bit  15    = true if block contains "first" event which gets written in each file split

        Bits 11-15 are ONLY for the CODA online use of evio.
        That's because only a single CODA event TYPE is placed into
        a single ET or cMsg buffer. Each user or control event has its own
        buffer. Thus all events parsed from a single buffer will be of a single CODA type.

################################
COMPOSITE DATA:
################################
  This is a new type of data (value = 0xf) which originated with Hall B.
  It is a composite type and allows for possible expansion in the future
  if there is a demand. Basically it allows the user to specify a custom
  format by means of a string - stored in a tagsegment. The data in that
  format follows in a bank. The routine to swap this data must be provided
  by the definer of the composite type - in this case Hall B. The swapping
  function is plugged into this evio library's swapping routine.
  Here's what it looks like.

MSB(31)                          LSB(0)
<---  32 bits ------------------------>
+---------+------+--------------------+
+  tag    + type +    length          + --> tagsegment header
+---------+------+--------------------+
+        Data Format String           +
+                                     +
+-------------------------------------+
+              length                 + \
+----------------+---------+----------+  \  bank header
+       tag      +  type   +   num    +  /
+----------------+---------+----------+ /
+               Data                  +
+                                     +
+-------------------------------------+

  The beginning tagsegment is a normal evio tagsegment containing a string
  (type = 0x3). Currently its type and tag are not used - at least not for
  data formatting.
  The bank is a normal evio bank header with data following.
  The format string is used to read/write this data so that takes care of any
  padding that may exist. As with the tagsegment, the tags and type are ignored.

########################################
Evio block or record header, version 6+:
########################################

 GENERAL RECORD HEADER STRUCTURE ( 56 bytes, 14 integers (32 bit) )

   +----------------------------------+
 1 +         Record Length            + // 32bit words, inclusive
   +----------------------------------+
 2 +         Record Number            +
   +----------------------------------+
 3 +         Header Length            + // 14 (words)
   +----------------------------------+
 4 +       Event (Index) Count        +
   +----------------------------------+
 5 +      Index Array Length          + // bytes
   +-----------------------+----------+
 6 +       Bit Info        + Version  + // version (8 bits)
   +-----------------------+----------+
 7 +      User Header Length          + // bytes
   +----------------------------------+
 8 +          Magic Number            + // 0xc0da0100
   +----------------------------------+
 9 +     Uncompressed Data Length     + // bytes
   +------+---------------------------+
10 +  CT  +  Data Length Compressed   + // CT = compression type (4 bits); compressed len in words
   +------+---------------------------+
11 +          User Register 1         + // UID 1st (64 bits)
   +--                              --+
12 +                                  +
   +----------------------------------+
13 +          User Register 2         + // UID 2nd (64 bits)
   +--                              --+
14 +                                  +
   +----------------------------------+

-------------------
  Compression Type
-------------------
    0  = none
    1  = LZ4 fastest
    2  = LZ4 best
    3  = gzip

-------------------
  Bit Info Word
-------------------
    0-7  = version
    8    = true if dictionary is included (relevant for first record only)
    9    = true if this record has "first" event (to be in every split file)
   10    = true if this record is the last in file or stream
   11-14 = type of events contained: 0 = ROC Raw,
                                     1 = Physics
                                     2 = PartialPhysics
                                     3 = DisentangledPhysics
                                     4 = User
                                     5 = Control
                                    15 = Other
   15-19 = reserved
   20-21 = pad 1
   22-23 = pad 2
   24-25 = pad 3
   26-27 = reserved
   28-31 = general header type: 0 = Evio record,
                                3 = Evio file trailer
                                4 = HIPO record,
                                7 = HIPO file trailer

------------------------------------------------------------
------------------------------------------------------------

  TRAILER HEADER STRUCTURE ( 56 bytes, 14 integers (32 bit) )

   +----------------------------------+
 1 +         Record Length            + // 32bit words, inclusive
   +----------------------------------+
 2 +         Record Number            +
   +----------------------------------+
 3 +               14                 +
   +----------------------------------+
 4 +                0                 +
   +----------------------------------+
 5 +      Index Array Length          + // bytes
   +-----------------------+----------+
 6 +       Bit Info        + Version  +
   +-----------------------+----------+
 7 +                0                 +
   +----------------------------------+
 8 +           0xc0da0100             +
   +----------------------------------+
 9 +     Uncompressed Data Length     + // bytes
   +----------------------------------+
10 +                0                 +
   +----------------------------------+
11 +                0                 +
   +--                              --+
12 +                0                 +
   +----------------------------------+
13 +                0                 +
   +--                              --+
14 +                0                 +
   +----------------------------------+

----------------------------------
  Bit Info Word (bit num = value)
----------------------------------
    0-7  = 6
    8    = 0
    9    = 0
   10    = 1
   11-14 = 0
   15-19 = 0
   20-21 = 0
   22-23 = 0
   24-25 = 0
   26-27 = 0
   28-31 = 3


        THE FULL TRAILER FORMAT IS:

   +----------------------------------+
   +         Trailer Header           +
   +          (14 words)              +
   +----------------------------------+

   +----------------------------------+
   +            Optional              +
   +      Uncompressed Array of       +
   +     a record length in bytes,    +
   +           followed by            +
   +  an event count for that record  +
   +       (2 words / record)         +
   +          (all records)           +
   +----------------------------------+

  HOWEVER, in this library, the optional index of lengths and counts is NOT written.

------------------------------------------------------------
------------------------------------------------------------

        THE FULL RECORD FORMAT IS:

   +----------------------------------+
   +         Record Header            +
   +          (14 words)              +
   +----------------------------------+

   +----------------------------------+
   +           Index Array            +
   +     (required index of all       +
   +      event lengths in bytes,     +
   +       one word / length )        +
   +----------------------------------+

   +----------------------------------+
   +          User Header             +
   +    (any user data)    +----------+
   +                       +  Pad 1   +
   +-----------------------+----------+

   +----------------------------------+
   +             Events               +
   +                       +----------+
   +                       +  Pad 2   +
   +-----------------------+----------+


Records may be compressed, but that is only handled in the Java and C++ libs.
The record header is never compressed and so is always readable.
If events are in the evio format, pad_2 will be 0.


################################
Evio FILE header, version 6+:
################################

FILE HEADER STRUCTURE ( 56 bytes, 14 integers (32 bit) )

   +----------------------------------+
 1 +              ID                  + // HIPO: 0x43455248, Evio: 0x4556494F
   +----------------------------------+
 2 +          File Number             + // split file #
   +----------------------------------+
 3 +         Header Length            + // 14 (words)
   +----------------------------------+
 4 +      Record (Index) Count        +
   +----------------------------------+
 5 +      Index Array Length          + // bytes
   +-----------------------+----------+
 6 +       Bit Info        + Version  + // version (8 bits)
   +-----------------------+----------+
 7 +      User Header Length          + // bytes
   +----------------------------------+
 8 +          Magic Number            + // 0xc0da0100
   +----------------------------------+
 9 +          User Register           +
   +--                              --+
10 +                                  +
   +----------------------------------+
11 +         Trailer Position         + // File offset to trailer head (64 bits).
   +--                              --+ // 0 = no offset available or no trailer exists.
12 +                                  +
   +----------------------------------+
13 +          User Integer 1          +
   +----------------------------------+
14 +          User Integer 2          +
   +----------------------------------+

-------------------
  Bit Info Word
-------------------
    0-7  = version
    8    = true if dictionary is included (relevant for first record only)
    9    = true if this file has "first" event (in every split file)
   10    = File trailer with index array of record lengths exists
   11-19 = reserved
   20-21 = pad 1
   22-23 = pad 2
   24-25 = pad 3 (always 0)
   26-27 = reserved
   28-31 = general header type: 1 = Evio file
                                2 = Evio extended file
                                5 = HIPO file
                                6 = HIPO extended file

In this library, the Trailer Position is never written and therefore is always 0.
It's unneeded since the trailer's index is never written.

---------------------------------------------------------------
---------------------------------------------------------------

The file header occurs once at the beginning of the file.
The full file format looks like:

        THE FULL FILE FORMAT IS:

   +----------------------------------+
   +          File Header             +
   +          (14 words)              +
   +----------------------------------+

   +----------------------------------+
   +           Index Array            +
   +   (optional index, same format   +
   +      as file trailer index:      +
   +   1 word of record len in bytes, +
   +           followed by            +
   +      1 word of event count       +
   +----------------------------------+

   +----------------------------------+
   +          User Header             +
   +    (any user data)    +----------+
   +                       +  Pad 1   +
   +-----------------------+----------+

   +----------------------------------+
   +             Record 1             +
   +----------------------------------+
                  ___
   +----------------------------------+
   +             Record N             +
   +----------------------------------+

   The last record may be a trailer.

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Enable GNU extensions to C lib such as strdup, strndup, asprintf, pid_t.

◆ clearDictionaryBit

#define clearDictionaryBit (   a)    ((a)[EV_HD_VER] &= ~EV_DICTIONARY_MASK)

Turn off 9th bit to indicate dictionary included in block.

◆ clearLastBlockBit

#define clearLastBlockBit (   a)    ((a)[EV_HD_VER] &= ~EV_LASTBLOCK_MASK)

Turn off bit to indicate last block of file/transmission.

◆ clearLastBlockBitInt

#define clearLastBlockBitInt (   i)    (i &= ~EV_LASTBLOCK_MASK)

Turn off bit to indicate last block of file/transmission.

◆ EV_BLOCKSIZE

#define EV_BLOCKSIZE   150

Version 4&6's target block size in 32 bit words (16MB).

It is a soft limit since a single event larger than this limit may need to be written.

◆ EV_BLOCKSIZE_MAX

#define EV_BLOCKSIZE_MAX   33554432

The upper limit of maximum size for a single block used for writing is 2^25 ints or words.

This gives block sizes of about 134MB. It is a soft limit since a single event larger than this limit may need to be written.

◆ EV_BLOCKSIZE_MIN

#define EV_BLOCKSIZE_MIN   1000000

Minimum block size in 32 bit words allowed if size reset (4MB)

◆ EV_BLOCKSIZE_V3

#define EV_BLOCKSIZE_V3   8192

Version 3's fixed block size in 32 bit words.

◆ EV_COMPRESSED_MASK

#define EV_COMPRESSED_MASK   0xf

In version 6, # of bits in record's compression word that specifies type of compression after shift right.

◆ EV_COMPRESSED_SHIFT

#define EV_COMPRESSED_SHIFT   28

In version 6, number of bits to shift compression word right to get type of compression.

◆ EV_DICTIONARY_MASK

#define EV_DICTIONARY_MASK   0x100

In version 4 & 6, dictionary presence is 9th bit in version/info word.

◆ EV_EVENTS_MAX

#define EV_EVENTS_MAX   100000

In versions 4 & 6, upper limit on maximum max number of events per block.

◆ EV_EVENTS_MAX_DEF

#define EV_EVENTS_MAX_DEF   10000

In versions 4 & 6, default max number of events per block.

◆ EV_FILE_TYPE

#define EV_FILE_TYPE   0x4556494F

In version 6, the file header's file type.

◆ EV_FIRSTEVENT_MASK

#define EV_FIRSTEVENT_MASK   0x4000

In version 4 & 6, "first event" is 15th bit in version/info word.

◆ EV_HD_BLKNUM

#define EV_HD_BLKNUM   1

Position of blk hdr word for block number, starting at 0 (v 1-6).

◆ EV_HD_BLKSIZ

#define EV_HD_BLKSIZ   0

Position of blk hdr word for size of block in 32-bit words (v 1-6).

◆ EV_HD_COMPDATALEN

#define EV_HD_COMPDATALEN   9

Position of blk hdr word for compressed data length (v 6).

◆ EV_HD_COUNT

#define EV_HD_COUNT   3

Position of blk hdr word for number of events in block (version 4,6).

◆ EV_HD_HDSIZ

#define EV_HD_HDSIZ   2

Position of blk hdr word for size of header in 32-bit words (v 1-4, =8) (v 6 =14).

◆ EV_HD_INDEXARRAYLEN

#define EV_HD_INDEXARRAYLEN   4

Position of file & blk hdr word for index array length (v 6).

◆ EV_HD_MAGIC

#define EV_HD_MAGIC   7

Position of blk hdr word for magic number for endianness tracking (v 4,6).

◆ EV_HD_RESVD1

#define EV_HD_RESVD1   4

Position of blk hdr word for reserved (v 1-4).

◆ EV_HD_RESVD2

#define EV_HD_RESVD2   6

Position of blk hdr word for reserved (v 1-4).

◆ EV_HD_START

#define EV_HD_START   3

Position of blk hdr word for first start of event in this block (ver 1-3).

◆ EV_HD_TRAILERPOS

#define EV_HD_TRAILERPOS   10

Position of file hdr word for trailer position (v 6).

◆ EV_HD_UNCOMPDATALEN

#define EV_HD_UNCOMPDATALEN   8

Position of blk hdr word for uncompressed data length (v 6).

◆ EV_HD_USED

#define EV_HD_USED   4

Position of blk hdr word for number of words used in block (<= BLKSIZ) (ver 1-3).

◆ EV_HD_USERHDRLEN

#define EV_HD_USERHDRLEN   6

Position of file & blk hdr word for user header length (v 6).

◆ EV_HD_USERREG1

#define EV_HD_USERREG1   10

Position of blk hdr word for user register 1 (v 6).

◆ EV_HD_USERREG2

#define EV_HD_USERREG2   12

Position of blk hdr word for user register 2 (v 6).

◆ EV_HD_USERREGFILE

#define EV_HD_USERREGFILE   8

Position of file hdr word for user register (v 6).

◆ EV_HD_VER

#define EV_HD_VER   5

Position of blk hdr word for version of file format (+ bit info in ver 4,6).

◆ EV_LASTBLOCK_MASK

#define EV_LASTBLOCK_MASK   0x200

In version 4 & 6, "last block" is 10th bit in version/info word.

◆ EV_MAGIC

#define EV_MAGIC   0xc0da0100

Number used to determine data endian.

◆ EV_READ_BYTES_V3

#define EV_READ_BYTES_V3   16384000

In versions 1-3, default size for a single file read in bytes.

Equivalent to 500, 32,768 byte blocks. This constant MUST BE an integer multiple of 32768.

◆ EV_READBUF

#define EV_READBUF   3

Read from a buffer.

◆ EV_READFILE

#define EV_READFILE   0

Read from a file.

◆ EV_READPIPE

#define EV_READPIPE   1

Read from a pipe.

◆ EV_READSOCK

#define EV_READSOCK   2

Read from a socket.

◆ EV_SPLIT_SIZE

#define EV_SPLIT_SIZE   2000000000L

In versions 4 & 6, if splitting file, default split size in bytes (2GB)

◆ EV_VERSION_MASK

#define EV_VERSION_MASK   0xFF

In version 4 & 6, lowest 8 bits are version, rest is bit info.

◆ EV_WRITEBUF

#define EV_WRITEBUF   7

Write to a buffer.

◆ EV_WRITEFILE

#define EV_WRITEFILE   4

Write to a file.

◆ EV_WRITEPIPE

#define EV_WRITEPIPE   5

Write to a pipe.

◆ EV_WRITESOCK

#define EV_WRITESOCK   6

Write to a socket.

◆ getPad1

#define getPad1 (   i)    (((int)i >> 20) & 0x3)

Get padding #1 from bitinfo word (v6).

◆ getPad2

#define getPad2 (   i)    (((int)i >> 22) & 0x3)

Get padding #2 from bitinfo word (v6).

◆ getPad3

#define getPad3 (   i)    (((int)i >> 24) & 0x3)

Get padding #3 from bitinfo word (v6).

◆ hasDictionary

#define hasDictionary (   a)    (((a)[EV_HD_VER] & EV_DICTIONARY_MASK) > 0 ? 1 : 0)

Is there a dictionary in this block?

◆ hasDictionaryInt

#define hasDictionaryInt (   i)    ((i & EV_DICTIONARY_MASK) > 0 ? 1 : 0)

Is there a dictionary in this block?

◆ initBlockHeader

#define initBlockHeader (   a)
Value:
{ \
(a)[EV_HD_BLKNUM] = 1; \
(a)[EV_HD_COUNT] = 0; \
(a)[EV_HD_INDEXARRAYLEN] = 0; \
(a)[EV_HD_USERHDRLEN] = 0; \
(a)[EV_HD_UNCOMPDATALEN] = 0; \
(a)[EV_HD_COMPDATALEN] = 0; \
(a)[EV_HD_USERREG1] = 0; \
(a)[EV_HD_USERREG1 + 1] = 0; \
(a)[EV_HD_USERREG2] = 0; \
(a)[EV_HD_USERREG2 + 1] = 0; \
}
#define EV_HD_UNCOMPDATALEN
Position of blk hdr word for uncompressed data length (v 6).
Definition: evio.c:606
#define EV_HD_VER
Position of blk hdr word for version of file format (+ bit info in ver 4,6).
Definition: evio.c:600
#define EV_HD_BLKSIZ
Position of blk hdr word for size of block in 32-bit words (v 1-6).
Definition: evio.c:593
#define EV_HD_MAGIC
Position of blk hdr word for magic number for endianness tracking (v 4,6).
Definition: evio.c:602
#define EV_HD_USERHDRLEN
Position of file & blk hdr word for user header length (v 6).
Definition: evio.c:605
#define EV_HD_BLKNUM
Position of blk hdr word for block number, starting at 0 (v 1-6).
Definition: evio.c:594
#define EV_HD_INDEXARRAYLEN
Position of file & blk hdr word for index array length (v 6).
Definition: evio.c:604
#define EV_HD_HDSIZ
Position of blk hdr word for size of header in 32-bit words (v 1-4, =8) (v 6 =14).
Definition: evio.c:595
#define EV_HD_COMPDATALEN
Position of blk hdr word for compressed data length (v 6).
Definition: evio.c:607
#define EV_HD_COUNT
Position of blk hdr word for number of events in block (version 4,6).
Definition: evio.c:596
#define EV_HD_USERREG1
Position of blk hdr word for user register 1 (v 6).
Definition: evio.c:609
#define EV_HD_USERREG2
Position of blk hdr word for user register 2 (v 6).
Definition: evio.c:610
#define EV_MAGIC
Number used to determine data endian.
Definition: evio.c:128
#define EV_VERSION
Evio format version, not the evio package version #.
Definition: evio.h:31
#define EV_HDSIZ_V6
Definition: evio.h:36

‍** Initialize a record header *‍/

◆ initBlockHeader2

#define initBlockHeader2 (   a,
 
)
Value:
{ \
(a)[EV_HD_BLKNUM] = b; \
(a)[EV_HD_COUNT] = 0; \
(a)[EV_HD_INDEXARRAYLEN] = 0; \
(a)[EV_HD_USERHDRLEN] = 0; \
(a)[EV_HD_UNCOMPDATALEN] = 0; \
(a)[EV_HD_COMPDATALEN] = 0; \
(a)[EV_HD_USERREG1] = 0; \
(a)[EV_HD_USERREG1 + 1] = 0; \
(a)[EV_HD_USERREG2] = 0; \
(a)[EV_HD_USERREG2 + 1] = 0; \
}

Initialize a record header.

◆ initFileHeader

#define initFileHeader (   a)
Value:
{ \
(a)[0] = EV_FILE_TYPE; \
(a)[1] = 1; \
(a)[2] = EV_HDSIZ_V6; \
(a)[3] = 0; \
(a)[4] = 0; \
(a)[5] = (0x10000000 | EV_VERSION); \
(a)[6] = 0; \
(a)[7] = EV_MAGIC; \
(a)[8] = 0; \
(a)[9] = 0; \
(a)[10] = 0; \
(a)[11] = 0; \
(a)[12] = 0; \
(a)[13] = 0; \
}
#define EV_FILE_TYPE
In version 6, the file header's file type.
Definition: evio.c:182

Initialize a file header, with split# = 1, record count = 0 (4th word).

◆ isCompressed

#define isCompressed (   i)    (((i >> 28) && 0xf) == 0 ? 0 : 1)

Is the record data compressed (version 6, 10th header word)?

◆ isLastBlock

#define isLastBlock (   a)    (((a)[EV_HD_VER] & EV_LASTBLOCK_MASK) > 0 ? 1 : 0)

Is this the last block of file/transmission?

◆ isLastBlockInt

#define isLastBlockInt (   i)    ((i & EV_LASTBLOCK_MASK) > 0 ? 1 : 0)

Is this the last block of file/transmission?

◆ setDictionaryBit

#define setDictionaryBit (   a)    ((a)[EV_HD_VER] |= EV_DICTIONARY_MASK)

Turn on 9th bit to indicate dictionary included in block.

◆ setLastBlockBit

#define setLastBlockBit (   a)    ((a)[EV_HD_VER] |= EV_LASTBLOCK_MASK)

Turn on bit to indicate last block of file/transmission.

Function Documentation

◆ evFileStructInit()

void evFileStructInit ( EVFILE a)

Routine to intialize an EVFILE structure for writing.

If reading, relevant stuff gets overwritten anyway.

Parameters
apointer to structure being inititalized

References evfilestruct::append, evfilestruct::baseFileName, evfilestruct::bigEndian, evfilestruct::blkEvCount, evfilestruct::blkEvMax, evfilestruct::blknum, evfilestruct::blkNumDiff, evfilestruct::blksiz, evfilestruct::blkSizeTarget, evfilestruct::blocksToParse, evfilestruct::buf, evfilestruct::bufRealSize, evfilestruct::bufSize, evfilestruct::byte_swapped, evfilestruct::bytesToBuf, evfilestruct::bytesToDataBuf, evfilestruct::bytesToFile, evfilestruct::commonBlkCount, evfilestruct::curRecordIndexArrayLen, evfilestruct::curRecordUserHeaderLen, evfilestruct::currentHeader, evfilestruct::dataBuf, evfilestruct::dataLeft, evfilestruct::dataNext, evfilestruct::dictBuf, evfilestruct::dictionary, evfilestruct::dictLength, EV_BLOCKSIZE, EV_EVENTS_MAX_DEF, EV_HDSIZ, EV_HDSIZ_BYTES, EV_HDSIZ_BYTES_V6, EV_HDSIZ_V6, EV_MAGIC, EV_SPLIT_SIZE, EV_VERSION, evfilestruct::eventCount, evfilestruct::eventLengths, evfilestruct::eventLengthsLen, evfilestruct::eventsToBuf, evfilestruct::eventsToFile, evioIsLocalHostBigEndian(), evfilestruct::file, evfilestruct::fileIndexArrayLen, evfilestruct::fileName, evfilestruct::filePosition, evfilestruct::fileSize, evfilestruct::fileUserHeaderLen, evfilestruct::firstEventBuf, evfilestruct::firstEventLength, evfilestruct::handle, evfilestruct::hasAppendDictionary, evfilestruct::isLastBlock, evfilestruct::lastEmptyBlockHeaderExists, evfilestruct::left, evfilestruct::lockingOn, evfilestruct::magic, evfilestruct::mmapFile, evfilestruct::mmapFileSize, evfilestruct::next, evfilestruct::pBuf, evfilestruct::pTable, evfilestruct::randomAccess, evfilestruct::runNumber, evfilestruct::runType, evfilestruct::rw, evfilestruct::rwBuf, evfilestruct::rwBufSize, evfilestruct::rwBytesIn, evfilestruct::rwBytesOut, evfilestruct::rwFirstWrite, evfilestruct::sockFd, evfilestruct::specifierCount, evfilestruct::split, evfilestruct::splitNumber, evfilestruct::splitting, evfilestruct::streamCount, evfilestruct::streamId, evfilestruct::trailerPosition, evfilestruct::version, and evfilestruct::wroteDictionary.

Referenced by evOpenFake().

◆ evGenerateBaseFileName()

int evGenerateBaseFileName ( const char *  origName,
char **  baseName,
int *  count 
)

This routine generates a (base) file name from a name containing format specifiers and enviromental variables.

The file name may contain characters of the form $(ENV_VAR) which will be substituted with the value of the associated environmental variable or a blank string if none is found.

The given name may contain up to 3, C-style integer format specifiers (such as %03d, or x). If more than 3 are found, an error is returned. If no "0" precedes any integer between the "%" and the "d" or "x" of the format specifier, it will be added automatically in order to avoid spaces in the final, generated file name.

See the doc for evGenerateFileName. The details of what is substituted for the int specifiers is given there.

Parameters
origNamefile name to modify
baseNamepointer which gets filled with resulting file name
countpointer to int filled with number of format specifiers found
Returns
S_SUCCESS if successful
S_FAILURE if bad format specifiers or more that 3 specifiers found
S_EVFILE_BADARG if args are null or origName is invalid
S_EVFILE_ALLOCFAIL if out-of-memory

References evStrFindSpecifiers(), evStrReplaceEnvVar(), S_EVFILE_ALLOCFAIL, S_EVFILE_BADARG, S_FAILURE, and S_SUCCESS.

◆ evGenerateFileName()

char* evGenerateFileName ( EVFILE a,
int  specifierCount,
uint32_t  runNumber,
int  splitting,
uint32_t  splitNumber,
char *  runType,
uint32_t  streamId,
uint32_t  streamCount,
int  debug 
)

This method generates a complete file name from the previously determined baseFileName obtained from calling evGenerateBaseFileName(char *, char **, int *) and stored in the evOpen handle.

All occurrences of the string "%s" in the baseFileName will be substituted with the value of the runType arg or nothing if the runType is null.

The given fileName may contain up to 3, C-style int format specifiers which will be substituted with runNumber, splitNumber and streamId in the manner described below.

  • If file is to be split:

    • If no specifiers:
      • for one stream, splitNumber is tacked onto the end of the file name as .<splitNumber>
      • for multiple streams, streamId and splitNumber are tacked onto the end of the file name as .<streamId>.<splitNumber>
      • No run numbers are ever tacked on without a specifier
    • If 1 specifier:
      • add runNumber according to specifier
      • for one stream, splitNumber is tacked onto the end of the file name as .<splitNumber>
      • for multiple streams, streamId and splitNumber are tacked onto the end of the file name as .<streamId>.<splitNumber>
    • If 2 specifiers:
      • add runNumber according to first specifier
      • for one stream, add splitNumber according to second specifier
      • for multiple streams, add splitNumber according to second specifier, but place <streamId>. just before the splitNumber
    • If 3 specifiers:
      • add runNumber according to first specifier, streamId according to second specifier, and splitNumber according to third specifier

  • If file is NOT split:
    • If no specifiers:
      • streamId is tacked onto the end of the file name as .<streamId>
      • No run numbers are ever tacked on without a specifier.
    • If 1 specifier:
      • add runNumber according to specifier
      • for multiple streams, streamId is tacked onto the end of the file name as ..<streamId>
    • If 2 specifiers:
      • add runNumber according to first specifier
      • remove second specifier
      • for multiple streams, streamId is tacked onto the end of the file name as .<streamId>
    • If 3 specifiers:
      • add runNumber according to first specifier
      • add streamId according to second specifier
      • remove third specifier

If there are more than 3 specifiers, NO SUBSTITUTIONS ARE DONE on the extra specifiers.

Parameters
aevio handle (contains file name to use as a basis for the generated file name)
specifierCountnumber of C-style int format specifiers in file name arg
runNumberCODA run number
splittingis file being split (split > 0)? 1 - yes, 0 - no
splitNumbernumber of the split file
runTyperun type name
streamIdstreamId number (100 > id > -1)
streamCounttotal number of streams in DAQ (100 > id > 0)
debugif = 0, no debug output
Returns
NULL if error
generated file name (free if non-NULL)

If we're not splitting files, then CODA isn't being used and stream id is probably meaningless.

◆ evGenerateFileNameOld()

char* evGenerateFileNameOld ( EVFILE a,
int  specifierCount,
int  runNumber,
int  splitting,
int  splitNumber,
char *  runType,
uint32_t  streamId 
)

This method generates a complete file name from the previously determined baseFileName obtained from calling evGenerateBaseFileName(char *, char **, int *) and stored in the evOpen handle.

All occurrences of the string "%s" in the baseFileName will be substituted with the value of the runType arg or nothing if the runType is null.

If evio data is to be split up into multiple files (split > 0), numbers are used to distinguish between the split files with splitNumber. If baseFileName contains C-style int format specifiers (specifierCount > 0), then the first occurrence will be substituted with the given runNumber value. If the file is being split, the second will be substituted with the splitNumber. If 2 specifiers exist and the file is not being split, no substitutions are made. If no specifier for the splitNumber exists, it is tacked onto the end of the file name. It returns the final file name or NULL if error. Free the result if non-NULL.

If multiple streams of data, each writing a file, end up with the same file name, they can be differentiated by a stream id number. If the id is > 0, the string, ".strm" is appended to the very end of the file followed by the id number (e.g. filename.strm1). This is done after the run type, run number, split numbers, and env vars have been inserted into the file name.

Parameters
aevio handle (contains file name to use as a basis for the generated file name)
specifierCountnumber of C-style int format specifiers in file name arg
runNumberCODA run number
splittingis file being split (split > 0)? 1 - yes, 0 - no
splitNumbernumber of the split file
runTyperun type name
streamIdstreamId number (100 > id > -1)
Returns
NULL if error
generated file name (free if non-NULL)

References evfilestruct::baseFileName, EV_WRITEFILE, evStrRemoveSpecifiers(), evStrReplace(), and evfilestruct::rw.

◆ evIsLastBlock()

int evIsLastBlock ( uint32_t  sixthWord)

Routine to take the 6th word of a block header and tell whether it's the last block or not.

Parameters
sixthWord6th word of an evio block header
Returns
1 of this is the last block, else 0

References EV_LASTBLOCK_MASK.

◆ evOpenFake()

int evOpenFake ( char *  filename,
char *  flags,
int *  handle,
char **  evf 
)

For test purposes only ...

References evFileStructInit().

◆ evPrintBuffer()

void evPrintBuffer ( uint32_t p,
uint32_t  len,
int  swap 
)

Routine to print the contents of a buffer.

Parameters
ppointer to buffer
lennumber of 32-bit words to print out
swapswap if true

References EVIO_SWAP32.

◆ evStrFindSpecifiers()

char* evStrFindSpecifiers ( const char *  orig,
int *  specifierCount 
)

This routine checks a string for C-style printing integer format specifiers.

More specifically, it checks for nd and nx where n can be multiple digits. It makes sure that there is at least one digit between % and x/d and that the first digit is a "0" so that generated filenames contain no white space. It returns the modified string or NULL if error. Free the result if non-NULL. It also returns the number of valid specifiers found in the orig argument.

Parameters
origstring to be checked/modified
specifierCountpointer to int which gets filled with the number of valid format specifiers in the orig arg
Returns
resulting string which is NULL if there is a problem and needs to be freed if not NULL.

Referenced by evGenerateBaseFileName().

◆ evStrInsertBeforeSpecifier()

int evStrInsertBeforeSpecifier ( char *  str,
uint32_t  n,
const char *  insert,
char *  result,
size_t  result_size 
)

Inserts a string just before the first occurrence of a format specifier that starts with '' and ends with a conversion specifier of 'd' or 'x'.

The existing format specifier can include flags made of ints indicating width (ie %03x). This function partly courtesy of ChatGPT. Remember, when this is called, the substitution for s with runType will have already been made.

Parameters
strstring to scan
nnumber of "%"s to skip over before making the insert
insertstring to insert before the int specifier
resultresulting string
result_sizesize of result string
Returns
1 if specifier successfully inserted, 0 if nothing done, -1 if result is too small. If 1 is not returned, result is not written into.

◆ evStrRemoveSpecifiers()

char* evStrRemoveSpecifiers ( const char *  orig,
int  skip 
)

This routine checks a string for C-style printing integer format specifiers.

More specifically, it checks for nd and nx where n can be multiple digits. It removes all such specifiers and returns the modified string or NULL if error. Skips over given # of int specifiers. Free the result if non-NULL.

Parameters
origstring to be checked/modified
skip# of int specifiers to skip
Returns
resulting string which is NULL if there is a problem and needs to be freed if not NULL.

How many int specifiers skipped so far.

Referenced by evGenerateFileNameOld().

◆ evStrReplace()

char* evStrReplace ( char *  orig,
const char *  replace,
const char *  with 
)

This routine substitutes a given string for a specified substring.

Free the result if non-NULL.

Parameters
origstring to modify
replacesubstring in orig arg to replace
withstring to substitute for replace arg
Returns
resulting string which is NULL if there is a problem and needs to be freed if not NULL.

Referenced by evGenerateFileNameOld(), and evStrReplaceEnvVar().

◆ evStrReplaceEnvVar()

char* evStrReplaceEnvVar ( const char *  orig)

This routine finds constructs of the form and replaces it with the value of the ENV environmental variable if it exists or with nothing if it doesn't.

Simple enough to do without regular expressions. Free the result if non-NULL.

Parameters
origstring to modify
Returns
resulting string which is NULL if there is a problem and needs to be freed if not NULL.

References evStrReplace().

Referenced by evGenerateBaseFileName().

Variable Documentation

◆ handleList

EVFILE** handleList = NULL

Array that holds all pointers to structures created with evOpen().

Space in the array is allocated as needed, beginning with 100 and adding 50% every time more are needed.