HeaderBase.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "Qt.h"
00024 #include "HeaderBase.h"
00025 #include "Imports.cpp"
00026
00028 HeaderBase::HeaderBase()
00029 : d_ptr (new Data)
00030 {
00031 }
00032
00034 HeaderBase::HeaderBase (Data *d)
00035 : d_ptr (d)
00036 {
00037 }
00038
00040 HeaderBase::~HeaderBase()
00041 {
00042 }
00043
00045 bool HeaderBase::operator== (const HeaderBase &other) const
00046 {
00047 return toRawBytes() == other.toRawBytes();
00048 }
00049
00051 bool HeaderBase::operator!= (const HeaderBase &other) const
00052 {
00053 return !operator== (other);
00054 }
00055
00057 auto_ptr <DataBase> HeaderBase::copy() const
00058 {
00059 return auto_ptr <DataBase> (new HeaderBase (*this));
00060 }
00061
00063
00073 bool HeaderBase::parse (const QByteArray &rawBytes)
00074 {
00075 auto_ptr <DataBase> tmpCopy = copy();
00076 HeaderBase &tempHeader = dynamic_cast <HeaderBase &> (*tmpCopy);
00077 if (tempHeader.doParse (rawBytes)) {
00078 *this = tempHeader;
00079 return true;
00080 } else {
00081 return false;
00082 }
00083 }
00084
00086
00101 QByteArray HeaderBase::toRawBytes() const
00102 {
00103 Q_SD (const Data);
00104 QByteArray ret = rawStartLine();
00105 foreach (const QByteArray &fieldName, d->orderedFieldList)
00106 ret += rawHeaderLine (fieldName);
00107 ret += "\r\n";
00108 return ret;
00109 }
00110
00112
00120 QByteArray HeaderBase::fieldValue (const QByteArray &fieldName) const
00121 {
00122 Q_SD (const Data);
00123 QByteArray nameLower = fieldName.toLower();
00124 if (!d->fieldValues.contains (nameLower))
00125 return QByteArray();
00126 else {
00127 QByteArray res;
00128 foreach (const QByteArray &value, d->fieldValues [nameLower])
00129 res += value + ", ";
00130 res.chop (2);
00131 return res;
00132 }
00133 }
00134
00136
00139 QList <QByteArray> HeaderBase::fields() const
00140 {
00141 Q_SD (const Data);
00142 return d->fieldValues.keys();
00143 }
00144
00146
00153 bool HeaderBase::hasField (const QByteArray &fieldName) const
00154 {
00155 Q_SD (const Data);
00156 return d->fieldValues.contains (fieldName.toLower());
00157 }
00158
00160
00166 QList <QByteArray> HeaderBase::fieldValues (const QByteArray &fieldName) const
00167 {
00168 Q_SD (const Data);
00169 QByteArray nameLower = fieldName.toLower();
00170 if (!d->fieldValues.contains (nameLower))
00171 return QList <QByteArray>();
00172 else
00173 return d->fieldValues [nameLower];
00174 }
00175
00177
00187 void HeaderBase::setFieldValue (const QByteArray &fieldName,
00188 const QByteArray &fieldValue)
00189 {
00190 removeField (fieldName);
00191 addFieldValues (fieldName, fieldValue.split (','));
00192 }
00193
00195
00200 void HeaderBase::addFieldValue (const QByteArray &fieldName,
00201 const QByteArray &fieldValue)
00202 {
00203 Q_SD (Data);
00204 QByteArray nameLower = fieldName.toLower();
00205 QByteArray trimmedValue = fieldValue.trimmed();
00206 if (trimmedValue != "")
00207 d->fieldValues [nameLower].push_back (fieldValue.trimmed());
00208 else
00209 d->fieldValues [nameLower];
00210 d->originalCaseFieldNames [nameLower] = fieldName;
00211 if (!d->orderedFieldList.contains (nameLower))
00212 d->orderedFieldList.append (nameLower);
00213 }
00214
00216
00221 void HeaderBase::addFieldValues (const QByteArray &fieldName,
00222 const QList <QByteArray> &fieldValues)
00223 {
00224 foreach (const QByteArray &value, fieldValues)
00225 addFieldValue (fieldName, value);
00226 }
00227
00229
00232 void HeaderBase::removeField (const QByteArray &fieldName)
00233 {
00234 Q_SD (Data);
00235 QByteArray nameLower (fieldName.toLower());
00236 if (d->fieldValues.contains (nameLower)) {
00237 d->fieldValues.remove (nameLower);
00238 d->originalCaseFieldNames.remove (nameLower);
00239 d->orderedFieldList.removeAll (nameLower);
00240 }
00241 }
00242
00244 struct lineAppender : public std::unary_function <QString, void>
00245 {
00246 QList <QByteArray> &m_lines;
00247 lineAppender (QList <QByteArray> &lines) : m_lines (lines) {
00248 }
00249 void operator() (QByteArray &line) {
00250 if (!line.isEmpty()) {
00251 if (isspace (line[0])) {
00252 if (!m_lines.isEmpty()) {
00253 m_lines.last() += " ";
00254 m_lines.last() += line.trimmed();
00255 }
00256 } else {
00257 m_lines.append (line);
00258 }
00259 }
00260 }
00261 };
00262
00264
00267 QByteArray HeaderBase::rawStartLine() const
00268 {
00269 return QByteArray();
00270 }
00271
00273 QByteArray HeaderBase::rawHeaderLine (const QByteArray &fieldName) const
00274 {
00275 Q_SD (const Data);
00276 QByteArray ret;
00277 int oldLength = ret.length();
00278 ret += d->originalCaseFieldNames [fieldName] + ":";
00279 foreach (const QByteArray &value, d->fieldValues [fieldName]) {
00280
00281 if (ret.length() - oldLength + value.length() + 1 > 80) {
00282
00283 oldLength = ret.length() + 2;
00284 ret += "\r\n\t" + value + ",";
00285 }
00286 else
00287 ret += " " + value + ",";
00288 }
00289 if (d->fieldValues [fieldName].size() > 0)
00290 ret.chop(1);
00291 ret += "\r\n";
00292 return ret;
00293 }
00294
00296
00300 bool HeaderBase::doParse (const QByteArray &rawBytes)
00301 {
00302 QList <QByteArray> lst = splitStringIntoLines (rawBytes);
00303 if (lst.isEmpty())
00304 return true;
00305
00306 QList <QByteArray> lines;
00307 std::for_each (lst.begin(), lst.end(), lineAppender(lines));
00308 return parseAllLines (lines);
00309 }
00310
00312
00315 QList <QByteArray> HeaderBase::splitStringIntoLines (const QByteArray &str)
00316 {
00317 QByteArray normalizedStr = str;
00318 normalizedStr.replace ("\r\n", "\n");
00319 QList <QByteArray> lines = normalizedStr.split('\n');
00320 lines.removeAll(QByteArray());
00321 return lines;
00322 }
00323
00325
00330 bool HeaderBase::parseAllLines (const QList <QByteArray> &lines)
00331 {
00332 QList <QByteArray>::const_iterator it = lines.begin();
00333 if (it != lines.end())
00334 if (!parseStartLine (*it++))
00335 return false;
00336 for(; it != lines.end(); ++it)
00337 if (!parseHeaderLine(*it))
00338 return false;
00339 return true;
00340 }
00341
00343
00350 bool HeaderBase::parseStartLine (const QByteArray &line)
00351 {
00352 return parseHeaderLine (line);
00353 }
00354
00356
00360 bool HeaderBase::parseHeaderLine (const QByteArray &line)
00361 {
00362 int i = line.indexOf(':');
00363 if (i == -1)
00364 return false;
00365
00366 addFieldValue (line.left (i).trimmed (), line.mid (i + 1));
00367 return true;
00368 }