10#include <QRegularExpression>
11#include "PvlKeyword.h"
12#include "IException.h"
16#include "PvlSequence.h"
19using json = nlohmann::json;
103 if (
size() == 0)
return true;
104 if (index < 0 || index >= (
int)
m_values.size()) {
121 QString
final =
name.trimmed();
122 if (
final.contains(QRegExp(
"\\s"))) {
123 QString msg =
"[" +
name +
"] is invalid. Keyword name cannot ";
124 msg +=
"contain whitespace.";
134 QByteArray finalAscii =
final.toLatin1();
135 m_name =
new char[finalAscii.size() + 1];
136 strncpy(
m_name, finalAscii.data(),
final.size() + 1);
186 m_units =
new std::vector<QString>();
191 for (
int i = 0; i <
m_values.size(); i++) {
209 while(!found && ++i < (
int)
m_values.size()) {
223 (*m_units)[i] = units;
226 IString msg =
"PvlKeyword::setUnits called with value [" + value +
227 "] which does not exist in this Keyword";
304 if (jsonobj.is_array()) {
305 QString msg =
"Unable to convert " +
name() +
" with nested json array value into PvlKeyword";
308 else if (jsonobj.is_number())
310 value = QString::number(jsonobj.get<
double>(),
'g', 16);
312 else if (jsonobj.is_boolean())
314 value = QString(jsonobj.get<
bool>() ?
"true" :
"false");
316 else if (jsonobj.is_null())
318 value = QString(
"Null");
322 value = QString::fromStdString(jsonobj);
358 PvlKeyword::operator QString()
const {
359 return operator[](0);
376 if (index < 0 || index >= (
int)
m_values.size()) {
378 "for Keyword [" + QString(
m_name) +
"]";
398 if (index < 0 || index >= (
int)
m_values.size()) {
417 if (index < 0 || index >= (
int)
m_units->size()) {
444 else if (
comment.size() == 1) {
472 token = cmt.
Token(
" ");
473 int length = temp.size() + token.size() + 1;
474 while((length < 72) && (token.size() > 0)) {
476 token = cmt.
Token(
" ");
477 length = temp.size() + token.size() + 1;
481 if (token.size() != 0)
addComment(token.c_str());
501 if (index < 0 || index >= (
int)
m_comments->size()) {
517 static bool firstTime =
true;
518 static bool iPVL =
true;
526 if (s ==
"PVL") iPVL =
false;
529 if (iPVL)
return toIPvl(value);
542 bool lastlower =
true;
543 for (
int i = 0; i < value.size(); i++) {
544 if ((lastlower) && (value[i].isUpper())) upcase =
true;
545 if (value[i] ==
'_') {
549 out += value[i].toUpper();
554 out += value[i].toLower();
555 if (value[i].isLower()) lastlower =
true;
569 bool lastlower =
false;
570 for (
int i = 0; i < value.size(); i++) {
571 if ((lastlower) && (value[i].isUpper())) out +=
"_";
572 if (value[i] ==
'_') {
577 out += value[i].toUpper();
578 if (value[i].isLower()) lastlower =
true;
593 const QString &QString2) {
597 s1.ConvertWhiteSpace();
598 s2.ConvertWhiteSpace();
606 if (s1 == s2)
return true;
620 if (index < 0 || index >= (
int)
m_values.size()) {
635 for (
int i = 0; i < seq.Size(); i++) {
637 for (
int j = 0; j < (int)seq[i].
size(); j++) {
638 QString val = seq[i][j];
639 if (val.contains(
" ")) {
640 temp +=
"\"" + val +
"\"";
645 if (j < (
int) seq[i].size() - 1) temp +=
", ";
669 const QString &textToWrite,
720 QString remainingText = textToWrite;
726 vector< pair<int, int> > quotedAreas;
730 if (textToWrite.count() > 0 && (textToWrite[0] ==
'(' || textToWrite[0] ==
'"')) {
741 vector< pair<char, char> > quoteStartEnds;
742 quoteStartEnds.push_back(pair<char, char>(
'"',
'"'));
743 quoteStartEnds.push_back(pair<char, char>(
'\'',
'\''));
744 quoteStartEnds.push_back(pair<char, char>(
'<',
'>'));
748 for (
int pos = 0; pos < remainingText.size(); pos++) {
750 if (remainingText[pos] ==
'\n' || remainingText[pos] ==
'\r') {
751 if (pos != remainingText.size() - 1) {
752 remainingText = remainingText.mid(0, pos) +
753 remainingText.mid(pos + 1);
756 remainingText = remainingText.mid(0, pos);
761 if (quoteStart == -1) {
763 remainingText[pos-1] ==
' ' &&
764 remainingText[pos] ==
' ') {
765 remainingText = remainingText.mid(0, pos) +
766 remainingText.mid(pos + 1);
771 for (
unsigned int i = 0;
772 (quoteStart < 0) && i < quoteStartEnds.size();
774 if (quoteStartEnds[i].first == remainingText[pos]) {
784 if (quoteStart != (
int)pos && quoteStart != -1) {
785 for (
unsigned int i = 0; i < quoteStartEnds.size(); i++) {
786 if (quoteStartEnds[i].second == remainingText[pos]) {
787 if (quoteStartEnds[i].first != remainingText[quoteStart]) {
792 quotedAreas.push_back(pair<int, int>(quoteStart, pos));
806 int charsLeft = spaceForText;
807 int printedSoFar = 0;
810 while(!remainingText.isEmpty()) {
812 int lastSpacePosition = charsLeft;
816 if (lastSpacePosition >= (
int)remainingText.length()) {
817 lastSpacePosition = remainingText.length();
824 int excellentSpace = -1;
825 int searchPosition = lastSpacePosition;
826 bool doneSearching =
false;
828 while(!doneSearching) {
829 bool currentPosQuoted =
false;
831 for (
unsigned int i = 0; i < quotedAreas.size(); i++) {
832 if (searchPosition + printedSoFar >= quotedAreas[i].first &&
833 searchPosition + printedSoFar <= quotedAreas[i].second) {
834 currentPosQuoted =
true;
838 if (remainingText[searchPosition] ==
' ') {
839 bool validSpace =
true;
843 if (searchPosition > 0 && remainingText[searchPosition - 1] ==
'-') {
847 if (validSpace && goodSpace < 0) {
848 goodSpace = searchPosition;
854 if (validSpace && !currentPosQuoted) {
855 if ((
int)searchPosition < (int)(remainingText.size() - 1) &&
856 remainingText[searchPosition+1] !=
'<') {
857 excellentSpace = searchPosition;
862 doneSearching = (excellentSpace >= 0 || searchPosition <= 1);
867 if (excellentSpace > 0) {
868 lastSpacePosition = excellentSpace;
870 else if (goodSpace > 0) {
871 lastSpacePosition = goodSpace;
874 lastSpacePosition = -1;
880 if (lastSpacePosition >= 0) {
881 os << remainingText.mid(0, lastSpacePosition);
883 remainingText = remainingText.mid(lastSpacePosition);
884 printedSoFar += lastSpacePosition;
890 if (remainingText.mid(charsLeft-1, 2) ==
"//") {
891 os << remainingText.mid(0, charsLeft - 2);
893 remainingText = remainingText.mid(charsLeft - 2);
894 printedSoFar += charsLeft - 2;
897 os << remainingText.mid(0, charsLeft - 1);
899 remainingText = remainingText.mid(charsLeft - 1);
900 printedSoFar += charsLeft - 1;
905 if (!remainingText.isEmpty()) {
910 if (remainingText[0] ==
' ') {
911 remainingText = remainingText.mid(1);
916 charsLeft = spaceForText;
930 for (
int space = 0; space < numSpaces; space ++) {
969 QString keywordString;
971 bool keywordDone =
false;
972 bool multiLineComment =
false;
973 bool error = !is.good();
975 while(!error && !keywordDone) {
976 istream::pos_type beforeLine = is.tellg();
983 if (line.isEmpty() && !is.good()) {
984 if (keywordString.isEmpty() ||
985 keywordString[keywordString.size()-1] ==
'\n') {
988 if (multiLineComment) {
997 bool comment =
false;
999 if (!multiLineComment) {
1000 if (line.size() > 0 && line[0] ==
'#') {
1004 if (line.size() > 1 && line[0] ==
'/' &&
1005 (line[1] ==
'*' || line[1] ==
'/')) {
1008 if (line[1] ==
'*') {
1009 multiLineComment =
true;
1010 keywordString += line.mid(0, 2);
1011 line = line.mid(2).trimmed();
1016 if (multiLineComment) {
1019 if (line.contains(
"/*")) {
1020 IString msg =
"Error when reading a pvl: Cannot have ['/*'] inside a "
1021 "multi-line comment";
1025 if (line.contains(
"*/")) {
1026 multiLineComment =
false;
1028 line = line.mid(0, line.indexOf(
"*/")).trimmed() +
" */";
1032 if (line.isEmpty()) {
1037 keywordString += line +
'\n';
1041 else if (keywordString.isEmpty()) {
1042 keywordString = line;
1045 else if (!comment && keywordString[keywordString.size()-1] ==
'-') {
1046 keywordString = keywordString.mid(0, keywordString.size() - 1) + line;
1050 keywordString +=
" " + line;
1053 if (line[line.size()-1] ==
'-') {
1057 std::vector<QString> keywordComments;
1058 QString keywordName;
1059 std::vector< std::pair<QString, QString> > keywordValues;
1061 bool attemptedRead =
false;
1070 if (is.eof() && !is.bad()) {
1075 is.seekg(beforeLine, ios::beg);
1077 QString msg =
"Unable to read PVL keyword [";
1078 msg += keywordString;
1085 if (attemptedRead) {
1089 if (is.good() && is.peek() ==
'<' && !keywordValues.empty()) {
1096 for (
unsigned int value = 0; value < keywordValues.size(); value++) {
1097 result.
addValue(keywordValues[value].first,
1098 keywordValues[value].second);
1104 if (!attemptedRead) {
1105 error = error || !is.good();
1112 while(keywordString.contains(
'\n')) {
1113 keywordString = keywordString.mid(keywordString.indexOf(
'\n') + 1);
1118 if (keywordString.isEmpty() && !multiLineComment) {
1119 msg =
"PVL input contains no Pvl Keywords";
1121 else if (multiLineComment) {
1122 msg =
"PVL input ends while still in a multi-line comment";
1125 msg =
"The PVL keyword [" + keywordString +
"] does not appear to be";
1126 msg +=
" a valid Pvl Keyword";
1134 while(keywordString.contains(
'\n'))
1135 keywordString = keywordString.mid(keywordString.indexOf(
'\n') + 1);
1139 if (keywordString.isEmpty()) {
1140 msg =
"Error reading PVL keyword";
1143 msg =
"The PVL keyword [" + keywordString +
"] does not appear to be";
1160 for (
unsigned int i = 0; i <
comments.size(); i++) {
1181 std::vector<QString> &keywordComments,
1182 QString &keywordName,
1183 std::vector< std::pair<QString, QString> > &keywordValues) {
1185 keywordComments.clear();
1187 keywordValues.clear();
1190 bool explicitIncomplete =
false;
1199 if (keyword.isEmpty())
return 0;
1218 while(keyword.contains(
"\n")) {
1221 bool noneStripped =
true;
1225 QString keywordStart = keyword.mid(0, 2);
1228 if (keywordStart ==
"/*") {
1229 noneStripped =
false;
1230 bool inComment =
true;
1232 while(inComment && keyword.contains(
"*/")) {
1235 int closePos = keyword.indexOf(
"*/\n");
1237 if (closePos == -1) {
1238 closePos = keyword.indexOf(
"*/") + 2;
1239 keyword = keyword.mid(0, closePos) +
"\n" +
1240 keyword.mid(closePos);
1243 QString
comment = keyword.mid(0, keyword.indexOf(
"\n")).trimmed();
1247 bool needsStart = (
comment.size() < 2);
1248 bool needsStartSpace =
comment.size() < 3;
1250 int commentEndPos =
comment.size() - 2;
1251 bool needsEnd = (commentEndPos < 0);
1252 bool needsEndSpace =
comment.size() < 3;
1258 needsStart = (
comment.mid(0, 2) !=
"/*");
1262 needsEnd = (
comment.mid(commentEndPos, 2) !=
"*/");
1265 if (!needsStartSpace) {
1266 needsStartSpace = (
comment.mid(0, 3) !=
"/* ");
1269 if (!needsEndSpace) {
1270 needsEndSpace = (
comment.mid(commentEndPos - 1, 3) !=
" */");
1276 else if (needsStartSpace) {
1283 else if (needsEndSpace) {
1287 inComment = needsEnd;
1289 keywordComments.push_back(
comment);
1291 if (keyword.contains(
"\n")) {
1292 keyword = keyword.mid(keyword.indexOf(
"\n") + 1).trimmed();
1297 if (keyword.size() >= 2)
1298 keywordStart = keyword.mid(0, 2);
1300 inComment = (keywordStart ==
"/*");
1307 for (
unsigned int index = 0; index < keywordComments.size(); index++) {
1308 QString
comment = keywordComments[index];
1315 for (
unsigned int index = 0; index < keywordComments.size(); index++) {
1316 QString
comment = keywordComments[index];
1318 while(
comment.size() < longest) {
1323 keywordComments[index] =
comment;
1329 for (
unsigned int commentType = 0;
1330 commentType <
sizeof(
comments) /
sizeof(QString);
1333 if (keywordStart.startsWith(
comments[commentType])) {
1336 QString
comment = keyword.mid(0, keyword.indexOf(
"\n"));
1337 keywordComments.push_back(
comment.trimmed());
1339 noneStripped =
false;
1341 if (keyword.contains(
"\n")) {
1342 keyword = keyword.mid(keyword.indexOf(
"\n") + 1).trimmed();
1349 if (noneStripped && keyword.contains(
"/*") &&
1350 keyword.contains(
"*/")) {
1351 QString firstPart = keyword.mid(0, keyword.indexOf(
"\n"));
1352 QString lastPart = keyword.mid(keyword.indexOf(
"\n") + 1);
1354 keyword = firstPart.trimmed() +
" " + lastPart.trimmed();
1355 noneStripped =
false;
1359 QString msg =
"Expected a comment in PVL but found [";
1367 if (keyword.isEmpty()) {
1382 keywordName = readValue(keyword, explicitIncomplete);
1386 if (keyword.isEmpty()) {
1400 if (keyword[0] !=
'=') {
1401 QString msg =
"Expected an assignment [=] when reading PVL, but found [";
1408 keyword = keyword.mid(1).trimmed();
1410 if (keyword.isEmpty()) {
1415 if (keyword[0] ==
'(' || keyword[0] ==
'{') {
1425 char closingParen = ((keyword[0] ==
'(') ?
')' :
'}');
1426 char wrongClosingParen = ((keyword[0] ==
'(') ?
'}' :
')');
1427 bool closedProperly =
false;
1429 vector< pair<char, char> > extraDelims;
1430 extraDelims.push_back(pair<char, char>(
'(',
')'));
1431 extraDelims.push_back(pair<char, char>(
'{',
'}'));
1435 keyword = keyword.mid(1).trimmed();
1438 if (!keyword.isEmpty() && keyword[0] == closingParen) {
1439 closedProperly =
true;
1445 while(!keyword.isEmpty() && keyword[0] != closingParen) {
1448 bool foundComma =
false;
1451 QString nextItem = readValue(keyword, explicitIncomplete, extraDelims);
1453 if (!keyword.isEmpty() && keyword[0] == wrongClosingParen) {
1455 QString msg =
"Incorrect array close when reading PVL; expected [";
1456 msg += closingParen;
1457 msg +=
"] but found [";
1458 msg += wrongClosingParen;
1459 msg +=
"] in keyword named [";
1466 pair<QString, QString> keywordValue;
1469 keywordValue.first = nextItem;
1473 if (!keyword.isEmpty() && keyword[0] ==
'<') {
1474 QString unitsValue = readValue(keyword, explicitIncomplete);
1475 keywordValue.second = unitsValue;
1479 if (!keyword.isEmpty() && keyword[0] ==
',') {
1481 keyword = keyword.mid(1).trimmed();
1487 if (!foundComma && keyword.isEmpty()) {
1491 bool foundCloseParen = (!keyword.isEmpty() && keyword[0] == closingParen);
1493 if (foundCloseParen) {
1494 closedProperly =
true;
1500 if (foundComma && foundCloseParen) {
1501 QString msg =
"Unexpected close of keyword-value array when reading "
1507 if (!foundComma && !foundCloseParen) {
1509 if (explicitIncomplete)
return false;
1512 QString msg =
"Found extra data after [";
1514 msg +=
"] in array when reading PVL";
1519 keywordValues.push_back(keywordValue);
1522 if (!closedProperly) {
1527 if (!keyword.isEmpty()) {
1528 keyword = keyword.mid(1).trimmed();
1533 if (!keyword.isEmpty() && keyword[0] ==
'<') {
1534 QString units = readValue(keyword, explicitIncomplete);
1535 for (
unsigned int val = 0; val < keywordValues.size(); val++) {
1536 if (keywordValues[val].second.isEmpty()) {
1537 keywordValues[val].second = units;
1551 pair<QString, QString> keywordValue;
1552 keywordValue.first = readValue(keyword, explicitIncomplete);
1554 if (!keyword.isEmpty() && keyword[0] ==
'<') {
1555 keywordValue.second = readValue(keyword, explicitIncomplete);
1558 keywordValues.push_back(keywordValue);
1565 if (explicitIncomplete) {
1572 if (!keyword.isEmpty()) {
1574 if (keyword[0] ==
'#' ||
1575 ((keyword.size() > 1 && keyword[0] ==
'/') &&
1576 (keyword[1] ==
'/' || keyword[1] ==
'*'))) {
1577 keywordComments.push_back(keyword);
1579 if (keyword.size() > 1 && keyword.mid(0, 2) ==
"/*") {
1580 if (keyword.mid(keyword.size() - 2, 2) !=
"*/")
1589 QRegularExpression regex(
"^,");
1590 QRegularExpressionMatch match = regex.match(keyword);
1591 if (!keyword.isEmpty() && match.hasMatch()) {
1592 keywordValues.at(0).first += keyword;
1599 if (!keyword.isEmpty()) {
1600 QString msg =
"Keyword has extraneous data [";
1602 msg +=
"] at the end";
1611 QString PvlKeyword::readValue(QString &keyword,
bool "eProblem) {
1612 std::vector< std::pair<char, char> > otherDelims;
1614 return readValue(keyword, quoteProblem, otherDelims);
1633 QString PvlKeyword::readValue(QString &keyword,
bool "eProblem,
1634 const std::vector< std::pair<char, char> > &
1640 keyword = keyword.trimmed();
1642 if (keyword.isEmpty()) {
1650 bool impliedQuote =
true;
1651 QChar quoteEnd =
' ';
1652 bool keepQuotes =
false;
1654 if (keyword[0] ==
'\'' || keyword[0] ==
'"') {
1655 quoteEnd = keyword[0];
1656 impliedQuote =
false;
1658 else if (keyword[0] ==
'<') {
1660 impliedQuote =
false;
1664 char implicitQuotes[] = {
1674 bool foundImplicitQuote =
false;
1677 while(!foundImplicitQuote && currentPos != keyword.size()) {
1678 for (
unsigned int quote = 0;
1679 quote <
sizeof(implicitQuotes) /
sizeof(
char);
1681 if (keyword[currentPos] == implicitQuotes[quote]) {
1682 quoteEnd = implicitQuotes[quote];
1683 foundImplicitQuote =
true;
1687 if (!foundImplicitQuote) {
1693 for (
unsigned int delim = 0; delim < otherDelimiters.size(); delim ++) {
1694 if (keyword[0] == otherDelimiters[delim].first) {
1695 quoteEnd = otherDelimiters[delim].second;
1697 impliedQuote =
false;
1705 if (!impliedQuote) {
1706 startQuote += keyword[0];
1707 keyword = keyword.mid(1);
1711 int quoteEndPos = keyword.indexOf(quoteEnd);
1713 if (quoteEndPos != -1) {
1714 value = keyword.mid(0, quoteEndPos);
1720 if (!impliedQuote) {
1721 keyword = keyword.mid(quoteEndPos + 1);
1724 keyword = keyword.mid(quoteEndPos);
1728 keyword = keyword.trimmed();
1731 value = startQuote + value + quoteEnd;
1738 else if (!impliedQuote) {
1740 keyword = startQuote + keyword;
1741 quoteProblem =
true;
1633 QString PvlKeyword::readValue(QString &keyword,
bool "eProblem, {
…}
1771 while(is.good() && lineOfData.isEmpty()) {
1775 (!lineOfData.size() || lineOfData[lineOfData.size() - 1] !=
'\n')) {
1776 char next = is.get();
1780 is.seekg(0, ios::end);
1791 if (insideComment &&
1792 lineOfData.size() >= 2 && lineOfData[lineOfData.size() - 2] ==
'*' &&
1793 lineOfData[lineOfData.size() - 1] ==
'/') {
1797 else if (lineOfData.size() >= 2 &&
1798 lineOfData[lineOfData.size() - 2] ==
'/' &&
1799 lineOfData[lineOfData.size() - 1] ==
'*') {
1800 insideComment =
true;
1805 lineOfData = lineOfData.trimmed();
1809 (is.peek() ==
' ' ||
1810 is.peek() ==
'\r' ||
1811 is.peek() ==
'\n')) {
1833 bool removeFormatter =
false;
1834 if (tempFormat == NULL) {
1836 removeFormatter =
true;
1840 for (
int i = 0; i < keyword.
comments(); i++) {
1841 for (
int j = 0; j < keyword.
indent(); j++) os <<
" ";
1842 os << keyword.
comment(i) << tempFormat->formatEOL();
1846 int startColumn = 0;
1847 for (
int i = 0; i < keyword.
indent(); i++) {
1851 QString keyname = tempFormat->formatName(keyword);
1853 startColumn += keyname.length();
1856 for (
int i = 0; i < keyword.
width() - (
int)keyname.size(); ++i) {
1864 if (keyword.
size() == 0) {
1865 os << tempFormat->formatValue(keyword);
1869 QString stringToWrite;
1870 for (
int i = 0; i < keyword.
size(); i ++) {
1871 stringToWrite += tempFormat->formatValue(keyword, i);
1879 if (removeFormatter)
delete tempFormat;
1887 if (
this != &other) {
1906 if (other.m_units) {
1907 m_units =
new std::vector<QString>(*other.m_units);
1915 if (other.m_comments) {
1916 m_comments =
new std::vector<QString>(*other.m_comments);
1940 int iSize = pvlKwrd.size();
1942 QString sType =
m_values[0].toLower();
1945 if (psValueType.length()) {
1946 psValueType = psValueType.toLower();
1949 double dRangeMin=0, dRangeMax=0;
1950 bool bRange =
false;
1951 bool bValue =
false;
1952 if (pvlKwrdValue != NULL) {
1953 QString sValueName = pvlKwrdValue->name();
1956 if (sValueName.contains(
"__Range")) {
1957 dRangeMin =
toDouble((*pvlKwrdValue)[0]);
1958 dRangeMax =
toDouble((*pvlKwrdValue)[1]);
1961 else if (sValueName.contains(
"__Value")) {
1967 if (sType ==
"integer") {
1968 for (
int i=0; i<iSize; i++) {
1969 QString sValue = pvlKwrd[i].toLower();
1970 if (sValue !=
"null"){
1973 iValue =
toInt(sValue);
1975 QString sErrMsg =
"\"" +pvlKwrd.name() +
"\" expects an Integer value";
1978 if (bRange && (iValue < dRangeMin || iValue > dRangeMax)) {
1979 QString sErrMsg =
"\"" +pvlKwrd.name() +
"\" is not in the specified Range";
1983 bool bFound =
false;
1984 for (
int j=0; j<pvlKwrdValue->size(); j++) {
1985 if (iValue ==
toInt((*pvlKwrdValue)[j])) {
1991 QString sErrMsg =
"\"" +pvlKwrd.name() +
"\" has value not in the accepted list";
1996 if (psValueType.length()) {
1997 if ((psValueType ==
"positive" && iValue < 0) || (psValueType ==
"negative" && iValue >= 0) ) {
1998 QString sErrMsg =
"\"" +pvlKwrd.name() +
"\" has invalid value";
2008 if (sType ==
"double") {
2009 for (
int i=0; i<iSize; i++) {
2010 QString sValue = pvlKwrd[i].toLower();
2011 if (sValue !=
"null"){
2013 if (bRange && (dValue < dRangeMin || dValue > dRangeMax)) {
2014 QString sErrMsg =
"\"" +pvlKwrd.name() +
"\" is not in the specified Range";
2018 bool bFound =
false;
2019 for (
int j=0; j<pvlKwrdValue->size(); j++) {
2020 if (dValue ==
toDouble((*pvlKwrdValue)[j])) {
2026 QString sErrMsg =
"\"" +pvlKwrd.name() +
"\" has value not in the accepted list";
2031 if (psValueType.length()) {
2032 if ((psValueType ==
"positive" && dValue < 0) || (psValueType ==
"negative" && dValue >= 0) ) {
2033 QString sErrMsg =
"\"" +pvlKwrd.name() +
"\" has invalid value";
2043 if (sType ==
"boolean") {
2044 for (
int i=0; i<iSize; i++) {
2045 QString sValue = pvlKwrd[i].toLower();
2046 if (sValue !=
"null" && sValue !=
"true" && sValue !=
"false"){
2047 QString sErrMsg =
"Wrong Type of value in the Keyword \"" +
name() +
"\" \n";
2055 if (sType ==
"string") {
2056 for (
int i=0; i<iSize; i++) {
2057 QString sValue = pvlKwrd[i].toLower();
2059 bool bValFound =
false;
2060 for (
int i=0; i<pvlKwrdValue->size(); i++) {
2061 if (sValue == (*pvlKwrdValue)[i].toLower()) {
2067 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 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.
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.
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.