Isis 3 Programmer Reference
Table.cpp
Go to the documentation of this file.
1 
23 #include "Table.h"
24 
25 #include <fstream>
26 #include <string>
27 
28 #include "Endian.h"
29 #include "IException.h"
30 #include "Pvl.h"
31 #include "TableField.h"
32 
33 using namespace std;
34 namespace Isis {
35 
54  Table::Table(const QString &tableName, Isis::TableRecord &rec) :
55  Blob(tableName, "Table") {
56  p_assoc = Table::None;
57  p_blobPvl += Isis::PvlKeyword("Records", 0);
58  p_blobPvl += Isis::PvlKeyword("ByteOrder", "NULL");
59  for (int f = 0; f < rec.Fields(); f++) p_blobPvl.addGroup(rec[f].pvlGroup());
60  p_record = rec;
61  }
62 
75  Table::Table(const QString &tableName) :
76  Isis::Blob(tableName, "Table") {
77  p_assoc = Table::None;
78  }
79 
94  Table::Table(const QString &tableName, const QString &file) :
95  Blob(tableName, "Table") {
96  p_assoc = Table::None;
97  Read(file);
98  }
99 
115  Table::Table(const QString &tableName, const QString &file,
116  const Pvl &fileHeader) : Blob(tableName, "Table") {
117  p_assoc = Table::None;
118  Read(file, fileHeader);
119  }
120 
121 
128  Table::Table(const Table &other) : Blob(other) {
129  p_record = other.p_record;
130  p_records = other.p_records;
131  p_assoc = other.p_assoc;
132  p_swap = other.p_swap;
133 
134  for (unsigned int i = 0; i < other.p_recbufs.size(); i++) {
135  char *data = new char[RecordSize()];
136 
137  for (int j = 0; j < RecordSize(); j++) {
138  data[j] = other.p_recbufs[i][j];
139  }
140 
141  p_recbufs.push_back(data);
142  }
143  }
144 
155  Clear();
156  *((Isis::Blob *)this) = *((Isis::Blob *)&other);
157  p_record = other.p_record;
158  p_records = other.p_records;
159  p_assoc = other.p_assoc;
160  p_swap = other.p_swap;
161 
162  for (unsigned int i = 0; i < other.p_recbufs.size(); i++) {
163  char *data = new char[RecordSize()];
164 
165  for (int j = 0; j < RecordSize(); j++) {
166  data[j] = other.p_recbufs[i][j];
167  }
168 
169  p_recbufs.push_back(data);
170  }
171 
172  return *this;
173  }
174 
177  Clear();
178  }
179 
185  void Table::SetAssociation(const Table::Association assoc) {
186  p_assoc = assoc;
187  }
188 
196  return (p_assoc == Table::Samples);
197  }
198 
206  return (p_assoc == Table::Lines);
207  }
208 
216  return (p_assoc == Table::Bands);
217  }
218 
224  int Table::Records() const {
225  return p_recbufs.size();
226  }
227 
233  int Table::RecordFields() const {
234  return p_record.Fields();
235  }
236 
242  int Table::RecordSize() const {
243  return p_record.RecordSize();
244  }
245 
254  p_record.Unpack(p_recbufs[index]);
255  return p_record;
256  }
257 
264  if (RecordSize() == 0) {
265  IString msg = "Unable to add records to Isis Table ["
266  + p_blobName + "]. Bytes per record = [0 bytes].";
268  }
269 
270  if (RecordSize() != rec.RecordSize()) {
271  QString msg = "Unable to add the given record with size = ["
272  + Isis::toString(rec.RecordSize()) + " bytes] to to Isis Table ["
273  + p_blobName + "] with record size = ["
274  + Isis::toString(RecordSize()) + " bytes]. Record sizes must match.";
276  }
277  char *newbuf = new char[RecordSize()];
278  rec.Pack(newbuf);
279  p_recbufs.push_back(newbuf);
280  }
281 
288  void Table::Update(const Isis::TableRecord &rec, const int index) {
289  rec.Pack(p_recbufs[index]);
290  }
291 
297  void Table::Delete(const int index) {
298  vector<char *>::iterator it = p_recbufs.begin();
299  for (int i = 0; i < index; i++, it++);
300  delete [] p_recbufs[index];
301  p_recbufs.erase(it);
302  }
303 
307  void Table::Clear() {
308  for (int i = 0; i < (int)p_recbufs.size(); i++) delete [] p_recbufs[i];
309  p_recbufs.clear();
310  }
311 
314  p_records = p_blobPvl["Records"];
315 
316  Isis::TableRecord rec;
317  for (int g = 0; g < p_blobPvl.groups(); g++) {
318  if (p_blobPvl.group(g).isNamed("Field")) {
320  rec += f;
321  }
322  }
323 
324  p_record = rec;
325 
326  if (p_blobPvl.hasKeyword("Association")) {
327  QString temp = (QString) p_blobPvl["Association"];
328  temp = temp.toUpper();
329  if (temp == "SAMPLES") p_assoc = Table::Samples;
330  if (temp == "LINES") p_assoc = Table::Lines;
331  if (temp == "BANDS") p_assoc = Table::Bands;
332  }
333 
334  // Determine if we need to swap stuff when we read the data
335  Isis::ByteOrder bo = Isis::ByteOrderEnumeration(p_blobPvl["ByteOrder"]);
336  p_swap = false;
337  if (Isis::IsLsb() && (bo == Isis::Msb)) p_swap = true;
338  if (Isis::IsMsb() && (bo == Isis::Lsb)) p_swap = true;
339 
340  // Cleanup in case of a re-read
341  Clear();
342  }
343 
351  void Table::ReadData(std::istream &stream) {
352  for (int rec = 0; rec < p_records; rec++) {
353  streampos sbyte = (streampos)(p_startByte - 1) +
354  (streampos)(rec * RecordSize());
355  stream.seekg(sbyte, std::ios::beg);
356  if (!stream.good()) {
357  QString msg = "Error preparing to read record [" + Isis::toString(rec + 1) +
358  "] from Table [" + p_blobName + "]";
359  throw IException(IException::Io, msg, _FILEINFO_);
360  }
361 
362  char *buf = new char[RecordSize()];
363  stream.read(buf, RecordSize());
364  if (!stream.good()) {
365  QString msg = "Error reading record [" + Isis::toString(rec + 1) +
366  "] from Table [" + p_blobName + "]";
367  throw IException(IException::Io, msg, _FILEINFO_);
368  }
369 
370  if (p_swap) p_record.Swap(buf);
371  p_recbufs.push_back(buf);
372  }
373  }
374 
377  p_blobPvl["Records"] = Isis::toString(Records());
378  p_nbytes = Records() * RecordSize();
379 
380  if (Isis::IsLsb()) {
381  p_blobPvl["ByteOrder"] = Isis::ByteOrderName(Isis::Lsb);
382  }
383  else {
384  p_blobPvl["ByteOrder"] = Isis::ByteOrderName(Isis::Msb);
385  }
386 
387  if (p_blobPvl.hasKeyword("Association")) {
388  p_blobPvl.deleteKeyword("Association");
389  }
390  if (p_assoc == Samples) {
391  p_blobPvl += Isis::PvlKeyword("Association", "Samples");
392  }
393  else if (p_assoc == Lines) {
394  p_blobPvl += Isis::PvlKeyword("Association", "Lines");
395  }
396  else if (p_assoc == Bands) {
397  p_blobPvl += Isis::PvlKeyword("Association", "Bands");
398  }
399  }
400 
406  void Table::WriteData(std::fstream &os) {
407  for (int rec = 0; rec < Records(); rec++) {
408  os.write(p_recbufs[rec], RecordSize());
409  }
410  }
411 
412 
413  QString Table::toString(Table table, QString fieldDelimiter) {
414  QString tableValues;
415  // add the first record with header, the given delimiter, and a new line after each record
416  tableValues += TableRecord::toString(table[0], fieldDelimiter, true, true);
417  // add remaining records without header, the same delimeter, and new line after each record
418  for (int recordIndex = 1; recordIndex < table.Records(); recordIndex++) {
419  tableValues += TableRecord::toString(table[recordIndex], fieldDelimiter);
420  }
421  return tableValues;
422  }
423 
424 }
int RecordSize() const
Returns the number of bytes per record.
void WriteInit()
Virtual Function to prepare labels for writing.
Definition: Table.cpp:376
int Records() const
Returns the number of records.
Definition: Table.cpp:224
QString p_blobName
Name of the Blob object.
Definition: Blob.h:95
bool IsBandAssociated()
Checks to see if association is Bands.
Definition: Table.cpp:215
TableRecord p_record
The current table record.
Definition: Table.h:137
int RecordSize() const
Returns the number of bytes per record.
Definition: Table.cpp:242
void Read(const QString &file)
This method reads Pvl values from a specified file.
Definition: Blob.cpp:243
bool IsLineAssociated()
Checks to see if association is Lines.
Definition: Table.cpp:205
void WriteData(std::fstream &os)
Virtual function to write the data.
Definition: Table.cpp:406
void addGroup(const Isis::PvlGroup &group)
Add a group to the object.
Definition: PvlObject.h:198
int p_records
Holds record count read from labels, may differ from the size of p_recbufs.
Definition: Table.h:140
Namespace for the standard library.
ByteOrder
Tests the current architecture for byte order.
Definition: Endian.h:59
void Unpack(const char *buf)
Reads record information from the binary buffer.
int p_nbytes
Size of blob data (in bytes)
Definition: Blob.h:99
PvlObject p_blobPvl
Pvl Blob object.
Definition: Blob.h:94
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:226
A type of error that occurred when performing an actual I/O operation.
Definition: IException.h:171
~Table()
Destroys the Table object.
Definition: Table.cpp:176
std::vector< char * > p_recbufs
Buffers containing record values.
Definition: Table.h:138
Association p_assoc
Association Type of the table.
Definition: Table.h:143
void Clear()
Clear the table of all records.
Definition: Table.cpp:307
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 ...
Definition: PvlObject.cpp:207
int RecordFields() const
Returns the number of fields per record.
Definition: Table.cpp:233
void Pack(char *buf) const
Writes record information into the binary buffer.
void Swap(char *buf) const
Swaps bytes of the buffer, depending on the TableField::Type.
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
A single keyword-value pair.
Definition: PvlKeyword.h:98
bool IsLsb()
Return true if this host is an LSB first machine and false if it is not.
Definition: Endian.h:84
A type of error that cannot be classified as any of the other error types.
Definition: IException.h:134
void Delete(const int index)
Deletes a TableRecord from the Table.
Definition: Table.cpp:297
Container for cube-like labels.
Definition: Pvl.h:135
void Update(const TableRecord &rec, const int index)
Updates a TableRecord.
Definition: Table.cpp:288
void SetAssociation(const Table::Association assoc)
Sets the association to the input parameter.
Definition: Table.cpp:185
Table & operator=(const Isis::Table &other)
Sets the Table equal to the input Table object.
Definition: Table.cpp:154
bool isNamed(const QString &match) const
Returns whether the given string is equal to the container name or not.
Definition: PvlContainer.h:86
PvlGroup & group(const int index)
Return the group at the specified index.
Definition: PvlObject.cpp:423
Class for storing Table blobs information.
Definition: Table.h:77
void operator+=(TableRecord &rec)
Adds a TableRecord to the Table.
Definition: Table.cpp:263
TableRecord & operator[](const int index)
Reads a TableRecord from the Table.
Definition: Table.cpp:253
Isis exception class.
Definition: IException.h:107
Adds specific functionality to C++ strings.
Definition: IString.h:181
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
void ReadInit()
Virtual function to validate PVL table information.
Definition: Table.cpp:313
int Fields() const
Returns the number of fields that are currently in the record.
Definition: TableRecord.cpp:94
bool IsSampleAssociated()
Checks to see if association is Samples.
Definition: Table.cpp:195
Class for storing an Isis::Table&#39;s field information.
Definition: TableField.h:63
int groups() const
Returns the number of groups contained.
Definition: PvlObject.h:87
bool IsMsb()
Return true if this host is an MSB first machine and false if it is not.
Definition: Endian.h:100
void ReadData(std::istream &stream)
Virtual function to Read the data.
Definition: Table.cpp:351
BigInt p_startByte
Byte blob data starts at in buffer.
Definition: Blob.h:98
bool p_swap
Only used for reading.
Definition: Table.h:144
void deleteKeyword(const QString &name)
Remove a specified keyword.