Hall A ROOT/C++ Analyzer (podd)
Loading...
Searching...
No Matches
THaUsrstrutils.cxx
Go to the documentation of this file.
1
2//
3// R. Michaels, March 2000
4// Updated string_from_buffer, May 2007/
5// THaUsrstrutils = USeR STRing UTILitieS.
6// The code below is what is used by DAQ to interpret strings
7// like prescale factors
8// Yes, this is mostly old-style C, but it
9// has the advantage that the interpretation should
10// be identical to what the DAQ used.
11//
13
14#include "THaUsrstrutils.h"
15#include <cctype> // for isspace
16#include <cstring>
17#include <cstdio>
18#include <cstdlib>
19#include <algorithm> // find_if_not
20#include <iterator> // for std::distance
21#include <iostream>
22
23using namespace std;
24
25namespace Decoder {
26
27static const int BUFLEN=256;
28
29int THaUsrstrutils::getflag(const char *s) const
30{
31 const char *pos,*val;
32
33 getflagpos(s,&pos,&val);
34 if(!pos) return(0);
35 if(!val) return(1);
36 return(2);
37}
38
39char* THaUsrstrutils::getstr(const char *s) const
40{
41 const char *pos,*val;
42
43 getflagpos(s,&pos,&val);
44 if(!val){
45 return nullptr;
46 }
47 const char* end = strchr(val,','); /* value string ends at next keyword */
48 size_t slen = (end) ? end - val
49 : strlen(val); /* No more keywords, value is rest of string */
50 char* ret = new char[slen+1];
51 strncpy(ret,val,slen);
52 ret[slen] = '\0';
53 return(ret);
54}
55
56unsigned int THaUsrstrutils::getint(const char *s) const
57{
58 char* sval = getstr(s);
59 if(!sval) return(0); /* Just return zero if no value string */
60 long retval = strtol(sval,nullptr,0);
61 if( retval < 0 || retval > kMaxUInt )
62 retval = 0; /* Return zero if out of range of unsigned int */
63 delete [] sval;
64 return(retval);
65}
66
67long THaUsrstrutils::getSignedInt(const char *s) const
68{
69 char* sval = getstr(s);
70 if(!sval) return(-1); /* Return -1 if no value string */
71 long retval = strtol(sval,nullptr,0);
72 delete [] sval;
73 return(retval);
74}
75
76void THaUsrstrutils::getflagpos_instring( const char* confstr,
77 const char* s,
78 const char** pos_ret,
79 const char** val_ret )
80{
81 size_t slen = strlen(s);
82 const char *pos = confstr;
83 *val_ret = nullptr;
84
85 while(pos) {
86 pos = strstr(pos,s);
87 if(pos) {
88 /* Make sure it is an isolated keyword */
89 if((pos != confstr && pos[-1] != ',') ||
90 (pos[slen] != '=' && pos[slen] != ',' && pos[slen] != '\0')) {
91 pos++; continue;
92 } else break; /* It's good */
93 }
94 }
95 *pos_ret = pos;
96 if( pos && pos[slen] == '=' ) {
97 *val_ret = pos + slen + 1;
98 }
99}
100
102{
103// Routine string_from_evbuffer loads the configstr from the event buffer.
104// It has the same strengths and weaknesses as the DAQ code,
105// hence the interpretation should be the same.
106//
107// nlen is the length of the string data (from CODA) in longwords (4 bytes)
108//
109// R. Michaels, updated to make the algorithm closely resemble the
110// usrstrutils.c used by trigger supervisor.
111// O. Hansen, converted the C code to C++, painstakingly preserving the
112// original algorithm.
113
114 // The following could be written in C without requiring any new memory
115 // allocations, albeit it would be much less readable and more error-prone
116
117 // Copy the entire input buffer to a std::string, which is safe even if the
118 // buffer isn't null-terminated. This usually costs less than 500 bytes.
119 string strbuff(reinterpret_cast<const char*>(evbuffer), sizeof(UInt_t) * nlen);
120
121 // Remove trailing zero padding, if any
122 string::size_type pos = strbuff.find('\0');
123 if( pos != string::npos )
124 strbuff.erase(pos);
125
126 #ifdef USRSTRDEBUG
127 cout << "Check THaUsrstrutils::string_from_buffer "<<endl;
128 cout << "strbuff length "<<strbuff.length()<<endl;
129 cout << "strbuff == \n"<<strbuff<<endl<<endl;
130#endif
131
132 configstr.clear();
133
134// In order to make this as nearly identical to the online VME code,
135// we unpack the buffer into lines separated by '\n'.
136// This is like the reading of the prescale.dat file done
137// by fgets(s,255,fd) in usrstrutils.c
138// For each line, we extract the configuration strings using the same
139// algorithm as in usrstrutils.c
140 pos = 0;
141 string::size_type buflen = strbuff.length();
142 while( pos < buflen ) {
143 // Inspect each line until an uncommented, non-empty line is found
144 string::size_type pos1 = strbuff.find('\n', pos);
145#ifdef USRSTRDEBUG
146 cout << "strbuff parse pos,pos1,line=" << pos << "," << pos1
147 << ",\"" << strbuff.substr(pos, pos1 - pos) << "\"" << endl;
148#endif
149 string sline = strbuff.substr(pos, pos1 - pos);
150 // Skip lines starting with a comment character
151 auto p = sline.find(COMMENT_CHAR);
152 if( p > 0 ) {
153 // Blow away trailing comments
154 if( p != string::npos )
155 sline.erase(p);
156 // Skip leading whitespace using isspace(), like the C version does
157 auto it = find_if_not(sline.begin(), sline.end(),
158 static_cast<int(*)(int)>(isspace));
159 if( it != sline.end() ) {
160 // We have a config string
161 auto textstart = distance(sline.begin(), it);
162 configstr = sline.substr(textstart);
163 break;
164 }
165 }
166 if( pos1 == string::npos )
167 // Last line did not end with \n
168 break;
169 pos = pos1 + 1;
170 }
171#ifdef USRSTRDEBUG
172 cout << "configstr = " << configstr << endl;
173#endif
174}
175
176// This routine reads a file to load file_configustr.
177// It is like what is used by the DAQ code to load prescale factors, etc.
178
179void THaUsrstrutils::string_from_file(const char *ffile_name)
180{
181 /* check that filename exists */
182 configstr.clear();
183 FILE* fd = fopen(ffile_name,"r");
184 if(fd == nullptr) {
185 cerr << "Failed to open usr flag file " << ffile_name << endl;
186 return;
187 }
188 /* Read till an uncommented line is found */
189 char buf[BUFLEN];
190 char* flag_line = nullptr;
191 while( fgets(buf, BUFLEN, fd) ) {
192 char* arg = strchr(buf, COMMENT_CHAR);
193 if( arg ) *arg = '\0'; /* Blow away comments */
194 arg = buf; /* Skip whitespace */
195 while( *arg && isspace(*arg) ) {
196 arg++;
197 }
198 if( *arg ) {
199 flag_line = arg;
200 break;
201 }
202 }
203 if( flag_line ) { /* We have a config string */
204 configstr = string(flag_line);
205#ifdef USRSTRDEBUG
206 cout << "configstr = " << configstr << endl;
207#endif
208 }
209 fclose(fd);
210}
211
212}
213
215
unsigned int UInt_t
const UInt_t kMaxUInt
winID h TVirtualViewer3D TVirtualGLPainter p
#define COMMENT_CHAR
char * getstr(const char *s) const
void string_from_evbuffer(const UInt_t *evbuffer, UInt_t nlen)
long getSignedInt(const char *s) const
unsigned int getint(const char *s) const
int getflag(const char *s) const
void getflagpos(const char *s, const char **pos_ret, const char **val_ret) const
static void getflagpos_instring(const char *confstr, const char *s, const char **pos_ret, const char **val_ret)
void string_from_file(const char *ffile_name)
static const int BUFLEN
end
STL namespace.
ClassImp(TPyArg)