10#include <QRegularExpression>
11#include "PvlKeyword.h"
12#include "IException.h"
16#include "PvlSequence.h"
21using json = nlohmann::json;
105 if (
size() == 0)
return true;
106 if (index < 0 || index >= (
int)
m_values.size()) {
123 QString
final =
name.trimmed();
124 if (
final.contains(QRegExp(
"\\s"))) {
125 QString msg =
"[" +
name +
"] is invalid. Keyword name cannot ";
126 msg +=
"contain whitespace.";
136 QByteArray finalAscii =
final.toLatin1();
137 m_name =
new char[finalAscii.size() + 1];
138 strncpy(
m_name, finalAscii.data(),
final.size() + 1);
188 m_units =
new std::vector<QString>();
193 for (
int i = 0; i <
m_values.size(); i++) {
211 while(!found && ++i < (
int)
m_values.size()) {
225 (*m_units)[i] = units;
228 IString msg =
"PvlKeyword::setUnits called with value [" + value +
229 "] which does not exist in this Keyword";
306 if (jsonobj.is_array()) {
307 QString msg =
"Unable to convert " +
name() +
" with nested json array value into PvlKeyword";
310 else if (jsonobj.is_number())
312 value = QString::number(jsonobj.get<
double>(),
'g', 16);
314 else if (jsonobj.is_boolean())
316 value = QString(jsonobj.get<
bool>() ?
"true" :
"false");
318 else if (jsonobj.is_null())
320 value = QString(
"Null");
324 value = QString::fromStdString(jsonobj);
360 PvlKeyword::operator QString()
const {
361 return operator[](0);
378 if (index < 0 || index >= (
int)
m_values.size()) {
380 "for Keyword [" + QString(
m_name) +
"]";
400 if (index < 0 || index >= (
int)
m_values.size()) {
419 if (index < 0 || index >= (
int)
m_units->size()) {
446 else if (
comment.size() == 1) {
474 token = cmt.
Token(
" ");
475 int length = temp.size() + token.size() + 1;
476 while((length < 72) && (token.size() > 0)) {
478 token = cmt.
Token(
" ");
479 length = temp.size() + token.size() + 1;
483 if (token.size() != 0)
addComment(token.c_str());
503 if (index < 0 || index >= (
int)
m_comments->size()) {
519 static bool firstTime =
true;
520 static bool iPVL =
true;
528 if (s ==
"PVL") iPVL =
false;
531 if (iPVL)
return toIPvl(value);
544 bool lastlower =
true;
545 for (
int i = 0; i < value.size(); i++) {
546 if ((lastlower) && (value[i].isUpper())) upcase =
true;
547 if (value[i] ==
'_') {
551 out += value[i].toUpper();
556 out += value[i].toLower();
557 if (value[i].isLower()) lastlower =
true;
571 bool lastlower =
false;
572 for (
int i = 0; i < value.size(); i++) {
573 if ((lastlower) && (value[i].isUpper())) out +=
"_";
574 if (value[i] ==
'_') {
579 out += value[i].toUpper();
580 if (value[i].isLower()) lastlower =
true;
595 const QString &QString2) {
608 if (s1 == s2)
return true;
622 if (index < 0 || index >= (
int)
m_values.size()) {
637 for (
int i = 0; i < seq.
Size(); i++) {
639 for (
int j = 0; j < (int)seq[i].size(); j++) {
640 QString val = seq[i][j];
641 if (val.contains(
" ")) {
642 temp +=
"\"" + val +
"\"";
647 if (j < (
int) seq[i].
size() - 1) temp +=
", ";
671 const QString &textToWrite,
722 QString remainingText = textToWrite;
723 int spaceForText =
format.charLimit() - 1 -
format.formatEOL().length() - startColumn;
728 vector< pair<int, int> > quotedAreas;
732 if (textToWrite.count() > 0 && (textToWrite[0] ==
'(' || textToWrite[0] ==
'"')) {
743 vector< pair<char, char> > quoteStartEnds;
744 quoteStartEnds.push_back(pair<char, char>(
'"',
'"'));
745 quoteStartEnds.push_back(pair<char, char>(
'\'',
'\''));
746 quoteStartEnds.push_back(pair<char, char>(
'<',
'>'));
750 for (
int pos = 0; pos < remainingText.size(); pos++) {
752 if (remainingText[pos] ==
'\n' || remainingText[pos] ==
'\r') {
753 if (pos != remainingText.size() - 1) {
754 remainingText = remainingText.mid(0, pos) +
755 remainingText.mid(pos + 1);
758 remainingText = remainingText.mid(0, pos);
763 if (quoteStart == -1) {
765 remainingText[pos-1] ==
' ' &&
766 remainingText[pos] ==
' ') {
767 remainingText = remainingText.mid(0, pos) +
768 remainingText.mid(pos + 1);
773 for (
unsigned int i = 0;
774 (quoteStart < 0) && i < quoteStartEnds.size();
776 if (quoteStartEnds[i].first == remainingText[pos]) {
786 if (quoteStart != (
int)pos && quoteStart != -1) {
787 for (
unsigned int i = 0; i < quoteStartEnds.size(); i++) {
788 if (quoteStartEnds[i].second == remainingText[pos]) {
789 if (quoteStartEnds[i].first != remainingText[quoteStart]) {
794 quotedAreas.push_back(pair<int, int>(quoteStart, pos));
808 int charsLeft = spaceForText;
809 int printedSoFar = 0;
812 while(!remainingText.isEmpty()) {
814 int lastSpacePosition = charsLeft;
818 if (lastSpacePosition >= (
int)remainingText.length()) {
819 lastSpacePosition = remainingText.length();
826 int excellentSpace = -1;
827 int searchPosition = lastSpacePosition;
828 bool doneSearching =
false;
830 while(!doneSearching) {
831 bool currentPosQuoted =
false;
833 for (
unsigned int i = 0; i < quotedAreas.size(); i++) {
834 if (searchPosition + printedSoFar >= quotedAreas[i].first &&
835 searchPosition + printedSoFar <= quotedAreas[i].second) {
836 currentPosQuoted =
true;
840 if (remainingText[searchPosition] ==
' ') {
841 bool validSpace =
true;
845 if (searchPosition > 0 && remainingText[searchPosition - 1] ==
'-') {
849 if (validSpace && goodSpace < 0) {
850 goodSpace = searchPosition;
856 if (validSpace && !currentPosQuoted) {
857 if ((
int)searchPosition < (
int)(remainingText.size() - 1) &&
858 remainingText[searchPosition+1] !=
'<') {
859 excellentSpace = searchPosition;
864 doneSearching = (excellentSpace >= 0 || searchPosition <= 1);
869 if (excellentSpace > 0) {
870 lastSpacePosition = excellentSpace;
872 else if (goodSpace > 0) {
873 lastSpacePosition = goodSpace;
876 lastSpacePosition = -1;
882 if (lastSpacePosition >= 0) {
883 os << remainingText.mid(0, lastSpacePosition);
885 remainingText = remainingText.mid(lastSpacePosition);
886 printedSoFar += lastSpacePosition;
892 if (remainingText.mid(charsLeft-1, 2) ==
"//") {
893 os << remainingText.mid(0, charsLeft - 2);
895 remainingText = remainingText.mid(charsLeft - 2);
896 printedSoFar += charsLeft - 2;
899 os << remainingText.mid(0, charsLeft - 1);
901 remainingText = remainingText.mid(charsLeft - 1);
902 printedSoFar += charsLeft - 1;
907 if (!remainingText.isEmpty()) {
912 if (remainingText[0] ==
' ') {
913 remainingText = remainingText.mid(1);
918 charsLeft = spaceForText;
932 for (
int space = 0; space < numSpaces; space ++) {
971 QString keywordString;
973 bool keywordDone =
false;
974 bool multiLineComment =
false;
975 bool error = !is.good();
977 while(!error && !keywordDone) {
978 istream::pos_type beforeLine = is.tellg();
985 if (line.isEmpty() && !is.good()) {
986 if (keywordString.isEmpty() ||
987 keywordString[keywordString.size()-1] ==
'\n') {
990 if (multiLineComment) {
1001 if (!multiLineComment) {
1002 if (line.size() > 0 && line[0] ==
'#') {
1006 if (line.size() > 1 && line[0] ==
'/' &&
1007 (line[1] ==
'*' || line[1] ==
'/')) {
1010 if (line[1] ==
'*') {
1011 multiLineComment =
true;
1012 keywordString += line.mid(0, 2);
1013 line = line.mid(2).trimmed();
1018 if (multiLineComment) {
1021 if (line.contains(
"/*")) {
1022 IString msg =
"Error when reading a pvl: Cannot have ['/*'] inside a "
1023 "multi-line comment";
1027 if (line.contains(
"*/")) {
1028 multiLineComment =
false;
1030 line = line.mid(0, line.indexOf(
"*/")).trimmed() +
" */";
1034 if (line.isEmpty()) {
1039 keywordString += line +
'\n';
1043 else if (keywordString.isEmpty()) {
1044 keywordString = line;
1047 else if (!
comment && keywordString[keywordString.size()-1] ==
'-') {
1048 keywordString = keywordString.mid(0, keywordString.size() - 1) + line;
1052 keywordString +=
" " + line;
1055 if (line[line.size()-1] ==
'-') {
1059 std::vector<QString> keywordComments;
1060 QString keywordName;
1061 std::vector< std::pair<QString, QString> > keywordValues;
1063 bool attemptedRead =
false;
1072 if (is.eof() && !is.bad()) {
1077 is.seekg(beforeLine, ios::beg);
1079 QString msg =
"Unable to read PVL keyword [";
1080 msg += keywordString;
1087 if (attemptedRead) {
1091 if (is.good() && is.peek() ==
'<' && !keywordValues.empty()) {
1098 for (
unsigned int value = 0; value < keywordValues.size(); value++) {
1099 result.
addValue(keywordValues[value].first,
1100 keywordValues[value].second);
1106 if (!attemptedRead) {
1107 error = error || !is.good();
1114 while(keywordString.contains(
'\n')) {
1115 keywordString = keywordString.mid(keywordString.indexOf(
'\n') + 1);
1120 if (keywordString.isEmpty() && !multiLineComment) {
1121 msg =
"PVL input contains no Pvl Keywords";
1123 else if (multiLineComment) {
1124 msg =
"PVL input ends while still in a multi-line comment";
1127 msg =
"The PVL keyword [" + keywordString +
"] does not appear to be";
1128 msg +=
" a valid Pvl Keyword";
1136 while(keywordString.contains(
'\n'))
1137 keywordString = keywordString.mid(keywordString.indexOf(
'\n') + 1);
1141 if (keywordString.isEmpty()) {
1142 msg =
"Error reading PVL keyword";
1145 msg =
"The PVL keyword [" + keywordString +
"] does not appear to be";
1162 for (
unsigned int i = 0; i <
comments.size(); i++) {
1183 std::vector<QString> &keywordComments,
1184 QString &keywordName,
1185 std::vector< std::pair<QString, QString> > &keywordValues) {
1187 keywordComments.clear();
1189 keywordValues.clear();
1192 bool explicitIncomplete =
false;
1201 if (keyword.isEmpty())
return 0;
1220 while(keyword.contains(
"\n")) {
1223 bool noneStripped =
true;
1227 QString keywordStart = keyword.mid(0, 2);
1230 if (keywordStart ==
"/*") {
1231 noneStripped =
false;
1232 bool inComment =
true;
1234 while(inComment && keyword.contains(
"*/")) {
1237 int closePos = keyword.indexOf(
"*/\n");
1239 if (closePos == -1) {
1240 closePos = keyword.indexOf(
"*/") + 2;
1241 keyword = keyword.mid(0, closePos) +
"\n" +
1242 keyword.mid(closePos);
1245 QString
comment = keyword.mid(0, keyword.indexOf(
"\n")).trimmed();
1249 bool needsStart = (
comment.size() < 2);
1250 bool needsStartSpace =
comment.size() < 3;
1252 int commentEndPos =
comment.size() - 2;
1253 bool needsEnd = (commentEndPos < 0);
1254 bool needsEndSpace =
comment.size() < 3;
1260 needsStart = (
comment.mid(0, 2) !=
"/*");
1264 needsEnd = (
comment.mid(commentEndPos, 2) !=
"*/");
1267 if (!needsStartSpace) {
1268 needsStartSpace = (
comment.mid(0, 3) !=
"/* ");
1271 if (!needsEndSpace) {
1272 needsEndSpace = (
comment.mid(commentEndPos - 1, 3) !=
" */");
1278 else if (needsStartSpace) {
1285 else if (needsEndSpace) {
1289 inComment = needsEnd;
1291 keywordComments.push_back(
comment);
1293 if (keyword.contains(
"\n")) {
1294 keyword = keyword.mid(keyword.indexOf(
"\n") + 1).trimmed();
1299 if (keyword.size() >= 2)
1300 keywordStart = keyword.mid(0, 2);
1302 inComment = (keywordStart ==
"/*");
1309 for (
unsigned int index = 0; index < keywordComments.size(); index++) {
1310 QString
comment = keywordComments[index];
1317 for (
unsigned int index = 0; index < keywordComments.size(); index++) {
1318 QString
comment = keywordComments[index];
1320 while(
comment.size() < longest) {
1325 keywordComments[index] =
comment;
1331 for (
unsigned int commentType = 0;
1332 commentType <
sizeof(
comments) /
sizeof(QString);
1335 if (keywordStart.startsWith(
comments[commentType])) {
1338 QString
comment = keyword.mid(0, keyword.indexOf(
"\n"));
1339 keywordComments.push_back(
comment.trimmed());
1341 noneStripped =
false;
1343 if (keyword.contains(
"\n")) {
1344 keyword = keyword.mid(keyword.indexOf(
"\n") + 1).trimmed();
1351 if (noneStripped && keyword.contains(
"/*") &&
1352 keyword.contains(
"*/")) {
1353 QString firstPart = keyword.mid(0, keyword.indexOf(
"\n"));
1354 QString lastPart = keyword.mid(keyword.indexOf(
"\n") + 1);
1356 keyword = firstPart.trimmed() +
" " + lastPart.trimmed();
1357 noneStripped =
false;
1361 QString msg =
"Expected a comment in PVL but found [";
1369 if (keyword.isEmpty()) {
1384 keywordName = readValue(keyword, explicitIncomplete);
1388 if (keyword.isEmpty()) {
1398 bool allowedValueless =
false;
1399 static const std::vector<QString> reservedKeywordNames = {
"OBJECT",
1407 const QString keywordNameUpper = keywordName.toUpper();
1408 for (
const auto &reservedKeywordName : reservedKeywordNames) {
1409 if (keywordNameUpper == reservedKeywordName) {
1410 allowedValueless =
true;
1414 return allowedValueless;
1419 if (keyword[0] !=
'=') {
1420 QString msg =
"Expected an assignment [=] when reading PVL, but found [";
1427 keyword = keyword.mid(1).trimmed();
1429 if (keyword.isEmpty()) {
1434 if (keyword[0] ==
'(' || keyword[0] ==
'{') {
1444 char closingParen = ((keyword[0] ==
'(') ?
')' :
'}');
1445 char wrongClosingParen = ((keyword[0] ==
'(') ?
'}' :
')');
1446 bool closedProperly =
false;
1448 vector< pair<char, char> > extraDelims;
1449 extraDelims.push_back(pair<char, char>(
'(',
')'));
1450 extraDelims.push_back(pair<char, char>(
'{',
'}'));
1454 keyword = keyword.mid(1).trimmed();
1457 if (!keyword.isEmpty() && keyword[0] == closingParen) {
1458 closedProperly =
true;
1464 while(!keyword.isEmpty() && keyword[0] != closingParen) {
1467 bool foundComma =
false;
1470 QString nextItem = readValue(keyword, explicitIncomplete, extraDelims);
1472 if (!keyword.isEmpty() && keyword[0] == wrongClosingParen) {
1474 QString msg =
"Incorrect array close when reading PVL; expected [";
1475 msg += closingParen;
1476 msg +=
"] but found [";
1477 msg += wrongClosingParen;
1478 msg +=
"] in keyword named [";
1485 pair<QString, QString> keywordValue;
1488 keywordValue.first = nextItem;
1492 if (!keyword.isEmpty() && keyword[0] ==
'<') {
1493 QString unitsValue = readValue(keyword, explicitIncomplete);
1494 keywordValue.second = unitsValue;
1498 if (!keyword.isEmpty() && keyword[0] ==
',') {
1500 keyword = keyword.mid(1).trimmed();
1506 if (!foundComma && keyword.isEmpty()) {
1510 bool foundCloseParen = (!keyword.isEmpty() && keyword[0] == closingParen);
1512 if (foundCloseParen) {
1513 closedProperly =
true;
1519 if (foundComma && foundCloseParen) {
1520 QString msg =
"Unexpected close of keyword-value array when reading "
1526 if (!foundComma && !foundCloseParen) {
1528 if (explicitIncomplete)
return false;
1531 QString msg =
"Found extra data after [";
1533 msg +=
"] in array when reading PVL";
1538 keywordValues.push_back(keywordValue);
1541 if (!closedProperly) {
1546 if (!keyword.isEmpty()) {
1547 keyword = keyword.mid(1).trimmed();
1552 if (!keyword.isEmpty() && keyword[0] ==
'<') {
1553 QString units = readValue(keyword, explicitIncomplete);
1554 for (
unsigned int val = 0; val < keywordValues.size(); val++) {
1555 if (keywordValues[val].second.isEmpty()) {
1556 keywordValues[val].second = units;
1570 pair<QString, QString> keywordValue;
1571 keywordValue.first = readValue(keyword, explicitIncomplete);
1573 if (!keyword.isEmpty() && keyword[0] ==
'<') {
1574 keywordValue.second = readValue(keyword, explicitIncomplete);
1577 keywordValues.push_back(keywordValue);
1584 if (explicitIncomplete) {
1591 if (!keyword.isEmpty()) {
1593 if (keyword[0] ==
'#' ||
1594 ((keyword.size() > 1 && keyword[0] ==
'/') &&
1595 (keyword[1] ==
'/' || keyword[1] ==
'*'))) {
1596 keywordComments.push_back(keyword);
1598 if (keyword.size() > 1 && keyword.mid(0, 2) ==
"/*") {
1599 if (keyword.mid(keyword.size() - 2, 2) !=
"*/")
1608 QRegularExpression regex(
"^,");
1609 QRegularExpressionMatch match = regex.match(keyword);
1610 if (!keyword.isEmpty() && match.hasMatch()) {
1611 keywordValues.at(0).first += keyword;
1618 if (!keyword.isEmpty()) {
1619 QString msg =
"Keyword has extraneous data [";
1621 msg +=
"] at the end";
1630 QString PvlKeyword::readValue(QString &keyword,
bool "eProblem) {
1631 std::vector< std::pair<char, char> > otherDelims;
1633 return readValue(keyword, quoteProblem, otherDelims);
1652 QString PvlKeyword::readValue(QString &keyword,
bool "eProblem,
1653 const std::vector< std::pair<char, char> > &
1659 keyword = keyword.trimmed();
1661 if (keyword.isEmpty()) {
1669 bool impliedQuote =
true;
1670 QChar quoteEnd =
' ';
1671 bool keepQuotes =
false;
1673 if (keyword[0] ==
'\'' || keyword[0] ==
'"') {
1674 quoteEnd = keyword[0];
1675 impliedQuote =
false;
1677 else if (keyword[0] ==
'<') {
1679 impliedQuote =
false;
1683 char implicitQuotes[] = {
1693 bool foundImplicitQuote =
false;
1696 while(!foundImplicitQuote && currentPos != keyword.size()) {
1697 for (
unsigned int quote = 0;
1698 quote <
sizeof(implicitQuotes) /
sizeof(char);
1700 if (keyword[currentPos] == implicitQuotes[quote]) {
1701 quoteEnd = implicitQuotes[quote];
1702 foundImplicitQuote =
true;
1706 if (!foundImplicitQuote) {
1712 for (
unsigned int delim = 0; delim < otherDelimiters.size(); delim ++) {
1713 if (keyword[0] == otherDelimiters[delim].first) {
1714 quoteEnd = otherDelimiters[delim].second;
1716 impliedQuote =
false;
1724 if (!impliedQuote) {
1725 startQuote += keyword[0];
1726 keyword = keyword.mid(1);
1730 int quoteEndPos = keyword.indexOf(quoteEnd);
1732 if (quoteEndPos != -1) {
1733 value = keyword.mid(0, quoteEndPos);
1739 if (!impliedQuote) {
1740 keyword = keyword.mid(quoteEndPos + 1);
1743 keyword = keyword.mid(quoteEndPos);
1747 keyword = keyword.trimmed();
1750 value = startQuote + value + quoteEnd;
1757 else if (!impliedQuote) {
1759 keyword = startQuote + keyword;
1760 quoteProblem =
true;
1652 QString PvlKeyword::readValue(QString &keyword,
bool "eProblem, {
…}
1790 while(is.good() && lineOfData.isEmpty()) {
1794 (!lineOfData.size() || lineOfData[lineOfData.size() - 1] !=
'\n')) {
1795 char next = is.get();
1799 is.seekg(0, ios::end);
1810 if (insideComment &&
1811 lineOfData.size() >= 2 && lineOfData[lineOfData.size() - 2] ==
'*' &&
1812 lineOfData[lineOfData.size() - 1] ==
'/') {
1816 else if (lineOfData.size() >= 2 &&
1817 lineOfData[lineOfData.size() - 2] ==
'/' &&
1818 lineOfData[lineOfData.size() - 1] ==
'*') {
1819 insideComment =
true;
1824 lineOfData = lineOfData.trimmed();
1828 (is.peek() ==
' ' ||
1829 is.peek() ==
'\r' ||
1830 is.peek() ==
'\n')) {
1852 bool removeFormatter =
false;
1853 if (tempFormat == NULL) {
1855 removeFormatter =
true;
1859 for (
int i = 0; i < keyword.
comments(); i++) {
1860 for (
int j = 0; j < keyword.
indent(); j++) os <<
" ";
1861 os << keyword.
comment(i) << tempFormat->formatEOL();
1865 int startColumn = 0;
1866 for (
int i = 0; i < keyword.
indent(); i++) {
1870 QString keyname = tempFormat->formatName(keyword);
1872 startColumn += keyname.length();
1875 for (
int i = 0; i < keyword.
width() - (
int)keyname.size(); ++i) {
1883 if (keyword.
size() == 0) {
1884 os << tempFormat->formatValue(keyword);
1888 QString stringToWrite;
1889 for (
int i = 0; i < keyword.
size(); i ++) {
1890 stringToWrite += tempFormat->formatValue(keyword, i);
1898 if (removeFormatter)
delete tempFormat;
1906 if (
this != &other) {
1959 int iSize = pvlKwrd.
size();
1961 QString sType =
m_values[0].toLower();
1964 if (psValueType.length()) {
1965 psValueType = psValueType.toLower();
1968 double dRangeMin=0, dRangeMax=0;
1969 bool bRange =
false;
1970 bool bValue =
false;
1971 if (pvlKwrdValue != NULL) {
1972 QString sValueName = pvlKwrdValue->
name();
1975 if (sValueName.contains(
"__Range")) {
1976 dRangeMin =
toDouble((*pvlKwrdValue)[0]);
1977 dRangeMax =
toDouble((*pvlKwrdValue)[1]);
1980 else if (sValueName.contains(
"__Value")) {
1986 if (sType ==
"integer") {
1987 for (
int i=0; i<iSize; i++) {
1988 QString sValue = pvlKwrd[i].toLower();
1989 if (sValue !=
"null"){
1992 iValue =
toInt(sValue);
1994 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" expects an Integer value";
1997 if (bRange && (iValue < dRangeMin || iValue > dRangeMax)) {
1998 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" is not in the specified Range";
2002 bool bFound =
false;
2003 for (
int j=0; j<pvlKwrdValue->
size(); j++) {
2004 if (iValue ==
toInt((*pvlKwrdValue)[j])) {
2010 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" has value not in the accepted list";
2015 if (psValueType.length()) {
2016 if ((psValueType ==
"positive" && iValue < 0) || (psValueType ==
"negative" && iValue >= 0) ) {
2017 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" has invalid value";
2027 if (sType ==
"double") {
2028 for (
int i=0; i<iSize; i++) {
2029 QString sValue = pvlKwrd[i].toLower();
2030 if (sValue !=
"null"){
2032 if (bRange && (dValue < dRangeMin || dValue > dRangeMax)) {
2033 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" is not in the specified Range";
2037 bool bFound =
false;
2038 for (
int j=0; j<pvlKwrdValue->
size(); j++) {
2039 if (dValue ==
toDouble((*pvlKwrdValue)[j])) {
2045 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" has value not in the accepted list";
2050 if (psValueType.length()) {
2051 if ((psValueType ==
"positive" && dValue < 0) || (psValueType ==
"negative" && dValue >= 0) ) {
2052 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" has invalid value";
2062 if (sType ==
"boolean") {
2063 for (
int i=0; i<iSize; i++) {
2064 QString sValue = pvlKwrd[i].toLower();
2065 if (sValue !=
"null" && sValue !=
"true" && sValue !=
"false"){
2066 QString sErrMsg =
"Wrong Type of value in the Keyword \"" +
name() +
"\" \n";
2074 if (sType ==
"string") {
2075 for (
int i=0; i<iSize; i++) {
2076 QString sValue = pvlKwrd[i].toLower();
2078 bool bValFound =
false;
2079 for (
int i=0; i<pvlKwrdValue->
size(); i++) {
2080 if (sValue == (*pvlKwrdValue)[i].toLower()) {
2086 QString sErrMsg =
"Wrong Type of value in the Keyword \"" +
name() +
"\" \n";
@ Unknown
A type of error that cannot be classified as any of the other error types.
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
@ Programmer
This error is for when a programmer made an API call that was illegal.
Adds specific functionality to C++ strings.
IString Remove(const std::string &del)
Remove all instances of any character in the string from the IString.
IString UpCase()
Converst any lower case characters in the object IString with uppercase characters.
IString Token(const IString &separator)
Returns the first token in the IString.
IString ConvertWhiteSpace()
Returns the string with all "new lines", "carriage returns", "tabs", "formfeeds", "vertical tabs" and...
Contains multiple PvlContainers.
A single keyword-value pair.
PvlKeyword()
Constructs a blank PvlKeyword object.
std::vector< QString > * m_comments
The comments for the keyword.
QVarLengthArray< QString, 1 > m_values
The values in the keyword.
const QString & operator[](int index) const
Gets value for this object at specified index.
void setName(QString name)
Sets the keyword name.
void setJsonValue(nlohmann::json jsonobj, QString unit="")
Sets new value from Json.
QString toIPvl(const QString &value) const
Converts a value to iPVL format.
int width() const
Returns the current set longest keyword name.
QString name() const
Returns the keyword name.
int size() const
Returns the number of values stored in this keyword.
PvlKeyword & operator+=(QString value)
Adds a value.
std::vector< QString > * m_units
The units for the values.
bool isNull(const int index=0) const
Decides whether a value is null or not at a given index.
char * m_name
The keyword's name... This is a c-string for memory efficiency.
static bool readCleanKeyword(QString keyword, std::vector< QString > &keywordComments, QString &keywordName, std::vector< std::pair< QString, QString > > &keywordValues)
This reads a keyword compressed back to 1 line of data (excluding comments, which are included on sep...
QString unit(const int index=0) const
Returns the units of measurement of the element of the array of values for the object at the specifie...
~PvlKeyword()
Destructs a PvlKeyword object.
void setFormat(PvlFormat *formatter)
Set the PvlFormatter used to format the keyword name and value(s)
int comments() const
Returns the number of lines of comments associated with this keyword.
QString comment(const int index) const
Return a comment at the specified index.
PvlFormat * m_formatter
Formatter object.
int indent() const
Returns the current indent level.
QString reform(const QString &value) const
Checks if the value needs to be converted to PVL or iPVL and returns it in the correct format.
void setUnits(QString units)
Sets the unit of measure for all current values if any exist.
static bool stringEqual(const QString &string1, const QString &string2)
Checks to see if two QStrings are equal.
PvlFormat * format()
Get the current PvlFormat or create one.
void addCommentWrapped(QString comment)
Automatically wraps and adds long comments to the PvlKeyword.
QString toPvl(const QString &value) const
Converts a value to PVL format.
void addJsonValue(nlohmann::json jsonobj, QString unit="")
Adds a value with units.
PvlKeyword & operator=(QString value)
Sets new values.
void writeSpaces(std::ostream &, int) const
This writes numSpaces spaces to the ostream.
std::ostream & writeWithWrap(std::ostream &os, const QString &textToWrite, int startColumn, PvlFormat &format) const
Wraps output so that length doesn't exceed the character limit.
void setValue(QString value, QString unit="")
Sets new values.
void addComment(QString comment)
Add a comment to the PvlKeyword.
int m_width
The width of the longest keyword.
bool isEquivalent(QString string1, int index=0) const
Checks to see if a value with a specified index is equivalent to another QString.
void clearComment()
Clears the current comments.
void addComments(const std::vector< QString > &comments)
This method adds multiple comments at once by calling AddComments on each element in the vector.
static QString readLine(std::istream &is, bool insideComment)
This method reads one line of data from the input stream.
int m_indent
The number of indentations to make.
void clear()
Clears all values and units for this PvlKeyword object.
void validateKeyword(PvlKeyword &pvlKwrd, QString psValueType="", PvlKeyword *pvlKwrdRange=NULL)
Validate Keyword for type and required values.
void init()
Clears all PvlKeyword data.
void addValue(QString value, QString unit="")
Adds a value with units.
@ Traverse
Search child objects.
Parse and return elements of a Pvl sequence.
int Size() const
Number of arrays in the sequence.
QString ArraySubscriptNotInRange(int index)
This error should be used when an Isis object or application is checking array bounds and the legal r...
This is free and unencumbered software released into the public domain.
int toInt(const QString &string)
Global function to convert from a string to an integer.
std::istream & operator>>(std::istream &is, CSVReader &csv)
Input read operator for input stream sources.
double toDouble(const QString &string)
Global function to convert from a string to a double.
QDebug operator<<(QDebug debug, const Hillshade &hillshade)
Print this class out to a QDebug object.
Namespace for the standard library.