00001
00002
00003
00004
00005
00006
00008
00009 #include "Rotorooter/RotoSocket.h"
00010
00011 #include "MessageService/MsgService.h"
00012
00013 #include <cassert>
00014
00015 ClassImp(RotoSocket)
00016 CVSID("$Id: RotoSocket.cxx,v 1.8 2006/06/21 05:02:32 rhatcher Exp $");
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 RotoSocket::RotoSocket(const char* fileName) :
00031 fCommand(INITIALISE),
00032 fAction(PREPARE_NEXT_COMMAND),
00033 fTransCmd(0),
00034 fTransLen(0),
00035 fTransAlloc(MAXBUFFER),
00036 fTransData(new long[MAXBUFFER / sizeof(long)]),
00037 fFileName(fileName),
00038 fFile(0)
00039 {
00040
00041 MsgService::Instance()->GetStream("Roto")->SetLogLevel(Msg::kInfo);
00042
00043 MSG("Roto",Msg::kInfo) << "Opening: " << fileName << endl;
00044
00045 fFile=fopen(fileName,"rb");
00046 if (fFile==NULL) {
00047 printf("Failed to open input file: '%s'\n",fileName);
00048 fCommand = SEND_SHUTDOWN;
00049 }
00050
00051 }
00052
00053
00054 RotoSocket::~RotoSocket() {
00055
00056 delete [] fTransData;
00057 if ( fFile ) fclose(fFile);
00058 fFile = 0;
00059
00060 }
00061
00062
00063
00064 void RotoSocket::NotImp(const char* method) const {
00065
00066 MSG("Roto",Msg::kError) << "RotoSocket: Attempting to use un implimented"
00067 << " method: " << method << endl;
00068 }
00069
00070
00071 Int_t RotoSocket::RecvRaw(void *buffer, Int_t length,
00072 ESendRecvOptions ) {
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 if ( fAction == PREPARE_NEXT_COMMAND ) PrepareCommand();
00085 return Transmit(buffer,length);
00086
00087 }
00088
00089
00090 void RotoSocket::PrepareCommand() {
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 static int nRecords =0;
00103 const int bitDataToFollow = (1 << 15);
00104 Int_t instr = 0;
00105
00106
00107
00108
00109 switch ( fCommand ) {
00110 case INITIALISE: fCommand = OPEN_SOCKET; break;
00111 case OPEN_SOCKET: fCommand = OPEN_FILE; break;
00112 case OPEN_FILE: fCommand = SEND_DATA; break;
00113 case SEND_DATA: break;
00114 default:
00115 cout << " fCommand was " << (int)fCommand << endl;
00116 assert(0);
00117 }
00118
00119
00120
00121 switch ( fCommand ) {
00122
00123 case OPEN_SOCKET:
00124 instr = MINOS_ROOTER_OPENSOCKET;
00125 fTransLen = 0;
00126 break;
00127
00128 case OPEN_FILE:
00129 instr = MINOS_ROOTER_OPENFILE;
00130 {
00131 int* iptr = (int*) fTransData;
00132 char* cptr = (char*) fTransData + sizeof(int);
00133
00134
00135 *iptr = MINOS_DCS | bitDataToFollow;
00136
00137 const char* lastslash = strrchr(fFileName.c_str(),'/');
00138 if (lastslash) lastslash++;
00139 else lastslash = fFileName.c_str();
00140 sprintf(cptr,"%s",lastslash);
00141 int fnlen = strlen(cptr);
00142 cptr[fnlen] = 0;
00143 fTransLen = sizeof(int) + fnlen + 1;
00144
00145 }
00146 break;
00147
00148 case SEND_DATA:
00149 instr = MINOS_ROOTER_SHUTDOWN;
00150 fTransLen = 0;
00151 if ( feof(fFile) ) {
00152 printf("Seen EOF after record %d Quiting ...\n",nRecords);
00153 break;
00154 }
00155 if ( fread(&fTransLen,sizeof(long),1,fFile) !=1 ) {
00156 if ( feof(fFile) ) {
00157 printf("Seen EOF after record %d Quiting ...\n",nRecords);
00158 }
00159 else {
00160 printf("Read error on record %d Quiting ...\n",nRecords);
00161 }
00162 break;
00163 }
00164 nRecords++;
00165 fTransLen -= sizeof(long);
00166 if ( fTransLen > fTransAlloc ) {
00167 if ( ! ReallocateBuffer(fTransLen) ) {
00168 printf("Record %d Size %ld bytes too large for buffer (%ld) Quiting ...\n",
00169 nRecords,fTransLen,fTransAlloc);
00170 fTransLen = 0;
00171 }
00172 else {
00173 printf("Record %d Size %ld bytes, buffer reallocated to %ld.\n",
00174 nRecords,fTransLen,fTransAlloc);
00175 }
00176 }
00177 if ( fread(fTransData,fTransLen,1,fFile) != 1 ) {
00178 printf("Read error on record %d Quiting ...\n",nRecords);
00179 fTransLen = 0;
00180 break;
00181 }
00182 instr = MINOS_ROOTER_RECBUFFER;
00183 break;
00184
00185 case SEND_SHUTDOWN:
00186 instr = MINOS_ROOTER_SHUTDOWN;
00187 fTransLen = 0;
00188 break;
00189
00190 default:
00191 assert(0);
00192
00193 }
00194
00195
00196 fTransCmd = RotoRcCmd(MINOS_DCP,
00197 MINOS_ROOTER,
00198 MINOS_ROOTER_COMMAND,
00199 instr,
00200 fTransLen > 0);
00201
00202
00203 fAction = TRANSMIT_COMMAND;
00204
00205 }
00206
00207
00208
00209 Int_t RotoSocket::Transmit(void* buffer,Int_t length) {
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 switch ( fAction ) {
00222 int nbytes;
00223
00224 case TRANSMIT_COMMAND:
00225 memcpy(buffer,&fTransCmd.fEncoded,sizeof(long));
00226 fAction = ( fTransLen > 0 ) ? TRANSMIT_LENGTH : PREPARE_NEXT_COMMAND;
00227 return sizeof(long);
00228
00229 case TRANSMIT_LENGTH:
00230 nbytes = fTransLen + sizeof(int);
00231 memcpy(buffer,&nbytes,sizeof(long));
00232 fAction = TRANSMIT_DATA;
00233 return sizeof(long);
00234
00235 case TRANSMIT_DATA:
00236 nbytes = ( fTransLen < length ) ? fTransLen : length;
00237 memcpy(buffer,fTransData,nbytes);
00238 fAction = PREPARE_NEXT_COMMAND;
00239 return nbytes;
00240
00241 default:
00242 assert(0);
00243 }
00244
00245 return -1;
00246 }
00247
00248
00249
00250 Bool_t RotoSocket::ReallocateBuffer(long minBytes) {
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 long oldsize = fTransAlloc;
00262 long mrequest = minBytes;
00263 int failures = 0;
00264
00265
00266 if (fTransData) {
00267 delete [] fTransData;
00268 fTransData = 0;
00269 }
00270
00271
00272 if ( mrequest < MAXBUFFER ) mrequest = MAXBUFFER;
00273
00274
00275 mrequest = ((mrequest >> 20) + 1 ) << 20;
00276
00277 while ( ! fTransData ) {
00278 fTransData = new long[mrequest / sizeof(long)];
00279 if ( fTransData ) break;
00280 failures++;
00281 mrequest -= 1024*sizeof(char);
00282 }
00283 fTransAlloc = mrequest;
00284
00285 if ( fTransAlloc >= minBytes ) return true;
00286
00287 printf("RotoSocket::ReallocateBuffer was unable to allocate requested "
00288 "%ld bytes \n from initial size %ld, only got final size %ld.",
00289 minBytes,oldsize,fTransAlloc);
00290 return false;
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312