Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

Isis 3 Programmer Reference
ImportPdsTable.cpp
1
5
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "ImportPdsTable.h"
8
9#include <cctype>
10#include <iomanip>
11#include <iostream>
12#include <sstream>
13
14#include <QDebug>
15#include <QRegularExpression>
16#include <QScopedPointer>
17#include <QString>
18
19#include "EndianSwapper.h"
20#include "FileName.h"
21#include "IString.h"
22#include "Pvl.h"
23#include "PvlObject.h"
24#include "Table.h"
25#include "TableField.h"
26#include "TableRecord.h"
27#include "TextFile.h"
28
29
30using namespace std;
31
32namespace Isis {
33
34
45 // just inititalize the member variables
46 init();
47 m_tableName = "TABLE";
48 }
49
50
74 ImportPdsTable::ImportPdsTable(const QString &pdsLabFile,
75 const QString &pdsTableFile,
76 const QString &pdsTableName) {
77 m_tableName = pdsTableName;
78 load(pdsLabFile, pdsTableFile, pdsTableName);
79 }
80
81
87
88
90 QString ImportPdsTable::name() const {
91 return (m_tableName);
92 }
93
99 void ImportPdsTable::setName(const QString &name) {
101 return;
102 }
103
104
133 void ImportPdsTable::load(const QString &pdsLabFile,
134 const QString &pdsTableFile,
135 const QString &pdsTableName) {
136
137 init();
138 QString tempTblFile;
139 loadLabel(pdsLabFile, tempTblFile, pdsTableName);
140 if (!pdsTableFile.isEmpty()) tempTblFile = pdsTableFile;
141 // Vet the table filename. Many PDS files record the filename in
142 // uppercase and in practice, the filename is in lowercase. Do this
143 // check here.
144 FileName tableFile(tempTblFile);
145 try {
146 int tableStartRecord = toInt(tableFile.baseName());
147 tempTblFile = pdsLabFile;
148 m_pdsTableStart = tableStartRecord;
149 }
150 catch (IException &e) {
151 // if we are unable to cast the table file value to an integer, it must be a
152 // file name, not a location in the label file.
153 if (!tableFile.fileExists()) {
154 // if the table file name doesn't exist, try lowercased version...
155 FileName tableFileLowercase(tableFile.path() + "/"
156 + tableFile.name().toLower());
157 if (!tableFileLowercase.fileExists()) {
158 IString msg = "Unable to import PDS table. Neither of the following "
159 "possible table files were found: ["
160 + tableFile.expanded() + "] or ["
161 + tableFileLowercase.expanded() + "]";
162 throw IException(e, IException::Unknown, msg, _FILEINFO_);
163 }
164 tableFile = tableFileLowercase.expanded();
165 tempTblFile = tableFile.expanded();
166 }
167 m_pdsTableStart = 1;
168 }
169 if (m_pdsTableType == "ASCII") {
170 loadTable(tempTblFile);
171 }
172 m_pdsTableFile = tempTblFile;
173 return;
174 }
175
176
187 bool ImportPdsTable::hasColumn(const QString &colName) const {
188 return (findColumn(colName) != 0);
189 }
190
191
212 QString ImportPdsTable::getColumnName(const unsigned int &index,
213 const bool &formatted) const {
214 if ((int) index >= columns() - 1) {
215 QString msg = "Unable to import the binary PDS table [" + m_tableName
216 + "] into Isis. The requested column index ["
217 + toString((int) index) + "] exceeds the last column index ["
218 + toString(columns() - 1) + "]";
219 throw IException(IException::Programmer, msg.toStdString(), _FILEINFO_);
220 }
221 QString name = m_coldesc[index].m_name;
222 if (formatted) name = getFormattedName(name);
223 return (name);
224 }
225
226
243 QStringList ImportPdsTable::getColumnNames(const bool &formatted) const {
244 QStringList colnames;
245 for (int i = 0 ; i < columns() ; i++) {
246 QString name = m_coldesc[i].m_name;
247 if (formatted) name = getFormattedName(name);
248 colnames.push_back(name);
249 }
250 return (colnames);
251 }
252
253
269 QString ImportPdsTable::getType(const QString &colName) const {
270 const ColumnDescr *column = findColumn(colName);
271 QString dtype("");
272 if (column != 0) {
273 dtype = column->m_dataType;
274 }
275 return (dtype);
276 }
277
278
296 bool ImportPdsTable::setType(const QString &colName,
297 const QString &dataType) {
298 ColumnDescr *column = findColumn(colName);
299 if (column != 0) {
300 column->m_dataType = dataType.toUpper();
301 }
302 return (column != 0);
303 }
304
305
319 Table ImportPdsTable::importTable(const QString &isisTableName) {
320 try {
321 TableRecord record = makeRecord(m_coldesc);
322 Table table(isisTableName, record);
323 fillTable(table, m_coldesc, record);
324 return (table);
325 }
326 catch (IException &e) {
327 QString msg = "Unable to import the PDS table [" + m_tableName
328 + "] from the PDS file [" + m_pdsTableFile + "] into Isis.";
329 throw IException(e, IException::Unknown, msg.toStdString(), _FILEINFO_);
330
331 }
332 }
333
334
351 Table ImportPdsTable::importTable(const QString &colnames,
352 const QString &isisTableName) {
353 return (importTable(colnames.split(","), isisTableName));
354 }
355
356
375 const QString &isisTableName) {
376 ColumnTypes ctypes;
377 for (int i = 0 ; i < colnames.size() ; i++) {
378 const ColumnDescr *descr = findColumn(colnames[i]);
379 if (!descr) {
380 QString msg = "Unable to import the PDS table [" + m_tableName
381 + "] into Isis. The requested column name ["
382 + colnames[i] + "] does not "
383 "exist in table.";
384 throw IException(IException::Programmer, msg.toStdString(), _FILEINFO_);
385 }
386 ctypes.push_back(*descr);
387 }
388
389 // Create and populate the table
390 TableRecord record = makeRecord(ctypes);
391 Table table(isisTableName, record);
392 fillTable(table, ctypes, record);
393 return (table);
394 }
395
396
403
404 m_byteOrder = "";
405 m_trows = 0;
406 m_pdsTableStart = 0;
407 m_coldesc.clear();
408 m_rows.clear();
409 m_pdsTableType = "";
410 m_pdsTableFile = "";
411 return;
412 }
413
414
439 void ImportPdsTable::loadLabel(const QString &pdsLabFile,
440 QString &pdsTableFile,
441 const QString &tblname) {
442
443 Isis::Pvl label(pdsLabFile);
444
445 QString tableName = ( tblname.isEmpty() ) ? m_tableName : tblname;
446 if (!label.hasObject(tableName)) {
447 QString msg = "The PDS file " + pdsLabFile +
448 " does not have the required TABLE object, ["
449 + tableName +"]. The PDS label file is probably invalid";
450 throw IException(IException::Unknown, msg.toStdString(), _FILEINFO_);
451 }
452 // Get some pertinent information from the label
453 PvlObject &tabObj = label.findObject(tableName);
454 // The table description contains the actual "RECORD_BYTES"
455 if (tabObj.hasKeyword("RECORD_BYTES")) {
456 m_recordBytes = (int) tabObj.findKeyword("RECORD_BYTES");
457 }
458 // The table description has "ROW_BYTES" and "ROW_SUFFIX_BYTES". These summed is the
459 // record length. Can be for detached and attached labels
460 else if (tabObj.hasKeyword("ROW_BYTES") && tabObj.hasKeyword("ROW_SUFFIX_BYTES")) {
461 m_recordBytes = (int) tabObj.findKeyword("ROW_BYTES") +
462 (int) tabObj.findKeyword("ROW_SUFFIX_BYTES");
463 }
464 // The table record length is defined by the file record
465 // length (i.e., table is in with the image)
466 else {
467 m_recordBytes = (int) label.findKeyword("RECORD_BYTES");
468 }
469
470 QString trueTableName;
471 PvlObject *tableDetails = &tabObj;
472 if (label.hasKeyword("^" + tableName)) {
473 trueTableName = tableName;
474 pdsTableFile = FileName(pdsLabFile).path() + "/"
475 + label["^" + tableName][0];
476 }
477 else if (tabObj.objects() == 1) {
478 trueTableName = tabObj.object(0).name();
479 tableDetails = &tabObj.object(0);
480 pdsTableFile = FileName(pdsLabFile).path() + "/"
481 + tabObj["^" + trueTableName][0];
482 }
483 m_trows = (int) tableDetails->findKeyword("ROWS");
484 int ncols = (int) tableDetails->findKeyword("COLUMNS");
485 m_pdsTableType = QString(tableDetails->findKeyword("INTERCHANGE_FORMAT"));
486 if (m_pdsTableType != "ASCII" && m_pdsTableType.toUpper() != "BINARY") {
487 QString msg = "Unable to import the PDS table [" + tableName
488 + "] from the PDS file ["
489 + pdsTableFile + "] into Isis. "
490 "The PDS INTERCHANGE_FORMAT [" + m_pdsTableType
491 + "] is not supported. Valid values are ASCII or BINARY.";
492 throw IException(IException::User, msg.toStdString(), _FILEINFO_);
493 }
494 m_rowBytes = tableDetails->findKeyword("ROW_BYTES");
495
496 m_coldesc.clear();
497 PvlObject::PvlObjectIterator colobj = tableDetails->beginObject();
498 int icol(0);
499 while (colobj != tableDetails->endObject()) {
500 if (colobj->isNamed("COLUMN")) {
501 m_coldesc.push_back(getColumnDescription(*colobj, icol));
502 icol++;
503 }
504 ++colobj;
505 }
506
507 // Test to ensure columns match the number listed in the label
508 if (ncols != columns()) {
509 ostringstream msg;
510 msg << "Number of columns in the COLUMNS label keyword (" << ncols
511 << ") does not match number of COLUMN objects found ("
512 << columns() << ")";
513 cout << msg.str() << endl;
514 }
515 return;
516 }
517
518
535 void ImportPdsTable::loadTable(const QString &pdsTableFile) {
536
537 // Vet the filename. Many PDS files record the filename in uppercase and
538 // in practice, the filename is in lowercase. Do this check here.
539 QString tempTblFile(pdsTableFile);
540 TextFile tfile(tempTblFile);
541 QString tline;
542 m_rows.clear();
543 int irow(0);
544 while (tfile.GetLine(tline, false)) {
545 if (irow >= m_trows) break;
546
547 (void) processRow(irow, tline);
548
549 irow++;
550 }
551 return;
552 }
553
554
573 ImportPdsTable::getColumnDescription(PvlObject &colobj, int nth) const {
574 ColumnDescr cd;
575 cd.m_name = colobj["NAME"][0];
576 cd.m_colnum = nth; // 0-based indexing, will be COLUMN_NUM - 1
577
578 if (m_pdsTableType == "ASCII") {
579 cd.m_dataType = getGenericType(colobj["DATA_TYPE"][0]).toUpper();
580 }
581 else {
582 cd.m_dataType = colobj["DATA_TYPE"][0].toUpper();
583 }
584
585 cd.m_startByte = ((int) colobj["START_BYTE"]) - 1; // 0-based indexing
586 cd.m_numBytes = (int) colobj["BYTES"];
587
588
589 cd.m_itemBytes = cd.m_numBytes;
590 if ( colobj.hasKeyword("ITEM_BYTES") ) {
591 cd.m_itemBytes = (int) colobj["ITEM_BYTES"];
592 }
593
594 cd.m_items = 1;
595 if ( colobj.hasKeyword("ITEMS") ) {
596 cd.m_items = (int) colobj["ITEMS"];
597 }
598
599 return (cd);
600 }
601
602
616
617 // Ensure the nrequested column is valid
618 if ( (nth >= columns()) || ( nth < 0) ) {
619 QString mess = "Index (" + QString::number(nth) +
620 ") into Columns invalid (max: " + QString::number(columns()) + ")";
621 throw IException(IException::Programmer, mess, _FILEINFO_);
622 }
623
624 // All good, return the expected
625 return (m_coldesc[nth]);
626 }
627
628
644 QString cName = getFormattedName(colName);
645 ColumnTypes::iterator col = m_coldesc.begin();
646 while (col != m_coldesc.end()) {
647 QString c = getFormattedName(col->m_name);
648 if (c.toUpper() == cName.toUpper()) { return (&(*col)); }
649 col++;
650 }
651 return (0);
652 }
653
654
669 const ImportPdsTable::ColumnDescr *ImportPdsTable::findColumn(const QString &colName) const {
670 QString cName = getFormattedName(colName);
671 ColumnTypes::const_iterator col = m_coldesc.begin();
672 while (col != m_coldesc.end()) {
673 QString c = getFormattedName(col->m_name);
674 if (c.toUpper() == cName.toUpper()) { return (&(*col)); }
675 col++;
676 }
677 return (0);
678 }
679
680
691 QString ImportPdsTable::getColumnValue(const QString &tline,
692 const ColumnDescr &cdesc,
693 const QString &delimiter) const {
694 return (tline.mid(cdesc.m_startByte, cdesc.m_numBytes));
695 }
696
697
714 const ColumnDescr &cdesc,
715 const QString &delimiter) const {
716
717 // If item count is 1, simply return the whole column
718 QString value = getColumnValue(tline, cdesc, delimiter);
719 if ( 1 == cdesc.m_items) return ( QStringList(value) );
720
721 // If there is no item size specified, see if we should seperate with
722 // delimiter
723 if ( 0 == cdesc.m_itemBytes ) {
724 if ( delimiter.isEmpty() ) return ( QStringList(value));
725
726 return ( value.split(delimiter, Qt::SkipEmptyParts) );
727 }
728
729 // Have an item size specified. Assume it has single character separator
730 QStringList fields;
731 int pos = 0;
732 for (int i = 0 ; i < cdesc.m_items ; i++) {
733 fields.push_back(value.mid(pos, cdesc.m_itemBytes));
734 pos += cdesc.m_itemBytes + 1;
735 }
736
737 return (fields);
738 }
739
740
760 QString ImportPdsTable::getFormattedName(const QString &colname) const {
761 QString cname = QString(colname).replace(QRegularExpression("[(),]"), " ").simplified();
762
763 bool uppercase = true;
764 QString oString;
765 for (int i = 0 ; i < cname.size() ; i++) {
766 if (uppercase) {
767 oString.push_back(cname[i].toUpper());
768 uppercase = false;
769 }
770 else if ( (cname[i] == ' ') || (cname[i] == '_') ) {
771 uppercase = true;
772 }
773 else {
774 oString.push_back(cname[i].toLower());
775 }
776 }
777
778 return (oString);
779 }
780
781
799 QString ImportPdsTable::getGenericType(const QString &ttype) const {
800 return ttype.split("_").last();
801 }
802
803
821 TableField ImportPdsTable::makeField(const ColumnDescr &cdesc) {
822 QString dtype = cdesc.m_dataType;
823 QString name = getFormattedName(cdesc.m_name);
824 if (m_pdsTableType == "ASCII") {
825 if ( dtype == "INTEGER" ) {
826 return (TableField(name, TableField::Integer));
827 }
828 else if ( ((dtype == "DOUBLE")
829 || (dtype == "REAL")
830 || (dtype == "FLOAT")) ) {
831 return (TableField(name, TableField::Double));
832 }
833 else {
834 return (TableField(name, TableField::Text, cdesc.m_numBytes));
835 }
836 }
837 else {
838 return makeFieldFromBinaryTable(cdesc);
839 }
840 }
841
842
857 TableRecord ImportPdsTable::makeRecord(const ColumnTypes &ctypes) {
858 TableRecord rec;
859 for (int i = 0 ; i < ctypes.size() ; i++) {
860 TableField field = makeField(ctypes[i]);
861 rec += field;
862 }
863 return (rec);
864 }
865
866
883 TableField &ImportPdsTable::extract(const Columns &cols,
884 const ColumnDescr &cdesc,
885 TableField &tfield) const {
886 int ith = cdesc.m_colnum;
887 try {
888 IString data(cols[ith]);
889 if (tfield.isInteger()) {
890 data.Trim(" \t\r\n");
891 tfield = data.ToInteger();
892 }
893 else if (tfield.isDouble()) {
894 data.Trim(" \t\r\n");
895 tfield = data.ToDouble();
896 }
897 else { // Its a text field
898 QString str(tfield.size(), ' ');
899 str.insert(0, data.Trim(" \t\r\n").ToQt());
900 tfield = str;
901 }
902 }
903 catch (IException &e) {
904 QString msg = "Conversion failure of column " + cdesc.m_name;
905 throw IException(e, IException::Programmer, msg, _FILEINFO_);
906 }
907
908 return (tfield);
909 }
910
911
926 TableRecord &ImportPdsTable::extract(const Columns &cols,
927 const ColumnTypes &ctypes,
928 TableRecord &record) const {
929 for (int i = 0 ; i < ctypes.size() ; i++) {
930 extract(cols, ctypes[i], record[i]);
931 }
932 return (record);
933 }
934
935
951 void ImportPdsTable::fillTable(Table &table,
952 const ColumnTypes &cols,
953 TableRecord &record) const {
954 if (m_pdsTableType == "ASCII") {
955 for (int i = 0 ; i < m_rows.size() ; i++) {
956 try {
957 table += extract(m_rows[i], cols, record);
958 }
959 catch (IException &e) {
960 QString msg = "Failed to convert data in row [" + toString((int) i) + "]";
961 throw IException(e, IException::Programmer, msg, _FILEINFO_);
962 }
963 }
964 }
965
966 else {
967 QString tempTblFile = m_pdsTableFile;
968 ifstream pdsFileStream(tempTblFile.toLatin1().data(), ifstream::binary);
969
970 if (!pdsFileStream) {
971 IString msg = "Unable to open file containing PDS table ["
972 + tempTblFile + "].";
973 throw IException(IException::Unknown, msg, _FILEINFO_);
974 }
975
976 // read and discard the rows above the table data
977 QScopedPointer<char, QScopedPointerArrayDeleter<char> > rowBuffer(new char[m_recordBytes]);
978 for (int i = 1; i < m_pdsTableStart; i++) {
979 pdsFileStream.read(rowBuffer.data(), m_recordBytes);
980 }
981 // now, import and add the records to the table
982 for (int rowIndex = 0; rowIndex < m_trows; rowIndex++) {
983 pdsFileStream.read(rowBuffer.data(), m_recordBytes);
984 TableRecord rec = extractBinary(rowBuffer.data(), record);
985 table += rec;
986 }
987 }
988
989 return;
990 }
991
992
1001 return (m_coldesc.size());
1002 }
1003
1004
1013 return (m_rows.size());
1014 }
1015
1016
1032 TableRecord ImportPdsTable::extractBinary(char *rowBuffer, TableRecord &record) const {
1033 // for each record loop through the columns to get field values
1034 for (int colIndex = 0; colIndex < columns(); colIndex++) {
1035 QString columnName = m_coldesc[colIndex].m_name;
1036 for (int fieldIndex = 0 ; fieldIndex < record.Fields() ; fieldIndex++) {
1037 QString fieldName = record[fieldIndex].name();
1038 if (fieldName == columnName) {
1039 int startByte = m_coldesc[colIndex].m_startByte;
1040 int numBytes = m_coldesc[colIndex].m_numBytes;
1041
1042 if (record[fieldIndex].isInteger()) {
1043 int columnValue;
1044 memmove(&columnValue, &rowBuffer[startByte], numBytes);
1045 EndianSwapper endianSwap(m_byteOrder);
1046 int fieldValue = endianSwap.Int(&columnValue);
1047 record[fieldIndex] = fieldValue;
1048 }
1049
1050 else if (record[fieldIndex].isDouble()) {
1051 EndianSwapper endianSwap(m_byteOrder);
1052 double columnValue;
1053 memmove(&columnValue, &rowBuffer[startByte], numBytes);
1054 double fieldValue = endianSwap.Double(&columnValue);
1055 record[fieldIndex] = fieldValue;
1056 }
1057
1058 else if (record[fieldIndex].isReal()) {
1059 EndianSwapper endianSwap(m_byteOrder);
1060 float columnValue;
1061 memmove(&columnValue, &rowBuffer[startByte], numBytes);
1062 float fieldValue = endianSwap.Float(&columnValue);
1063 record[fieldIndex] = fieldValue;
1064 }
1065
1066 else if (record[fieldIndex].isText()) {
1067 QString fieldValue(numBytes, '\0');
1068 for (int byte = 0; byte < numBytes; byte++) {
1069 fieldValue[byte] = rowBuffer[startByte + byte];
1070 }
1071 record[fieldIndex] = fieldValue;
1072 }
1073
1074 }
1075 }
1076 }
1077 return record;
1078 }
1079
1080
1104 QString dataType = cdesc.m_dataType;
1105 // For binary tables, we will not reformat the name of the column
1106 QString name = cdesc.m_name;
1107 if (dataType == "MSB_INTEGER" || dataType == "INTEGER"
1108 || dataType == "SUN_INTEGER" || dataType == "MAC_INTEGER") {
1109 if (cdesc.m_numBytes != 4) {
1110 QString msg = "Only 4 byte integer values are supported in Isis. "
1111 "PDS Column [" + cdesc.m_name
1112 + "] has an integer DATA_TYPE with [BYTES = "
1113 + toString(cdesc.m_numBytes) + "].";
1114 throw IException(IException::Unknown, msg, _FILEINFO_);
1115 }
1116 setPdsByteOrder("MSB");
1117 return TableField(name, TableField::Integer);
1118 }
1119 else if (dataType == "LSB_INTEGER" || dataType == "VAX_INTEGER"
1120 || dataType == "PC_INTEGER" ) {
1121 if (cdesc.m_numBytes != 4) {
1122 QString msg = "Only 4 byte integer values are supported in Isis. "
1123 "PDS Column [" + cdesc.m_name
1124 + "] has an integer DATA_TYPE with [BYTES = "
1125 + toString(cdesc.m_numBytes) + "].";
1126 throw IException(IException::Unknown, msg, _FILEINFO_);
1127 }
1128 setPdsByteOrder("LSB");
1129 return TableField(name, TableField::Integer);
1130 }
1131 else if (dataType == "FLOAT" //IEEE_REAL alias (MSB)
1132 || dataType == "REAL" //IEEE_REAL alias (MSB)
1133 || dataType == "SUN_REAL" //IEEE_REAL alias (MSB)
1134 || dataType == "MAC_REAL" //IEEE_REAL alias (MSB)
1135 || dataType == "IEEE_REAL" ) {
1136 setPdsByteOrder("MSB");
1137 if (cdesc.m_numBytes == 8) {
1138 return TableField(name, TableField::Double);
1139 }
1140 else if (cdesc.m_numBytes == 4) {
1141 return TableField(name, TableField::Real);
1142 }
1143 else {
1144 IString msg = "Only 4 byte or 8 byte real values are supported in Isis. "
1145 "PDS Column [" + cdesc.m_name
1146 + "] has a real DATA_TYPE with [BYTES = "
1147 + toString(cdesc.m_numBytes) + "].";
1148 throw IException(IException::Unknown, msg, _FILEINFO_);
1149 }
1150 }
1151 else if (dataType == "PC_REAL") {
1152 setPdsByteOrder("LSB");
1153 if (cdesc.m_numBytes == 8) {
1154 return TableField(name, TableField::Double);
1155 }
1156 else if (cdesc.m_numBytes == 4) {
1157 return TableField(name, TableField::Real);
1158 }
1159 else {
1160 QString msg = "Only 4 byte or 8 byte real values are supported in Isis. "
1161 "PDS Column [" + cdesc.m_name
1162 + "] has a real DATA_TYPE with [BYTES = "
1163 + toString(cdesc.m_numBytes) + "].";
1164 throw IException(IException::Unknown, msg, _FILEINFO_);
1165 }
1166 }
1167 else if (dataType.contains("CHARACTER")
1168 || dataType.contains("ASCII")
1169 || dataType == "DATE" || dataType == "TIME" ) {
1170 return TableField(name, TableField::Text, cdesc.m_numBytes);
1171 }
1172 // Isis tables currently don't support any of the following PDS DATA_TYPE:
1173 // BIT_STRING, COMPLEX, N/A, BOOLEAN, UNSIGNED_INTEGER, IBM types, some VAX types
1174 IString msg = "PDS Column [" + cdesc.m_name
1175 + "] has an unsupported DATA_TYPE ["
1176 + dataType + "].";
1177 throw IException(IException::Unknown, msg, _FILEINFO_);
1178 }
1179
1180
1192 void ImportPdsTable::setPdsByteOrder(QString byteOrder) {
1193 if (!m_byteOrder.isEmpty() && m_byteOrder != byteOrder) {
1194 QString msg = "Unable to import the binary PDS table [" + m_tableName
1195 + "]. The column DATA_TYPE values indicate differing byte "
1196 "orders. ";
1197 throw IException(IException::Unknown, msg.toStdString(), _FILEINFO_);
1198 }
1199 m_byteOrder = byteOrder;
1200 }
1201
1202
1213 bool ImportPdsTable::processRow(const int &row, const QString &rowdata) {
1214 Columns cols;
1215 for (int i = 0 ; i < columns() ; i++) {
1216 cols.push_back(getColumnValue(rowdata, m_coldesc[i]));
1217 }
1218 m_rows.append(cols);
1219
1220 return (true);
1221 }
1222
1223} // namespace Isis
float Float(void *buf)
Swaps a floating point value.
int Int(void *buf)
Swaps a 4 byte integer value.
double Double(void *buf)
Swaps a double precision value.
void init()
Initialize object variables.
ColumnDescr * findColumn(const QString &colName)
Searches internal column descriptors for a named column.
virtual bool processRow(const int &row, const QString &rowdata)
Process a freshly read PDS table line of data.
void setName(const QString &name="TABLE")
Set the name of the PDS table object.
QString name() const
Return the name of the PDS table.
QString getFormattedName(const QString &colname) const
Converts a column name to a camel-case after it has been cleansed.
int rows() const
Returns the number of rows in the table.
void loadLabel(const QString &labfile, QString &tblfile, const QString &tblname="")
Loads the contents of a PDS table label description.
const ColumnDescr & getColumnDescriptor(const int &nth) const
Retrieve a column description by index.
int m_pdsTableStart
The start byte of the PDS table data.
Table importTable(const QString &isisTableName)
Populate a Table object with the PDS table and return it.
QString m_pdsTableFile
The name of the file containing the table data.
QString getColumnValue(const QString &tline, const ColumnDescr &cdesc, const QString &delimiter="") const
Extracts a column from a QString based upon a description.
void load(const QString &pdsLabFile, const QString &pdsTabFile="", const QString &pdsTableName="TABLE")
Loads a PDS table label and (optional) data file.
void setPdsByteOrder(QString byteOrder)
Sets the byte order for BINARY PDS table files.
int m_rowBytes
The number of bytes for one PDS table row.
QString m_pdsTableType
The INTERCHANGE_FORMAT value for the table.
TableField & extract(const Columns &columns, const ColumnDescr &cdesc, TableField &field) const
Extract a TableField from a PDS column in the text row.
TableRecord makeRecord(const ColumnTypes &ctypes)
Creates a TableRecord for columns.
TableRecord extractBinary(char *rowBuffer, TableRecord &record) const
This method is used to set the field values for the given record.
int m_trows
Number rows in table according to label.
QString m_tableName
The name of the PDS table object.
int m_recordBytes
The number of bytes for one Isis table record.
ColumnTypes m_coldesc
Column descriptions.
void loadTable(const QString &tabfile)
Loads the contents of a PDS table data file.
TableField makeFieldFromBinaryTable(const ColumnDescr &cdesc)
Creates an empty TableField with the appropriate type from a binary PDS table column description.
QString m_byteOrder
The byte order of the PDS table file, if binary.
virtual ~ImportPdsTable()
Destructs the ImportPdsTable object.
bool setType(const QString &colName, const QString &dataType)
Change the datatype for a column.
Rows m_rows
Table data.
QString getGenericType(const QString &ttype) const
Determine generic data type of a column.
ColumnDescr getColumnDescription(PvlObject &colobj, int nth) const
Extract a column description from a COLUMN object.
ImportPdsTable()
Default constructor.
QString getType(const QString &colName) const
Get the type associated with the specified column.
bool hasColumn(const QString &colName) const
This method determines whether the PDS table has a column with the given name.
void fillTable(Table &table, const ColumnTypes &columns, TableRecord &record) const
Fill the ISIS Table object with PDS table data.
QStringList getColumnNames(const bool &formatted=true) const
Return the names of all the columns.
QString getColumnName(const unsigned int &index=0, const bool &formatted=true) const
Returns the name of the specifed column.
TableField makeField(const ColumnDescr &cdesc)
Creates a TableField for the column type.
int columns() const
Returns the number of columns in the table.
QStringList getColumnFields(const QString &tline, const ColumnDescr &cdesc, const QString &delimiter="") const
Extracts column fields from a QString based upon a description.
Provides access to sequential ASCII stream I/O.
Definition TextFile.h:38
bool GetLine(QString &line, const bool skipComments=true)
Gets next line from file.
Definition TextFile.cpp:411
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(const LinearAlgebra::Vector &vector, int precision)
A global function to format LinearAlgebra::Vector as a QString with the given precision.
Namespace for the standard library.
int m_startByte
Starting byte of data.
int m_numBytes
Number bytes in column.
QString m_dataType
PDS table DATA_TYPE of column.
int m_itemBytes
Number bytes per item.
int m_items
Number of items in column.