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
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#include "PvlKeyword.h"
18
19
20using namespace std;
21namespace Isis {
22
23 Table::Table(Blob &blob) {
24 initFromBlob(blob);
25 }
26
27
46 Table::Table(const QString &tableName, Isis::TableRecord &rec) {
47 p_name = tableName;
48 p_assoc = Table::None;
49 p_label += Isis::PvlKeyword("Records", 0);
50 p_label += Isis::PvlKeyword("ByteOrder", "NULL");
51 for (int f = 0; f < rec.Fields(); f++) {
52 p_label.addGroup(rec[f].pvlGroup());
53 }
54 p_record = rec;
55 }
56
57
70 Table::Table(const QString &tableName) {
71 p_name = tableName;
72 p_assoc = Table::None;
73 }
74
75
90 Table::Table(const QString &tableName, const QString &file) {
91 Blob blob(tableName, "Table", file);
92 initFromBlob(blob);
93 }
94
95
111 Table::Table(const QString &tableName, const QString &file, const Pvl &fileHeader) {
112 Blob blob(tableName, "Table");
113 blob.Read(file, fileHeader);
114 initFromBlob(blob);
115 }
116
117
124 Table::Table(const Table &other) {
125 p_name = other.p_name;
126 p_label = other.p_label;
127 p_record = other.p_record;
128 p_records = other.p_records;
129 p_assoc = other.p_assoc;
130 p_swap = other.p_swap;
131
132 for (unsigned int i = 0; i < other.p_recbufs.size(); i++) {
133 char *data = new char[RecordSize()];
134
135 for (int j = 0; j < RecordSize(); j++) {
136 data[j] = other.p_recbufs[i][j];
137 }
138
139 p_recbufs.push_back(data);
140 }
141 }
142
150 Table::Table(const QString &tableName, const std::string &tableString, const char &fieldDelimiter, const vector<PvlKeyword> &tableAttrs) {
151 p_name = tableName;
152
153 std::stringstream tableStream;
154 tableStream << tableString;
155
156 std::vector<std::string> tableLinesStringList;
157 std::string line;
158 while(std::getline(tableStream, line, '\n')) {
159 tableLinesStringList.push_back(line);
160 }
161
162 int numOfFieldValues = tableLinesStringList.size() - 1; // minus the header line
163
164 std::string fieldNamesLineString = tableLinesStringList.front();
165 std::stringstream fieldNamesStringStream;
166 fieldNamesStringStream << fieldNamesLineString;
167
168 std::vector<QString> fieldNames;
169 std::string fieldNameString;
170 while(std::getline(fieldNamesStringStream, fieldNameString, fieldDelimiter)) {
171 fieldNames.push_back(QString::fromStdString(fieldNameString));
172 }
173
174 // Clear error flags and set pointer back to beginning
175 tableStream.clear();
176 tableStream.seekg(0, ios::beg);
177
178 // Add records to table
179 std::string recordString;
180 int index = 0;
181 while(std::getline(tableStream, recordString, '\n')) {
182 // skip first line bc that's the header line
183 if (index == 0) {
184 index++;
185 continue;
186 }
187
188 TableRecord tableRecord(recordString, fieldDelimiter, fieldNames, numOfFieldValues);
189 p_record = tableRecord;
190 this->operator+=(tableRecord);
191 index++;
192 }
193
194 // Add fields
195 for (int f = 0; f < p_record.Fields(); f++) {
196 p_label.addGroup(p_record[f].pvlGroup());
197 }
198
199 // Add attributes
200 if (!tableAttrs.empty()) {
201 for (PvlKeyword attr : tableAttrs) {
202 p_label += attr;
203 }
204 }
205 }
206
207
214 Clear();
215
216 p_label = blob.Label();
217
218 p_name = p_label["Name"][0];
219 p_records = p_label["Records"];
220
222 for (int g = 0; g < p_label.groups(); g++) {
223 if (p_label.group(g).isNamed("Field")) {
224 Isis::TableField f(p_label.group(g));
225 rec += f;
226 }
227 }
228
229 p_record = rec;
230
231 p_assoc = Table::None;
232 if (p_label.hasKeyword("Association")) {
233 QString temp = (QString) p_label["Association"];
234 temp = temp.toUpper();
235 if (temp == "SAMPLES") p_assoc = Table::Samples;
236 if (temp == "LINES") p_assoc = Table::Lines;
237 if (temp == "BANDS") p_assoc = Table::Bands;
238 }
239
240 // Determine if we need to swap stuff when we read the data
241 Isis::ByteOrder bo = Isis::ByteOrderEnumeration(p_label["ByteOrder"]);
242 p_swap = false;
243 if (Isis::IsLsb() && (bo == Isis::Msb)) p_swap = true;
244 if (Isis::IsMsb() && (bo == Isis::Lsb)) p_swap = true;
245
246 for (int rec = 0; rec < p_records; rec++) {
247 size_t bufferPos = rec * RecordSize();
248
249 char *buf = new char[RecordSize()];
250 memcpy(buf, &blob.getBuffer()[bufferPos], RecordSize());
251
252 if (p_swap) p_record.Swap(buf);
253 p_recbufs.push_back(buf);
254 }
255 }
256
257
267 Table &Table::operator=(const Isis::Table &other) {
268 Clear();
269 p_name = other.p_name;
270 p_label = other.p_label;
271 p_record = other.p_record;
272 p_records = other.p_records;
273 p_assoc = other.p_assoc;
274 p_swap = other.p_swap;
275
276 for (unsigned int i = 0; i < other.p_recbufs.size(); i++) {
277 char *data = new char[RecordSize()];
278
279 for (int j = 0; j < RecordSize(); j++) {
280 data[j] = other.p_recbufs[i][j];
281 }
282
283 p_recbufs.push_back(data);
284 }
285
286 return *this;
287 }
288
289
292 Clear();
293 }
294
295
303 void Table::Write(const QString &file) {
304 Blob blob = toBlob();
305 blob.Write(file);
306 }
307
308
314 QString Table::Name() const {
315 return p_name;
316 }
317
318
328 return p_label;
329 }
330
331
337 void Table::SetAssociation(const Table::Association assoc) {
338 p_assoc = assoc;
339 }
340
341
349 return (p_assoc == Table::Samples);
350 }
351
352
360 return (p_assoc == Table::Lines);
361 }
362
363
371 return (p_assoc == Table::Bands);
372 }
373
374
380 int Table::Records() const {
381 return p_recbufs.size();
382 }
383
384
391 return p_record.Fields();
392 }
393
394
400 int Table::RecordSize() const {
401 return p_record.RecordSize();
402 }
403
404
413 p_record.Unpack(p_recbufs[index]);
414 return p_record;
415 }
416
417
424 if (RecordSize() == 0) {
425 IString msg = "Unable to add records to Isis Table ["
426 + p_name + "]. Bytes per record = [0 bytes].";
427 throw IException(IException::Unknown, msg, _FILEINFO_);
428 }
429
430 if (RecordSize() != rec.RecordSize()) {
431 QString msg = "Unable to add the given record with size = ["
432 + Isis::toString(rec.RecordSize()) + " bytes] to to Isis Table ["
433 + p_name + "] with record size = ["
434 + Isis::toString(RecordSize()) + " bytes]. Record sizes must match.";
435 throw IException(IException::Unknown, msg, _FILEINFO_);
436 }
437 char *newbuf = new char[RecordSize()];
438 rec.Pack(newbuf);
439 p_recbufs.push_back(newbuf);
440 }
441
442
449 void Table::Update(const Isis::TableRecord &rec, const int index) {
450 rec.Pack(p_recbufs[index]);
451 }
452
453
459 void Table::Delete(const int index) {
460 vector<char *>::iterator it = p_recbufs.begin();
461 for (int i = 0; i < index; i++, it++);
462 delete [] p_recbufs[index];
463 p_recbufs.erase(it);
464 }
465
466
471 for (int i = 0; i < (int)p_recbufs.size(); i++) delete [] p_recbufs[i];
472 p_recbufs.clear();
473 }
474
475
482 Blob tableBlob(Name(), "Table");
483 PvlObject &blobLabel = tableBlob.Label();
484
485 // Label setup
486 blobLabel += PvlKeyword("Records", Isis::toString(Records()));
487 int nbytes = Records() * RecordSize();
488
489 if (Isis::IsLsb()) {
490 blobLabel+= PvlKeyword("ByteOrder", Isis::ByteOrderName(Isis::Lsb));
491 }
492 else {
493 blobLabel+= PvlKeyword("ByteOrder", Isis::ByteOrderName(Isis::Msb));
494 }
495
496 if (p_assoc == Samples) {
497 blobLabel += Isis::PvlKeyword("Association", "Samples");
498 }
499 else if (p_assoc == Lines) {
500 blobLabel += Isis::PvlKeyword("Association", "Lines");
501 }
502 else if (p_assoc == Bands) {
503 blobLabel += Isis::PvlKeyword("Association", "Bands");
504 }
505
506 for (int i = 0; i < p_label.keywords(); i++) {
507 if (!blobLabel.hasKeyword(p_label[i].name())) {
508 blobLabel += p_label[i];
509 }
510 }
511
512 for (int i = 0; i < p_label.comments(); i++){
513 blobLabel.addComment(p_label.comment(i));
514 }
515
516 for (int g = 0; g < p_label.groups(); g++) {
517 blobLabel += p_label.group(g);
518 }
519
520 // Binary data setup
521 char *buf = new char[nbytes];
522
523 for (int rec = 0; rec < Records(); rec++) {
524 size_t bufferPos = rec * RecordSize();
525
526 memcpy(&buf[bufferPos], p_recbufs[rec], RecordSize());
527 }
528
529 tableBlob.takeData(buf, nbytes);
530
531 return tableBlob;
532 }
533
534
547 QString Table::toString(Table table, QString fieldDelimiter) {
548 QString tableValues;
549 // add the first record with header, the given delimiter, and a new line after each record
550 tableValues += TableRecord::toString(table[0], fieldDelimiter, true, true);
551 // add remaining records without header, the same delimeter, and new line after each record
552 for (int recordIndex = 1; recordIndex < table.Records(); recordIndex++) {
553 tableValues += TableRecord::toString(table[recordIndex], fieldDelimiter);
554 }
555 return tableValues;
556 }
557
558}
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:291
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:400
int RecordFields() const
Returns the number of fields per record.
Definition Table.cpp:390
bool IsSampleAssociated()
Checks to see if association is Samples.
Definition Table.cpp:348
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:459
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:380
PvlObject & Label()
The Table's label.
Definition Table.cpp:327
void Write(const QString &file)
Write the Table to a file.
Definition Table.cpp:303
bool p_swap
Only used for reading.
Definition Table.h:133
void operator+=(TableRecord &rec)
Adds a TableRecord to the Table.
Definition Table.cpp:423
void SetAssociation(const Table::Association assoc)
Sets the association to the input parameter.
Definition Table.cpp:337
TableRecord & operator[](const int index)
Reads a TableRecord from the Table.
Definition Table.cpp:412
QString Name() const
The Table's name.
Definition Table.cpp:314
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:370
bool IsLineAssociated()
Checks to see if association is Lines.
Definition Table.cpp:359
Table & operator=(const Isis::Table &other)
Sets the Table equal to the input Table object.
Definition Table.cpp:267
void Clear()
Clear the table of all records.
Definition Table.cpp:470
void Update(const TableRecord &rec, const int index)
Updates a TableRecord.
Definition Table.cpp:449
void initFromBlob(Blob &blob)
Initialize a Table from a Blob that has been read from a file.
Definition Table.cpp:213
static QString toString(Table table, QString fieldDelimiter=",")
Convert the data from a Table into a string.
Definition Table.cpp:547
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:481
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.