8 #include "Alignment/Geners/interface/BinaryArchiveBase.hh"
9 #include "Alignment/Geners/interface/CatalogIO.hh"
10 #include "Alignment/Geners/interface/binaryIO.hh"
12 #ifdef GENERS_BINARY_ARCHIVE_FORMAT_ID
13 #undef GENERS_BINARY_ARCHIVE_FORMAT_ID
15 #define GENERS_BINARY_ARCHIVE_FORMAT_ID (0x1f2e3d4c)
20 const unsigned long value = strtoul(
c, &endptr, 0);
21 if (errno || *endptr !=
'\0') {
22 err <<
"expected an unsigned integer, got \"" <<
c <<
'"';
24 err <<
", " << strerror(errno);
27 if (
value > UINT_MAX) {
28 err <<
"unsigned value \"" <<
c <<
"\" is out of range";
38 const long value = strtol(
c, &endptr, 0);
39 if (errno || *endptr !=
'\0') {
40 err <<
"expected an integer, got \"" <<
c <<
'"';
42 err <<
", " << strerror(errno);
45 if (value < INT_MIN || value > INT_MAX) {
46 err <<
"integer value \"" <<
c <<
"\" is out of range";
54 BinaryArchiveBase::BinaryArchiveBase(
const char *
name,
const char *
mode)
56 mode_(parseMode(
mode)),
57 errorStream_(nullptr),
60 storedEntryId_(nullptr),
61 storedLocationId_(nullptr),
63 addCatalogToData_(
false) {
64 CStringStream::CompressionMode
m = CStringStream::NOT_COMPRESSED;
66 unsigned minSizeToCompress = 1024
U;
67 unsigned bufSize = 1048576
U;
69 std::ostringstream
err;
75 errorStream() <<
"In BinaryArchiveBase constructor: "
76 <<
"invalid archive opening mode \"" <<
mode <<
'"';
79 errorStream() <<
": " << errInfo;
83 void BinaryArchiveBase::releaseClassIds() {
84 delete storedEntryId_;
85 storedEntryId_ =
nullptr;
86 delete storedLocationId_;
87 storedLocationId_ =
nullptr;
90 BinaryArchiveBase::~BinaryArchiveBase() {
102 const unsigned multiplex = addCatalogToData_ ? 1 : 0;
103 const unsigned sizeoflong =
sizeof(long);
104 const unsigned infoword = (sizeoflong << 1) | multiplex;
105 write_pod(os, infoword);
110 storedEntryId_ =
new ClassId(ClassId::makeId<CatalogEntry>());
111 storedEntryId_->write(os);
112 storedLocationId_ =
new ClassId(ClassId::makeId<ItemLocation>());
113 storedLocationId_->write(os);
119 is.seekg(0, std::ios_base::beg);
122 if (
format != expectedFormat)
125 unsigned infoword = 0xffffffff;
126 read_pod(is, &infoword);
127 const unsigned multiplex = infoword & 0x1
U;
128 const unsigned sizeoflong = infoword >> 1;
133 if (sizeoflong !=
sizeof(
long))
136 addCatalogToData_ = multiplex;
137 if (addCatalogToData_) {
139 storedEntryId_ =
new ClassId(is, 1);
140 storedLocationId_ =
new ClassId(is, 1);
146 const ClassId &entryId = ClassId::makeId<CatalogEntry>();
147 const ClassId &locId = ClassId::makeId<ItemLocation>();
148 if (entryId != *storedEntryId_ || locId != *storedLocationId_)
150 "In gs::BinaryArchiveBase::readHeader: this "
151 "archive can no longer be open for update as it was "
152 "created using an older version of I/O software");
158 void BinaryArchiveBase::openDataFile(std::fstream &
stream,
const char *
filename) {
165 throw IOOpeningFailure(
"gs::BinaryArchiveBase::openDataFile",
filename);
168 bool writeHead =
false;
172 else if (isEmptyFile(
stream))
181 "In gs::BinaryArchiveBase::openDataFile: "
182 "failed to write archive header to file \"";
185 throw IOWriteFailure(
e);
191 std::string e =
"In gs::BinaryArchiveBase::openDataFile: ";
193 e +=
"could not read archive header from file \"";
196 throw IOReadFailure(
e);
198 e +=
"no valid archive header in file \"";
201 throw IOInvalidData(
e);
207 void BinaryArchiveBase::setCatalog(AbsCatalog *
c) {
210 catalogIsSet_ =
true;
216 void BinaryArchiveBase::itemSearch(
const SearchSpecifier &namePattern,
217 const SearchSpecifier &categoryPattern,
218 std::vector<unsigned long long> *idsFound)
const {
220 catalog_->search(namePattern, categoryPattern, idsFound);
227 bool BinaryArchiveBase::parseArchiveOptions(std::ostringstream &
err,
229 CStringStream::CompressionMode *
m,
231 unsigned *minSizeToCompress,
233 bool *multiplexCatalog) {
239 char *
mode = const_cast<char *>(cmode.c_str());
242 for (
char *
opt = strtok(
mode,
":");
opt;
opt = strtok(
nullptr,
":"), ++cnt) {
246 char *eq = strchr(
opt,
'=');
250 while (isspace(*optname) && optname < eq)
253 err <<
"invalid binary archive option \"\"";
256 char *optend = eq - 1;
257 while (isspace(*optend))
263 char *optval = eq + 1;
264 while (*optval && isspace(*optval))
267 err <<
"invalid binary archive option value \"\"";
270 char *valend =
opt + strlen(
opt) - 1;
271 while (isspace(*valend))
275 if (strlen(optval) == 0) {
276 err <<
"invalid binary archive option value \"\"";
281 if (!strcasecmp(optname,
"z")) {
283 if (!CStringStream::getCompressionModeByName(optval,
m)) {
284 err <<
"invalid compression type \"" << optval <<
'"';
287 }
else if (!strcasecmp(optname,
"cl")) {
291 if (*compressionLevel < -1 || *compressionLevel > 9) {
292 err <<
"compression level is out of range";
295 }
else if (!strcasecmp(optname,
"cb")) {
299 }
else if (!strcasecmp(optname,
"cm")) {
303 }
else if (!strcasecmp(optname,
"cat")) {
305 if (optval[0] ==
'i' || optval[0] ==
'I')
306 *multiplexCatalog =
true;
307 else if (optval[0] ==
's' || optval[0] ==
'S')
308 *multiplexCatalog =
false;
310 err <<
"invalid catalog mode \"" << optval <<
'"';
315 err <<
"unrecognized binary archive option \"" << optname <<
'"';
319 err <<
"invalid binary archive option \"" <<
opt <<
'"';
326 std::ios_base::openmode BinaryArchiveBase::parseMode(
const char *
mode) {
327 std::ios_base::openmode
m = std::ios_base::binary;
329 const unsigned len = strlen(
mode);
330 for (
unsigned i = 0;
i < len; ++
i) {
335 else if (
mode[
i] ==
'w')
337 else if (
mode[
i] ==
'a')
339 else if (
mode[
i] ==
'+')
341 else if (
mode[
i] ==
':')
354 std::vector<unsigned long long> idlist;
356 const unsigned long nfound = idlist.size();
357 for (
unsigned long i = 0;
i <
nfound; ++
i) {
358 std::shared_ptr<const CatalogEntry> pentry = catalog_->retrieveEntry(idlist[
i]);
365 bool BinaryArchiveBase::isEmptyFile(std::fstream &
s) {
367 return s.tellg() == std::streampos(0);
370 std::istream &BinaryArchiveBase::inputStream(
const unsigned long long id,
long long *sz) {
371 unsigned long long length = 0;
372 unsigned compressionCode = 0;
373 std::istream &is = plainInputStream(
id, &compressionCode, &length);
374 if (cStream_->compressionMode() == CStringStream::NOT_COMPRESSED) {
379 cStream_->readCompressed(is, compressionCode, length);
381 std::streamoff off = cStream_->tellp();
388 std::ostream &BinaryArchiveBase::outputStream() {
return plainOutputStream(); }
390 std::ostream &BinaryArchiveBase::compressedStream(std::ostream &os) {
391 if (cStream_->compressionMode() == CStringStream::NOT_COMPRESSED)
395 cStream_->setSink(os);
400 unsigned BinaryArchiveBase::flushCompressedRecord(std::ostream &) {
401 CStringStream::CompressionMode
m = cStream_->compressionMode();
402 if (
m != CStringStream::NOT_COMPRESSED) {
404 m = cStream_->writeCompressed();
406 return static_cast<unsigned>(
m);