00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "claraty/fdm_cdr_file.h"
00024 #include <map>
00025
00026 using namespace std;
00027
00028 FDM_CDR_File::FDM_CDR_File(FDM::Direction dir) :
00029 FDM_CDR(dir), _conn(), _io_file(NULL), _file_ok(false),
00030 _file_eof(false), _got_block(false), _topform_typename("")
00031 {
00032 }
00033
00034 FDM_CDR_File::FDM_CDR_File(const string &filename,
00035 FDM::Direction dir, bool append) :
00036 FDM_CDR(dir), _conn(), _io_file(NULL), _file_ok(false),
00037 _file_eof(false), _got_block(false), _topform_typename("")
00038 {
00039 open(filename, append);
00040 }
00041
00042 FDM_CDR_File::FDM_CDR_File(auto_ptr<ACE_FILE_IO> fio, FDM::Direction dir):
00043 FDM_CDR(dir), _conn(), _io_file(NULL), _file_ok(false),
00044 _file_eof(false), _got_block(false), _topform_typename("")
00045 {
00046 if(fio.get()!=NULL) {
00047 _io_file = fio.release();
00048 _file_ok=true;
00049 }
00050 }
00051 FDM_CDR_File::~FDM_CDR_File() {
00052 close();
00053 }
00054
00055 bool
00056 FDM_CDR_File::open(const string &filename, bool append)
00057 {
00058 if(_io_file!=NULL) {
00059
00060 delete _io_file;
00061 _io_file = NULL;
00062 _file_ok = false;
00063 }
00064
00065 _io_file = new ACE_FILE_IO();
00066 _file_ok = false;
00067
00068 if(is_read()) {
00069
00070 if(_conn.connect (*_io_file,
00071 ACE_FILE_Addr (filename.c_str()),
00072 0,
00073 ACE_Addr::sap_any,
00074 0,
00075 O_RDONLY,
00076 ACE_DEFAULT_FILE_PERMS) < 0) {
00077
00078 _file_ok=false;
00079 return(false);
00080 }
00081
00082 _file_ok=true;
00083 _file_eof=false;
00084 _got_block=false;
00085 return(true);
00086 }
00087 else {
00088
00089 int appflag = (append) ? (O_APPEND) : (O_TRUNC);
00090 if(_conn.connect (*_io_file,
00091 ACE_FILE_Addr (filename.c_str()),
00092 0,
00093 ACE_Addr::sap_any,
00094 0,
00095 O_RDWR|O_CREAT|appflag,
00096 ACE_DEFAULT_FILE_PERMS) < 0) {
00097
00098 _file_ok=false;
00099 return(false);
00100 }
00101
00102 _file_ok=true;
00103 _file_eof=false;
00104 return(true);
00105
00106 }
00107 }
00108
00109 void
00110 FDM_CDR_File::close()
00111 {
00112 if(_io_file != NULL) {
00113 if(is_write() && _file_ok && _ostr != NULL) {
00114
00115 flush();
00116 }
00117 delete _io_file;
00118 _io_file = NULL;
00119 }
00120 _file_ok = false;
00121 }
00122
00123 bool
00124 FDM_CDR_File::_read_block(auto_ptr<ACE_Message_Block> &msg)
00125 {
00126 if(!_file_ok || _file_eof || _io_file == NULL) {
00127 return(false);
00128 }
00129
00130
00131 ACE_Message_Block header(ACE_DEFAULT_CDR_BUFSIZE);
00132
00133 ACE_CDR::mb_align(&header);
00134
00135
00136 size_t nread;
00137 nread = _io_file->recv_n(header.wr_ptr(), 8);
00138 if(nread == 0) {
00139
00140 _file_eof = true;
00141 return(false);
00142 }
00143 else if(nread != 8) {
00144 cerr << "fdm_cdr_ file: ..ader file read failed" << endl;
00145 _file_ok = false;
00146 return(false);
00147 }
00148
00149 header.wr_ptr(8);
00150
00151
00152 ACE_InputCDR h_in(&header);
00153 char idstr[5];
00154 ACE_CDR::ULong len;
00155 bool ok = true;
00156
00157
00158 ok &= h_in.read_char_array(idstr, 4);
00159 idstr[4] = 0;
00160
00161 ok &= h_in.read_ulong(len);
00162
00163 if(!ok || string(idstr) != FDM_CDR_FILETAG) {
00164 cerr << "fdm_cdr_ file: ..ader read failed" << endl;
00165 _file_ok = false;
00166 return(false);
00167 }
00168
00169
00170
00171 msg.reset(new ACE_Message_Block(len + ACE_CDR::MAX_ALIGNMENT));
00172 ACE_CDR::mb_align(msg.get());
00173
00174 size_t remsize = len;
00175 bool done=false;
00176
00177 while(!done) {
00178 nread = _io_file->recv(msg->wr_ptr(), remsize);
00179 if(nread == 0) {
00180
00181 _file_eof = true;
00182 return(true);
00183 }
00184 remsize -= nread;
00185 msg->wr_ptr(nread);
00186
00187 if(remsize == 0) {
00188 done=true;
00189 }
00190 }
00191 return(true);
00192 }
00193
00194 bool
00195 FDM_CDR_File::_write_block(const ACE_Message_Block &msg)
00196 {
00197 if(!_file_ok || _file_eof || _io_file == NULL) {
00198 return(false);
00199 }
00200
00201
00202 ACE_OutputCDR header(ACE_CDR::MAX_ALIGNMENT +8);
00203 ACE_CDR::ULong len = msg.total_length();
00204 bool ok = true;
00205
00206 ok &= header.write_char_array(FDM_CDR_FILETAG,4);
00207 ok &= header.write_ulong(len);
00208
00209
00210 if(_io_file->send_n(header.begin()) < 0) {
00211
00212 _file_ok = false;
00213 return(false);
00214 }
00215
00216
00217 if(_io_file->send_n(&msg) < 0) {
00218
00219 _file_ok = false;
00220 return(false);
00221 }
00222 return(true);
00223 }
00224
00225 bool
00226 FDM_CDR_File::flush()
00227 {
00228 const ACE_Message_Block &msg = get_message_block();
00229 if(msg.total_length() == 0) {
00230
00231 return(true);
00232 }
00233
00234 if(_write_block(msg)) {
00235
00236 clear();
00237 return(true);
00238 }
00239 return(false);
00240 }
00241
00242
00243
00244 bool
00245 FDM_CDR_File::message_block_to_file(const ACE_Message_Block &mb,
00246 string filename,
00247 bool append)
00248 {
00249
00250 FDM_CDR_File out(filename, FDM::Write, append);
00251
00252
00253 return(out._write_block(mb));
00254 }
00255
00256
00257 bool
00258 FDM_CDR_File::file_to_message_block(ACE_Message_Block &mb,
00259 const string &filename)
00260 {
00261
00262 FDM_CDR_File in(filename, FDM::Read);
00263
00264
00265 if(in._file_ok && in._process_next_block()) {
00266 assert(in._istr!=NULL);
00267
00268 ACE_CDR::consolidate(&mb, in._istr->start());
00269 return(true);
00270 }
00271 return(false);
00272 }
00273
00274
00275 void
00276 FDM_CDR_File::summarize(ostream &os)
00277 {
00278 if(is_write()) {
00279 os << "File type FDM_CDR_File " << endl;
00280 return;
00281 }
00282
00283 map<std::string,int> bmap;
00284 int i=0;
00285 while(_file_ok && !_file_eof && _process_next_block()) {
00286
00287 string tname;
00288 if(_io_object(tname)) {
00289 if(bmap.find(tname) == bmap.end()) {
00290 bmap[tname] = 1;
00291 }
00292 else {
00293 bmap[tname]++;
00294 }
00295 i++;
00296 }
00297 }
00298 os << "FDM_CDR_File, " << i << " records";
00299 if(bmap.size()==1) {
00300 os << " of type " << bmap.begin()->first;
00301 }
00302 else {
00303 os << " of the following types: " << endl;
00304 std::map<std::string, int>::const_iterator it = bmap.begin();
00305 for (it = bmap.begin(); it != bmap.end(); it++) {
00306 os << " " << it->first << "\t[" << it->second << "]" << endl;
00307 }
00308 }
00309 }
00310 bool
00311 FDM_CDR_File::show_file_contents(ostream &os, const string &filename)
00312 {
00313
00314 FDM_CDR_File in(filename, FDM::Read);
00315
00316 if(!in._file_ok) {
00317 return(false);
00318 }
00319
00320
00321 int i=0;
00322 while(in._file_ok && !in._file_eof && in._process_next_block()) {
00323 assert(in._istr!=NULL);
00324
00325 string tname="";
00326 in._peek_object(tname);
00327 os << "----------------------------------------------------" << endl;
00328 os << "Block " << i++ << ": Type " << tname << endl;
00329 os << *(in._istr->start());
00330 }
00331 return(true);
00332 }
00333
00334 bool
00335 FDM_CDR_File::_start_topform(const char *type_name)
00336 {
00337 bool ok = true;
00338
00339 if(is_read() && !_got_block) {
00340 ok &= _process_next_block();
00341 }
00342
00343 _topform_typename = type_name;
00344 _io_object(_topform_typename);
00345 if(is_read()) {
00346 if(_topform_typename != type_name) {
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 }
00358 }
00359 return(ok & FDM_Stream::_start_topform(type_name));
00360 }
00361 bool
00362 FDM_CDR_File::_end_topform()
00363 {
00364 bool ok = true;
00365
00366 if(is_write()) {
00367 ok &= flush();
00368 }
00369 else {
00370
00371 _got_block=false;
00372
00373 if(_istr->length() != 0) {
00374 cerr << "WARNING: In fdm_cdr_file, " << _istr->length()
00375 << " bytes left in read block, skipping" << endl;
00376 }
00377 }
00378 return(ok);
00379 }
00380
00381 bool
00382 FDM_CDR_File::_process_next_block()
00383 {
00384 if(!_file_ok || _file_eof || _io_file == NULL) {
00385 return(false);
00386 }
00387
00388 auto_ptr<ACE_Message_Block> msg;
00389
00390 bool ok = _read_block(msg);
00391 if(!ok) {
00392 _file_ok=false;
00393 return(false);
00394 }
00395
00396 assert(msg.get()!=NULL && msg->cont()==NULL);
00397 set_message_block(*msg);
00398
00399
00400 _got_block = true;
00401
00402
00403
00404
00405 return(true);
00406 }
00407
00408 bool
00409 FDM_CDR_File::_check_streams(size_t size)
00410 {
00411 bool ok = FDM_CDR::_check_streams(size);
00412 if(!ok || !_file_ok || _io_file==NULL) {
00413
00414 return(false);
00415 }
00416 return(true);
00417 }