00001 #include "RootIOSvc/RootInputStream.h"
00002 #include "RootIOSvc/RootInputFile.h"
00003
00004 RootInputStream::RootInputStream(void* addr,
00005 const std::string& treepath,
00006 const std::string& branchname)
00007 : RootIOStream(addr)
00008 , m_files()
00009 , m_entry(-1)
00010 , m_clid(0)
00011 , m_entries(-1)
00012 , m_treepath(treepath)
00013 , m_branchname(branchname)
00014 , log("RootInputStream")
00015 {
00016 }
00017
00018
00019 RootInputStream::~RootInputStream()
00020 {
00021
00022 }
00023
00024 int RootInputStream::clID()
00025 {
00026 return m_clid;
00027 }
00028
00029 std::string RootInputStream::path()
00030 {
00031 return m_treepath;
00032 }
00033
00034 std::string RootInputStream::filename()
00035 {
00036 RootInputFile* rif = m_files.current();
00037 if (rif) return rif->filename();
00038 return "";
00039 }
00040
00041 int RootInputStream::fileNumber()
00042 {
00043 return m_files.index();
00044 }
00045
00046 bool RootInputStream::append(const std::string& filename)
00047 {
00048 if ("" == m_treepath || "" == m_branchname) {
00049 log << MSG::ERROR << "Can not guess tree path or branch name for "
00050 << filename << endreq;
00051 return false;
00052 }
00053
00054 int clid = RootInputFile::TestForObject(filename,m_treepath,m_branchname);
00055 if (!clid || (m_clid && clid != m_clid)) {
00056 log << MSG::ERROR << "Bad class ID from new file " << filename
00057 << " got " << clid << " (had " << m_clid << ")"
00058 << endreq;
00059 return false;
00060 }
00061 m_clid = clid;
00062
00063 m_files.push_back(new RootInputFile(filename,m_treepath,m_branchname));
00064 if (1 == m_files.size()) {
00065 m_files.next();
00066 }
00067 return true;
00068 }
00069
00070 bool RootInputStream::append(const std::string& filename,
00071 const std::string& treepath,
00072 const std::string& branchname)
00073 {
00074 if ("" != m_treepath) m_treepath = treepath;
00075 if ("" != m_branchname) m_branchname = branchname;
00076
00077 return append(filename);
00078 }
00079
00080
00081 bool RootInputStream::read()
00082 {
00083 RootInputFile* rif = m_files.current();
00084 if (!rif) {
00085 log << MSG::ERROR << "No current file" << endreq;
00086 return false;
00087 }
00088
00089 int nbytes = 0;
00090 bool ok = rif->read(m_addr,nbytes);
00091 log << MSG::DEBUG << "read() " << nbytes
00092 << " bytes at entry " << m_entry
00093 << " from file \"" << rif->filename()
00094 << "\" to path \"" << this->path()
00095 << endreq;
00096 return ok;
00097 }
00098
00099 bool RootInputStream::setEntry(int entry, bool read)
00100 {
00101 int steps = entry - m_entry;
00102 log << MSG::DEBUG << "setEntry(entry="<<entry<<",read="<<read<<") steps = " << steps
00103 << " (stream=\"" << this->path() << "\")"
00104 << endreq;
00105 if (steps < 0) return prev(-steps, read);
00106 if (steps > 0) return next(steps, read);
00107 return true;
00108 }
00109
00110 bool RootInputStream::setFileEntry(int file, int entry, bool read)
00111 {
00112 if (!m_files.jump(file)) {
00113 log << MSG::ERROR
00114 << "jump("<<file<<"): failed"
00115 << endreq;
00116 return false;
00117 }
00118 RootInputFile* rif = m_files.current();
00119 if (!rif) {
00120 log << MSG::ERROR << "Failed to get current file #" << file << endreq;
00121 return false;
00122 }
00123 if (!rif->setEntry(entry)) {
00124 log << MSG::ERROR << "Failed to set entry " << entry << " on file #" << file << endreq;
00125 return false;
00126 }
00127
00129 int totEntries = m_files.entriesBefore(file);
00130 if (totEntries < 0) {
00131 log << MSG::ERROR << "Failed to get sane number of entries before file#" << file << endreq;
00132 return false;
00133 }
00134 m_entry = totEntries + entry;
00135 log << MSG::DEBUG << "setFileEntry(file="<<file<<",entry="<<entry<<",read="<<read<<") "
00136 << "totEntries=" << totEntries <<" m_entry=" << m_entry
00137 << " (stream=\"" << this->path()
00138 << "\", filename=\"" << rif->filename() << "\")"
00139 << endreq;
00140
00141 if (read) return this->read();
00142 return true;
00143
00144 }
00145
00146 bool RootInputStream::next(int nsteps, bool read)
00147 {
00148 RootInputFile* rif = m_files.current();
00149
00150 if (!rif) {
00151 log << MSG::ERROR << "No files" << endreq;
00152 return false;
00153 }
00154
00155 log << MSG::DEBUG << "next(nsteps="<<nsteps<<",read="<<read<<")"
00156 << " (stream=\"" << this->path() << "\")"
00157 << endreq;
00158
00159 while (nsteps) {
00160
00161
00162 if (rif->entry() + nsteps >= rif->entries()) {
00163
00164
00165 int jump = rif->entries() - (rif->entry() + 1);
00166 nsteps -= jump;
00167 m_entry += jump;
00168 if (!m_files.next()) {
00169 log << MSG::INFO
00170 << "next(): no more files to go to next:"
00171 << " jump = " << jump
00172 << " nsteps = " << nsteps
00173 << " entry = " << m_entry
00174 << " tentries=" << rif->entries() << endreq;
00175 return false;
00176 }
00177 rif = m_files.current();
00178 continue;
00179 }
00180
00181
00182 rif->next(nsteps);
00183 m_entry += nsteps;
00184 nsteps = 0;
00185 break;
00186 }
00187 log << MSG::DEBUG << "next(): at stream entry " << m_entry
00188 << " (file: " << rif->filename() << " file entry: " << rif->entry() << ")"
00189 << " (stream=\"" << this->path() << "\")"
00190 << endreq;
00191 if (read) return this->read();
00192 return true;
00193 }
00194
00195 bool RootInputStream::prev(int nsteps, bool read)
00196 {
00197 RootInputFile* rif = m_files.current();
00198 if (!rif) {
00199 log << MSG::ERROR << "No files yet, cannot go prev" << endreq;
00200 return false;
00201 }
00202
00203 log << MSG::DEBUG << "prev(nsteps="<<nsteps<<",read="<<read<<")"
00204 << " (stream=\"" << this->path() << "\")"
00205 << endreq;
00206
00207 while (nsteps) {
00208
00209
00210 if (rif->entry()-nsteps < 0) {
00211
00212
00213 int jump = 1 + rif->entry();
00214 nsteps -= jump;
00215 m_entry -= jump;
00216 if (!m_files.prev()) {
00217 log << MSG::ERROR << "Already at first file, cannot go prev"
00218 << endreq;
00219 return false;
00220 }
00221 rif = m_files.current();
00222 rif->ending();
00223 continue;
00224 }
00225
00226
00227 rif->prev(nsteps);
00228 m_entry -= nsteps;
00229 nsteps = 0;
00230 break;
00231 }
00232
00233 log << MSG::DEBUG << "prev(): at stream entry " << m_entry
00234 << " (file: " << rif->filename() << " file entry: " << rif->entry() << ")"
00235 << " (stream=\"" << this->path() << "\")"
00236 << endreq;
00237
00238 if (read) return this->read();
00239 return true;
00240 }
00241
00242
00243 bool RootInputStream::first(bool read)
00244 {
00245 bool okay = m_files.first();
00246 if (!okay) {
00247 log << MSG::ERROR << "first(): failed to go to first file in stream"
00248 << endreq;
00249 return false;
00250 }
00251
00252 RootInputFile* rif = m_files.current();
00253 if (!rif) {
00254 log << MSG::ERROR << "first(): failed to get current file in stream"
00255 << endreq;
00256 return false;
00257 }
00258
00259 okay = rif->beginning();
00260 if (!okay) return false;
00261
00262 if (read) return this->read();
00263 return true;
00264 }
00265
00266
00267 bool RootInputStream::last(bool read)
00268 {
00269 bool okay = m_files.last();
00270 if (!okay) {
00271 log << MSG::ERROR << "last(): failed to go to last file in stream"
00272 << endreq;
00273 return false;
00274 }
00275
00276 RootInputFile* rif = m_files.current();
00277 if (!rif) {
00278 log << MSG::ERROR << "last(): failed to get current file in stream"
00279 << endreq;
00280 return false;
00281 }
00282
00283 okay = rif->ending();
00284 if (!okay) return false;
00285
00286 if (read) return this->read();
00287 return true;
00288 }
00289
00290 int RootInputStream::entries()
00291 {
00292 if( m_entries>=0 ) {
00293 return m_entries;
00294 } else {
00295 m_entries=0;
00296 RootInputFileList::iterator it,itend = m_files.end();
00297 for( it=m_files.begin(); it!=itend; it++ ) {
00298 m_entries+= (*it)->entries();
00299 }
00300 return m_entries;
00301 }
00302 }