00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "FileReadoutFormat/MetadataStrings.h"
00010
00011 #include "FileReadoutFormat/FileTraits.h"
00012 #include <cstring>
00013
00014 using DybDaq::ByteBuffer;
00015 using DybDaq::FileTraits;
00016 using DybDaq::MetadataStrings;
00017 using std::pair;
00018 using std::string;
00019 using std::vector;
00020
00021 MetadataStrings::MetadataStrings(const MetadataStringPtrList& metadataStrings,
00022 const FileTraits& traits) :
00023 FileBuffer(new char[traits.recordSize(FileTraits::kMetadataStrings) * kBytesInInt],
00024 traits,
00025 FileTraits::kMetadataStrings),
00026 m_strings(0),
00027 m_stringBuffer(0) {
00028 setMetadataStrings(metadataStrings);
00029 }
00030
00031 MetadataStrings::MetadataStrings(const ByteBuffer& byteBuffer,
00032 const FileTraits& traits) :
00033 FileBuffer(byteBuffer,
00034 traits),
00035 m_strings(0),
00036 m_stringBuffer(0) {
00037 }
00038
00039 MetadataStrings::~MetadataStrings() {
00040 if (0 != m_stringBuffer) {
00041 delete m_stringBuffer;
00042 }
00043 if (0 != m_strings) {
00044 MetadataStringPtrList::const_iterator entry;
00045 for (entry = m_strings->begin();
00046 entry != m_strings->end();
00047 ++entry) {
00048 delete const_cast<MetadataString*>(*entry);
00049 }
00050 delete m_strings;
00051 }
00052 }
00053
00054 bool MetadataStrings::isMarked(unsigned int marker) const {
00055 return FileTraits::kMetadataStrings == marker;
00056 }
00057
00058 const MetadataStrings::MetadataStringPtrList& MetadataStrings::metadataStrings() const {
00059 if (0 == m_strings) {
00060 m_strings = new MetadataStringPtrList();
00061 const unsigned int finished = readUnsignedInt(FileTraits::kMetadataCount);
00062 const char* start;
00063 if (hasByteBuffer()) {
00064 start = buffer() + (fileTraits().firstMetadataLengthOffset() * kBytesInInt);
00065 } else {
00066 start = m_stringBuffer;
00067 }
00068 for (unsigned int metadata = 0;
00069 metadata != finished ;
00070 ++metadata) {
00071 string entry = readString(start);
00072 const unsigned int length = entry.size();
00073 const unsigned int paddedLength = length + (kBytesInInt - 1) - ((length - 1) % kBytesInInt );
00074 start += paddedLength + kBytesInInt;
00075 size_t found = entry.find('=');
00076 if (found != string::npos) {
00077 string first = entry.substr(0,
00078 found);
00079 string second = entry.substr(found + 1, length - (found + 1));
00080 m_strings->push_back(new MetadataString(first,
00081 second));
00082 }
00083 }
00084 }
00085 return *m_strings;
00086 }
00087
00088 unsigned int MetadataStrings::gather(OutputBufferList& outputBuffers) const {
00089 if (hasByteBuffer()) {
00090 return FileBuffer::gather(outputBuffers);
00091 }
00092 const unsigned int fixedLength = fileTraits().recordSize(FileTraits::kMetadataStrings) * kBytesInInt;
00093 outputBuffers.push_back(OutputBuffer(buffer(),
00094 fixedLength));
00095 unsigned int stringsLength = (size() * kBytesInInt) - fixedLength;
00096 outputBuffers.push_back(OutputBuffer(m_stringBuffer,
00097 stringsLength));
00098 return fixedLength + stringsLength;
00099 }
00100
00101 unsigned int MetadataStrings::formatComponent() const {
00102 return FileTraits::kMetadataStrings;
00103 }
00104
00105 void MetadataStrings::setMetadataStrings(const MetadataStringPtrList& metadataStrings) {
00106 if (0 != m_stringBuffer) {
00107 delete m_stringBuffer;
00108 }
00109 unsigned int stringsLength = calculateStringsLength(metadataStrings);
00110 setSize(fileTraits().recordSize(FileTraits::kMetadataStrings) + (stringsLength / kBytesInInt));
00111 m_stringBuffer = new char[stringsLength];
00112 char* start = m_stringBuffer;
00113 MetadataStrings::MetadataStringPtrList::const_iterator metadata;
00114 for (metadata = metadataStrings.begin();
00115 metadata != metadataStrings.end();
00116 ++metadata) {
00117 const string entry = (*metadata)->first + "=" + (*metadata)->second;
00118 start += writeString(entry,
00119 start);
00120 }
00121 writeField((unsigned int)(metadataStrings.size()),
00122 FileTraits::kMetadataCount);
00123 if (0 != m_strings) {
00124 delete m_strings;
00125 m_strings = 0;
00126 }
00127 }
00128
00129 string MetadataStrings::readString(const char* buffer) {
00130 unsigned int length = *((unsigned int*)(buffer));
00131 char* base = new char[length + 1];
00132 memcpy(base,
00133 buffer + kBytesInInt,
00134 length);
00135 base[length] = 0;
00136 string result(base);
00137 delete base;
00138 return result;
00139 }
00140
00141 unsigned int MetadataStrings::calculateStringsLength(const MetadataStringPtrList& metadataStrings) {
00142 unsigned int result = 0;
00143 MetadataStrings::MetadataStringPtrList::const_iterator metadata;
00144 for (metadata = metadataStrings.begin();
00145 metadata != metadataStrings.end();
00146 ++metadata) {
00147 const string entry = (*metadata)->first + "=" + (*metadata)->second;
00148 const unsigned int length = entry.size();
00149 const unsigned int paddedLength = length + (kBytesInInt - 1) - ((length - 1) % kBytesInInt );
00150 result += paddedLength + kBytesInInt;
00151 }
00152 return result;
00153 }
00154
00155 unsigned int MetadataStrings::writeString(const string& value,
00156 char* buffer) {
00157 unsigned int length = value.size();
00158 char* start = buffer;
00159 *((unsigned int*)(start)) = length;
00160 start += kBytesInInt;
00161 memcpy(start,
00162 value.data(),
00163 length);
00164 unsigned int padding = (kBytesInInt - 1) - ((length - 1) % kBytesInInt );
00165 start += length;
00166 for (unsigned int index = 0;
00167 index != padding;
00168 ++index) {
00169 *start = ' ';
00170 ++start;
00171 }
00172 return kBytesInInt + length + padding;
00173 }