00001
00002
00003
00004
00005
00006
00007 #ifndef DATACHANNEL_H
00008 #define DATACHANNEL_H
00009
00010 #include <cmath>
00011 #include <string>
00012
00013 #include "ByteArray.h"
00014 #include "MyException.h"
00015 #include "TableData.hxx"
00016
00025 template<typename DataType>
00026 class DataChannel
00027 {
00028 public:
00031 virtual void input(TableData<DataType>& data,
00032 int colNo,
00033 ByteArray& bytes) = 0;
00034
00037 virtual void output(TableData<DataType>& data,
00038 int colNo,
00039 ByteArray& bytes) = 0;
00040
00041 virtual void output(DataType& data, ByteArray& bytes) = 0;
00042
00045 virtual int getWordSize() = 0;
00046
00048 virtual ~DataChannel() {}
00049 };
00050
00052 template<typename DataType>
00053 class DataChannel_SQL_tinyint : public DataChannel<DataType>
00054 {
00055 public:
00057 void input(TableData<DataType>& data, int colNo, ByteArray& bytes)
00058 {
00059
00060 char word;
00061 for (int recNo = 0; recNo < bytes.getNumRecords(); ++recNo) {
00062
00063
00064 bytes.getNextWord(1, &word);
00065
00066
00067
00068 data.assign(colNo, recNo, (Numeric)word);
00069 }
00070
00071 }
00072
00074 void output(TableData<DataType>& data, int colNo, ByteArray& bytes)
00075 {
00076 for (int recNo = 0; recNo < bytes.getNumRecords(); ++recNo)
00077 {
00078 Numeric v;
00079 data.value(colNo, recNo, v);
00080
00081
00082
00083 char word = static_cast<char>(floor(v));
00084
00085 bytes.putNextWord(1, &word);
00086 }
00087 }
00088
00089 void output(DataType& data, ByteArray& bytes)
00090 {
00091
00092
00093 char word = (char)floor(data);
00094
00095 bytes.putNextWord(1, &word);
00096 }
00097
00099 int getWordSize() {
00100 return 1;
00101 }
00102
00103
00104 virtual ~DataChannel_SQL_tinyint() {}
00105 };
00106
00108 template<typename DataType>
00109 class DataChannel_SQL_smallint : public DataChannel<DataType> {
00110
00111 private:
00112
00113 static const int wordSize = 2;
00114
00115 union {
00116 char bytes[wordSize];
00117 short x;
00118 } word;
00119
00120 public:
00121
00123 void input(TableData<DataType>& data, int colNo, ByteArray& bytes) {
00124
00125 for (int recNo = 0; recNo < bytes.getNumRecords(); ++recNo) {
00126 bytes.getNextWord(wordSize, word.bytes);
00127 data.assign(colNo, recNo, (Numeric)word.x);
00128 }
00129
00130 }
00131
00133 void output(TableData<DataType>& data, int colNo, ByteArray& bytes) {
00134
00135 for (int recNo = 0; recNo < bytes.getNumRecords(); ++recNo) {
00136 Numeric v;
00137 data.value(colNo, recNo, v);
00138 word.x = (short)floor(v);
00139 bytes.putNextWord(wordSize, word.bytes);
00140 }
00141
00142 }
00143
00144 void output(DataType& data, ByteArray& bytes)
00145 {
00146 word.x = (short)floor(data);
00147 bytes.putNextWord(wordSize, word.bytes);
00148 }
00149
00151 int getWordSize() {
00152 return wordSize;
00153 }
00154
00155
00156 virtual ~DataChannel_SQL_smallint() {}
00157 };
00158
00160 template<typename DataType>
00161 class DataChannel_SQL_int : public DataChannel<DataType> {
00162
00163 private:
00164
00165 static const int wordSize = 4;
00166
00167 union {
00168 char bytes[wordSize];
00169 int x;
00170 } word;
00171
00172 public:
00173
00175 void input(TableData<DataType>& data, int colNo, ByteArray& bytes) {
00176
00177 for (int recNo = 0; recNo < bytes.getNumRecords(); ++recNo) {
00178 bytes.getNextWord(wordSize, word.bytes);
00179 data.assign(colNo, recNo, (Numeric)word.x);
00180 }
00181
00182 }
00183
00185 void output(TableData<DataType>& data, int colNo, ByteArray& bytes) {
00186
00187 for (int recNo = 0; recNo < bytes.getNumRecords(); ++recNo) {
00188 Numeric v;
00189 data.value(colNo, recNo, v);
00190 word.x = (int)floor(v);
00191 bytes.putNextWord(wordSize, word.bytes);
00192 }
00193
00194 }
00195
00196 void output(DataType& data, ByteArray& bytes)
00197 {
00198 word.x = (int)floor(data);
00199 bytes.putNextWord(wordSize, word.bytes);
00200 }
00201
00203 int getWordSize() {
00204 return wordSize;
00205 }
00206
00207
00208 virtual ~DataChannel_SQL_int() {}
00209 };
00210
00212 template<typename DataType>
00213 class DataChannel_SQL_bigint : public DataChannel<DataType> {
00214
00215 private:
00216
00217 static const int wordSize = 8;
00218
00219 union {
00220 char bytes[wordSize];
00221 long long x;
00222 } word;
00223
00224 public:
00225
00227 void input(TableData<DataType>& data, int colNo, ByteArray& bytes) {
00228
00229 for (int recNo = 0; recNo < bytes.getNumRecords(); ++recNo) {
00230 bytes.getNextWord(wordSize, word.bytes);
00231 data.assign(colNo, recNo, (Numeric)word.x);
00232 }
00233
00234 }
00235
00237 void output(TableData<DataType>& data, int colNo, ByteArray& bytes) {
00238
00239 for (int recNo = 0; recNo < bytes.getNumRecords(); ++recNo) {
00240 Numeric v;
00241 data.value(colNo, recNo, v);
00242 word.x = (long long)floor(v);
00243 bytes.putNextWord(wordSize, word.bytes);
00244 }
00245
00246 }
00247
00248 void output(DataType& data, ByteArray& bytes)
00249 {
00250 word.x = (long long)floor(data);
00251 bytes.putNextWord(wordSize, word.bytes);
00252 }
00253
00255 int getWordSize() {
00256 return wordSize;
00257 }
00258
00259
00260 virtual ~DataChannel_SQL_bigint() {}
00261 };
00262
00264 template<typename DataType>
00265 class DataChannel_SQL_real : public DataChannel<DataType> {
00266
00267 private:
00268
00269 static const int wordSize = 4;
00270
00271 union {
00272 char bytes[wordSize];
00273 float x;
00274 } word;
00275
00276 public:
00277
00279 void input(TableData<DataType>& data, int colNo, ByteArray& bytes) {
00280
00281 for (int recNo = 0; recNo < bytes.getNumRecords(); ++recNo) {
00282 bytes.getNextWord(wordSize, word.bytes);
00283 data.assign(colNo, recNo, (Numeric)word.x);
00284 }
00285
00286 }
00287
00289 void output(TableData<DataType>& data, int colNo, ByteArray& bytes) {
00290
00291 for (int recNo = 0; recNo < bytes.getNumRecords(); ++recNo) {
00292 Numeric v;
00293 data.value(colNo, recNo, v);
00294 word.x = (float)v;
00295 bytes.putNextWord(wordSize, word.bytes);
00296 }
00297
00298 }
00299
00300 void output(DataType& data, ByteArray& bytes)
00301 {
00302 word.x = (float)data;
00303 bytes.putNextWord(wordSize, word.bytes);
00304 }
00305
00307 int getWordSize() {
00308 return wordSize;
00309 }
00310
00311
00312 virtual ~DataChannel_SQL_real() {}
00313 };
00314
00316 template<typename DataType>
00317 class DataChannel_SQL_float : public DataChannel<DataType> {
00318
00319 private:
00320
00321 static const int wordSize = 8;
00322
00323 union {
00324 char bytes[wordSize];
00325 double x;
00326 } word;
00327
00328 public:
00329
00331 void input(TableData<DataType>& data, int colNo, ByteArray& bytes) {
00332
00333 for (int recNo = 0; recNo < bytes.getNumRecords(); ++recNo) {
00334 bytes.getNextWord(wordSize, word.bytes);
00335 data.assign(colNo, recNo, (Numeric)word.x);
00336 }
00337
00338 }
00339
00341 void output(TableData<DataType>& data, int colNo, ByteArray& bytes) {
00342
00343 for (int recNo = 0; recNo < bytes.getNumRecords(); ++recNo) {
00344 Numeric v;
00345 data.value(colNo, recNo, v);
00346 word.x = (double)v;
00347 bytes.putNextWord(wordSize, word.bytes);
00348 }
00349
00350 }
00351
00353 void output(DataType& data, ByteArray& bytes)
00354 {
00355 word.x = (double)data;
00356 bytes.putNextWord(wordSize, word.bytes);
00357 }
00358
00360 int getWordSize() {
00361 return wordSize;
00362 }
00363
00364
00365 virtual ~DataChannel_SQL_float() {}
00366 };
00367
00368 extern inline DataChannel<Numeric>* selectChannel(const std::string& type)
00369 {
00370 if (type == "tinyint") {
00371 return new DataChannel_SQL_tinyint<Numeric>();
00372 }
00373 else if (type == "smallint") {
00374 return new DataChannel_SQL_smallint<Numeric>();
00375 }
00376 else if (type == "int") {
00377 return new DataChannel_SQL_int<Numeric>();
00378 }
00379 else if (type == "bigint") {
00380 return new DataChannel_SQL_bigint<Numeric>();
00381 }
00382 else if (type == "real") {
00383 return new DataChannel_SQL_real<Numeric>();
00384 }
00385 else if (type == "float") {
00386 return new DataChannel_SQL_float<Numeric>();
00387 }
00388 else {
00389 throw MyException("Cannot open a data channel for type " + type);
00390 }
00391 }
00392
00393 #endif
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407