File failed to load: https://isis.astrogeology.usgs.gov/9.0.0/Object/assets/jax/output/NativeMML/config.js
Isis 3 Programmer Reference
Table.cpp
1
5
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "Table.h"
8
9#include <fstream>
10#include <sstream>
11#include <string>
12
13#include "Blob.h"
14#include "Endian.h"
15#include "IException.h"
16#include "TableField.h"
17
18using namespace std;
19namespace Isis {
20
21 Table::Table(Blob &blob) {
22 initFromBlob(blob);
23 }
24
25
44 Table::Table(const QString &tableName, Isis::TableRecord &rec) {
45 p_name = tableName;
46 p_assoc = Table::None;
47 p_label += Isis::PvlKeyword("Records", 0);
48 p_label += Isis::PvlKeyword("ByteOrder", "NULL");
49 for (int f = 0; f < rec.Fields(); f++) {
50 p_label.addGroup(rec[f].pvlGroup());
51 }
52 p_record = rec;
53 }
54
55
68 Table::Table(const QString &tableName) {
69 p_name = tableName;
70 p_assoc = Table::None;
71 }
72
73
88 Table::Table(const QString &tableName, const QString &file) {
89 Blob blob(tableName, "Table", file);
90 initFromBlob(blob);
91 }
92
93
109 Table::Table(const QString &tableName, const QString &file, const Pvl &fileHeader) {
110 Blob blob(tableName, "Table");
111 blob.Read(file, fileHeader);
112 initFromBlob(blob);
113 }
114
115
122 Table::Table(const Table &other) {
123 p_name = other.p_name;
124 p_label = other.p_label;
125 p_record = other.p_record;
126 p_records = other.p_records;
127 p_assoc = other.p_assoc;
128 p_swap = other.p_swap;
129
130 for (unsigned int i = 0; i < other.p_recbufs.size(); i++) {
131 char *data = new char[RecordSize()];
132
133 for (int j = 0; j < RecordSize(); j++) {
134 data[j] = other.p_recbufs[i][j];
135 }
136
137 p_recbufs.push_back(data);
138 }
139 }
140
148 Table::Table(const QString &tableName, const std::string &tableString, const char &fieldDelimiter) {
149 p_name = tableName;
150
151 std::stringstream tableStream;
152 tableStream << tableString;
153
154 std::vector<std::string> tableLinesStringList;
155 std::string line;
156 while(std::getline(tableStream, line, '\n')) {
157 tableLinesStringList.push_back(line);
158 }
159
160 int numOfFieldValues = tableLinesStringList.size() - 1; // minus the header line
161
162 std::string fieldNamesLineString = tableLinesStringList.front();
163 std::stringstream fieldNamesStringStream;
164 fieldNamesStringStream << fieldNamesLineString;
165
166 std::vector<QString> fieldNames;
167 std::string fieldNameString;
168 while(std::getline(fieldNamesStringStream, fieldNameString, fieldDelimiter)) {
169 fieldNames.push_back(QString::fromStdString(fieldNameString));
170 }
171
172 // Clear error flags and set pointer back to beginning
173 tableStream.clear();
174 tableStream.seekg(0, ios::beg);
175
176 // Add records to table
177 std::string recordString;
178 int index = 0;
179 while(std::getline(tableStream, recordString, '\n')) {
180 // skip first line bc that's the header line
181 if (index == 0) {
182 index++;
183 continue;
184 }
185
186 TableRecord tableRecord(recordString, fieldDelimiter, fieldNames, numOfFieldValues);
187 p_record = tableRecord;
188 this->operator+=(tableRecord);
189 index++;
190 }
191
192 // Add fields
193 for (int f = 0; f < p_record.Fields(); f++) {
194 p_label.addGroup(p_record[f].pvlGroup());
195 }
196 }
197
198
205 Clear();
206
207 p_label = blob.Label();
208
209 p_name = p_label["Name"][0];
210 p_records = p_label["Records"];
211
213 for (int g = 0; g < p_label.groups(); g++) {
214 if (p_label.group(g).isNamed("Field")) {
215 Isis::TableField f(p_label.group(g));
216 rec += f;
217 }
218 }
219
220 p_record = rec;
221
222 p_assoc = Table::None;
223 if (p_label.hasKeyword("Association")) {
224 QString temp = (QString) p_label["Association"];
225 temp = temp.toUpper();
226 if (temp == "SAMPLES") p_assoc = Table::Samples;
227 if (temp == "LINES") p_assoc = Table::Lines;
228 if (temp == "BANDS") p_assoc = Table::Bands;
229 }
230
231 // Determine if we need to swap stuff when we read the data
232 Isis::ByteOrder bo = Isis::ByteOrderEnumeration(p_label["ByteOrder"]);
233 p_swap = false;
234 if (Isis::IsLsb() && (bo == Isis::Msb)) p_swap = true;
235 if (Isis::IsMsb() && (bo == Isis::Lsb)) p_swap = true;
236
237 for (int rec = 0; rec < p_records; rec++) {
238 size_t bufferPos = rec * RecordSize();
239
240 char *buf = new char[RecordSize()];
241 memcpy(buf, &blob.getBuffer()[bufferPos], RecordSize());
242
243 if (p_swap) p_record.Swap(buf);
244 p_recbufs.push_back(buf);
245 }
246 }
247
248
258 Table &Table::operator=(const Isis::Table &other) {
259 Clear();
260 p_name = other.p_name;
261 p_label = other.p_label;
262 p_record = other.p_record;
263 p_records = other.p_records;
264 p_assoc = other.p_assoc;
265 p_swap = other.p_swap;
266
267 for (unsigned int i = 0; i < other.p_recbufs.size(); i++) {
268 char *data = new char[RecordSize()];
269
270 for (int j = 0; j < RecordSize(); j++) {
271 data[j] = other.p_recbufs[i][j];
272 }
273
274 p_recbufs.push_back(data);
275 }
276
277 return *this;
278 }
279
280
283 Clear();
284 }
285
286
294 void Table::Write(const QString &file) {
295 Blob blob = toBlob();
296 blob.Write(file);
297 }
298
299
305 QString Table::Name() const {
306 return p_name;
307 }
308
309
319 return p_label;
320 }
321
322
328 void Table::SetAssociation(const Table::Association assoc) {
329 p_assoc = assoc;
330 }
331
332
340 return (p_assoc == Table::Samples);
341 }
342
343
351 return (p_assoc == Table::Lines);
352 }
353
354
362 return (p_assoc == Table::Bands);
363 }
364
365
371 int Table::Records() const {
372 return p_recbufs.size();
373 }
374
375
382 return p_record.Fields();
383 }
384
385
391 int Table::RecordSize() const {
392 return p_record.RecordSize();
393 }
394
395
404 p_record.Unpack(p_recbufs[index]);
405 return p_record;
406 }
407
408
415 if (RecordSize() == 0) {
416 IString msg = "Unable to add records to Isis Table ["
417 + p_name + "]. Bytes per record = [0 bytes].";
418 throw IException(IException::Unknown, msg, _FILEINFO_);
419 }
420
421 if (RecordSize() != rec.RecordSize()) {
422 QString msg = "Unable to add the given record with size = ["
423 + Isis::toString(rec.RecordSize()) + " bytes] to to Isis Table ["
424 + p_name + "] with record size = ["
425 + Isis::toString(RecordSize()) + " bytes]. Record sizes must match.";
426 throw IException(IException::Unknown, msg, _FILEINFO_);
427 }
428 char *newbuf = new char[RecordSize()];
429 rec.Pack(newbuf);
430 p_recbufs.push_back(newbuf);
431 }
432
433
440 void Table::Update(const Isis::TableRecord &rec, const int index) {
441 rec.Pack(p_recbufs[index]);
442 }
443
444
450 void Table::Delete(const int index) {
451 vector<char *>::iterator it = p_recbufs.begin();
452 for (int i = 0; i < index; i++, it++);
453 delete [] p_recbufs[index];
454 p_recbufs.erase(it);
455 }
456
457
462 for (int i = 0; i < (int)p_recbufs.size(); i++) delete [] p_recbufs[i];
463 p_recbufs.clear();
464 }
465
466
473 Blob tableBlob(Name(), "Table");
474 PvlObject &blobLabel = tableBlob.Label();
475
476 // Label setup
477 blobLabel += PvlKeyword("Records", Isis::toString(Records()));
478 int nbytes = Records() * RecordSize();
479
480 if (Isis::IsLsb()) {
481 blobLabel+= PvlKeyword("ByteOrder", Isis::ByteOrderName(Isis::Lsb));
482 }
483 else {
484 blobLabel+= PvlKeyword("ByteOrder", Isis::ByteOrderName(Isis::Msb));
485 }
486
487 if (p_assoc == Samples) {
488 blobLabel += Isis::PvlKeyword("Association", "Samples");
489 }
490 else if (p_assoc == Lines) {
491 blobLabel += Isis::PvlKeyword("Association", "Lines");
492 }
493 else if (p_assoc == Bands) {
494 blobLabel += Isis::PvlKeyword("Association", "Bands");
495 }
496
497 for (int i = 0; i < p_label.keywords(); i++) {
498 if (!blobLabel.hasKeyword(p_label[i].name())) {
499 blobLabel += p_label[i];
500 }
501 }
502
503 for (int i = 0; i < p_label.comments(); i++){
504 blobLabel.addComment(p_label.comment(i));
505 }
506
507 for (int g = 0; g < p_label.groups(); g++) {
508 blobLabel += p_label.group(g);
509 }
510
511 // Binary data setup
512 char *buf = new char[nbytes];
513
514 for (int rec = 0; rec < Records(); rec++) {
515 size_t bufferPos = rec * RecordSize();
516
517 memcpy(&buf[bufferPos], p_recbufs[rec], RecordSize());
518 }
519
520 tableBlob.takeData(buf, nbytes);
521
522 return tableBlob;
523 }
524
525
538 QString Table::toString(Table table, QString fieldDelimiter) {
539 QString tableValues;
540 // add the first record with header, the given delimiter, and a new line after each record
541 tableValues += TableRecord::toString(table[0], fieldDelimiter, true, true);
542 // add remaining records without header, the same delimeter, and new line after each record
543 for (int recordIndex = 1; recordIndex < table.Records(); recordIndex++) {
544 tableValues += TableRecord::toString(table[recordIndex], fieldDelimiter);
545 }
546 return tableValues;
547 }
548
549}
void Read(const QString &file, const std::vector< PvlKeyword > keywords=std::vector< PvlKeyword >())
This method reads Pvl values from a specified file.
Definition Blob.cpp:255
void Write(const QString &file)
Write the blob data out to a file.
Definition Blob.cpp:417
char * getBuffer()
Get the internal data buff of the Blob.
Definition Blob.cpp:546
PvlObject & Label()
Accessor method that returns a PvlObject containing the Blob label.
Definition Blob.cpp:151
void takeData(char *buffer, int nbytes)
Set the data stored in the BLOB without copying it.
Definition Blob.cpp:398
Isis exception class.
Definition IException.h:91
@ Unknown
A type of error that cannot be classified as any of the other error types.
Definition IException.h:118
Adds specific functionality to C++ strings.
Definition IString.h:165
Container for cube-like labels.
Definition Pvl.h:119
A single keyword-value pair.
Definition PvlKeyword.h:87
Contains Pvl Groups and Pvl Objects.
Definition PvlObject.h:61
bool hasKeyword(const QString &kname, FindOptions opts) const
See if a keyword is in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within ...
Class for storing an Isis::Table's field information.
Definition TableField.h:47
Class for storing Table blobs information.
Definition Table.h:61
~Table()
Destroys the Table object.
Definition Table.cpp:282
QString p_name
The name of the Table.
Definition Table.h:135
int RecordSize() const
Returns the number of bytes per record.
Definition Table.cpp:391
int RecordFields() const
Returns the number of fields per record.
Definition Table.cpp:381
bool IsSampleAssociated()
Checks to see if association is Samples.
Definition Table.cpp:339
Association p_assoc
Association Type of the table.
Definition Table.h:132
void Delete(const int index)
Deletes a TableRecord from the Table.
Definition Table.cpp:450
int p_records
Holds record count read from labels, may differ from the size of p_recbufs.
Definition Table.h:129
int Records() const
Returns the number of records.
Definition Table.cpp:371
PvlObject & Label()
The Table's label.
Definition Table.cpp:318
void Write(const QString &file)
Write the Table to a file.
Definition Table.cpp:294
bool p_swap
Only used for reading.
Definition Table.h:133
void operator+=(TableRecord &rec)
Adds a TableRecord to the Table.
Definition Table.cpp:414
void SetAssociation(const Table::Association assoc)
Sets the association to the input parameter.
Definition Table.cpp:328
TableRecord & operator[](const int index)
Reads a TableRecord from the Table.
Definition Table.cpp:403
QString Name() const
The Table's name.
Definition Table.cpp:305
std::vector< char * > p_recbufs
Buffers containing record values.
Definition Table.h:127
TableRecord p_record
The current table record.
Definition Table.h:126
bool IsBandAssociated()
Checks to see if association is Bands.
Definition Table.cpp:361
bool IsLineAssociated()
Checks to see if association is Lines.
Definition Table.cpp:350
Table & operator=(const Isis::Table &other)
Sets the Table equal to the input Table object.
Definition Table.cpp:258
void Clear()
Clear the table of all records.
Definition Table.cpp:461
void Update(const TableRecord &rec, const int index)
Updates a TableRecord.
Definition Table.cpp:440
void initFromBlob(Blob &blob)
Initialize a Table from a Blob that has been read from a file.
Definition Table.cpp:204
static QString toString(Table table, QString fieldDelimiter=",")
Convert the data from a Table into a string.
Definition Table.cpp:538
PvlObject p_label
The label for storing additional information.
Definition Table.h:136
Blob toBlob() const
Serialze the Table to a Blob that can be written to a file.
Definition Table.cpp:472
int RecordSize() const
Returns the number of bytes per record.
int Fields() const
Returns the number of fields that are currently in the record.
void Pack(char *buf) const
Writes record information into the binary buffer.
ByteOrder
Tests the current architecture for byte order.
Definition Endian.h:42
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
bool IsLsb()
Return true if this host is an LSB first machine and false if it is not.
Definition Endian.h:67
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
bool IsMsb()
Return true if this host is an MSB first machine and false if it is not.
Definition Endian.h:83
Namespace for the standard library.