File indexing completed on 2025-01-18 10:11:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef ROOT_MPSendRecv
0013 #define ROOT_MPSendRecv
0014
0015 #include "TBufferFile.h"
0016 #include "TClass.h"
0017 #include "TError.h"
0018 #include "TSocket.h"
0019 #include <memory> //unique_ptr
0020 #include <type_traits> //enable_if
0021 #include <typeinfo> //typeid
0022 #include <utility> //pair
0023 #include <string>
0024
0025
0026
0027
0028
0029
0030
0031
0032 using MPCodeBufPair = std::pair<unsigned, std::unique_ptr<TBufferFile>>;
0033
0034
0035
0036
0037
0038
0039
0040 int MPSend(TSocket *s, unsigned code);
0041
0042 template<class T, typename std::enable_if<std::is_class<T>::value>::type * = nullptr>
0043 int MPSend(TSocket *s, unsigned code, T obj);
0044
0045 template < class T, typename std::enable_if < !std::is_class<T>::value &&!std::is_pointer<T>::value >::type * = nullptr >
0046 int MPSend(TSocket *s, unsigned code, T obj);
0047
0048 template<class T, typename std::enable_if<std::is_same<const char *, T>::value>::type * = nullptr>
0049 int MPSend(TSocket *s, unsigned code, T obj);
0050
0051 template < class T, typename std::enable_if < std::is_pointer<T>::value &&std::is_constructible<TObject *, T>::value >::type * = nullptr >
0052 int MPSend(TSocket *s, unsigned code, T obj);
0053
0054 MPCodeBufPair MPRecv(TSocket *s);
0055
0056
0057
0058 template<class T, typename std::enable_if<std::is_class<T>::value>::type * = nullptr>
0059 T ReadBuffer(TBufferFile *buf);
0060
0061
0062 template < class T, typename std::enable_if < !std::is_class<T>::value &&!std::is_pointer<T>::value >::type * = nullptr >
0063 T ReadBuffer(TBufferFile *buf);
0064
0065
0066 template<class T, typename std::enable_if<std::is_same<const char *, T>::value>::type * = nullptr>
0067 T ReadBuffer(TBufferFile *buf);
0068
0069
0070 template < class T, typename std::enable_if < std::is_pointer<T>::value &&std::is_constructible<TObject *, T>::value >::type * = nullptr >
0071 T ReadBuffer(TBufferFile *buf);
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091 template<class T, typename std::enable_if<std::is_class<T>::value>::type *>
0092 int MPSend(TSocket *s, unsigned code, T obj)
0093 {
0094 TClass *c = TClass::GetClass<T>();
0095 if (!c) {
0096 Error("MPSend", "[E] Could not find cling definition for class %s\n", typeid(T).name());
0097 return -1;
0098 }
0099 TBufferFile objBuf(TBuffer::kWrite);
0100 objBuf.WriteObjectAny(&obj, c);
0101 TBufferFile wBuf(TBuffer::kWrite);
0102 wBuf.WriteUInt(code);
0103 wBuf.WriteULong(objBuf.Length());
0104 wBuf.WriteBuf(objBuf.Buffer(), objBuf.Length());
0105 return s->SendRaw(wBuf.Buffer(), wBuf.Length());
0106 }
0107
0108
0109
0110
0111 template < class T, typename std::enable_if < !std::is_class<T>::value &&!std::is_pointer<T>::value >::type * >
0112 int MPSend(TSocket *s, unsigned code, T obj)
0113 {
0114 TBufferFile wBuf(TBuffer::kWrite);
0115 ULong_t size = sizeof(T);
0116 wBuf << code << size << obj;
0117 return s->SendRaw(wBuf.Buffer(), wBuf.Length());
0118 }
0119
0120
0121
0122 template<class T, typename std::enable_if<std::is_same<const char *, T>::value>::type *>
0123 int MPSend(TSocket *s, unsigned code, T obj)
0124 {
0125 TBufferFile wBuf(TBuffer::kWrite);
0126 wBuf.WriteUInt(code);
0127 wBuf.WriteULong(strlen(obj) + 1);
0128 wBuf.WriteString(obj);
0129 return s->SendRaw(wBuf.Buffer(), wBuf.Length());
0130 }
0131
0132
0133 template < class T, typename std::enable_if < std::is_pointer<T>::value && std::is_constructible<TObject *, T>::value >::type * >
0134 int MPSend(TSocket *s, unsigned code, T obj)
0135 {
0136
0137 TBufferFile objBuf(TBuffer::kWrite);
0138 if(obj != nullptr)
0139 objBuf.WriteObjectAny(obj, obj->IsA());
0140
0141
0142 TBufferFile wBuf(TBuffer::kWrite);
0143 wBuf.WriteUInt(code);
0144 wBuf.WriteULong(objBuf.Length());
0145 if(objBuf.Length())
0146 wBuf.WriteBuf(objBuf.Buffer(), objBuf.Length());
0147 return s->SendRaw(wBuf.Buffer(), wBuf.Length());
0148 }
0149
0150
0151
0152
0153
0154
0155
0156
0157 template<class T, typename std::enable_if<std::is_class<T>::value>::type *>
0158 T ReadBuffer(TBufferFile *buf)
0159 {
0160 TClass *c = TClass::GetClass(typeid(T));
0161 T *objp = (T *)buf->ReadObjectAny(c);
0162 T obj = *objp;
0163 delete objp;
0164 return obj;
0165 }
0166
0167
0168 template < class T, typename std::enable_if < !std::is_class<T>::value &&!std::is_pointer<T>::value >::type * >
0169 T ReadBuffer(TBufferFile *buf)
0170 {
0171
0172 T obj;
0173 *(buf) >> obj;
0174 return obj;
0175 }
0176
0177 template<class T, typename std::enable_if<std::is_same<const char *, T>::value>::type *>
0178 T ReadBuffer(TBufferFile *buf)
0179 {
0180
0181 char *c = new char[buf->BufferSize()];
0182 buf->ReadString(c, buf->BufferSize());
0183 return c;
0184 }
0185
0186 template < class T, typename std::enable_if < std::is_pointer<T>::value &&std::is_constructible<TObject *, T>::value >::type * >
0187 T ReadBuffer(TBufferFile *buf)
0188 {
0189
0190 using objType = typename std::remove_pointer<T>::type;
0191 return (T)buf->ReadObjectAny(objType::Class());
0192 }
0193
0194
0195 #endif