22 #if defined(__linux) || defined(__APPLE__) || defined(__powerpc64__)
25 typedef abi::__class_type_info class_t;
26 using abi::__dynamic_cast;
39 inline uint64_t murmur_hash_64 (
const void *
key,
int len) {
40 #define seed 0xFEEDBABE
41 typedef unsigned long long int uint64;
43 #if INTPTR_MAX == INT32_MAX
44 const unsigned int * data = (
const unsigned int *)
key;
45 const unsigned int m = 0x5bd1e995;
48 unsigned int h1 = seed ^ len;
53 unsigned int k1 = *data++;
54 k1 *= m; k1 ^= k1 >> r; k1 *= m;
58 unsigned int k2 = *data++;
59 k2 *= m; k2 ^= k2 >> r; k2 *= m;
66 unsigned int k1 = *data++;
67 k1 *= m; k1 ^= k1 >> r; k1 *= m;
74 case 3: h2 ^= ((
unsigned char*)data)[2] << 16;
75 case 2: h2 ^= ((
unsigned char*)data)[1] << 8;
76 case 1: h2 ^= ((
unsigned char*)data)[0];
80 h1 ^= h2 >> 18; h1 *= m;
81 h2 ^= h1 >> 22; h2 *= m;
82 h1 ^= h2 >> 17; h1 *= m;
83 h2 ^= h1 >> 19; h2 *= m;
88 #elif INTPTR_MAX == INT64_MAX
89 const uint64* data = (
const uint64*)
key;
90 const uint64 m = 0xc6a4a7935bd1e995;
93 uint64 h = seed ^ (len * m);
95 const uint64 * end = data + (len/8);
109 const unsigned char * data2 = (
const unsigned char*)data;
113 case 7: h ^= uint64(data2[6]) << 48;
114 case 6: h ^= uint64(data2[5]) << 40;
115 case 5: h ^= uint64(data2[4]) << 32;
116 case 4: h ^= uint64(data2[3]) << 24;
117 case 3: h ^= uint64(data2[2]) << 16;
118 case 2: h ^= uint64(data2[1]) << 8;
119 case 1: h ^= uint64(data2[0]);
128 #error "Environment not 32 or 64-bit."
135 static const unsigned long long int hashinit = 14695981039346656037ull;
136 static constexpr
unsigned long long int doByte(
unsigned long long int hash,
unsigned char val)
137 {
return (
hash ^ val) * 1099511628211ull; }
140 static unsigned char crc8_table[] =
141 { 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
142 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
143 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
144 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
145 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
146 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
147 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
148 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
149 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
150 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
151 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
152 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
153 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
154 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
155 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
156 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53
159 static unsigned char pearson_hash(
const void *data,
size_t len) {
160 const char *s = (
const char*)data;
162 while (--len) c = crc8_table[c ^ *s++];
165 static unsigned char pearson_hash(
const char *data) {
166 const char *s = data;
168 while (*s) c = crc8_table[c ^ *s++];
174 std::string dd4hep::volumeID(
VolumeID vid) {
176 unsigned long long id = (
unsigned long long)vid;
177 ::snprintf(text,
sizeof(text),
"%016llx",
id);
182 unsigned long long int dd4hep::detail::hash64(
const char*
key) {
183 return update_hash64(FNV1a_64::hashinit,
key);
187 unsigned long long int dd4hep::detail::hash64(
const std::string&
key) {
188 return update_hash64(FNV1a_64::hashinit,
key.c_str(),
key.length());
192 unsigned long long int dd4hep::detail::hash64(
const void*
key, std::size_t len) {
193 return update_hash64(FNV1a_64::hashinit,
key, len);
197 unsigned long long int dd4hep::detail::update_hash64(
unsigned long long int hash,
const std::string&
key) {
198 return update_hash64(
hash,
key.c_str(),
key.length());
202 unsigned long long int dd4hep::detail::update_hash64(
unsigned long long int hash,
const char*
key) {
203 const unsigned char* str = (
const unsigned char*)
key;
204 for ( ; *str; ++str)
hash = FNV1a_64::doByte(
hash, *str);
209 unsigned long long int dd4hep::detail::update_hash64(
unsigned long long int hash,
const void*
key, std::size_t len) {
210 const unsigned char* str = (
const unsigned char*)
key;
212 for ( ; --len; ++str)
hash = FNV1a_64::doByte(
hash, *str);
218 unsigned short dd4hep::detail::hash16(
const void*
key, std::size_t len) {
219 unsigned short value = (
unsigned short)hash32(
key, len);
224 unsigned char dd4hep::detail::hash8(
const void*
key, std::size_t len) {
225 return pearson_hash(
key, len);
229 unsigned char dd4hep::detail::hash8(
const char*
key) {
230 return pearson_hash(
key);
234 std::string dd4hep::detail::str_replace(
const std::string& str,
235 const std::string& pattern,
236 const std::string& replacement) {
237 std::string res = str;
238 for(
size_t id=res.find(pattern);
id != std::string::npos;
id = res.find(pattern) )
239 res.replace(
id, pattern.length(), replacement);
244 std::string dd4hep::detail::str_replace(
const std::string& str,
246 const std::string& replacement) {
247 std::string res = str;
248 for(
size_t id=res.find(pattern);
id != std::string::npos;
id = res.find(pattern) )
249 res.replace(
id, 1, replacement);
254 std::string dd4hep::detail::str_replace(
const std::string& str,
257 std::string res = str;
258 for(
size_t id=res.find(pattern);
id != std::string::npos;
id = res.find(pattern) )
259 res.replace(
id, 1, 1, replacement);
264 std::string dd4hep::detail::str_lower(
const std::string& str) {
265 std::string res = str.c_str();
266 std::transform(res.begin(), res.end(), res.begin(), ::tolower);
271 std::string dd4hep::detail::str_upper(
const std::string& str) {
272 std::string res = str.c_str();
273 std::transform(res.begin(), res.end(), res.begin(), ::toupper);
277 long int dd4hep::detail::makeTime(
int year,
int month,
int day,
278 int hour,
int minutes,
int seconds)
281 ::memset(&tm_init,0,
sizeof(tm_init));
282 tm_init.tm_year = year > 1900 ? year-1900 : year;
283 tm_init.tm_mon = month;
284 tm_init.tm_mday = day;
285 tm_init.tm_hour = hour;
286 tm_init.tm_min = minutes;
287 tm_init.tm_sec = seconds;
288 tm_init.tm_isdst = -1;
289 long int ti = ::mktime(&tm_init);
290 if ( ti >= 0 )
return ti;
291 except(
"dd4hep",
"Invalid time data given for conversion to epoch: %d-%d-%d %02d:%02d:%02d",
292 year, month, day, hour, minutes, seconds);
297 long int dd4hep::detail::makeTime(
const std::string& date,
const char* fmt) {
299 char* c = ::strptime(date.c_str(),fmt,&tm);
302 "Invalid time format given for update:%s should be: %s",
305 long ti = ::mktime(&tm);
306 if ( ti >= 0 )
return ti;
308 "Invalid time string given for conversion to epoch: %s (fmt='%s')",
313 static const std::string __typeinfoName(
const std::type_info& tinfo) {
314 const char* class_name = tinfo.name();
318 if ( ::strncmp(class_name,
"class ", 6) == 0 ) {
322 if ( ::strncmp(class_name,
"struct ", 7) == 0 ) {
326 if ( off != std::string::npos ) {
327 std::string tmp = class_name + off;
329 while( (loc = tmp.find(
"class ")) != std::string::npos ) {
333 while( (loc = tmp.find(
"struct ")) != std::string::npos ) {
342 while ( (off=result.find(
" *")) != std::string::npos ) {
343 result.replace(off, 2,
"*");
346 while ( (off=result.find(
" &")) != std::string::npos ) {
347 result.replace(off, 2,
"&");
351 #elif !defined(__ICC)
352 if (::strlen(class_name) == 1) {
355 switch (class_name[0]) {
369 result =
"unsigned char";
375 result =
"unsigned short";
381 result =
"unsigned int";
387 result =
"unsigned long";
390 result =
"long long";
393 result =
"unsigned long long";
399 result =
"unsigned __int128";
408 result =
"long double";
411 result =
"__float128";
419 char buff[16 * 1024];
420 std::size_t len =
sizeof(buff);
422 result = __cxxabiv1::__cxa_demangle(class_name, buff, &len, &status);
426 throw std::runtime_error(
"CXXABI is missing for ICC!");
431 std::string dd4hep::typeName(
const std::type_info& typ) {
432 return __typeinfoName(typ);
435 void dd4hep::invalidHandleError(
const std::type_info& type)
437 throw invalid_handle_exception(
"Attempt to access invalid object of type "+typeName(type)+
" [Invalid Handle]");
440 void dd4hep::invalidHandleAssignmentError(
const std::type_info& from,
441 const std::type_info& to)
443 std::string msg =
"Wrong assingment from ";
444 msg += typeName(from);
447 msg +=
" not possible!!";
448 throw invalid_handle_exception(msg);
452 void dd4hep::notImplemented(
const std::string& msg)
454 std::string m =
"The requested feature " + msg +
" is not implemented!";
455 throw std::runtime_error(m);
458 void dd4hep::typeinfoCheck(
const std::type_info& typ1,
const std::type_info& typ2,
const std::string& text)
461 throw unrelated_type_error(typ1, typ2, text);
467 template<>
const char* Primitive<bool>::default_format() {
return "%d"; }
468 template<>
const char* Primitive<char>::default_format() {
return "%c"; }
469 template<>
const char* Primitive<unsigned char>::default_format() {
return "%02X"; }
470 template<>
const char* Primitive<short>::default_format() {
return "%d"; }
471 template<>
const char* Primitive<unsigned short>::default_format() {
return "%04X"; }
472 template<>
const char* Primitive<int>::default_format() {
return "%d"; }
473 template<>
const char* Primitive<unsigned int>::default_format() {
return "%08X"; }
474 template<>
const char* Primitive<long>::default_format() {
return "%ld"; }
475 template<>
const char* Primitive<unsigned long>::default_format() {
return "%016X"; }
476 template<>
const char* Primitive<float>::default_format() {
return "%f"; }
477 template<>
const char* Primitive<double>::default_format() {
return "%g"; }
478 template<>
const char* Primitive<char*>::default_format() {
return "%s"; }
479 template<>
const char* Primitive<const char*>::default_format() {
return "%s"; }
480 template<>
const char* Primitive<std::string>::default_format() {
return "%s"; }
485 ::snprintf(text,
sizeof(text),default_format(),value);
494 throw std::runtime_error(
"Failed to convert (char*)NULL to std::string!");
501 throw std::runtime_error(
"Failed to convert (char*)NULL to std::string!");
523 dd4hep::Cast::Cast(
const std::type_info& t, cast_t c) : type(t), cast(c) {
527 dd4hep::Cast::Cast(
const std::type_info& t) : type(t) {
529 abi_class =
dynamic_cast<const class_t*
>(&
type);
531 throw std::runtime_error(
"Class type " + typeName(
type) +
" is not an abi object type!");
537 dd4hep::Cast::~Cast() {
541 void* dd4hep::Cast::apply_dynCast(
const Cast& to,
const void* ptr)
const
548 void *r = (*to.cast)(ptr);
554 throw unrelated_type_error(type, to.type,
"Failed to apply abi dynamic cast operation!");
556 void* r = (
void*)ptr;
557 if ( to.abi_class ) {
558 bool cast_worked = type.__do_upcast((
const class_t*)to.abi_class,&r);
559 if ( cast_worked )
return r;
561 cast_worked = to.type.__do_upcast((
const class_t*)abi_class,&r);
562 if ( cast_worked )
return r;
564 const class_t* src_type = (
const class_t*)to.abi_class;
567 void *r = cast_wrap(ptr, src_type, (
const class_t*) abi_class, -1);
570 r = cast_wrap(ptr, (
const class_t*) abi_class, src_type, -1);
574 throw unrelated_type_error(type, to.type,
"Failed to apply abi dynamic cast operation!");
577 throw unrelated_type_error(type, to.type,
"Target type is not an abi class type!");
581 void* dd4hep::Cast::apply_upCast(
const Cast& to,
const void* ptr)
const
586 return apply_dynCast(to, ptr);
590 void* dd4hep::Cast::apply_downCast(
const Cast& to,
const void* ptr)
const
596 void *r = (*to.cast)(ptr);
598 throw unrelated_type_error(type, to.type,
"Failed to apply abi dynamic cast operation!");
600 if ( to.abi_class ) {
603 void* r = (
void*)ptr;
604 bool cast_worked = type.__do_upcast((
const class_t*)to.abi_class,&r);
605 if ( cast_worked )
return r;
607 void *r = cast_wrap(ptr, src_type, (
const class_t*)abi_class, -1);
610 throw unrelated_type_error(type, to.type,
"Failed to apply abi dynamic cast operation!");
612 throw unrelated_type_error(type, to.type,
"Target type is not an abi class type!");