Isis 3 Programmer Reference
TableRecord.cpp
Go to the documentation of this file.
1 
24 #include "TableRecord.h"
25 
26 #include <iostream>
27 #include <string>
28 #include <vector>
29 
30 #include "IException.h"
31 #include "IString.h"
32 #include "TableField.h"
33 
34 using namespace std;
35 namespace Isis {
37  TableRecord::TableRecord(){
38  }
39 
41  TableRecord::~TableRecord() {
42  }
43 
44 
50  void TableRecord::operator+=(Isis::TableField &field) {
51  p_fields.push_back(field);
52  }
53 
61  Isis::TableField &TableRecord::operator[](const int field) {
62  return p_fields[field];
63  }
64 
76  TableField &TableRecord::operator[](const QString &field) {
77  Isis::IString upTemp = field;
78  upTemp.UpCase();
79  for (int i = 0; i < (int)p_fields.size(); i++) {
80  Isis::IString upField = p_fields[i].name();
81  upField.UpCase();
82  if (upTemp == upField) return p_fields[i];
83  }
84 
85  QString msg = "Field [" + field + "] does not exist in record";
86  throw IException(IException::Programmer, msg, _FILEINFO_);
87  }
88 
94  int TableRecord::Fields() const {
95  return p_fields.size();
96  }
97 
103  int TableRecord::RecordSize() const {
104  int bytes = 0;
105  for (int i = 0; i < (int)p_fields.size(); i++) bytes += p_fields[i].bytes();
106  return bytes;
107  }
108 
116  void TableRecord::Pack(char *buf) const {
117  int sbyte = 0;
118  for (int f = 0; f < Fields(); f++) {
119  const Isis::TableField &field = p_fields[f];
120  if (field.isDouble()) {
121  vector<double> vals = field;
122  for (unsigned int i = 0; i < vals.size(); i++) {
123  //*((double *)(buf+sbyte)) = vals[i];
124  memmove(buf + sbyte, &vals[i], 8);
125  sbyte += sizeof(double);
126  }
127  }
128  else if (field.isInteger()) {
129  vector<int> vals = field;
130  for (unsigned int i = 0; i < vals.size(); i++) {
131  //*((int *)(buf+sbyte)) = vals[i];
132  memmove(buf + sbyte, &vals[i], 4);
133  sbyte += sizeof(int);
134  }
135  }
136  else if (field.isText()) {
137  QString val = (QString)field;
138  for (int i = 0; i < field.size(); i++) {
139  if (i < (int)val.length()) {
140  buf[sbyte] = val[i].toLatin1();
141  }
142  else {
143  buf[sbyte] = 0;
144  }
145  sbyte++;
146  }
147  }
148  else if (field.isReal()) {
149  vector<float> vals = field;
150  for (unsigned int i = 0; i < vals.size(); i++) {
151  //*((int *)(buf+sbyte)) = vals[i];
152  memmove(buf + sbyte, &vals[i], 4);
153  sbyte += sizeof(float);
154  }
155  }
156  else {
157  string msg = "Invalid field type";
158  throw IException(IException::Programmer, msg, _FILEINFO_);
159  }
160  }
161  }
162 
168  void TableRecord::Unpack(const char *buf) {
169  int sbyte = 0;
170  for (int f = 0; f < Fields(); f++) {
171  Isis::TableField &field = p_fields[f];
172  field = (void *)&buf[sbyte];
173  sbyte += field.bytes();
174  }
175  }
176 
184  void TableRecord::Swap(char *buf) const {
185  int sbyte = 0;
186  for (int f = 0; f < Fields(); f++) {
187  const Isis::TableField &field = p_fields[f];
188  if (field.isDouble()) {
189  for (int i = 0; i < field.size(); i++) {
190  char *swap = &buf[sbyte];
191  char temp;
192  temp = swap[0];
193  swap[0] = swap[7];
194  swap[7] = temp;
195  temp = swap[1];
196  swap[1] = swap[6];
197  swap[6] = temp;
198  temp = swap[2];
199  swap[2] = swap[5];
200  swap[5] = temp;
201  temp = swap[3];
202  swap[3] = swap[4];
203  swap[4] = temp;
204 
205  sbyte += sizeof(double);
206  }
207  }
208  else if (field.isInteger()) {
209  for (int i = 0; i < field.size(); i++) {
210  char *swap = &buf[sbyte];
211  char temp;
212  temp = swap[0];
213  swap[0] = swap[3];
214  swap[3] = temp;
215  temp = swap[1];
216  swap[1] = swap[2];
217  swap[2] = temp;
218  sbyte += sizeof(int);
219  }
220  }
221  else if (field.isText()) {
222  sbyte += field.bytes();
223  }
224  else if (field.isReal()) {
225  for (int i = 0; i < field.size(); i++) {
226  char *swap = &buf[sbyte];
227  char temp;
228  temp = swap[0];
229  swap[0] = swap[3];
230  swap[3] = temp;
231  temp = swap[1];
232  swap[1] = swap[2];
233  swap[2] = temp;
234  sbyte += sizeof(float);
235  }
236  }
237  else {
238  string msg = "Unable to swap bytes. Invalid field type";
239  throw IException(IException::Programmer, msg, _FILEINFO_);
240  }
241  }
242  }
243 
244 
245 
246  QString TableRecord::toString(TableRecord record, QString fieldDelimiter, bool fieldNames, bool endLine) {
247  QString recordValues;
248  if (fieldNames) {
249  for (int fieldIndex = 0;fieldIndex < record.Fields();fieldIndex++) {
250  // write out the name of each field
251  if (record[fieldIndex].size() == 1) {
252  recordValues += record[fieldIndex].name();
253  }
254  else {
255  for (int fieldValueIndex = 0;fieldValueIndex < record[fieldIndex].size();fieldValueIndex++) {
256  recordValues += record[fieldIndex].name();
257  if (record[fieldIndex].isText()) {
258  // if it's a text field, exit the loop by adding the appropriate number of bytes
259  fieldValueIndex += record[fieldIndex].bytes();
260  }
261  else {
262  // if the field is multivalued, write the index of the field
263  recordValues += "(" + Isis::toString(fieldValueIndex) + ")";
264  }
265  if (fieldValueIndex != record[fieldIndex].size() - 1) {
266  // add a delimiter to all but the last value in this field
267  recordValues += fieldDelimiter;
268  }
269  }
270  }
271  // add a delimiter to all but the last field in this record
272  if (fieldIndex != record.Fields() - 1) {
273  recordValues += fieldDelimiter;
274  }
275  }
276  // end field names line
277  recordValues += "\n";
278  }
279 
280  for (int fieldIndex = 0;fieldIndex < record.Fields();fieldIndex++) {
281  // add value for each field in the record
282  recordValues += TableField::toString(record[fieldIndex], fieldDelimiter);
283  if (fieldIndex != record.Fields() - 1) {
284  // add delimiter to all but the last field in the record
285  recordValues += fieldDelimiter;
286  }
287  }
288  if (endLine) {
289  recordValues += "\n";
290  }
291  return recordValues;
292  }
293 
294 } // end namespace isis
Namespace for the standard library.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:226
bool isReal() const
Determines whether the field type is Text.
Definition: TableField.cpp:166
int bytes() const
Returns the number of bytes in the field value.
Definition: TableField.cpp:175
bool isInteger() const
Determines whether the field type is Integer.
Definition: TableField.cpp:138
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
int size() const
Returns the number of values stored for the field at each record.
Definition: TableField.cpp:184
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
int Fields() const
Returns the number of fields that are currently in the record.
Definition: TableRecord.cpp:94
bool isText() const
Determines whether the field type is Text.
Definition: TableField.cpp:157
Class for storing an Isis::Table&#39;s field information.
Definition: TableField.h:63
bool isDouble() const
Determines whether the field type is Double.
Definition: TableField.cpp:148
IString UpCase()
Converst any lower case characters in the object IString with uppercase characters.
Definition: IString.cpp:632