12 #include "PvlKeyword.h"
13 #include "IException.h"
16 #include "PvlFormat.h"
17 #include "PvlSequence.h"
22 PvlKeyword::PvlKeyword() {
32 PvlKeyword::PvlKeyword(QString name) {
46 PvlKeyword::PvlKeyword(QString name, QString value,
50 addValue(value, unit);
64 PvlKeyword::~PvlKeyword() {
83 void PvlKeyword::init() {
102 bool PvlKeyword::isNull(
int index)
const {
103 if (size() == 0)
return true;
104 if (index < 0 || index >= (
int)m_values.size()) {
105 QString msg = Message::ArraySubscriptNotInRange(index);
106 throw IException(IException::Programmer, msg, _FILEINFO_);
108 if (stringEqual(
"NULL", m_values[index]))
return true;
109 if (stringEqual(
"", m_values[index]))
return true;
110 if (stringEqual(
"\"\"", m_values[index]))
return true;
111 if (stringEqual(
"''", m_values[index]))
return true;
120 void PvlKeyword::setName(QString name) {
121 QString
final = name.trimmed();
122 if (
final.contains(QRegExp(
"\\s"))) {
123 QString msg =
"[" + name +
"] is invalid. Keyword name cannot ";
124 msg +=
"contain whitespace.";
125 throw IException(IException::User, msg, _FILEINFO_);
134 QByteArray finalAscii =
final.toLatin1();
135 m_name =
new char[finalAscii.size() + 1];
136 strncpy(m_name, finalAscii.data(),
final.size() + 1);
155 void PvlKeyword::setValue(QString value, QString unit) {
157 addValue(value, unit);
166 void PvlKeyword::setUnits(QString units) {
168 m_units =
new std::vector<QString>();
173 for (
int i = 0; i < m_values.size(); i++) {
174 m_units->push_back(units);
187 void PvlKeyword::setUnits(QString value, QString units) {
191 while(!found && ++i < (
int) m_values.size()) {
192 if (value == m_values[i]) {
199 m_units =
new std::vector<QString>(m_values.size());
202 m_units->resize(m_values.size());
205 ASSERT(i < (
int) m_units->size());
207 (*m_units)[i] = units;
210 IString msg =
"PvlKeyword::setUnits called with value [" + value +
211 "] which does not exist in this Keyword";
212 throw IException(IException::Programmer, msg, _FILEINFO_);
252 void PvlKeyword::addValue(QString value, QString unit) {
253 m_values.append(value);
257 m_units =
new std::vector<QString>(m_values.size());
260 m_units->resize(m_values.size());
263 (*m_units)[m_units->size() - 1] = unit;
266 m_units->push_back(
"");
291 void PvlKeyword::clear() {
301 PvlKeyword::operator QString()
const {
302 return operator[](0);
318 QString &PvlKeyword::operator[](
int index) {
319 if (index < 0 || index >= (
int)m_values.size()) {
320 QString msg = (Message::ArraySubscriptNotInRange(index)) +
321 "for Keyword [" + QString(m_name) +
"]";
322 throw IException(IException::Programmer, msg, _FILEINFO_);
325 return m_values[index];
340 const QString &PvlKeyword::operator[](
int index)
const {
341 if (index < 0 || index >= (
int)m_values.size()) {
342 QString msg = Message::ArraySubscriptNotInRange(index);
343 throw IException(IException::Programmer, msg, _FILEINFO_);
345 return m_values[index];
357 QString PvlKeyword::unit(
int index)
const {
358 if (!m_units)
return "";
360 if (index < 0 || index >= (
int)m_units->size()) {
361 QString msg = Message::ArraySubscriptNotInRange(index);
362 throw IException(IException::Programmer, msg, _FILEINFO_);
364 return (*m_units)[index];
376 void PvlKeyword::addComment(QString comment) {
378 m_comments =
new std::vector<QString>();
381 if (comment.size() == 0) {
382 m_comments->push_back(
"#");
384 if (comment[0] ==
'#') {
385 m_comments->push_back(comment);
387 else if (comment.size() == 1) {
388 m_comments->push_back(
"# " + comment);
390 else if ((comment[0] ==
'/') && (comment[1] ==
'*')) {
391 m_comments->push_back(comment);
393 else if ((comment[0] ==
'/') && (comment[1] ==
'/')) {
394 m_comments->push_back(comment);
397 m_comments->push_back(
"# " + comment);
410 void PvlKeyword::addCommentWrapped(QString comment) {
415 token = cmt.
Token(
" ");
416 int length = temp.size() + token.size() + 1;
417 while((length < 72) && (token.size() > 0)) {
419 token = cmt.
Token(
" ");
420 length = temp.size() + token.size() + 1;
422 addComment(temp.c_str());
424 if (token.size() != 0) addComment(token.c_str());
428 void PvlKeyword::clearComment() {
441 QString PvlKeyword::comment(
int index)
const {
442 if (!m_comments)
return "";
444 if (index < 0 || index >= (
int)m_comments->size()) {
445 QString msg = Message::ArraySubscriptNotInRange(index);
446 throw IException(IException::Programmer, msg, _FILEINFO_);
448 return (*m_comments)[index];
458 QString PvlKeyword::reform(
const QString &value)
const {
460 static bool firstTime =
true;
461 static bool iPVL =
true;
469 if (s ==
"PVL") iPVL =
false;
472 if (iPVL)
return toIPvl(value);
482 QString PvlKeyword::toIPvl(
const QString &value)
const {
485 bool lastlower =
true;
486 for (
int i = 0; i < value.size(); i++) {
487 if ((lastlower) && (value[i].isUpper())) upcase =
true;
488 if (value[i] ==
'_') {
492 out += value[i].toUpper();
497 out += value[i].toLower();
498 if (value[i].isLower()) lastlower =
true;
510 QString PvlKeyword::toPvl(
const QString &value)
const {
512 bool lastlower =
false;
513 for (
int i = 0; i < value.size(); i++) {
514 if ((lastlower) && (value[i].isUpper())) out +=
"_";
515 if (value[i] ==
'_') {
520 out += value[i].toUpper();
521 if (value[i].isLower()) lastlower =
true;
535 bool PvlKeyword::stringEqual(
const QString &QString1,
536 const QString &QString2) {
549 if (s1 == s2)
return true;
562 bool PvlKeyword::isEquivalent(QString QString1,
int index)
const {
563 if (index < 0 || index >= (
int)m_values.size()) {
564 QString msg = Message::ArraySubscriptNotInRange(index);
565 throw IException(IException::Programmer, msg, _FILEINFO_);
568 return stringEqual(m_values[index], QString1);
578 for (
int i = 0; i < seq.
Size(); i++) {
580 for (
int j = 0; j < (int)seq[i].size(); j++) {
581 QString val = seq[i][j];
582 if (val.contains(
" ")) {
583 temp +=
"\"" + val +
"\"";
588 if (j < (
int) seq[i].size() - 1) temp +=
", ";
591 this->operator+=(temp);
611 ostream &PvlKeyword::writeWithWrap(std::ostream &os,
612 const QString &textToWrite,
663 QString remainingText = textToWrite;
664 int spaceForText = format.
charLimit() - 1 - format.formatEOL().length() - startColumn;
669 vector< pair<int, int> > quotedAreas;
673 if (textToWrite.count() > 0 && (textToWrite[0] ==
'(' || textToWrite[0] ==
'"')) {
684 vector< pair<char, char> > quoteStartEnds;
685 quoteStartEnds.push_back(pair<char, char>(
'"',
'"'));
686 quoteStartEnds.push_back(pair<char, char>(
'\'',
'\''));
687 quoteStartEnds.push_back(pair<char, char>(
'<',
'>'));
691 for (
int pos = 0; pos < remainingText.size(); pos++) {
693 if (remainingText[pos] ==
'\n' || remainingText[pos] ==
'\r') {
694 if (pos != remainingText.size() - 1) {
695 remainingText = remainingText.mid(0, pos) +
696 remainingText.mid(pos + 1);
699 remainingText = remainingText.mid(0, pos);
704 if (quoteStart == -1) {
706 remainingText[pos-1] ==
' ' &&
707 remainingText[pos] ==
' ') {
708 remainingText = remainingText.mid(0, pos) +
709 remainingText.mid(pos + 1);
714 for (
unsigned int i = 0;
715 (quoteStart < 0) && i < quoteStartEnds.size();
717 if (quoteStartEnds[i].first == remainingText[pos]) {
727 if (quoteStart != (
int)pos && quoteStart != -1) {
728 for (
unsigned int i = 0; i < quoteStartEnds.size(); i++) {
729 if (quoteStartEnds[i].second == remainingText[pos]) {
730 if (quoteStartEnds[i].first != remainingText[quoteStart]) {
735 quotedAreas.push_back(pair<int, int>(quoteStart, pos));
749 int charsLeft = spaceForText;
750 int printedSoFar = 0;
753 while(!remainingText.isEmpty()) {
755 int lastSpacePosition = charsLeft;
759 if (lastSpacePosition >= (
int)remainingText.length()) {
760 lastSpacePosition = remainingText.length();
767 int excellentSpace = -1;
768 int searchPosition = lastSpacePosition;
769 bool doneSearching =
false;
771 while(!doneSearching) {
772 bool currentPosQuoted =
false;
774 for (
unsigned int i = 0; i < quotedAreas.size(); i++) {
775 if (searchPosition + printedSoFar >= quotedAreas[i].first &&
776 searchPosition + printedSoFar <= quotedAreas[i].second) {
777 currentPosQuoted =
true;
781 if (remainingText[searchPosition] ==
' ') {
782 bool validSpace =
true;
786 if (searchPosition > 0 && remainingText[searchPosition - 1] ==
'-') {
790 if (validSpace && goodSpace < 0) {
791 goodSpace = searchPosition;
797 if (validSpace && !currentPosQuoted) {
798 if ((
int)searchPosition < (int)(remainingText.size() - 1) &&
799 remainingText[searchPosition+1] !=
'<') {
800 excellentSpace = searchPosition;
805 doneSearching = (excellentSpace >= 0 || searchPosition <= 1);
810 if (excellentSpace > 0) {
811 lastSpacePosition = excellentSpace;
813 else if (goodSpace > 0) {
814 lastSpacePosition = goodSpace;
817 lastSpacePosition = -1;
823 if (lastSpacePosition >= 0) {
824 os << remainingText.mid(0, lastSpacePosition);
826 remainingText = remainingText.mid(lastSpacePosition);
827 printedSoFar += lastSpacePosition;
833 if (remainingText.mid(charsLeft-1, 2) ==
"//") {
834 os << remainingText.mid(0, charsLeft - 2);
836 remainingText = remainingText.mid(charsLeft - 2);
837 printedSoFar += charsLeft - 2;
840 os << remainingText.mid(0, charsLeft - 1);
842 remainingText = remainingText.mid(charsLeft - 1);
843 printedSoFar += charsLeft - 1;
848 if (!remainingText.isEmpty()) {
849 os << format.formatEOL();
850 writeSpaces(os, startColumn);
853 if (remainingText[0] ==
' ') {
854 remainingText = remainingText.mid(1);
859 charsLeft = spaceForText;
872 void PvlKeyword::writeSpaces(std::ostream &os,
int numSpaces)
const {
873 for (
int space = 0; space < numSpaces; space ++) {
886 m_formatter = formatter;
912 QString keywordString;
914 bool keywordDone =
false;
915 bool multiLineComment =
false;
916 bool error = !is.good();
918 while(!error && !keywordDone) {
919 istream::pos_type beforeLine = is.tellg();
921 line = PvlKeyword::readLine(is, multiLineComment);
926 if (line.isEmpty() && !is.good()) {
927 if (keywordString.isEmpty() ||
928 keywordString[keywordString.size()-1] ==
'\n') {
931 if (multiLineComment) {
940 bool comment =
false;
942 if (!multiLineComment) {
943 if (line.size() > 0 && line[0] ==
'#') {
947 if (line.size() > 1 && line[0] ==
'/' &&
948 (line[1] ==
'*' || line[1] ==
'/')) {
951 if (line[1] ==
'*') {
952 multiLineComment =
true;
953 keywordString += line.mid(0, 2);
954 line = line.mid(2).trimmed();
959 if (multiLineComment) {
962 if (line.contains(
"/*")) {
963 IString msg =
"Error when reading a pvl: Cannot have ['/*'] inside a "
964 "multi-line comment";
965 throw IException(IException::Unknown, msg, _FILEINFO_);
968 if (line.contains(
"*/")) {
969 multiLineComment =
false;
971 line = line.mid(0, line.indexOf(
"*/")).trimmed() +
" */";
975 if (line.isEmpty()) {
980 keywordString += line +
'\n';
984 else if (keywordString.isEmpty()) {
985 keywordString = line;
988 else if (!comment && keywordString[keywordString.size()-1] ==
'-') {
989 keywordString = keywordString.mid(0, keywordString.size() - 1) + line;
993 keywordString +=
" " + line;
996 if (line[line.size()-1] ==
'-') {
1000 std::vector<QString> keywordComments;
1001 QString keywordName;
1002 std::vector< std::pair<QString, QString> > keywordValues;
1004 bool attemptedRead =
false;
1007 attemptedRead = PvlKeyword::readCleanKeyword(keywordString,
1013 if (is.eof() && !is.bad()) {
1018 is.seekg(beforeLine, ios::beg);
1020 QString msg =
"Unable to read PVL keyword [";
1021 msg += keywordString;
1024 throw IException(e, IException::Unknown, msg, _FILEINFO_);
1028 if (attemptedRead) {
1032 if (is.good() && is.peek() ==
'<' && !keywordValues.empty()) {
1039 for (
unsigned int value = 0; value < keywordValues.size(); value++) {
1040 result.
addValue(keywordValues[value].first,
1041 keywordValues[value].second);
1047 if (!attemptedRead) {
1048 error = error || !is.good();
1055 while(keywordString.contains(
'\n')) {
1056 keywordString = keywordString.mid(keywordString.indexOf(
'\n') + 1);
1061 if (keywordString.isEmpty() && !multiLineComment) {
1062 msg =
"PVL input contains no Pvl Keywords";
1064 else if (multiLineComment) {
1065 msg =
"PVL input ends while still in a multi-line comment";
1068 msg =
"The PVL keyword [" + keywordString +
"] does not appear to be";
1069 msg +=
" a valid Pvl Keyword";
1072 throw IException(IException::Unknown, msg, _FILEINFO_);
1077 while(keywordString.contains(
'\n'))
1078 keywordString = keywordString.mid(keywordString.indexOf(
'\n') + 1);
1082 if (keywordString.isEmpty()) {
1083 msg =
"Error reading PVL keyword";
1086 msg =
"The PVL keyword [" + keywordString +
"] does not appear to be";
1090 throw IException(IException::Unknown, msg, _FILEINFO_);
1102 void PvlKeyword::addComments(
const std::vector<QString> &comments) {
1103 for (
unsigned int i = 0; i < comments.size(); i++) {
1104 addComment(comments[i]);
1123 bool PvlKeyword::readCleanKeyword(QString keyword,
1124 std::vector<QString> &keywordComments,
1125 QString &keywordName,
1126 std::vector< std::pair<QString, QString> > &keywordValues) {
1128 keywordComments.clear();
1130 keywordValues.clear();
1133 bool explicitIncomplete =
false;
1136 QString comments[] = {
1142 if (keyword.isEmpty())
return 0;
1161 while(keyword.contains(
"\n")) {
1164 bool noneStripped =
true;
1168 QString keywordStart = keyword.mid(0, 2);
1171 if (keywordStart ==
"/*") {
1172 noneStripped =
false;
1173 bool inComment =
true;
1175 while(inComment && keyword.contains(
"*/")) {
1178 int closePos = keyword.indexOf(
"*/\n");
1180 if (closePos == -1) {
1181 closePos = keyword.indexOf(
"*/") + 2;
1182 keyword = keyword.mid(0, closePos) +
"\n" +
1183 keyword.mid(closePos);
1186 QString comment = keyword.mid(0, keyword.indexOf(
"\n")).trimmed();
1190 bool needsStart = (comment.size() < 2);
1191 bool needsStartSpace = comment.size() < 3;
1193 int commentEndPos = comment.size() - 2;
1194 bool needsEnd = (commentEndPos < 0);
1195 bool needsEndSpace = comment.size() < 3;
1201 needsStart = (comment.mid(0, 2) !=
"/*");
1205 needsEnd = (comment.mid(commentEndPos, 2) !=
"*/");
1208 if (!needsStartSpace) {
1209 needsStartSpace = (comment.mid(0, 3) !=
"/* ");
1212 if (!needsEndSpace) {
1213 needsEndSpace = (comment.mid(commentEndPos - 1, 3) !=
" */");
1217 comment =
"/* " + comment;
1219 else if (needsStartSpace) {
1220 comment =
"/* " + comment.mid(2);
1224 comment = comment +
" */";
1226 else if (needsEndSpace) {
1227 comment = comment.mid(0, comment.size() - 2) +
" */";;
1230 inComment = needsEnd;
1232 keywordComments.push_back(comment);
1234 if (keyword.contains(
"\n")) {
1235 keyword = keyword.mid(keyword.indexOf(
"\n") + 1).trimmed();
1240 if (keyword.size() >= 2)
1241 keywordStart = keyword.mid(0, 2);
1243 inComment = (keywordStart ==
"/*");
1250 for (
unsigned int index = 0; index < keywordComments.size(); index++) {
1251 QString comment = keywordComments[index];
1253 if (comment.size() > longest)
1254 longest = comment.size();
1258 for (
unsigned int index = 0; index < keywordComments.size(); index++) {
1259 QString comment = keywordComments[index];
1261 while(comment.size() < longest) {
1263 comment = comment.mid(0, comment.size() - 2) +
" */";
1266 keywordComments[index] = comment;
1272 for (
unsigned int commentType = 0;
1273 commentType <
sizeof(comments) /
sizeof(QString);
1276 if (keywordStart.startsWith(comments[commentType])) {
1279 QString comment = keyword.mid(0, keyword.indexOf(
"\n"));
1280 keywordComments.push_back(comment.trimmed());
1282 noneStripped =
false;
1284 if (keyword.contains(
"\n")) {
1285 keyword = keyword.mid(keyword.indexOf(
"\n") + 1).trimmed();
1292 if (noneStripped && keyword.contains(
"/*") &&
1293 keyword.contains(
"*/")) {
1294 QString firstPart = keyword.mid(0, keyword.indexOf(
"\n"));
1295 QString lastPart = keyword.mid(keyword.indexOf(
"\n") + 1);
1297 keyword = firstPart.trimmed() +
" " + lastPart.trimmed();
1298 noneStripped =
false;
1302 QString msg =
"Expected a comment in PVL but found [";
1305 throw IException(IException::Unknown, msg, _FILEINFO_);
1310 if (keyword.isEmpty()) {
1325 keywordName = readValue(keyword, explicitIncomplete);
1329 if (keyword.isEmpty()) {
1343 if (keyword[0] !=
'=') {
1344 QString msg =
"Expected an assignment [=] when reading PVL, but found [";
1348 throw IException(IException::Unknown, msg, _FILEINFO_);
1351 keyword = keyword.mid(1).trimmed();
1353 if (keyword.isEmpty()) {
1358 if (keyword[0] ==
'(' || keyword[0] ==
'{') {
1368 char closingParen = ((keyword[0] ==
'(') ?
')' :
'}');
1369 char wrongClosingParen = ((keyword[0] ==
'(') ?
'}' :
')');
1370 bool closedProperly =
false;
1372 vector< pair<char, char> > extraDelims;
1373 extraDelims.push_back(pair<char, char>(
'(',
')'));
1374 extraDelims.push_back(pair<char, char>(
'{',
'}'));
1378 keyword = keyword.mid(1).trimmed();
1381 if (!keyword.isEmpty() && keyword[0] == closingParen) {
1382 closedProperly =
true;
1388 while(!keyword.isEmpty() && keyword[0] != closingParen) {
1391 bool foundComma =
false;
1394 QString nextItem = readValue(keyword, explicitIncomplete, extraDelims);
1396 if (!keyword.isEmpty() && keyword[0] == wrongClosingParen) {
1398 QString msg =
"Incorrect array close when reading PVL; expected [";
1399 msg += closingParen;
1400 msg +=
"] but found [";
1401 msg += wrongClosingParen;
1402 msg +=
"] in keyword named [";
1405 throw IException(IException::Unknown, msg, _FILEINFO_);
1409 pair<QString, QString> keywordValue;
1412 keywordValue.first = nextItem;
1416 if (!keyword.isEmpty() && keyword[0] ==
'<') {
1417 QString unitsValue = readValue(keyword, explicitIncomplete);
1418 keywordValue.second = unitsValue;
1422 if (!keyword.isEmpty() && keyword[0] ==
',') {
1424 keyword = keyword.mid(1).trimmed();
1430 if (!foundComma && keyword.isEmpty()) {
1434 bool foundCloseParen = (!keyword.isEmpty() && keyword[0] == closingParen);
1436 if (foundCloseParen) {
1437 closedProperly =
true;
1443 if (foundComma && foundCloseParen) {
1444 QString msg =
"Unexpected close of keyword-value array when reading "
1446 throw IException(IException::Unknown, msg, _FILEINFO_);
1450 if (!foundComma && !foundCloseParen) {
1452 if (explicitIncomplete)
return false;
1455 QString msg =
"Found extra data after [";
1457 msg +=
"] in array when reading PVL";
1458 throw IException(IException::Unknown, msg, _FILEINFO_);
1462 keywordValues.push_back(keywordValue);
1465 if (!closedProperly) {
1470 if (!keyword.isEmpty()) {
1471 keyword = keyword.mid(1).trimmed();
1476 if (!keyword.isEmpty() && keyword[0] ==
'<') {
1477 QString units = readValue(keyword, explicitIncomplete);
1478 for (
unsigned int val = 0; val < keywordValues.size(); val++) {
1479 if (keywordValues[val].second.isEmpty()) {
1480 keywordValues[val].second = units;
1494 pair<QString, QString> keywordValue;
1495 keywordValue.first = readValue(keyword, explicitIncomplete);
1497 if (!keyword.isEmpty() && keyword[0] ==
'<') {
1498 keywordValue.second = readValue(keyword, explicitIncomplete);
1501 keywordValues.push_back(keywordValue);
1508 if (explicitIncomplete) {
1515 if (!keyword.isEmpty()) {
1517 if (keyword[0] ==
'#' ||
1518 ((keyword.size() > 1 && keyword[0] ==
'/') &&
1519 (keyword[1] ==
'/' || keyword[1] ==
'*'))) {
1520 keywordComments.push_back(keyword);
1522 if (keyword.size() > 1 && keyword.mid(0, 2) ==
"/*") {
1523 if (keyword.mid(keyword.size() - 2, 2) !=
"*/")
1534 if (!keyword.isEmpty()) {
1535 QString msg =
"Keyword has extraneous data [";
1537 msg +=
"] at the end";
1538 throw IException(IException::Unknown, msg, _FILEINFO_);
1546 QString PvlKeyword::readValue(QString &keyword,
bool "eProblem) {
1547 std::vector< std::pair<char, char> > otherDelims;
1549 return readValue(keyword, quoteProblem, otherDelims);
1568 QString PvlKeyword::readValue(QString &keyword,
bool "eProblem,
1569 const std::vector< std::pair<char, char> > &
1575 keyword = keyword.trimmed();
1577 if (keyword.isEmpty()) {
1585 bool impliedQuote =
true;
1586 QChar quoteEnd =
' ';
1587 bool keepQuotes =
false;
1589 if (keyword[0] ==
'\'' || keyword[0] ==
'"') {
1590 quoteEnd = keyword[0];
1591 impliedQuote =
false;
1593 else if (keyword[0] ==
'<') {
1595 impliedQuote =
false;
1599 char implicitQuotes[] = {
1609 bool foundImplicitQuote =
false;
1612 while(!foundImplicitQuote && currentPos != keyword.size()) {
1613 for (
unsigned int quote = 0;
1614 quote <
sizeof(implicitQuotes) /
sizeof(
char);
1616 if (keyword[currentPos] == implicitQuotes[quote]) {
1617 quoteEnd = implicitQuotes[quote];
1618 foundImplicitQuote =
true;
1622 if (!foundImplicitQuote) {
1628 for (
unsigned int delim = 0; delim < otherDelimiters.size(); delim ++) {
1629 if (keyword[0] == otherDelimiters[delim].first) {
1630 quoteEnd = otherDelimiters[delim].second;
1632 impliedQuote =
false;
1640 if (!impliedQuote) {
1641 startQuote += keyword[0];
1642 keyword = keyword.mid(1);
1646 int quoteEndPos = keyword.indexOf(quoteEnd);
1648 if (quoteEndPos != -1) {
1649 value = keyword.mid(0, quoteEndPos);
1655 if (!impliedQuote) {
1656 keyword = keyword.mid(quoteEndPos + 1);
1659 keyword = keyword.mid(quoteEndPos);
1663 keyword = keyword.trimmed();
1666 value = startQuote + value + quoteEnd;
1673 else if (!impliedQuote) {
1675 keyword = startQuote + keyword;
1676 quoteProblem =
true;
1703 QString PvlKeyword::readLine(std::istream &is,
bool insideComment) {
1706 while(is.good() && lineOfData.isEmpty()) {
1710 (!lineOfData.size() || lineOfData[lineOfData.size() - 1] !=
'\n')) {
1711 char next = is.get();
1715 is.seekg(0, ios::end);
1726 if (insideComment &&
1727 lineOfData.size() >= 2 && lineOfData[lineOfData.size() - 2] ==
'*' &&
1728 lineOfData[lineOfData.size() - 1] ==
'/') {
1732 else if (lineOfData.size() >= 2 &&
1733 lineOfData[lineOfData.size() - 2] ==
'/' &&
1734 lineOfData[lineOfData.size() - 1] ==
'*') {
1735 insideComment =
true;
1740 lineOfData = lineOfData.trimmed();
1744 (is.peek() ==
' ' ||
1745 is.peek() ==
'\r' ||
1746 is.peek() ==
'\n')) {
1768 bool removeFormatter =
false;
1769 if (tempFormat == NULL) {
1771 removeFormatter =
true;
1775 for (
int i = 0; i < keyword.
comments(); i++) {
1776 for (
int j = 0; j < keyword.
indent(); j++) os <<
" ";
1777 os << keyword.
comment(i) << tempFormat->formatEOL();
1781 int startColumn = 0;
1782 for (
int i = 0; i < keyword.
indent(); i++) {
1786 QString keyname = tempFormat->formatName(keyword);
1788 startColumn += keyname.length();
1791 for (
int i = 0; i < keyword.
width() - (
int)keyname.size(); ++i) {
1799 if (keyword.
size() == 0) {
1800 os << tempFormat->formatValue(keyword);
1804 QString stringToWrite;
1805 for (
int i = 0; i < keyword.
size(); i ++) {
1806 stringToWrite += tempFormat->formatValue(keyword, i);
1814 if (removeFormatter)
delete tempFormat;
1822 if (
this != &other) {
1842 m_units =
new std::vector<QString>(*other.
m_units);
1851 m_comments =
new std::vector<QString>(*other.
m_comments);
1875 int iSize = pvlKwrd.
size();
1877 QString sType = m_values[0].toLower();
1880 if (psValueType.length()) {
1881 psValueType = psValueType.toLower();
1884 double dRangeMin=0, dRangeMax=0;
1885 bool bRange =
false;
1886 bool bValue =
false;
1887 if (pvlKwrdValue != NULL) {
1888 QString sValueName = pvlKwrdValue->
name();
1891 if (sValueName.contains(
"__Range")) {
1892 dRangeMin =
toDouble((*pvlKwrdValue)[0]);
1893 dRangeMax =
toDouble((*pvlKwrdValue)[1]);
1896 else if (sValueName.contains(
"__Value")) {
1902 if (sType ==
"integer") {
1903 for (
int i=0; i<iSize; i++) {
1904 QString sValue = pvlKwrd[i].toLower();
1905 if (sValue !=
"null"){
1908 iValue =
toInt(sValue);
1910 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" expects an Integer value";
1911 throw IException(e, IException::User, sErrMsg, _FILEINFO_);
1913 if (bRange && (iValue < dRangeMin || iValue > dRangeMax)) {
1914 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" is not in the specified Range";
1915 throw IException(IException::User, sErrMsg, _FILEINFO_);
1918 bool bFound =
false;
1919 for (
int j=0; j<pvlKwrdValue->
size(); j++) {
1920 if (iValue ==
toInt((*pvlKwrdValue)[j])) {
1926 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" has value not in the accepted list";
1927 throw IException(IException::User, sErrMsg, _FILEINFO_);
1931 if (psValueType.length()) {
1932 if ((psValueType ==
"positive" && iValue < 0) || (psValueType ==
"negative" && iValue >= 0) ) {
1933 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" has invalid value";
1934 throw IException(IException::User, sErrMsg, _FILEINFO_);
1943 if (sType ==
"double") {
1944 for (
int i=0; i<iSize; i++) {
1945 QString sValue = pvlKwrd[i].toLower();
1946 if (sValue !=
"null"){
1948 if (bRange && (dValue < dRangeMin || dValue > dRangeMax)) {
1949 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" is not in the specified Range";
1950 throw IException(IException::User, sErrMsg, _FILEINFO_);
1953 bool bFound =
false;
1954 for (
int j=0; j<pvlKwrdValue->
size(); j++) {
1955 if (dValue ==
toDouble((*pvlKwrdValue)[j])) {
1961 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" has value not in the accepted list";
1962 throw IException(IException::User, sErrMsg, _FILEINFO_);
1966 if (psValueType.length()) {
1967 if ((psValueType ==
"positive" && dValue < 0) || (psValueType ==
"negative" && dValue >= 0) ) {
1968 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" has invalid value";
1969 throw IException(IException::User, sErrMsg, _FILEINFO_);
1978 if (sType ==
"boolean") {
1979 for (
int i=0; i<iSize; i++) {
1980 QString sValue = pvlKwrd[i].toLower();
1981 if (sValue !=
"null" && sValue !=
"true" && sValue !=
"false"){
1982 QString sErrMsg =
"Wrong Type of value in the Keyword \"" + name() +
"\" \n";
1983 throw IException(IException::User, sErrMsg, _FILEINFO_);
1990 if (sType ==
"string") {
1991 for (
int i=0; i<iSize; i++) {
1992 QString sValue = pvlKwrd[i].toLower();
1994 bool bValFound =
false;
1995 for (
int i=0; i<pvlKwrdValue->
size(); i++) {
1996 if (sValue == (*pvlKwrdValue)[i].toLower()) {
2002 QString sErrMsg =
"Wrong Type of value in the Keyword \"" + name() +
"\" \n";
2003 throw IException(IException::User, sErrMsg, _FILEINFO_);