All Classes Namespaces Files Functions Variables Enumerations Enumerator
libs/connection/ConnectionRecorder.cpp
Go to the documentation of this file.
00001 
00010 #include <fstream>
00011 #include <string>
00012 #include "ConnectionRecorder.h"
00013 
00014 using namespace qrk;
00015 using namespace std;
00016 
00017 
00018 struct ConnectionRecorder::pImpl
00019 {
00020     enum {
00021         Recv = 0,
00022         Send,
00023     };
00024 
00025     Connection* con_;
00026     size_t unget_count_;
00027     ofstream fout_[2];
00028 
00029 
00030     pImpl(Connection* con) : con_(con), unget_count_(0)
00031     {
00032         setBaseName("recorder");
00033     }
00034 
00035 
00036     void setBaseName(const char* basename)
00037     {
00038         const char* suffix[] = {
00039             "_receive.txt",
00040             "_send.txt",
00041         };
00042 
00043         for (size_t i = 0; i < 2; ++i) {
00044             // 現状の接続を閉じる
00045             if (fout_[i].is_open()) {
00046                 fout_[i].close();
00047             }
00048 
00049             // 新しい名前で接続を開く
00050             string fname = string(basename) + suffix[i];
00051             fout_[i].open(fname.c_str(), ios::binary);
00052         }
00053     }
00054 };
00055 
00056 
00057 ConnectionRecorder::ConnectionRecorder(Connection* con)
00058     : pimpl(new pImpl(con))
00059 {
00060 }
00061 
00062 
00063 ConnectionRecorder::~ConnectionRecorder(void)
00064 {
00065 }
00066 
00067 
00068 const char* ConnectionRecorder::what(void) const
00069 {
00070     return pimpl->con_->what();
00071 }
00072 
00073 
00074 bool ConnectionRecorder::connect(const char* device, long baudrate)
00075 {
00076     return pimpl->con_->connect(device, baudrate);
00077 }
00078 
00079 
00080 void ConnectionRecorder::disconnect(void)
00081 {
00082     pimpl->con_->disconnect();
00083 }
00084 
00085 
00086 bool ConnectionRecorder::setBaudrate(long baudrate)
00087 {
00088     return pimpl->con_->setBaudrate(baudrate);
00089 }
00090 
00091 
00092 long ConnectionRecorder::baudrate(void) const
00093 {
00094     return pimpl->con_->baudrate();
00095 }
00096 
00097 
00098 bool ConnectionRecorder::isConnected(void) const
00099 {
00100     return pimpl->con_->isConnected();
00101 }
00102 
00103 
00104 int ConnectionRecorder::send(const char* data, size_t count)
00105 {
00106     int n = pimpl->con_->send(data, count);
00107 
00108     if (n > 0) {
00109         pimpl->fout_[pImpl::Send].write(data, n);
00110         pimpl->fout_[pImpl::Send].flush();
00111     }
00112     return n;
00113 }
00114 
00115 
00116 int ConnectionRecorder::receive(char* data, size_t count, int timeout)
00117 {
00118     int n = pimpl->con_->receive(data, count, timeout);
00119 
00120     // 過去に書き戻した分は、ファイルに書き出さない
00121     int skip_length = pimpl->unget_count_;
00122     if ((n > 0) && (skip_length > n)) {
00123         skip_length = n;
00124     }
00125     pimpl->unget_count_ -= skip_length;
00126 
00127     // ファイルへの受信データ書き出し
00128     if (n > 0) {
00129         pimpl->fout_[pImpl::Recv].write(&data[skip_length], n - skip_length);
00130         pimpl->fout_[pImpl::Recv].flush();
00131     }
00132     return n;
00133 }
00134 
00135 
00136 size_t ConnectionRecorder::size(void) const
00137 {
00138     return pimpl->con_->size();
00139 }
00140 
00141 
00142 void ConnectionRecorder::flush(void)
00143 {
00144     pimpl->con_->flush();
00145 }
00146 
00147 
00148 void ConnectionRecorder::clear(void)
00149 {
00150     pimpl->con_->clear();
00151 }
00152 
00153 
00154 void ConnectionRecorder::ungetc(const char ch)
00155 {
00156     ++pimpl->unget_count_;
00157     pimpl->con_->ungetc(ch);
00158 }
00159 
00160 
00161 void ConnectionRecorder::setBasename(const char* basename)
00162 {
00163     pimpl->setBaseName(basename);
00164 }