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