23 #if defined(__linux) || defined(__APPLE__) || defined(__powerpc64__)
26 typedef abi::__class_type_info class_t;
27 using abi::__dynamic_cast;
40 inline uint64_t murmur_hash_64 (
const void *
key,
int len) {
41 #define seed 0xFEEDBABE
42 typedef unsigned long long int uint64;
44 #if INTPTR_MAX == INT32_MAX
45 const unsigned int * data = (
const unsigned int *)
key;
46 const unsigned int m = 0x5bd1e995;
49 unsigned int h1 = seed ^ len;
54 unsigned int k1 = *data++;
55 k1 *= m; k1 ^= k1 >> r; k1 *= m;
59 unsigned int k2 = *data++;
60 k2 *= m; k2 ^= k2 >> r; k2 *= m;
67 unsigned int k1 = *data++;
68 k1 *= m; k1 ^= k1 >> r; k1 *= m;
75 case 3: h2 ^= ((
unsigned char*)data)[2] << 16;
76 case 2: h2 ^= ((
unsigned char*)data)[1] << 8;
77 case 1: h2 ^= ((
unsigned char*)data)[0];
81 h1 ^= h2 >> 18; h1 *= m;
82 h2 ^= h1 >> 22; h2 *= m;
83 h1 ^= h2 >> 17; h1 *= m;
84 h2 ^= h1 >> 19; h2 *= m;
89 #elif INTPTR_MAX == INT64_MAX
90 const uint64* data = (
const uint64*)
key;
91 const uint64 m = 0xc6a4a7935bd1e995;
94 uint64 h = seed ^ (len * m);
96 const uint64 * end = data + (len/8);
110 const unsigned char * data2 = (
const unsigned char*)data;
114 case 7: h ^= uint64(data2[6]) << 48;
115 case 6: h ^= uint64(data2[5]) << 40;
116 case 5: h ^= uint64(data2[4]) << 32;
117 case 4: h ^= uint64(data2[3]) << 24;
118 case 3: h ^= uint64(data2[2]) << 16;
119 case 2: h ^= uint64(data2[1]) << 8;
120 case 1: h ^= uint64(data2[0]);
129 #error "Environment not 32 or 64-bit."
136 static const unsigned long long int hashinit = 14695981039346656037ull;
137 static constexpr
unsigned long long int doByte(
unsigned long long int hash,
unsigned char val)
138 {
return (
hash ^ val) * 1099511628211ull; }
141 static unsigned char crc8_table[] =
142 { 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
143 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
144 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
145 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
146 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
147 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
148 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
149 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
150 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
151 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
152 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
153 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
154 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
155 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
156 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
157 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53
160 static unsigned char pearson_hash(
const void *data,
size_t len) {
161 const char *s = (
const char*)data;
163 while (--len) c = crc8_table[c ^ *s++];
166 static unsigned char pearson_hash(
const char *data) {
167 const char *s = data;
169 while (*s) c = crc8_table[c ^ *s++];
175 std::string dd4hep::volumeID(
VolumeID vid) {
177 unsigned long long id = (
unsigned long long)vid;
178 ::snprintf(text,
sizeof(text),
"%016llx",
id);
183 unsigned long long int dd4hep::detail::hash64(
const char*
key) {
184 return update_hash64(FNV1a_64::hashinit,
key);
188 unsigned long long int dd4hep::detail::hash64(
const std::string&
key) {
189 return update_hash64(FNV1a_64::hashinit,
key.c_str(),
key.length());
193 unsigned long long int dd4hep::detail::hash64(
const void*
key, std::size_t len) {
194 return update_hash64(FNV1a_64::hashinit,
key, len);
198 unsigned long long int dd4hep::detail::update_hash64(
unsigned long long int hash,
const std::string&
key) {
199 return update_hash64(
hash,
key.c_str(),
key.length());
203 unsigned long long int dd4hep::detail::update_hash64(
unsigned long long int hash,
const char*
key) {
204 const unsigned char* str = (
const unsigned char*)
key;
205 for ( ; *str; ++str)
hash = FNV1a_64::doByte(
hash, *str);
210 unsigned long long int dd4hep::detail::update_hash64(
unsigned long long int hash,
const void*
key, std::size_t len) {
211 const unsigned char* str = (
const unsigned char*)
key;
212 for (std::size_t i = 0; i < len; ++i)
hash = FNV1a_64::doByte(
hash, str[i]);
217 unsigned short dd4hep::detail::hash16(
const void*
key, std::size_t len) {
218 unsigned short value = (
unsigned short)hash32(
key, len);
223 unsigned char dd4hep::detail::hash8(
const void*
key, std::size_t len) {
224 return pearson_hash(
key, len);
228 unsigned char dd4hep::detail::hash8(
const char*
key) {
229 return pearson_hash(
key);
233 std::string dd4hep::detail::str_replace(
const std::string& str,
234 const std::string& pattern,
235 const std::string& replacement) {
236 std::string res = str;
237 for(
size_t id=res.find(pattern);
id != std::string::npos;
id = res.find(pattern) )
238 res.replace(
id, pattern.length(), replacement);
243 std::string dd4hep::detail::str_replace(
const std::string& str,
245 const std::string& replacement) {
246 std::string res = str;
247 for(
size_t id=res.find(pattern);
id != std::string::npos;
id = res.find(pattern) )
248 res.replace(
id, 1, replacement);
253 std::string dd4hep::detail::str_replace(
const std::string& str,
256 std::string res = str;
257 for(
size_t id=res.find(pattern);
id != std::string::npos;
id = res.find(pattern) )
258 res.replace(
id, 1, 1, replacement);
263 std::string dd4hep::detail::str_lower(
const std::string& str) {
264 std::string res = str.c_str();
265 std::transform(res.begin(), res.end(), res.begin(), ::tolower);
270 std::string dd4hep::detail::str_upper(
const std::string& str) {
271 std::string res = str.c_str();
272 std::transform(res.begin(), res.end(), res.begin(), ::toupper);
276 long int dd4hep::detail::makeTime(
int year,
int month,
int day,
277 int hour,
int minutes,
int seconds)
280 ::memset(&tm_init,0,
sizeof(tm_init));
281 tm_init.tm_year = year > 1900 ? year-1900 : year;
282 tm_init.tm_mon = month;
283 tm_init.tm_mday = day;
284 tm_init.tm_hour = hour;
285 tm_init.tm_min = minutes;
286 tm_init.tm_sec = seconds;
287 tm_init.tm_isdst = -1;
288 long int ti = ::mktime(&tm_init);
289 if ( ti >= 0 )
return ti;
290 except(
"dd4hep",
"Invalid time data given for conversion to epoch: %d-%d-%d %02d:%02d:%02d",
291 year, month, day, hour, minutes, seconds);
296 long int dd4hep::detail::makeTime(
const std::string& date,
const char* fmt) {
298 char* c = ::strptime(date.c_str(),fmt,&tm);
301 "Invalid time format given for update:%s should be: %s",
304 long ti = ::mktime(&tm);
305 if ( ti >= 0 )
return ti;
307 "Invalid time string given for conversion to epoch: %s (fmt='%s')",
312 static const std::string __typeinfoName(
const std::type_info& tinfo) {
313 const char* class_name = tinfo.name();
317 if ( ::strncmp(class_name,
"class ", 6) == 0 ) {
321 if ( ::strncmp(class_name,
"struct ", 7) == 0 ) {
325 if ( off != std::string::npos ) {
326 std::string tmp = class_name + off;
328 while( (loc = tmp.find(
"class ")) != std::string::npos ) {
332 while( (loc = tmp.find(
"struct ")) != std::string::npos ) {
341 while ( (off=result.find(
" *")) != std::string::npos ) {
342 result.replace(off, 2,
"*");
345 while ( (off=result.find(
" &")) != std::string::npos ) {
346 result.replace(off, 2,
"&");
350 #elif !defined(__ICC)
351 if (::strlen(class_name) == 1) {
354 switch (class_name[0]) {
368 result =
"unsigned char";
374 result =
"unsigned short";
380 result =
"unsigned int";
386 result =
"unsigned long";
389 result =
"long long";
392 result =
"unsigned long long";
398 result =
"unsigned __int128";
407 result =
"long double";
410 result =
"__float128";
418 char buff[16 * 1024];
419 std::size_t len =
sizeof(buff);
421 result = __cxxabiv1::__cxa_demangle(class_name, buff, &len, &status);
425 throw std::runtime_error(
"CXXABI is missing for ICC!");
430 std::string dd4hep::typeName(
const std::type_info& typ) {
431 return __typeinfoName(typ);
434 void dd4hep::invalidHandleError(
const std::type_info& type)
436 throw invalid_handle_exception(
"Attempt to access invalid object of type "+typeName(type)+
" [Invalid Handle]");
439 void dd4hep::invalidHandleAssignmentError(
const std::type_info& from,
440 const std::type_info& to)
442 std::string msg =
"Wrong assingment from ";
443 msg += typeName(from);
446 msg +=
" not possible!!";
447 throw invalid_handle_exception(msg);
451 void dd4hep::notImplemented(
const std::string& msg)
453 std::string m =
"The requested feature " + msg +
" is not implemented!";
454 throw std::runtime_error(m);
457 void dd4hep::typeinfoCheck(
const std::type_info& typ1,
const std::type_info& typ2,
const std::string& text)
460 throw unrelated_type_error(typ1, typ2, text);
466 template<>
const char* Primitive<bool>::default_format() {
return "%d"; }
467 template<>
const char* Primitive<char>::default_format() {
return "%c"; }
468 template<>
const char* Primitive<unsigned char>::default_format() {
return "%02X"; }
469 template<>
const char* Primitive<short>::default_format() {
return "%d"; }
470 template<>
const char* Primitive<unsigned short>::default_format() {
return "%04X"; }
471 template<>
const char* Primitive<int>::default_format() {
return "%d"; }
472 template<>
const char* Primitive<unsigned int>::default_format() {
return "%08X"; }
473 template<>
const char* Primitive<long>::default_format() {
return "%ld"; }
474 template<>
const char* Primitive<unsigned long>::default_format() {
return "%016X"; }
475 template<>
const char* Primitive<float>::default_format() {
return "%f"; }
476 template<>
const char* Primitive<double>::default_format() {
return "%g"; }
477 template<>
const char* Primitive<char*>::default_format() {
return "%s"; }
478 template<>
const char* Primitive<const char*>::default_format() {
return "%s"; }
479 template<>
const char* Primitive<std::string>::default_format() {
return "%s"; }
484 ::snprintf(text,
sizeof(text),default_format(),value);
493 throw std::runtime_error(
"Failed to convert (char*)NULL to std::string!");
500 throw std::runtime_error(
"Failed to convert (char*)NULL to std::string!");
522 dd4hep::Cast::Cast(
const std::type_info& t, cast_t c) : type(t), cast(c) {
526 dd4hep::Cast::Cast(
const std::type_info& t) : type(t) {
528 abi_class =
dynamic_cast<const class_t*
>(&
type);
530 throw std::runtime_error(
"Class type " + typeName(
type) +
" is not an abi object type!");
536 dd4hep::Cast::~Cast() {
540 void* dd4hep::Cast::apply_dynCast(
const Cast& to,
const void* ptr)
const
547 void *r = (*to.cast)(ptr);
553 throw unrelated_type_error(type, to.type,
"Failed to apply abi dynamic cast operation!");
555 void* r = (
void*)ptr;
556 if ( to.abi_class ) {
557 bool cast_worked = type.__do_upcast((
const class_t*)to.abi_class,&r);
558 if ( cast_worked )
return r;
560 cast_worked = to.type.__do_upcast((
const class_t*)abi_class,&r);
561 if ( cast_worked )
return r;
563 const class_t* src_type = (
const class_t*)to.abi_class;
566 void *r = cast_wrap(ptr, src_type, (
const class_t*) abi_class, -1);
569 r = cast_wrap(ptr, (
const class_t*) abi_class, src_type, -1);
573 throw unrelated_type_error(type, to.type,
"Failed to apply abi dynamic cast operation!");
576 throw unrelated_type_error(type, to.type,
"Target type is not an abi class type!");
580 void* dd4hep::Cast::apply_upCast(
const Cast& to,
const void* ptr)
const
585 return apply_dynCast(to, ptr);
589 void* dd4hep::Cast::apply_downCast(
const Cast& to,
const void* ptr)
const
595 void *r = (*to.cast)(ptr);
597 throw unrelated_type_error(type, to.type,
"Failed to apply abi dynamic cast operation!");
599 if ( to.abi_class ) {
602 void* r = (
void*)ptr;
603 bool cast_worked = type.__do_upcast((
const class_t*)to.abi_class,&r);
604 if ( cast_worked )
return r;
606 void *r = cast_wrap(ptr, src_type, (
const class_t*)abi_class, -1);
609 throw unrelated_type_error(type, to.type,
"Failed to apply abi dynamic cast operation!");
611 throw unrelated_type_error(type, to.type,
"Target type is not an abi class type!");