23 #include "IsisDebug.h" 38 PvlKeyword::PvlKeyword() {
48 PvlKeyword::PvlKeyword(QString name) {
62 PvlKeyword::PvlKeyword(QString name, QString value,
66 addValue(value, unit);
80 PvlKeyword::~PvlKeyword() {
99 void PvlKeyword::init() {
118 bool PvlKeyword::isNull(
int index)
const {
119 if (size() == 0)
return true;
120 if (index < 0 || index >= (
int)m_values.size()) {
124 if (stringEqual(
"NULL", m_values[index]))
return true;
125 if (stringEqual(
"", m_values[index]))
return true;
126 if (stringEqual(
"\"\"", m_values[index]))
return true;
127 if (stringEqual(
"''", m_values[index]))
return true;
136 void PvlKeyword::setName(QString name) {
137 QString
final = name.trimmed();
138 if (
final.contains(QRegExp(
"\\s"))) {
139 QString msg =
"[" + name +
"] is invalid. Keyword name cannot ";
140 msg +=
"contain whitespace.";
150 QByteArray finalAscii =
final.toLatin1();
151 m_name =
new char[finalAscii.size() + 1];
152 strncpy(m_name, finalAscii.data(),
final.size() + 1);
171 void PvlKeyword::setValue(QString value, QString unit) {
173 addValue(value, unit);
182 void PvlKeyword::setUnits(QString units) {
184 m_units =
new std::vector<QString>();
189 for (
int i = 0; i < m_values.size(); i++) {
190 m_units->push_back(units);
203 void PvlKeyword::setUnits(QString value, QString units) {
207 while(!found && ++i < (
int) m_values.size()) {
208 if (value == m_values[i]) {
215 m_units =
new std::vector<QString>(m_values.size());
218 m_units->resize(m_values.size());
221 ASSERT(i < (
int) m_units->size());
223 (*m_units)[i] = units;
226 IString msg =
"PvlKeyword::setUnits called with value [" + value +
227 "] which does not exist in this Keyword";
268 void PvlKeyword::addValue(QString value, QString unit) {
269 m_values.append(value);
273 m_units =
new std::vector<QString>(m_values.size());
276 m_units->resize(m_values.size());
279 (*m_units)[m_units->size() - 1] = unit;
282 m_units->push_back(
"");
307 void PvlKeyword::clear() {
317 PvlKeyword::operator QString()
const {
318 return operator[](0);
334 QString &PvlKeyword::operator[](
int index) {
335 if (index < 0 || index >= (
int)m_values.size()) {
337 "for Keyword [" + QString(m_name) +
"]";
341 return m_values[index];
356 const QString &PvlKeyword::operator[](
int index)
const {
357 if (index < 0 || index >= (
int)m_values.size()) {
361 return m_values[index];
373 QString PvlKeyword::unit(
int index)
const {
374 if (!m_units)
return "";
376 if (index < 0 || index >= (
int)m_units->size()) {
380 return (*m_units)[index];
392 void PvlKeyword::addComment(QString comment) {
394 m_comments =
new std::vector<QString>();
397 if (comment.size() == 0) {
398 m_comments->push_back(
"#");
400 if (comment[0] ==
'#') {
401 m_comments->push_back(comment);
403 else if (comment.size() == 1) {
404 m_comments->push_back(
"# " + comment);
406 else if ((comment[0] ==
'/') && (comment[1] ==
'*')) {
407 m_comments->push_back(comment);
409 else if ((comment[0] ==
'/') && (comment[1] ==
'/')) {
410 m_comments->push_back(comment);
413 m_comments->push_back(
"# " + comment);
426 void PvlKeyword::addCommentWrapped(QString comment) {
431 token = cmt.
Token(
" ");
432 int length = temp.size() + token.size() + 1;
433 while((length < 72) && (token.size() > 0)) {
435 token = cmt.
Token(
" ");
436 length = temp.size() + token.size() + 1;
438 addComment(temp.c_str());
440 if (token.size() != 0) addComment(token.c_str());
444 void PvlKeyword::clearComment() {
457 QString PvlKeyword::comment(
int index)
const {
458 if (!m_comments)
return "";
460 if (index < 0 || index >= (
int)m_comments->size()) {
464 return (*m_comments)[index];
474 QString PvlKeyword::reform(
const QString &value)
const {
476 static bool firstTime =
true;
477 static bool iPVL =
true;
485 if (s ==
"PVL") iPVL =
false;
488 if (iPVL)
return toIPvl(value);
498 QString PvlKeyword::toIPvl(
const QString &value)
const {
501 bool lastlower =
true;
502 for (
int i = 0; i < value.size(); i++) {
503 if ((lastlower) && (value[i].isUpper())) upcase =
true;
504 if (value[i] ==
'_') {
508 out += value[i].toUpper();
513 out += value[i].toLower();
514 if (value[i].isLower()) lastlower =
true;
526 QString PvlKeyword::toPvl(
const QString &value)
const {
528 bool lastlower =
false;
529 for (
int i = 0; i < value.size(); i++) {
530 if ((lastlower) && (value[i].isUpper())) out +=
"_";
531 if (value[i] ==
'_') {
536 out += value[i].toUpper();
537 if (value[i].isLower()) lastlower =
true;
551 bool PvlKeyword::stringEqual(
const QString &QString1,
552 const QString &QString2) {
565 if (s1 == s2)
return true;
578 bool PvlKeyword::isEquivalent(QString QString1,
int index)
const {
579 if (index < 0 || index >= (
int)m_values.size()) {
584 return stringEqual(m_values[index], QString1);
594 for (
int i = 0; i < seq.
Size(); i++) {
596 for (
int j = 0; j < (int)seq[i].size(); j++) {
597 QString val = seq[i][j];
598 if (val.contains(
" ")) {
599 temp +=
"\"" + val +
"\"";
604 if (j < (
int) seq[i].size() - 1) temp +=
", ";
607 this->operator+=(temp);
627 ostream &PvlKeyword::writeWithWrap(std::ostream &os,
628 const QString &textToWrite,
679 QString remainingText = textToWrite;
680 int spaceForText = format.
charLimit() - 1 - format.formatEOL().length() - startColumn;
685 vector< pair<int, int> > quotedAreas;
689 if (textToWrite.count() > 0 && (textToWrite[0] ==
'(' || textToWrite[0] ==
'"')) {
700 vector< pair<char, char> > quoteStartEnds;
701 quoteStartEnds.push_back(pair<char, char>(
'"',
'"'));
702 quoteStartEnds.push_back(pair<char, char>(
'\'',
'\''));
703 quoteStartEnds.push_back(pair<char, char>(
'<',
'>'));
707 for (
int pos = 0; pos < remainingText.size(); pos++) {
709 if (remainingText[pos] ==
'\n' || remainingText[pos] ==
'\r') {
710 if (pos != remainingText.size() - 1) {
711 remainingText = remainingText.mid(0, pos) +
712 remainingText.mid(pos + 1);
715 remainingText = remainingText.mid(0, pos);
720 if (quoteStart == -1) {
722 remainingText[pos-1] ==
' ' &&
723 remainingText[pos] ==
' ') {
724 remainingText = remainingText.mid(0, pos) +
725 remainingText.mid(pos + 1);
730 for (
unsigned int i = 0;
731 (quoteStart < 0) && i < quoteStartEnds.size();
733 if (quoteStartEnds[i].first == remainingText[pos]) {
743 if (quoteStart != (
int)pos && quoteStart != -1) {
744 for (
unsigned int i = 0; i < quoteStartEnds.size(); i++) {
745 if (quoteStartEnds[i].second == remainingText[pos]) {
746 if (quoteStartEnds[i].first != remainingText[quoteStart]) {
751 quotedAreas.push_back(pair<int, int>(quoteStart, pos));
765 int charsLeft = spaceForText;
766 int printedSoFar = 0;
769 while(!remainingText.isEmpty()) {
771 int lastSpacePosition = charsLeft;
775 if (lastSpacePosition >= (
int)remainingText.length()) {
776 lastSpacePosition = remainingText.length();
783 int excellentSpace = -1;
784 int searchPosition = lastSpacePosition;
785 bool doneSearching =
false;
787 while(!doneSearching) {
788 bool currentPosQuoted =
false;
790 for (
unsigned int i = 0; i < quotedAreas.size(); i++) {
791 if (searchPosition + printedSoFar >= quotedAreas[i].first &&
792 searchPosition + printedSoFar <= quotedAreas[i].second) {
793 currentPosQuoted =
true;
797 if (remainingText[searchPosition] ==
' ') {
798 bool validSpace =
true;
802 if (searchPosition > 0 && remainingText[searchPosition - 1] ==
'-') {
806 if (validSpace && goodSpace < 0) {
807 goodSpace = searchPosition;
813 if (validSpace && !currentPosQuoted) {
814 if ((
int)searchPosition < (int)(remainingText.size() - 1) &&
815 remainingText[searchPosition+1] !=
'<') {
816 excellentSpace = searchPosition;
821 doneSearching = (excellentSpace >= 0 || searchPosition <= 1);
826 if (excellentSpace > 0) {
827 lastSpacePosition = excellentSpace;
829 else if (goodSpace > 0) {
830 lastSpacePosition = goodSpace;
833 lastSpacePosition = -1;
839 if (lastSpacePosition >= 0) {
840 os << remainingText.mid(0, lastSpacePosition);
842 remainingText = remainingText.mid(lastSpacePosition);
843 printedSoFar += lastSpacePosition;
849 if (remainingText.mid(charsLeft-1, 2) ==
"//") {
850 os << remainingText.mid(0, charsLeft - 2);
852 remainingText = remainingText.mid(charsLeft - 2);
853 printedSoFar += charsLeft - 2;
856 os << remainingText.mid(0, charsLeft - 1);
858 remainingText = remainingText.mid(charsLeft - 1);
859 printedSoFar += charsLeft - 1;
864 if (!remainingText.isEmpty()) {
865 os << format.formatEOL();
866 writeSpaces(os, startColumn);
869 if (remainingText[0] ==
' ') {
870 remainingText = remainingText.mid(1);
875 charsLeft = spaceForText;
888 void PvlKeyword::writeSpaces(std::ostream &os,
int numSpaces)
const {
889 for (
int space = 0; space < numSpaces; space ++) {
902 m_formatter = formatter;
928 QString keywordString;
930 bool keywordDone =
false;
931 bool multiLineComment =
false;
932 bool error = !is.good();
934 while(!error && !keywordDone) {
935 istream::pos_type beforeLine = is.tellg();
937 line = PvlKeyword::readLine(is, multiLineComment);
942 if (line.isEmpty() && !is.good()) {
943 if (keywordString.isEmpty() ||
944 keywordString[keywordString.size()-1] ==
'\n') {
947 if (multiLineComment) {
956 bool comment =
false;
958 if (!multiLineComment) {
959 if (line.size() > 0 && line[0] ==
'#') {
963 if (line.size() > 1 && line[0] ==
'/' &&
964 (line[1] ==
'*' || line[1] ==
'/')) {
967 if (line[1] ==
'*') {
968 multiLineComment =
true;
969 keywordString += line.mid(0, 2);
970 line = line.mid(2).trimmed();
975 if (multiLineComment) {
978 if (line.contains(
"/*")) {
979 IString msg =
"Error when reading a pvl: Cannot have ['/*'] inside a " 980 "multi-line comment";
984 if (line.contains(
"*/")) {
985 multiLineComment =
false;
987 line = line.mid(0, line.indexOf(
"*/")).trimmed() +
" */";
991 if (line.isEmpty()) {
996 keywordString += line +
'\n';
1000 else if (keywordString.isEmpty()) {
1001 keywordString = line;
1004 else if (!comment && keywordString[keywordString.size()-1] ==
'-') {
1005 keywordString = keywordString.mid(0, keywordString.size() - 1) + line;
1009 keywordString +=
" " + line;
1012 if (line[line.size()-1] ==
'-') {
1016 std::vector<QString> keywordComments;
1017 QString keywordName;
1018 std::vector< std::pair<QString, QString> > keywordValues;
1020 bool attemptedRead =
false;
1023 attemptedRead = PvlKeyword::readCleanKeyword(keywordString,
1029 if (is.eof() && !is.bad()) {
1034 is.seekg(beforeLine, ios::beg);
1036 QString msg =
"Unable to read PVL keyword [";
1037 msg += keywordString;
1044 if (attemptedRead) {
1048 if (is.good() && is.peek() ==
'<' && !keywordValues.empty()) {
1055 for (
unsigned int value = 0; value < keywordValues.size(); value++) {
1056 result.
addValue(keywordValues[value].first,
1057 keywordValues[value].second);
1063 if (!attemptedRead) {
1064 error = error || !is.good();
1071 while(keywordString.contains(
'\n')) {
1072 keywordString = keywordString.mid(keywordString.indexOf(
'\n') + 1);
1077 if (keywordString.isEmpty() && !multiLineComment) {
1078 msg =
"PVL input contains no Pvl Keywords";
1080 else if (multiLineComment) {
1081 msg =
"PVL input ends while still in a multi-line comment";
1084 msg =
"The PVL keyword [" + keywordString +
"] does not appear to be";
1085 msg +=
" a valid Pvl Keyword";
1093 while(keywordString.contains(
'\n'))
1094 keywordString = keywordString.mid(keywordString.indexOf(
'\n') + 1);
1098 if (keywordString.isEmpty()) {
1099 msg =
"Error reading PVL keyword";
1102 msg =
"The PVL keyword [" + keywordString +
"] does not appear to be";
1118 void PvlKeyword::addComments(
const std::vector<QString> &comments) {
1119 for (
unsigned int i = 0; i < comments.size(); i++) {
1120 addComment(comments[i]);
1139 bool PvlKeyword::readCleanKeyword(QString keyword,
1140 std::vector<QString> &keywordComments,
1141 QString &keywordName,
1142 std::vector< std::pair<QString, QString> > &keywordValues) {
1144 keywordComments.clear();
1146 keywordValues.clear();
1149 bool explicitIncomplete =
false;
1152 QString comments[] = {
1158 if (keyword.isEmpty())
return 0;
1177 while(keyword.contains(
"\n")) {
1180 bool noneStripped =
true;
1184 QString keywordStart = keyword.mid(0, 2);
1187 if (keywordStart ==
"/*") {
1188 noneStripped =
false;
1189 bool inComment =
true;
1191 while(inComment && keyword.contains(
"*/")) {
1194 int closePos = keyword.indexOf(
"*/\n");
1196 if (closePos == -1) {
1197 closePos = keyword.indexOf(
"*/") + 2;
1198 keyword = keyword.mid(0, closePos) +
"\n" +
1199 keyword.mid(closePos);
1202 QString comment = keyword.mid(0, keyword.indexOf(
"\n")).trimmed();
1206 bool needsStart = (comment.size() < 2);
1207 bool needsStartSpace = comment.size() < 3;
1209 int commentEndPos = comment.size() - 2;
1210 bool needsEnd = (commentEndPos < 0);
1211 bool needsEndSpace = comment.size() < 3;
1217 needsStart = (comment.mid(0, 2) !=
"/*");
1221 needsEnd = (comment.mid(commentEndPos, 2) !=
"*/");
1224 if (!needsStartSpace) {
1225 needsStartSpace = (comment.mid(0, 3) !=
"/* ");
1228 if (!needsEndSpace) {
1229 needsEndSpace = (comment.mid(commentEndPos - 1, 3) !=
" */");
1233 comment =
"/* " + comment;
1235 else if (needsStartSpace) {
1236 comment =
"/* " + comment.mid(2);
1240 comment = comment +
" */";
1242 else if (needsEndSpace) {
1243 comment = comment.mid(0, comment.size() - 2) +
" */";;
1246 inComment = needsEnd;
1248 keywordComments.push_back(comment);
1250 if (keyword.contains(
"\n")) {
1251 keyword = keyword.mid(keyword.indexOf(
"\n") + 1).trimmed();
1256 if (keyword.size() >= 2)
1257 keywordStart = keyword.mid(0, 2);
1259 inComment = (keywordStart ==
"/*");
1266 for (
unsigned int index = 0; index < keywordComments.size(); index++) {
1267 QString comment = keywordComments[index];
1269 if (comment.size() > longest)
1270 longest = comment.size();
1274 for (
unsigned int index = 0; index < keywordComments.size(); index++) {
1275 QString comment = keywordComments[index];
1277 while(comment.size() < longest) {
1279 comment = comment.mid(0, comment.size() - 2) +
" */";
1282 keywordComments[index] = comment;
1288 for (
unsigned int commentType = 0;
1289 commentType <
sizeof(comments) /
sizeof(QString);
1292 if (keywordStart.startsWith(comments[commentType])) {
1295 QString comment = keyword.mid(0, keyword.indexOf(
"\n"));
1296 keywordComments.push_back(comment.trimmed());
1298 noneStripped =
false;
1300 if (keyword.contains(
"\n")) {
1301 keyword = keyword.mid(keyword.indexOf(
"\n") + 1).trimmed();
1308 if (noneStripped && keyword.contains(
"/*") &&
1309 keyword.contains(
"*/")) {
1310 QString firstPart = keyword.mid(0, keyword.indexOf(
"\n"));
1311 QString lastPart = keyword.mid(keyword.indexOf(
"\n") + 1);
1313 keyword = firstPart.trimmed() +
" " + lastPart.trimmed();
1314 noneStripped =
false;
1318 QString msg =
"Expected a comment in PVL but found [";
1326 if (keyword.isEmpty()) {
1341 keywordName = readValue(keyword, explicitIncomplete);
1345 if (keyword.isEmpty()) {
1359 if (keyword[0] !=
'=') {
1360 QString msg =
"Expected an assignment [=] when reading PVL, but found [";
1367 keyword = keyword.mid(1).trimmed();
1369 if (keyword.isEmpty()) {
1374 if (keyword[0] ==
'(' || keyword[0] ==
'{') {
1384 char closingParen = ((keyword[0] ==
'(') ?
')' :
'}');
1385 char wrongClosingParen = ((keyword[0] ==
'(') ?
'}' :
')');
1386 bool closedProperly =
false;
1388 vector< pair<char, char> > extraDelims;
1389 extraDelims.push_back(pair<char, char>(
'(',
')'));
1390 extraDelims.push_back(pair<char, char>(
'{',
'}'));
1394 keyword = keyword.mid(1).trimmed();
1397 if (!keyword.isEmpty() && keyword[0] == closingParen) {
1398 closedProperly =
true;
1404 while(!keyword.isEmpty() && keyword[0] != closingParen) {
1407 bool foundComma =
false;
1410 QString nextItem = readValue(keyword, explicitIncomplete, extraDelims);
1412 if (!keyword.isEmpty() && keyword[0] == wrongClosingParen) {
1414 QString msg =
"Incorrect array close when reading PVL; expected [";
1415 msg += closingParen;
1416 msg +=
"] but found [";
1417 msg += wrongClosingParen;
1418 msg +=
"] in keyword named [";
1425 pair<QString, QString> keywordValue;
1428 keywordValue.first = nextItem;
1432 if (!keyword.isEmpty() && keyword[0] ==
'<') {
1433 QString unitsValue = readValue(keyword, explicitIncomplete);
1434 keywordValue.second = unitsValue;
1438 if (!keyword.isEmpty() && keyword[0] ==
',') {
1440 keyword = keyword.mid(1).trimmed();
1446 if (!foundComma && keyword.isEmpty()) {
1450 bool foundCloseParen = (!keyword.isEmpty() && keyword[0] == closingParen);
1452 if (foundCloseParen) {
1453 closedProperly =
true;
1459 if (foundComma && foundCloseParen) {
1460 QString msg =
"Unexpected close of keyword-value array when reading " 1466 if (!foundComma && !foundCloseParen) {
1468 if (explicitIncomplete)
return false;
1471 QString msg =
"Found extra data after [";
1473 msg +=
"] in array when reading PVL";
1478 keywordValues.push_back(keywordValue);
1481 if (!closedProperly) {
1486 if (!keyword.isEmpty()) {
1487 keyword = keyword.mid(1).trimmed();
1492 if (!keyword.isEmpty() && keyword[0] ==
'<') {
1493 QString units = readValue(keyword, explicitIncomplete);
1494 for (
unsigned int val = 0; val < keywordValues.size(); val++) {
1495 if (keywordValues[val].second.isEmpty()) {
1496 keywordValues[val].second = units;
1510 pair<QString, QString> keywordValue;
1511 keywordValue.first = readValue(keyword, explicitIncomplete);
1513 if (!keyword.isEmpty() && keyword[0] ==
'<') {
1514 keywordValue.second = readValue(keyword, explicitIncomplete);
1517 keywordValues.push_back(keywordValue);
1524 if (explicitIncomplete) {
1531 if (!keyword.isEmpty()) {
1533 if (keyword[0] ==
'#' ||
1534 ((keyword.size() > 1 && keyword[0] ==
'/') &&
1535 (keyword[1] ==
'/' || keyword[1] ==
'*'))) {
1536 keywordComments.push_back(keyword);
1538 if (keyword.size() > 1 && keyword.mid(0, 2) ==
"/*") {
1539 if (keyword.mid(keyword.size() - 2, 2) !=
"*/")
1550 if (!keyword.isEmpty()) {
1551 QString msg =
"Keyword has extraneous data [";
1553 msg +=
"] at the end";
1562 QString PvlKeyword::readValue(QString &keyword,
bool "eProblem) {
1563 std::vector< std::pair<char, char> > otherDelims;
1565 return readValue(keyword, quoteProblem, otherDelims);
1584 QString PvlKeyword::readValue(QString &keyword,
bool "eProblem,
1585 const std::vector< std::pair<char, char> > &
1591 keyword = keyword.trimmed();
1593 if (keyword.isEmpty()) {
1601 bool impliedQuote =
true;
1602 QChar quoteEnd =
' ';
1603 bool keepQuotes =
false;
1605 if (keyword[0] ==
'\'' || keyword[0] ==
'"') {
1606 quoteEnd = keyword[0];
1607 impliedQuote =
false;
1609 else if (keyword[0] ==
'<') {
1611 impliedQuote =
false;
1615 char implicitQuotes[] = {
1625 bool foundImplicitQuote =
false;
1628 while(!foundImplicitQuote && currentPos != keyword.size()) {
1629 for (
unsigned int quote = 0;
1630 quote <
sizeof(implicitQuotes) /
sizeof(
char);
1632 if (keyword[currentPos] == implicitQuotes[quote]) {
1633 quoteEnd = implicitQuotes[quote];
1634 foundImplicitQuote =
true;
1638 if (!foundImplicitQuote) {
1644 for (
unsigned int delim = 0; delim < otherDelimiters.size(); delim ++) {
1645 if (keyword[0] == otherDelimiters[delim].first) {
1646 quoteEnd = otherDelimiters[delim].second;
1648 impliedQuote =
false;
1656 if (!impliedQuote) {
1657 startQuote += keyword[0];
1658 keyword = keyword.mid(1);
1662 int quoteEndPos = keyword.indexOf(quoteEnd);
1664 if (quoteEndPos != -1) {
1665 value = keyword.mid(0, quoteEndPos);
1671 if (!impliedQuote) {
1672 keyword = keyword.mid(quoteEndPos + 1);
1675 keyword = keyword.mid(quoteEndPos);
1679 keyword = keyword.trimmed();
1682 value = startQuote + value + quoteEnd;
1689 else if (!impliedQuote) {
1691 keyword = startQuote + keyword;
1692 quoteProblem =
true;
1719 QString PvlKeyword::readLine(std::istream &is,
bool insideComment) {
1722 while(is.good() && lineOfData.isEmpty()) {
1726 (!lineOfData.size() || lineOfData[lineOfData.size() - 1] !=
'\n')) {
1727 char next = is.get();
1731 is.seekg(0, ios::end);
1742 if (insideComment &&
1743 lineOfData.size() >= 2 && lineOfData[lineOfData.size() - 2] ==
'*' &&
1744 lineOfData[lineOfData.size() - 1] ==
'/') {
1748 else if (lineOfData.size() >= 2 &&
1749 lineOfData[lineOfData.size() - 2] ==
'/' &&
1750 lineOfData[lineOfData.size() - 1] ==
'*') {
1751 insideComment =
true;
1756 lineOfData = lineOfData.trimmed();
1760 (is.peek() ==
' ' ||
1761 is.peek() ==
'\r' ||
1762 is.peek() ==
'\n')) {
1784 bool removeFormatter =
false;
1785 if (tempFormat == NULL) {
1787 removeFormatter =
true;
1791 for (
int i = 0; i < keyword.
comments(); i++) {
1792 for (
int j = 0; j < keyword.
indent(); j++) os <<
" ";
1793 os << keyword.
comment(i) << tempFormat->formatEOL();
1797 int startColumn = 0;
1798 for (
int i = 0; i < keyword.
indent(); i++) {
1802 QString keyname = tempFormat->formatName(keyword);
1804 startColumn += keyname.length();
1807 for (
int i = 0; i < keyword.
width() - (int)keyname.size(); ++i) {
1815 if (keyword.
size() == 0) {
1816 os << tempFormat->formatValue(keyword);
1820 QString stringToWrite;
1821 for (
int i = 0; i < keyword.
size(); i ++) {
1822 stringToWrite += tempFormat->formatValue(keyword, i);
1830 if (removeFormatter)
delete tempFormat;
1838 if (
this != &other) {
1858 m_units =
new std::vector<QString>(*other.
m_units);
1867 m_comments =
new std::vector<QString>(*other.
m_comments);
1891 int iSize = pvlKwrd.
size();
1893 QString sType = m_values[0].toLower();
1896 if (psValueType.length()) {
1897 psValueType = psValueType.toLower();
1900 double dRangeMin=0, dRangeMax=0;
1901 bool bRange =
false;
1902 bool bValue =
false;
1903 if (pvlKwrdValue != NULL) {
1904 QString sValueName = pvlKwrdValue->
name();
1907 if (sValueName.contains(
"__Range")) {
1908 dRangeMin =
toDouble((*pvlKwrdValue)[0]);
1909 dRangeMax =
toDouble((*pvlKwrdValue)[1]);
1912 else if (sValueName.contains(
"__Value")) {
1918 if (sType ==
"integer") {
1919 for (
int i=0; i<iSize; i++) {
1920 QString sValue = pvlKwrd[i].toLower();
1921 if (sValue !=
"null"){
1924 iValue =
toInt(sValue);
1926 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" expects an Integer value";
1929 if (bRange && (iValue < dRangeMin || iValue > dRangeMax)) {
1930 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" is not in the specified Range";
1934 bool bFound =
false;
1935 for (
int j=0; j<pvlKwrdValue->
size(); j++) {
1936 if (iValue ==
toInt((*pvlKwrdValue)[j])) {
1942 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" has value not in the accepted list";
1947 if (psValueType.length()) {
1948 if ((psValueType ==
"positive" && iValue < 0) || (psValueType ==
"negative" && iValue >= 0) ) {
1949 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" has invalid value";
1959 if (sType ==
"double") {
1960 for (
int i=0; i<iSize; i++) {
1961 QString sValue = pvlKwrd[i].toLower();
1962 if (sValue !=
"null"){
1964 if (bRange && (dValue < dRangeMin || dValue > dRangeMax)) {
1965 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" is not in the specified Range";
1969 bool bFound =
false;
1970 for (
int j=0; j<pvlKwrdValue->
size(); j++) {
1971 if (dValue ==
toDouble((*pvlKwrdValue)[j])) {
1977 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" has value not in the accepted list";
1982 if (psValueType.length()) {
1983 if ((psValueType ==
"positive" && dValue < 0) || (psValueType ==
"negative" && dValue >= 0) ) {
1984 QString sErrMsg =
"\"" +pvlKwrd.
name() +
"\" has invalid value";
1994 if (sType ==
"boolean") {
1995 for (
int i=0; i<iSize; i++) {
1996 QString sValue = pvlKwrd[i].toLower();
1997 if (sValue !=
"null" && sValue !=
"true" && sValue !=
"false"){
1998 QString sErrMsg =
"Wrong Type of value in the Keyword \"" + name() +
"\" \n";
2006 if (sType ==
"string") {
2007 for (
int i=0; i<iSize; i++) {
2008 QString sValue = pvlKwrd[i].toLower();
2010 bool bValFound =
false;
2011 for (
int i=0; i<pvlKwrdValue->
size(); i++) {
2012 if (sValue == (*pvlKwrdValue)[i].toLower()) {
2018 QString sErrMsg =
"Wrong Type of value in the Keyword \"" + name() +
"\" \n";
Parse and return elements of a Pvl sequence.
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
std::vector< QString > * m_comments
The comments for the keyword.
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.
int indent() const
Returns the current indent level.
int toInt(const QString &string)
Global function to convert from a string to an integer.
void setName(QString name)
Sets the keyword name.
char * m_name
The keyword's name... This is a c-string for memory efficiency.
Namespace for the standard library.
double toDouble(const QString &string)
Global function to convert from a string to a double.
int Size() const
Number of arrays in the sequence.
void addComments(const std::vector< QString > &comments)
This method adds multiple comments at once by calling AddComments on each element in the vector...
int size() const
Returns the number of values stored in this keyword.
IString Token(const IString &separator)
Returns the first token in the IString.
int m_width
The width of the longest keyword.
std::istream & operator>>(std::istream &is, PvlKeyword &result)
Read in a keyword.
QVarLengthArray< QString, 1 > m_values
The values in the keyword.
Contains multiple PvlContainers.
#define _FILEINFO_
Macro for the filename and line number.
QString comment(const int index) const
Return a comment at the specified index.
A single keyword-value pair.
IString Remove(const std::string &del)
Remove all instances of any character in the string from the IString.
QString ArraySubscriptNotInRange(int index)
This error should be used when an Isis object or application is checking array bounds and the legal r...
std::vector< QString > * m_units
The units for the values.
ostream & operator<<(std::ostream &os, const Isis::PvlKeyword &keyword)
Write out the keyword.
QString name() const
Returns the keyword name.
Adds specific functionality to C++ strings.
Namespace for ISIS/Bullet specific routines.
PvlFormat * m_formatter
Formatter object.
int comments() const
Returns the number of lines of comments associated with this keyword.
IString ConvertWhiteSpace()
Returns the string with all "new lines", "carriage returns", "tabs", "form feeds", "vertical tabs" and "back spaces" converted to single spaces.
int m_indent
The number of indentations to make.
int width() const
Returns the current set longest keyword name.
IString UpCase()
Converst any lower case characters in the object IString with uppercase characters.
void addValue(QString value, QString unit="")
Adds a value with units.