Isis 3 Programmer Reference
TableRecord.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7
8#include "TableRecord.h"
9
10#include <iostream>
11#include <string>
12#include <vector>
13
14#include "IException.h"
15#include "IString.h"
16#include "TableField.h"
17
18using namespace std;
19namespace Isis {
23
27
28
35 p_fields.push_back(field);
36 }
37
46 return p_fields[field];
47 }
48
60 TableField &TableRecord::operator[](const QString &field) {
61 Isis::IString upTemp = field;
62 upTemp.UpCase();
63 for (int i = 0; i < (int)p_fields.size(); i++) {
64 Isis::IString upField = p_fields[i].name();
65 upField.UpCase();
66 if (upTemp == upField) return p_fields[i];
67 }
68
69 QString msg = "Field [" + field + "] does not exist in record";
70 throw IException(IException::Programmer, msg, _FILEINFO_);
71 }
72
78 int TableRecord::Fields() const {
79 return p_fields.size();
80 }
81
88 int bytes = 0;
89 for (int i = 0; i < (int)p_fields.size(); i++) bytes += p_fields[i].bytes();
90 return bytes;
91 }
92
100 void TableRecord::Pack(char *buf) const {
101 int sbyte = 0;
102 for (int f = 0; f < Fields(); f++) {
103 const Isis::TableField &field = p_fields[f];
104 if (field.isDouble()) {
105 vector<double> vals = field;
106 for (unsigned int i = 0; i < vals.size(); i++) {
107 //*((double *)(buf+sbyte)) = vals[i];
108 memmove(buf + sbyte, &vals[i], 8);
109 sbyte += sizeof(double);
110 }
111 }
112 else if (field.isInteger()) {
113 vector<int> vals = field;
114 for (unsigned int i = 0; i < vals.size(); i++) {
115 //*((int *)(buf+sbyte)) = vals[i];
116 memmove(buf + sbyte, &vals[i], 4);
117 sbyte += sizeof(int);
118 }
119 }
120 else if (field.isText()) {
121 QString val = (QString)field;
122 for (int i = 0; i < field.size(); i++) {
123 if (i < (int)val.length()) {
124 buf[sbyte] = val[i].toLatin1();
125 }
126 else {
127 buf[sbyte] = 0;
128 }
129 sbyte++;
130 }
131 }
132 else if (field.isReal()) {
133 vector<float> vals = field;
134 for (unsigned int i = 0; i < vals.size(); i++) {
135 //*((int *)(buf+sbyte)) = vals[i];
136 memmove(buf + sbyte, &vals[i], 4);
137 sbyte += sizeof(float);
138 }
139 }
140 else {
141 string msg = "Invalid field type";
142 throw IException(IException::Programmer, msg, _FILEINFO_);
143 }
144 }
145 }
146
152 void TableRecord::Unpack(const char *buf) {
153 int sbyte = 0;
154 for (int f = 0; f < Fields(); f++) {
155 Isis::TableField &field = p_fields[f];
156 field = (void *)&buf[sbyte];
157 sbyte += field.bytes();
158 }
159 }
160
168 void TableRecord::Swap(char *buf) const {
169 int sbyte = 0;
170 for (int f = 0; f < Fields(); f++) {
171 const Isis::TableField &field = p_fields[f];
172 if (field.isDouble()) {
173 for (int i = 0; i < field.size(); i++) {
174 char *swap = &buf[sbyte];
175 char temp;
176 temp = swap[0];
177 swap[0] = swap[7];
178 swap[7] = temp;
179 temp = swap[1];
180 swap[1] = swap[6];
181 swap[6] = temp;
182 temp = swap[2];
183 swap[2] = swap[5];
184 swap[5] = temp;
185 temp = swap[3];
186 swap[3] = swap[4];
187 swap[4] = temp;
188
189 sbyte += sizeof(double);
190 }
191 }
192 else if (field.isInteger()) {
193 for (int i = 0; i < field.size(); i++) {
194 char *swap = &buf[sbyte];
195 char temp;
196 temp = swap[0];
197 swap[0] = swap[3];
198 swap[3] = temp;
199 temp = swap[1];
200 swap[1] = swap[2];
201 swap[2] = temp;
202 sbyte += sizeof(int);
203 }
204 }
205 else if (field.isText()) {
206 sbyte += field.bytes();
207 }
208 else if (field.isReal()) {
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(float);
219 }
220 }
221 else {
222 string msg = "Unable to swap bytes. Invalid field type";
223 throw IException(IException::Programmer, msg, _FILEINFO_);
224 }
225 }
226 }
227
228
229
230 QString TableRecord::toString(TableRecord record, QString fieldDelimiter, bool fieldNames, bool endLine) {
231 QString recordValues;
232 if (fieldNames) {
233 for (int fieldIndex = 0;fieldIndex < record.Fields();fieldIndex++) {
234 // write out the name of each field
235 if (record[fieldIndex].size() == 1) {
236 recordValues += record[fieldIndex].name();
237 }
238 else {
239 for (int fieldValueIndex = 0;fieldValueIndex < record[fieldIndex].size();fieldValueIndex++) {
240 recordValues += record[fieldIndex].name();
241 if (record[fieldIndex].isText()) {
242 // if it's a text field, exit the loop by adding the appropriate number of bytes
243 fieldValueIndex += record[fieldIndex].bytes();
244 }
245 else {
246 // if the field is multivalued, write the index of the field
247 recordValues += "(" + Isis::toString(fieldValueIndex) + ")";
248 }
249 if (fieldValueIndex != record[fieldIndex].size() - 1) {
250 // add a delimiter to all but the last value in this field
251 recordValues += fieldDelimiter;
252 }
253 }
254 }
255 // add a delimiter to all but the last field in this record
256 if (fieldIndex != record.Fields() - 1) {
257 recordValues += fieldDelimiter;
258 }
259 }
260 // end field names line
261 recordValues += "\n";
262 }
263
264 for (int fieldIndex = 0;fieldIndex < record.Fields();fieldIndex++) {
265 // add value for each field in the record
266 recordValues += TableField::toString(record[fieldIndex], fieldDelimiter);
267 if (fieldIndex != record.Fields() - 1) {
268 // add delimiter to all but the last field in the record
269 recordValues += fieldDelimiter;
270 }
271 }
272 if (endLine) {
273 recordValues += "\n";
274 }
275 return recordValues;
276 }
277
278} // end namespace isis
Isis exception class.
Definition IException.h:91
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
Adds specific functionality to C++ strings.
Definition IString.h:165
IString UpCase()
Converst any lower case characters in the object IString with uppercase characters.
Definition IString.cpp:617
Class for storing an Isis::Table's field information.
Definition TableField.h:47
int bytes() const
Returns the number of bytes in the field value.
std::vector< TableField > p_fields
Vector of TableFields in the record.
Definition TableRecord.h:58
TableRecord()
Constructs an empty TableRecord object. No member variables are set.
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 Pack(char *buf) const
Writes record information into the binary buffer.
~TableRecord()
Destroys the TableRecord object.
void Swap(char *buf) const
Swaps bytes of the buffer, depending on the TableField::Type.
void operator+=(Isis::TableField &field)
Adds a TableField to a TableRecord.
TableField & operator[](const int field)
Returns the TableField at the specified location in the TableRecord.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
Namespace for the standard library.