Import Geant4 11.4.0 source tree
This commit is contained in:
+6
-325
@@ -10,7 +10,6 @@
|
||||
#include "info"
|
||||
#include "obj_list"
|
||||
|
||||
//#define TOOLS_RROOT_BRANCH_ELEMENT_DUMP
|
||||
|
||||
namespace tools {
|
||||
namespace rroot {
|
||||
@@ -42,8 +41,6 @@ public:
|
||||
unsigned int _s,_c;
|
||||
if(!a_buffer.read_version(v,_s,_c)) return false;
|
||||
|
||||
//::printf("debug : tools::branch_element::stream : version %d, count %d\n",v,c);
|
||||
|
||||
if(!parent::stream(a_buffer)) {
|
||||
m_out << "tools::rroot::branch_element::stream : parent::stream() failed." << std::endl;
|
||||
return false;
|
||||
@@ -57,36 +54,26 @@ public:
|
||||
if(!a_buffer.read(fStreamerType)) return false;
|
||||
} else { //v>=8
|
||||
if(!a_buffer.read(fClassName)) return false;
|
||||
//::printf("debug : tools::branch_element::stream : fClassName \"%s\"\n",fClassName.c_str());
|
||||
std::string fParentName;
|
||||
if(!a_buffer.read(fParentName)) return false;
|
||||
//::printf("debug : tools::branch_element::stream : fParentName \"%s\"\n",fParentName.c_str());
|
||||
std::string fCloneName;
|
||||
if(!a_buffer.read(fCloneName)) return false;
|
||||
//::printf("debug : tools::branch_element::stream : fCloneName \"%s\"\n",fCloneName.c_str());
|
||||
int dummy_int;
|
||||
if(!a_buffer.read(dummy_int)) return false; //fCheckSum
|
||||
//::printf("debug : tools::branch_element::stream : fCheckSum %d\n",dummy_int);
|
||||
|
||||
if(v>=10) {
|
||||
short dummy_short;
|
||||
if(!a_buffer.read(dummy_short)) return false; //fClassVersion
|
||||
//::printf("debug : tools::branch_element::stream : fClassVersion %d\n",dummy_short);
|
||||
} else {
|
||||
if(!a_buffer.read(dummy_int)) return false; //fClassVersion
|
||||
}
|
||||
|
||||
if(!a_buffer.read(fID)) return false;
|
||||
//::printf("debug : tools::branch_element::stream : fID %d\n",fID);
|
||||
if(!a_buffer.read(fType)) return false;
|
||||
//::printf("debug : tools::branch_element::stream : fType %d\n",fType);
|
||||
if(!a_buffer.read(fStreamerType)) return false;
|
||||
//::printf("debug : tools::branch_element::stream : fStreamerType %d\n",fStreamerType);
|
||||
|
||||
if(!a_buffer.read(dummy_int)) return false; //fMaximum
|
||||
//::printf("debug : tools::branch_element::stream : fMaximum %d\n",dummy_int);
|
||||
|
||||
//TBranchElement* fBranchCount;
|
||||
ifac::args args;
|
||||
if(!pointer_stream(a_buffer,m_fac,args,fBranchCount,fBranchCount_created)) {
|
||||
m_out << "tools::rroot::branch_element::stream : "
|
||||
@@ -95,7 +82,6 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
//TBranchElement* fBranchCount2;
|
||||
if(!pointer_stream(a_buffer,m_fac,args,fBranchCount2,fBranchCount2_created)) {
|
||||
m_out << "tools::rroot::branch_element::stream : "
|
||||
<< "can't read fBranchCount2."
|
||||
@@ -126,37 +112,14 @@ public: //branch
|
||||
//from v4-00-01
|
||||
int n;
|
||||
if(!a_buffer.read(n)) return false;
|
||||
/* ROOT-6.12.06 code :
|
||||
if ((n < 0) || (n > fMaximum)) {
|
||||
if (IsMissingCollection()) {
|
||||
n = 0;
|
||||
b.SetBufferOffset(b.Length() - sizeof(n));
|
||||
} else {
|
||||
Error("ReadLeaves", "Incorrect size read for the container in %s\nThe size read is %d when the maximum is %d\nThe size is reset to 0 for this entry (%lld)", GetName(), n, fMaximum, GetReadEntry());
|
||||
n = 0;
|
||||
}
|
||||
}*/
|
||||
//::printf("debug : uuuu : ndata %d\n",n);
|
||||
|
||||
fNdata = n;
|
||||
|
||||
//TClonesArray *clones = (TClonesArray*)fObject;
|
||||
//if (!clones) return;
|
||||
//if (clones->IsZombie()) return;
|
||||
//clones->Clear();
|
||||
//clones->ExpandCreateFast(fNdata);
|
||||
|
||||
//m_out << "debug : tools::rroot::branch_element::read_leaves :"
|
||||
// << " name " << m_name << " ref_cls " << fClassName
|
||||
// << " : type " << fType << ", fNdata " << n
|
||||
// << std::endl;
|
||||
return true;
|
||||
|
||||
} else if(fType==31) { // TClonesArray sub-branch (contains the elements).
|
||||
if(fStreamerType==kObject) { //to read EsbRoot fgd_dig.root.
|
||||
int ndata = fBranchCount->get_ndata();
|
||||
#ifdef TOOLS_RROOT_BRANCH_ELEMENT_DUMP
|
||||
::printf("debug : %s : fClassName %s : fID %d : kObject : ndata %d\n",m_name.c_str(),fClassName.c_str(),fID,ndata);
|
||||
#endif
|
||||
streamer_info* _info = a_file.find_streamer_info(fClassName);
|
||||
if(!_info) {
|
||||
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
|
||||
@@ -171,7 +134,6 @@ public: //branch
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
//::printf("debug : element type name %s\n",_element->type_name().c_str());
|
||||
|
||||
obj_list* _list = 0;
|
||||
if(!m_obj) {
|
||||
@@ -209,9 +171,6 @@ public: //branch
|
||||
//from v4-00-01
|
||||
if(fStreamerType==kDouble32) {
|
||||
int ndata = fBranchCount->get_ndata();
|
||||
#ifdef TOOLS_RROOT_BRANCH_ELEMENT_DUMP
|
||||
::printf("debug : %s : fID %d : double32 : ndata %d\n",m_name.c_str(),fID,ndata);
|
||||
#endif
|
||||
stl_vector<double>* vec = 0;
|
||||
if(!m_obj) {
|
||||
vec = new stl_vector<double>;
|
||||
@@ -236,7 +195,6 @@ public: //branch
|
||||
vec->clear();
|
||||
return false;
|
||||
}
|
||||
//::printf("debug : zzzz %g\n",afloat);
|
||||
(*vec)[ii] = afloat;
|
||||
}
|
||||
|
||||
@@ -244,9 +202,6 @@ public: //branch
|
||||
|
||||
} else if(fStreamerType==kDouble) {
|
||||
int ndata = fBranchCount->get_ndata();
|
||||
#ifdef TOOLS_RROOT_BRANCH_ELEMENT_DUMP
|
||||
::printf("debug : %s : fID %d : double : ndata %d\n",m_name.c_str(),fID,ndata);
|
||||
#endif
|
||||
stl_vector<double>* vec = 0;
|
||||
if(!m_obj) {
|
||||
vec = new stl_vector<double>;
|
||||
@@ -262,7 +217,7 @@ public: //branch
|
||||
}
|
||||
|
||||
vec->resize(ndata);
|
||||
double* _value = vec_data(*vec);
|
||||
double* _value = vec->data();
|
||||
if(!a_buffer.read_fast_array(_value,ndata)) {
|
||||
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
|
||||
<< " read_fast_array(double) failed."
|
||||
@@ -275,9 +230,6 @@ public: //branch
|
||||
|
||||
} else if(fStreamerType==kInt) {
|
||||
int ndata = fBranchCount->get_ndata();
|
||||
#ifdef TOOLS_RROOT_BRANCH_ELEMENT_DUMP
|
||||
::printf("debug : %s : fID %d : int : ndata %d\n",m_name.c_str(),fID,ndata);
|
||||
#endif
|
||||
stl_vector<int>* vec = 0;
|
||||
if(!m_obj) {
|
||||
vec = new stl_vector<int>;
|
||||
@@ -293,7 +245,7 @@ public: //branch
|
||||
}
|
||||
|
||||
vec->resize(ndata);
|
||||
int* _value = vec_data(*vec);
|
||||
int* _value = vec->data();
|
||||
if(!a_buffer.read_fast_array(_value,ndata)) {
|
||||
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
|
||||
<< " read_fast_array(int) failed."
|
||||
@@ -306,10 +258,6 @@ public: //branch
|
||||
|
||||
} else if((fStreamerType==kUInt)||(fStreamerType==kBits)) {
|
||||
int ndata = fBranchCount->get_ndata();
|
||||
#ifdef TOOLS_RROOT_BRANCH_ELEMENT_DUMP
|
||||
if(fStreamerType==kUInt) ::printf("debug : %s : fID %d : uint : ndata %d\n",m_name.c_str(),fID,ndata);
|
||||
else ::printf("debug : %s : fID %d : bits : ndata %d\n",m_name.c_str(),fID,ndata);
|
||||
#endif
|
||||
stl_vector<uint32>* vec = 0;
|
||||
if(!m_obj) {
|
||||
vec = new stl_vector<uint32>;
|
||||
@@ -325,7 +273,7 @@ public: //branch
|
||||
}
|
||||
|
||||
vec->resize(ndata);
|
||||
uint32* _value = vec_data(*vec);
|
||||
uint32* _value = vec->data();
|
||||
if(!a_buffer.read_fast_array(_value,ndata)) {
|
||||
m_out << "tools::rroot::branch_element::read_leaves : " << sout(m_name) << " :"
|
||||
<< " read_fast_array(uint) failed."
|
||||
@@ -343,37 +291,15 @@ public: //branch
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
//m_obj = clones_array<float>(m_fac,true,false); //true = owner of objects.
|
||||
uint32 ndata = 1;
|
||||
float* _value = new float[ndata];
|
||||
if(!a_buffer.read_fast_array(_value,ndata)) {
|
||||
m_out << "tools::rroot::branch_element::read_leaves : \"" << name() << "\" :"
|
||||
<< " read_fast_array failed."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
//} else if(fType<=2) { //in v5-18-00d
|
||||
|
||||
} else if(fType==0) { // to read wroot.root of examples/cpp/wroot.cpp.
|
||||
// if(fID>=0) {
|
||||
// // branch in split mode
|
||||
// m_out << "tools::rroot::branch_element::read_leaves :"
|
||||
// << " name " << m_name << " ref_cls " << fClassName << " :"
|
||||
// << " type 0 with ID " << fID << "."
|
||||
// << std::endl;
|
||||
// return true;
|
||||
//
|
||||
|
||||
|
||||
if((fID==-1)||
|
||||
(fID==1) // for pmx to read LHCb files :
|
||||
){
|
||||
//from v4-00-01
|
||||
//if (fBranchCount) fNdata = (Int_t)fBranchCount->GetValue(0,0);
|
||||
//else fNdata = 1;
|
||||
if(fBranchCount) {
|
||||
fNdata = fBranchCount->get_ndata();
|
||||
//::printf("debug : branch_element::read_leaves : (fType==0,fID==-1) : fNdata %d\n",fNdata);
|
||||
} else {
|
||||
fNdata = 1;
|
||||
}
|
||||
@@ -413,174 +339,6 @@ public: //branch
|
||||
<< " : type " << fType << " not treated, stream_type is " << fStreamerType << "."
|
||||
<< std::endl;
|
||||
return false;
|
||||
|
||||
/*
|
||||
///////////////////////////////////////////////////////
|
||||
/// STL container /////////////////////////////////////
|
||||
///////////////////////////////////////////////////////
|
||||
if(fType==4) {
|
||||
// STL container master branch (has only the number of elements).
|
||||
//from v4-00-01
|
||||
int n;
|
||||
if(!a_buffer.read(n)) return false;
|
||||
//fNdata = n;
|
||||
|
||||
m_out << "tools::rroot::branch_element::read_leaves :"
|
||||
<< " name " << m_name << " ref_cls " << fClassName
|
||||
<< " : type " << fType << " not treated."
|
||||
<< std::endl;
|
||||
return false;
|
||||
|
||||
} else if(fType==41) {
|
||||
// STL container sub-branch (contains the elements).
|
||||
m_out << "tools::rroot::branch_element::read_leaves :"
|
||||
<< " name " << m_name << " ref_cls " << fClassName
|
||||
<< " : type " << fType << " not treated."
|
||||
<< std::endl;
|
||||
return false;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
/// TClonesArray container ////////////////////////////
|
||||
///////////////////////////////////////////////////////
|
||||
} else if(fType==3) {
|
||||
// TClonesArray master branch (has only the number of elements).
|
||||
//from v4-00-01
|
||||
int n;
|
||||
if(!a_buffer.read(n)) return false;
|
||||
|
||||
//fNdata = n;
|
||||
//TClonesArray *clones = (TClonesArray*)fObject;
|
||||
//if (!clones) return;
|
||||
//if (clones->IsZombie()) return;
|
||||
//clones->Clear();
|
||||
//clones->ExpandCreateFast(fNdata);
|
||||
|
||||
m_out << "tools::rroot::branch_element::read_leaves :"
|
||||
<< " name " << m_name << " ref_cls " << fClassName
|
||||
<< " : type " << fType << " not treated."
|
||||
<< std::endl;
|
||||
return false;
|
||||
|
||||
} else if(fType==31) {
|
||||
// TClonesArray sub-branch (contains the elements).
|
||||
m_out << "tools::rroot::branch_element::read_leaves :"
|
||||
<< " name " << m_name << " ref_cls " << fClassName
|
||||
<< " : type " << fType << " not treated."
|
||||
<< std::endl;
|
||||
return false;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////
|
||||
} else if(fType<=2) {
|
||||
// branch in split mode
|
||||
|
||||
//from v4-00-01
|
||||
//if (fBranchCount) fNdata = (Int_t)fBranchCount->GetValue(0,0);
|
||||
//else fNdata = 1;
|
||||
//if (!fInfo) return;
|
||||
//fInfo->ReadBuffer(b,fObject,fID);
|
||||
//if (fStreamerType == 6) fNdata = (Int_t)GetValue(0,0);
|
||||
|
||||
//from 3.0.06
|
||||
//if (fID >= 0) {
|
||||
// fInfo->ReadBuffer(b,fAddress,fID);
|
||||
//} else if (fID == -1) { // top level branch in non split mode
|
||||
// char **ppointer = (char**)fAddress;
|
||||
// fInfo->ReadBuffer(b,*ppointer,fID);
|
||||
//}
|
||||
|
||||
//m_out << "tools::rroot::branch_element::read_leaves :"
|
||||
// << " name " << m_name << " ref_cls " << fClassName << " :"
|
||||
// << " type " << fType << " with ID " << fID << "."
|
||||
// << " and then ?"
|
||||
// << std::endl;
|
||||
|
||||
// read object ?
|
||||
bool created = false;
|
||||
if(!m_obj) {
|
||||
ifac::args args;
|
||||
m_obj = m_fac.create(fClassName,args);
|
||||
if(!m_obj) return false;
|
||||
created = true;
|
||||
}
|
||||
|
||||
if(!m_obj->stream(a_buffer)){
|
||||
m_out << "tools::rroot::branch_element::read_leaves :"
|
||||
<< " name " << m_name << " ref_cls " << fClassName << " :"
|
||||
<< " obj stream failed."
|
||||
<< std::endl;
|
||||
if(created) {delete m_obj;m_obj = 0;}
|
||||
return false;
|
||||
}
|
||||
|
||||
//m_out << "tools::rroot::branch_element::read_leaves :"
|
||||
// << " name " << m_name << " ref_cls " << fClassName << " :"
|
||||
// << " obj streamed."
|
||||
// << std::endl;
|
||||
|
||||
return true;
|
||||
|
||||
// } else if(fType==0) {
|
||||
// if(fID>=0) {
|
||||
// // branch in split mode
|
||||
// m_out << "tools::rroot::branch_element::read_leaves :"
|
||||
// << " name " << m_name << " ref_cls " << fClassName << " :"
|
||||
// << " type 0 with ID " << fID << "."
|
||||
// << std::endl;
|
||||
// return true;
|
||||
//
|
||||
// } else if(fID==-1) {
|
||||
// // top level branch in non split mode
|
||||
// m_out << "tools::rroot::branch_element::read_leaves :"
|
||||
// << " name " << m_name << " ref_cls " << fClassName << " :"
|
||||
// << " type 0 with ID " << fID
|
||||
// << " : fill object."
|
||||
// << std::endl;
|
||||
|
||||
// if(!m_obj) {
|
||||
// m_out << "tools::rroot::branch_element::read_leaves :"
|
||||
// << " name " << m_name << " ref_cls " << fClassName << " :"
|
||||
// << " m_obj is null."
|
||||
// << std::endl;
|
||||
// return false;
|
||||
// }
|
||||
// if(!m_obj->stream(a_buffer)){
|
||||
// m_out << "tools::rroot::branch_element::read_leaves :"
|
||||
// << " name " << m_name << " ref_cls " << fClassName << " :"
|
||||
// << " obj stream failed."
|
||||
// << std::endl;
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
|
||||
// } else {
|
||||
// m_out << "tools::rroot::branch_element::read_leaves :"
|
||||
// << " name " << m_name << " ref_cls " << fClassName << " :"
|
||||
// << " type 0 with ID " << fID << " not treated."
|
||||
// << std::endl;
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// //LHCb files :
|
||||
// } else if(fType==1) {
|
||||
// // parent branch is a base class branch.
|
||||
// // Ok, and then ?
|
||||
// m_out << "tools::rroot::branch_element::read_leaves :"
|
||||
// << " name " << m_name << " ref_cls " << fClassName << " :"
|
||||
// << " type " << fType << " with ID " << fID << "."
|
||||
// << std::endl;
|
||||
// return true;
|
||||
|
||||
} else {
|
||||
m_out << "tools::rroot::branch_element::read_leaves :"
|
||||
<< " name " << m_name << " ref_cls " << fClassName << " :"
|
||||
<< " type " << fType << " with ID " << fID << "."
|
||||
<< " unknown case."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
virtual bool find_entry(ifile& a_file,uint64 a_entry,uint32& a_nbytes){
|
||||
@@ -588,11 +346,6 @@ public: //branch
|
||||
if(!parent::find_entry(a_file,a_entry,a_nbytes)) return false;
|
||||
|
||||
if(m_branches.size()) {
|
||||
//if(!m_obj) {
|
||||
// m_obj = m_fac.create(fClassName);
|
||||
// if(!m_obj) return false;
|
||||
//}
|
||||
|
||||
tools_vforcit(branch*,m_branches,it) {
|
||||
uint32 n;
|
||||
if(!(*it)->find_entry(a_file,a_entry,n)) return false;
|
||||
@@ -615,7 +368,6 @@ public: //branch
|
||||
a_out << m_obj << std::endl;
|
||||
|
||||
return true;
|
||||
//return parent::show(a_out,a_file,a_entry);
|
||||
}
|
||||
public:
|
||||
branch_element(std::ostream& a_out,ifac& a_fac)
|
||||
@@ -721,76 +473,5 @@ protected:
|
||||
|
||||
}}
|
||||
|
||||
#ifdef TOOLS_RROOT_BRANCH_ELEMENT_DUMP
|
||||
#undef TOOLS_RROOT_BRANCH_ELEMENT_DUMP
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
/* In v4-00-01 version 8 :
|
||||
case 1: {b.ReadFastArray((Char_t*) fAddress, n); break;}
|
||||
case 2: {b.ReadFastArray((Short_t*) fAddress, n); break;}
|
||||
case 3: {b.ReadFastArray((Int_t*) fAddress, n); break;}
|
||||
case 4: {b.ReadFastArray((Long_t*) fAddress, n); break;}
|
||||
case 5: {b.ReadFastArray((Float_t*) fAddress, n); break;}
|
||||
case 6: {b.ReadFastArray((Int_t*) fAddress, n); break;}
|
||||
case 8: {b.ReadFastArray((Double_t*)fAddress, n); break;}
|
||||
case 11: {b.ReadFastArray((UChar_t*) fAddress, n); break;}
|
||||
case 12: {b.ReadFastArray((UShort_t*)fAddress, n); break;}
|
||||
case 13: {b.ReadFastArray((UInt_t*) fAddress, n); break;}
|
||||
case 14: {b.ReadFastArray((ULong_t*) fAddress, n); break;}
|
||||
case 15: {b.ReadFastArray((Long64_t*)fAddress, n); break;}
|
||||
case 16: {b.ReadFastArray((ULong64_t*)fAddress, n); break;}
|
||||
case 9: {Double_t *xx = (Double_t*)fAddress;
|
||||
Float_t afloat;
|
||||
for (Int_t ii=0;ii<n;ii++) {
|
||||
b>> afloat; xx[ii] = Double_t(afloat);
|
||||
} break;}
|
||||
*/
|
||||
/* 6.12.06 version 10 : fStreamerType : from meta/inc/TVirtualStreamerInfo.h :
|
||||
|
||||
enum EReadWrite {
|
||||
kBase = 0, kOffsetL = 20, kOffsetP = 40, kCounter = 6, kCharStar = 7,
|
||||
kChar = 1, kShort = 2, kInt = 3, kLong = 4, kFloat = 5,
|
||||
kDouble = 8, kDouble32= 9,
|
||||
kUChar = 11, kUShort = 12, kUInt = 13, kULong = 14, kBits = 15,
|
||||
kLong64 = 16, kULong64 = 17, kBool = 18, kFloat16 = 19,
|
||||
kObject = 61, kAny = 62, kObjectp = 63, kObjectP = 64, kTString = 65,
|
||||
kTObject = 66, kTNamed = 67, kAnyp = 68, kAnyP = 69, kAnyPnoVT = 70,
|
||||
kSTLp = 71,
|
||||
kSkip = 100, kSkipL = 120, kSkipP = 140,
|
||||
kConv = 200, kConvL = 220, kConvP = 240,
|
||||
kSTL = ROOT::kSTLany, // 300
|
||||
kSTLstring = ROOT::kSTLstring, // 365
|
||||
kStreamer = 500, kStreamLoop = 501,
|
||||
kCache = 600, // Cache the value in memory than is not part of the object but is accessible via a SchemaRule
|
||||
kArtificial = 1000,
|
||||
kCacheNew = 1001,
|
||||
kCacheDelete = 1002,
|
||||
kNeedObjectForVirtualBaseClass = 99997,
|
||||
kMissing = 99999
|
||||
};
|
||||
|
||||
// Some comments about EReadWrite
|
||||
// kBase : base class element
|
||||
// kOffsetL : fixed size array
|
||||
// kOffsetP : pointer to object
|
||||
// kCounter : counter for array size
|
||||
// kCharStar: pointer to array of char
|
||||
// kBits : TObject::fBits in case of a referenced object
|
||||
// kObject : Class derived from TObject
|
||||
// kObjectp : Class* derived from TObject and with comment field //->Class
|
||||
// kObjectP : Class* derived from TObject and with NO comment field //->Class
|
||||
// kAny : Class not derived from TObject
|
||||
// kAnyp : Class* not derived from TObject with comment field //->Class
|
||||
// kAnyP : Class* not derived from TObject with NO comment field //->Class
|
||||
// kAnyPnoVT: Class* not derived from TObject with NO comment field //->Class and Class has NO virtual table
|
||||
// kSTLp : Pointer to STL container.
|
||||
// kTString : TString, special case
|
||||
// kTObject : TObject, special case
|
||||
// kTNamed : TNamed , special case
|
||||
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user