USGS

Isis 3.0 Object Programmers' Reference

Home

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 
47  Table::Table(const QString &tableName, Isis::TableRecord &rec) :
48  Blob(tableName, "Table") {
49  p_assoc = Table::None;
50  p_blobPvl += Isis::PvlKeyword("Records", 0);
51  p_blobPvl += Isis::PvlKeyword("ByteOrder", "NULL");
52  for (int f = 0; f < rec.Fields(); f++) p_blobPvl.addGroup(rec[f].pvlGroup());
53  p_record = rec;
54  }
55 
68  Table::Table(const QString &tableName) :
69  Isis::Blob(tableName, "Table") {
70  p_assoc = Table::None;
71  }
72 
87  Table::Table(const QString &tableName, const QString &file) :
88  Blob(tableName, "Table") {
89  p_assoc = Table::None;
90  Read(file);
91  }
92 
108  Table::Table(const QString &tableName, const QString &file,
109  const Pvl &fileHeader) : Blob(tableName, "Table") {
110  p_assoc = Table::None;
111  Read(file, fileHeader);
112  }
113 
114 
121  Table::Table(const Table &other) : Blob(other) {
122  p_record = other.p_record;
123  p_records = other.p_records;
124  p_assoc = other.p_assoc;
125  p_swap = other.p_swap;
126 
127  for (unsigned int i = 0; i < other.p_recbufs.size(); i++) {
128  char *data = new char[RecordSize()];
129 
130  for (int j = 0; j < RecordSize(); j++) {
131  data[j] = other.p_recbufs[i][j];
132  }
133 
134  p_recbufs.push_back(data);
135  }
136  }
137 
148  *((Isis::Blob *)this) = *((Isis::Blob *)&other);
149  p_record = other.p_record;
150  p_records = other.p_records;
151  p_assoc = other.p_assoc;
152  p_swap = other.p_swap;
153 
154  for (unsigned int i = 0; i < other.p_recbufs.size(); i++) {
155  char *data = new char[RecordSize()];
156 
157  for (int j = 0; j < RecordSize(); j++) {
158  data[j] = other.p_recbufs[i][j];
159  }
160 
161  p_recbufs.push_back(data);
162  }
163 
164  return *this;
165  }
166 
169  Clear();
170  }
171 
177  void Table::SetAssociation(const Table::Association assoc) {
178  p_assoc = assoc;
179  }
180 
188  return (p_assoc == Table::Samples);
189  }
190 
198  return (p_assoc == Table::Lines);
199  }
200 
208  return (p_assoc == Table::Bands);
209  }
210 
216  int Table::Records() const {
217  return p_recbufs.size();
218  }
219 
225  int Table::RecordFields() const {
226  return p_record.Fields();
227  }
228 
234  int Table::RecordSize() const {
235  return p_record.RecordSize();
236  }
237 
246  p_record.Unpack(p_recbufs[index]);
247  return p_record;
248  }
249 
256  if (RecordSize() == 0) {
257  IString msg = "Unable to add records to Isis Table ["
258  + p_blobName + "]. Bytes per record = [0 bytes].";
260  }
261 
262  // TODO: Determine why this error message causes mapmos to fail.
263  // The call comes from ProcessMapMosaic::StartProcess >>
264  // ProcessMosaic::StartProcess when the InputImages table is
265  // being filled (see ProcessMosaic lines 704 - 732)
266  // if (RecordSize() != rec.RecordSize()) {
267  // IString msg = "Unable to add the given record with size = ["
268  // + IString(rec.RecordSize()) + " bytes] to to Isis Table ["
269  // + p_blobName + "] with record size = ["
270  // + IString(RecordSize()) + " bytes]. Record sizes must match.";
271  // throw IException(IException::Unknown, msg, _FILEINFO_);
272  // }
273  // Temporary substitution?
274  if (RecordSize() < rec.RecordSize()) {
275  QString msg = "Unable to add the given record with size = ["
276  + toString(rec.RecordSize()) + " bytes] to to Isis Table ["
277  + p_blobName + "] with record size = ["
278  + toString(RecordSize()) + " bytes]. Added record size can "
279  "not exceed table record size.";
281  }
282  char *newbuf = new char[RecordSize()];
283  rec.Pack(newbuf);
284  p_recbufs.push_back(newbuf);
285  }
286 
293  void Table::Update(const Isis::TableRecord &rec, const int index) {
294  rec.Pack(p_recbufs[index]);
295  }
296 
302  void Table::Delete(const int index) {
303  vector<char *>::iterator it = p_recbufs.begin();
304  for (int i = 0; i < index; i++, it++);
305  delete [] p_recbufs[index];
306  p_recbufs.erase(it);
307  }
308 
312  void Table::Clear() {
313  for (int i = 0; i < (int)p_recbufs.size(); i++) delete [] p_recbufs[i];
314  p_recbufs.clear();
315  }
316 
319  p_records = p_blobPvl["Records"];
320 
321  Isis::TableRecord rec;
322  for (int g = 0; g < p_blobPvl.groups(); g++) {
323  if (p_blobPvl.group(g).isNamed("Field")) {
325  rec += f;
326  }
327  }
328 
329  p_record = rec;
330 
331  if (p_blobPvl.hasKeyword("Association")) {
332  QString temp = (QString) p_blobPvl["Association"];
333  temp = temp.toUpper();
334  if (temp == "SAMPLES") p_assoc = Table::Samples;
335  if (temp == "LINES") p_assoc = Table::Lines;
336  if (temp == "BANDS") p_assoc = Table::Bands;
337  }
338 
339  // Determine if we need to swap stuff when we read the data
340  Isis::ByteOrder bo = Isis::ByteOrderEnumeration(p_blobPvl["ByteOrder"]);
341  p_swap = false;
342  if (Isis::IsLsb() && (bo == Isis::Msb)) p_swap = true;
343  if (Isis::IsMsb() && (bo == Isis::Lsb)) p_swap = true;
344 
345  // Cleanup in case of a re-read
346  Clear();
347  }
348 
356  void Table::ReadData(std::istream &stream) {
357  for (int rec = 0; rec < p_records; rec++) {
358  streampos sbyte = (streampos)(p_startByte - 1) +
359  (streampos)(rec * RecordSize());
360  stream.seekg(sbyte, std::ios::beg);
361  if (!stream.good()) {
362  QString msg = "Error preparing to read record [" + toString(rec + 1) +
363  "] from Table [" + p_blobName + "]";
364  throw IException(IException::Io, msg, _FILEINFO_);
365  }
366 
367  char *buf = new char[RecordSize()];
368  stream.read(buf, RecordSize());
369  if (!stream.good()) {
370  QString msg = "Error reading record [" + toString(rec + 1) +
371  "] from Table [" + p_blobName + "]";
372  throw IException(IException::Io, msg, _FILEINFO_);
373  }
374 
375  if (p_swap) p_record.Swap(buf);
376  p_recbufs.push_back(buf);
377  }
378  }
379 
382  p_blobPvl["Records"] = toString(Records());
383  p_nbytes = Records() * RecordSize();
384 
385  if (Isis::IsLsb()) {
386  p_blobPvl["ByteOrder"] = Isis::ByteOrderName(Isis::Lsb);
387  }
388  else {
389  p_blobPvl["ByteOrder"] = Isis::ByteOrderName(Isis::Msb);
390  }
391 
392  if (p_blobPvl.hasKeyword("Association")) {
393  p_blobPvl.deleteKeyword("Association");
394  }
395  if (p_assoc == Samples) {
396  p_blobPvl += Isis::PvlKeyword("Association", "Samples");
397  }
398  else if (p_assoc == Lines) {
399  p_blobPvl += Isis::PvlKeyword("Association", "Lines");
400  }
401  else if (p_assoc == Bands) {
402  p_blobPvl += Isis::PvlKeyword("Association", "Bands");
403  }
404  }
405 
411  void Table::WriteData(std::fstream &os) {
412  for (int rec = 0; rec < Records(); rec++) {
413  os.write(p_recbufs[rec], RecordSize());
414  }
415  }
416 
417 }