Back to index

nordugrid-arc-nox  1.1.0~rc6
BIOMCC.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <openssl/ssl.h>
00006 
00007 #include <arc/message/PayloadRaw.h>
00008 #include <arc/message/PayloadStream.h>
00009 #include <arc/message/MCC.h>
00010 #include <arc/message/Message.h>
00011 
00012 #include "BIOMCC.h"
00013 
00014 namespace Arc {
00015 
00016 class BIOMCC {
00017   private:
00018     PayloadStreamInterface* stream_;
00019     MCCInterface* next_;
00020   public:
00021     BIOMCC(MCCInterface* next) { next_=next; stream_=NULL; };
00022     BIOMCC(PayloadStreamInterface* stream) { next_=NULL; stream_=stream; };
00023     ~BIOMCC(void) { if(stream_ && next_) delete stream_; };
00024     PayloadStreamInterface* Stream() { return stream_; };
00025     void Stream(PayloadStreamInterface* stream) { stream_=stream; /*free ??*/ };
00026     MCCInterface* Next(void) { return next_; };
00027     void MCC(MCCInterface* next) { next_=next; };
00028 };
00029 
00030 static int  mcc_write(BIO *h, const char *buf, int num);
00031 static int  mcc_read(BIO *h, char *buf, int size);
00032 static int  mcc_puts(BIO *h, const char *str);
00033 static long mcc_ctrl(BIO *h, int cmd, long arg1, void *arg2);
00034 static int  mcc_new(BIO *h);
00035 static int  mcc_free(BIO *data);
00036 
00037 
00038 static BIO_METHOD methods_mcc = {
00039   BIO_TYPE_FD,"Message Chain Component",
00040   mcc_write,
00041   mcc_read,
00042   mcc_puts,
00043   NULL, /* gets, */
00044   mcc_ctrl,
00045   mcc_new,
00046   mcc_free,
00047   NULL,
00048 };
00049 
00050 BIO_METHOD *BIO_s_MCC(void) {
00051   return(&methods_mcc);
00052 }
00053 
00054 BIO *BIO_new_MCC(MCCInterface* mcc) {
00055   BIO *ret;
00056   ret=BIO_new(BIO_s_MCC());
00057   if (ret == NULL) return(NULL);
00058   BIO_set_MCC(ret,mcc);
00059   return(ret);
00060 }
00061 
00062 BIO* BIO_new_MCC(PayloadStreamInterface* stream) {
00063   BIO *ret;
00064   ret=BIO_new(BIO_s_MCC());
00065   if (ret == NULL) return(NULL);
00066   BIO_set_MCC(ret,stream);
00067   return(ret);
00068 }
00069 
00070 void BIO_set_MCC(BIO* b,MCCInterface* mcc) {
00071   BIOMCC* biomcc = (BIOMCC*)(b->ptr);
00072   if(biomcc == NULL) {
00073     biomcc=new BIOMCC(mcc);
00074     b->ptr=biomcc;
00075   };
00076 }
00077 
00078 void BIO_set_MCC(BIO* b,PayloadStreamInterface* stream) {
00079   BIOMCC* biomcc = (BIOMCC*)(b->ptr);
00080   if(biomcc == NULL) {
00081     biomcc=new BIOMCC(stream);
00082     b->ptr=biomcc;
00083   };
00084 }
00085 
00086 static int mcc_new(BIO *bi) {
00087   bi->init=1;
00088   bi->num=0;
00089   bi->ptr=NULL;
00090   // bi->flags=BIO_FLAGS_UPLINK; /* essentially redundant */
00091   return(1);
00092 }
00093 
00094 static int mcc_free(BIO *b) {
00095   if(b == NULL) return(0);
00096   BIOMCC* biomcc = (BIOMCC*)(b->ptr);
00097   b->ptr=NULL;
00098   if(biomcc) delete biomcc;
00099   return(1);
00100 }
00101   
00102 static int mcc_read(BIO *b, char *out,int outl) {
00103   int ret=0;
00104   if (out == NULL) return(ret);
00105   if(b == NULL) return(ret);
00106   BIOMCC* biomcc = (BIOMCC*)(b->ptr);
00107   if(biomcc == NULL) return(ret);
00108   PayloadStreamInterface* stream = biomcc->Stream();
00109   if(stream == NULL) return ret;
00110 
00111   //clear_sys_error();
00112   bool r = stream->Get(out,outl);
00113   BIO_clear_retry_flags(b);
00114   if(r) { ret=outl; } else { ret=-1; };
00115   return ret;
00116 }
00117 
00118 static int mcc_write(BIO *b, const char *in, int inl) {
00119   int ret = 0;
00120   //clear_sys_error();
00121   if(in == NULL) return(ret);
00122   if(b == NULL) return(ret);
00123   if(b->ptr == NULL) return(ret);
00124   BIOMCC* biomcc = (BIOMCC*)(b->ptr);
00125   if(biomcc == NULL) return(ret);
00126   PayloadStreamInterface* stream = biomcc->Stream();
00127   if(stream != NULL) {
00128     // If available just use stream directly
00129     // TODO: check if stream has changed ???
00130     bool r = stream->Put(in,inl);
00131     BIO_clear_retry_flags(b);
00132     if(r) { ret=inl; } else { ret=-1; };
00133     return ret;
00134   };
00135 
00136   MCCInterface* next = biomcc->Next();
00137   if(next == NULL) return(ret);
00138   PayloadRaw nextpayload;
00139   nextpayload.Insert(in,0,inl); // Not efficient !!!!
00140   Message nextinmsg;
00141   nextinmsg.Payload(&nextpayload);  
00142   Message nextoutmsg;
00143 
00144   MCC_Status mccret = next->process(nextinmsg,nextoutmsg);
00145   BIO_clear_retry_flags(b);
00146   if(mccret) { 
00147     if(nextoutmsg.Payload()) {
00148       PayloadStreamInterface* retpayload = NULL;
00149       try {
00150         retpayload=dynamic_cast<PayloadStreamInterface*>(nextoutmsg.Payload());
00151       } catch(std::exception& e) { };
00152       if(retpayload) {
00153         biomcc->Stream(retpayload);
00154       } else {
00155         delete nextoutmsg.Payload();
00156       };
00157     };
00158     ret=inl;
00159   } else {
00160     if(nextoutmsg.Payload()) delete nextoutmsg.Payload();
00161     ret=-1;
00162   };
00163   return(ret);
00164 }
00165 
00166 
00167 static long mcc_ctrl(BIO*, int cmd, long, void*) {
00168   long ret=0;
00169 
00170   switch (cmd) {
00171     case BIO_CTRL_RESET:
00172     case BIO_CTRL_SET_CLOSE:
00173     case BIO_CTRL_SET:
00174     case BIO_CTRL_EOF:
00175     case BIO_CTRL_FLUSH:
00176     case BIO_CTRL_DUP:
00177       ret=1;
00178       break;
00179   };
00180   return(ret);
00181 }
00182 
00183 static int mcc_puts(BIO *bp, const char *str) {
00184   int n,ret;
00185 
00186   n=strlen(str);
00187   ret=mcc_write(bp,str,n);
00188   return(ret);
00189 }
00190 
00191 } // namespace Arc