Isis 3 Programmer Reference
Table.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "Table.h"
8
9#include <fstream>
10#include <string>
11
12#include "Blob.h"
13#include "Endian.h"
14#include "IException.h"
15#include "TableField.h"
16
17using namespace std;
18namespace Isis {
19
20 Table::Table(Blob &blob) {
21 initFromBlob(blob);
22 }
23
24
43 Table::Table(const QString &tableName, Isis::TableRecord &rec) {
44 p_name = tableName;
45 p_assoc = Table::None;
46 p_label += Isis::PvlKeyword("Records", 0);
47 p_label += Isis::PvlKeyword("ByteOrder", "NULL");
48 for (int f = 0; f < rec.Fields(); f++) {
49 p_label.addGroup(rec[f].pvlGroup());
50 }
51 p_record = rec;
52 }
53
54
67 Table::Table(const QString &tableName) {
68 p_name = tableName;
69 p_assoc = Table::None;
70 }
71
72
87 Table::Table(const QString &tableName, const QString &file) {
88 Blob blob(tableName, "Table", file);
89 initFromBlob(blob);
90 }
91
92
108 Table::Table(const QString &tableName, const QString &file, const Pvl &fileHeader) {
109 Blob blob(tableName, "Table");
110 blob.Read(file, fileHeader);
111 initFromBlob(blob);
112 }
113
114
121 Table::Table(const Table &other) {
122 p_name = other.p_name;
123 p_label = other.p_label;
124 p_record = other.p_record;
125 p_records = other.p_records;
126 p_assoc = other.p_assoc;
127 p_swap = other.p_swap;
128
129 for (unsigned int i = 0; i < other.p_recbufs.size(); i++) {
130 char *data = new char[RecordSize()];
131
132 for (int j = 0; j < RecordSize(); j++) {
133 data[j] = other.p_recbufs[i][j];
134 }
135
136 p_recbufs.push_back(data);
137 }
138 }
139
140
147 Clear();
148
149 p_label = blob.Label();
150
151 p_name = p_label["Name"][0];
152 p_records = p_label["Records"];
153
155 for (int g = 0; g < p_label.groups(); g++) {
156 if (p_label.group(g).isNamed("Field")) {
158 rec += f;
159 }
160 }
161
162 p_record = rec;
163
164 p_assoc = Table::None;
165 if (p_label.hasKeyword("Association")) {
166 QString temp = (QString) p_label["Association"];
167 temp = temp.toUpper();
168 if (temp == "SAMPLES") p_assoc = Table::Samples;
169 if (temp == "LINES") p_assoc = Table::Lines;
170 if (temp == "BANDS") p_assoc = Table::Bands;
171 }
172
173 // Determine if we need to swap stuff when we read the data
174 Isis::ByteOrder bo = Isis::ByteOrderEnumeration(p_label["ByteOrder"]);
175 p_swap = false;
176 if (Isis::IsLsb() && (bo == Isis::Msb)) p_swap = true;
177 if (Isis::IsMsb() && (bo == Isis::Lsb)) p_swap = true;
178
179 for (int rec = 0; rec < p_records; rec++) {
180 size_t bufferPos = rec * RecordSize();
181
182 char *buf = new char[RecordSize()];
183 memcpy(buf, &blob.getBuffer()[bufferPos], RecordSize());
184
185 if (p_swap) p_record.Swap(buf);
186 p_recbufs.push_back(buf);
187 }
188 }
189
190
201 Clear();
202 p_name = other.p_name;
203 p_label = other.p_label;
204 p_record = other.p_record;
205 p_records = other.p_records;
206 p_assoc = other.p_assoc;
207 p_swap = other.p_swap;
208
209 for (unsigned int i = 0; i < other.p_recbufs.size(); i++) {
210 char *data = new char[RecordSize()];
211
212 for (int j = 0; j < RecordSize(); j++) {
213 data[j] = other.p_recbufs[i][j];
214 }
215
216 p_recbufs.push_back(data);
217 }
218
219 return *this;
220 }
221
222
225 Clear();
226 }
227
228
236 void Table::Write(const QString &file) {
237 Blob blob = toBlob();
238 blob.Write(file);
239 }
240
241
247 QString Table::Name() const {
248 return p_name;
249 }
250
251
261 return p_label;
262 }
263
264
270 void Table::SetAssociation(const Table::Association assoc) {
271 p_assoc = assoc;
272 }
273
274
282 return (p_assoc == Table::Samples);
283 }
284
285
293 return (p_assoc == Table::Lines);
294 }
295
296
304 return (p_assoc == Table::Bands);
305 }
306
307
313 int Table::Records() const {
314 return p_recbufs.size();
315 }
316
317
324 return p_record.Fields();
325 }
326
327
333 int Table::RecordSize() const {
334 return p_record.RecordSize();
335 }
336
337
346 p_record.Unpack(p_recbufs[index]);
347 return p_record;
348 }
349
350
357 if (RecordSize() == 0) {
358 IString msg = "Unable to add records to Isis Table ["
359 + p_name + "]. Bytes per record = [0 bytes].";
360 throw IException(IException::Unknown, msg, _FILEINFO_);
361 }
362
363 if (RecordSize() != rec.RecordSize()) {
364 QString msg = "Unable to add the given record with size = ["
365 + Isis::toString(rec.RecordSize()) + " bytes] to to Isis Table ["
366 + p_name + "] with record size = ["
367 + Isis::toString(RecordSize()) + " bytes]. Record sizes must match.";
368 throw IException(IException::Unknown, msg, _FILEINFO_);
369 }
370 char *newbuf = new char[RecordSize()];
371 rec.Pack(newbuf);
372 p_recbufs.push_back(newbuf);
373 }
374
375
382 void Table::Update(const Isis::TableRecord &rec, const int index) {
383 rec.Pack(p_recbufs[index]);
384 }
385
386
392 void Table::Delete(const int index) {
393 vector<char *>::iterator it = p_recbufs.begin();
394 for (int i = 0; i < index; i++, it++);
395 delete [] p_recbufs[index];
396 p_recbufs.erase(it);
397 }
398
399
404 for (int i = 0; i < (int)p_recbufs.size(); i++) delete [] p_recbufs[i];
405 p_recbufs.clear();
406 }
407
408
415 Blob tableBlob(Name(), "Table");
416 PvlObject &blobLabel = tableBlob.Label();
417
418 // Label setup
419 blobLabel += PvlKeyword("Records", Isis::toString(Records()));
420 int nbytes = Records() * RecordSize();
421
422 if (Isis::IsLsb()) {
423 blobLabel+= PvlKeyword("ByteOrder", Isis::ByteOrderName(Isis::Lsb));
424 }
425 else {
426 blobLabel+= PvlKeyword("ByteOrder", Isis::ByteOrderName(Isis::Msb));
427 }
428
429 if (p_assoc == Samples) {
430 blobLabel += Isis::PvlKeyword("Association", "Samples");
431 }
432 else if (p_assoc == Lines) {
433 blobLabel += Isis::PvlKeyword("Association", "Lines");
434 }
435 else if (p_assoc == Bands) {
436 blobLabel += Isis::PvlKeyword("Association", "Bands");
437 }
438
439 for (int i = 0; i < p_label.keywords(); i++) {
440 if (!blobLabel.hasKeyword(p_label[i].name())) {
441 blobLabel += p_label[i];
442 }
443 }
444
445 for (int i = 0; i < p_label.comments(); i++){
446 blobLabel.addComment(p_label.comment(i));
447 }
448
449 for (int g = 0; g < p_label.groups(); g++) {
450 blobLabel += p_label.group(g);
451 }
452
453 // Binary data setup
454 char *buf = new char[nbytes];
455
456 for (int rec = 0; rec < Records(); rec++) {
457 size_t bufferPos = rec * RecordSize();
458
459 memcpy(&buf[bufferPos], p_recbufs[rec], RecordSize());
460 }
461
462 tableBlob.takeData(buf, nbytes);
463
464 return tableBlob;
465 }
466
467
480 QString Table::toString(Table table, QString fieldDelimiter) {
481 QString tableValues;
482 // add the first record with header, the given delimiter, and a new line after each record
483 tableValues += TableRecord::toString(table[0], fieldDelimiter, true, true);
484 // add remaining records without header, the same delimeter, and new line after each record
485 for (int recordIndex = 1; recordIndex < table.Records(); recordIndex++) {
486 tableValues += TableRecord::toString(table[recordIndex], fieldDelimiter);
487 }
488 return tableValues;
489 }
490
491}
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
bool isNamed(const QString &match) const
Returns whether the given string is equal to the container name or not.
int keywords() const
Returns the number of keywords contained in the PvlContainer.
QString name() const
Returns the container name.
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 ...
PvlGroup & group(const int index)
Return the group at the specified index.
int groups() const
Returns the number of groups contained.
Definition PvlObject.h:75
void addGroup(const Isis::PvlGroup &group)
Add a group to the object.
Definition PvlObject.h:186
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:224
QString p_name
The name of the Table.
Definition Table.h:134
int RecordSize() const
Returns the number of bytes per record.
Definition Table.cpp:333
int RecordFields() const
Returns the number of fields per record.
Definition Table.cpp:323
bool IsSampleAssociated()
Checks to see if association is Samples.
Definition Table.cpp:281
Association p_assoc
Association Type of the table.
Definition Table.h:131
void Delete(const int index)
Deletes a TableRecord from the Table.
Definition Table.cpp:392
int p_records
Holds record count read from labels, may differ from the size of p_recbufs.
Definition Table.h:128
int Records() const
Returns the number of records.
Definition Table.cpp:313
PvlObject & Label()
The Table's label.
Definition Table.cpp:260
void Write(const QString &file)
Write the Table to a file.
Definition Table.cpp:236
bool p_swap
Only used for reading.
Definition Table.h:132
void operator+=(TableRecord &rec)
Adds a TableRecord to the Table.
Definition Table.cpp:356
void SetAssociation(const Table::Association assoc)
Sets the association to the input parameter.
Definition Table.cpp:270
TableRecord & operator[](const int index)
Reads a TableRecord from the Table.
Definition Table.cpp:345
QString Name() const
The Table's name.
Definition Table.cpp:247
std::vector< char * > p_recbufs
Buffers containing record values.
Definition Table.h:126
TableRecord p_record
The current table record.
Definition Table.h:125
bool IsBandAssociated()
Checks to see if association is Bands.
Definition Table.cpp:303
bool IsLineAssociated()
Checks to see if association is Lines.
Definition Table.cpp:292
Table & operator=(const Isis::Table &other)
Sets the Table equal to the input Table object.
Definition Table.cpp:200
void Clear()
Clear the table of all records.
Definition Table.cpp:403
void Update(const TableRecord &rec, const int index)
Updates a TableRecord.
Definition Table.cpp:382
void initFromBlob(Blob &blob)
Initialize a Table from a Blob that has been read from a file.
Definition Table.cpp:146
static QString toString(Table table, QString fieldDelimiter=",")
Convert the data from a Table into a string.
Definition Table.cpp:480
PvlObject p_label
The label for storing additional information.
Definition Table.h:135
Blob toBlob() const
Serialze the Table to a Blob that can be written to a file.
Definition Table.cpp:414
void Unpack(const char *buf)
Reads record information from the binary buffer.
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 Swap(char *buf) const
Swaps bytes of the buffer, depending on the TableField::Type.
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.