00001 //-------------------------------------------------------------------------- 00002 // File and Version Information: 00003 // $Id: IfdStrKey.cxx,v 1.1.1.1 2005/04/21 01:18:05 zhangy Exp $ 00004 // 00005 // Description: 00006 // Implementation of IfdStrKey. See .hh for details. 00007 // 00008 // Author List: 00009 // Ed Frank University of Pennsylvania 00010 // 00011 // History: 00012 // Ed Frank 18 Sep 97 Creation of first version 00013 // 00014 // Copyright Information: 00015 // Copyright (C) 1997 00016 // 00017 // Bugs: 00018 // 00019 //------------------------------------------------------------------------ 00020 00021 //#include "BaBar/BaBar.hh" 00022 #include "ProxyDict/IfdStrKey.h" 00023 #if !(defined(__GNUC__) && (__GNUC__ < 3) && (__GNUC_MINOR__ < 95)) // BABAR_IOSTREAMS_MIGRATION 00024 using std::ostream; 00025 #endif // BABAR_IOSTREAMS_MIGRATION 00026 00027 //**************************************************************************** 00028 IfdStrKey::IfdStrKey( const char *s ) 00029 //**************************************************************************** 00030 00031 : IfdKey( strKey ) 00032 00033 { 00034 00035 // NB: strncpy would be nice below, but we've already died in strlen 00036 // if thats an issue. 00037 00038 register size_t strSize = strlen(s)+1; 00039 00040 // If the space allocated in this instance of IfdStrKey is big enough 00041 // to hold the string, then put it there; otherwise do the slower operation 00042 // of allocating it in the heap. Either way, make strVal point at it 00043 // to avoid "if allocated" sort of logic later. 00044 00045 if ( strSize < IFDKEY_BUFSIZE ) { 00046 strcpy(_stringBuf, s); 00047 strVal = &_stringBuf[0]; 00048 _onHeap = false; 00049 } else { 00050 strVal = new char[ strSize ]; 00051 strcpy(strVal, s); 00052 _onHeap = true; 00053 } 00054 00055 enum { 00056 MaxChar = 64 // Limit computation. Don't need strlen() 00057 }; 00058 00059 _hashVal = 0; 00060 00061 size_t n = 0; 00062 while ( (s[n] != '\0') && (n < MaxChar) ) { 00063 _hashVal = ( (_hashVal<<8) + s[n] ) % _nHashBuckets; 00064 n++; 00065 } 00066 } 00067 00068 #ifndef VXWORKS 00069 //**************************************************************************** 00070 IfdStrKey::IfdStrKey( const std::string& str ) 00071 //**************************************************************************** 00072 00073 : IfdKey( strKey ) 00074 00075 { 00076 using std::string; 00077 const char* s = str.c_str(); 00078 register size_t strSize = str.size()+1; 00079 00080 // register size_t strSize = strlen(s)+1; 00081 00082 // If the space allocated in this instance of IfdStrKey is big enough 00083 // to hold the string, then put it there; otherwise do the slower operation 00084 // of allocating it in the heap. Either way, make strVal point at it 00085 // to avoid "if allocated" sort of logic later. 00086 00087 if ( strSize < IFDKEY_BUFSIZE ) { 00088 strcpy(_stringBuf, s); 00089 strVal = &_stringBuf[0]; 00090 _onHeap = false; 00091 } else { 00092 strVal = new char[ strSize ]; 00093 strcpy(strVal, s); 00094 _onHeap = true; 00095 } 00096 00097 enum { 00098 MaxChar = 64 // Limit computation. Don't need strlen() 00099 }; 00100 00101 _hashVal = 0; 00102 00103 size_t n = 0; 00104 while ( (s[n] != '\0') && (n < MaxChar) ) { 00105 _hashVal = ( (_hashVal<<8) + s[n] ) % _nHashBuckets; 00106 n++; 00107 } 00108 } 00109 #endif 00110 00111 //**************************************************************************** 00112 IfdStrKey::IfdStrKey( const char *s, unsigned int hashVal ) 00113 //**************************************************************************** 00114 // Used for the clone function. We keep this private because we don't trust 00115 // anyone else to set the hash value correctly/consistently. The aim here 00116 // is to save the cost of calling the hash function during a clone. 00117 00118 : IfdKey( strKey ) 00119 { 00120 00121 // This code is cut/paste from the other constructor. This is harder 00122 // to maintain but in this case we very much need the speed gained by 00123 // saving a call. 00124 00125 register size_t strSize = strlen(s)+1; 00126 00127 if ( strSize < IFDKEY_BUFSIZE ) { 00128 strcpy(_stringBuf, s); 00129 strVal = &_stringBuf[0]; 00130 _onHeap = false; 00131 } else { 00132 strVal = new char[strlen(s)+1]; 00133 strcpy(strVal, s); 00134 _onHeap = true; 00135 } 00136 00137 _hashVal = hashVal; // Override the IfdKey base class init of this. 00138 } 00139 00140 //**************************************************************************** 00141 IfdStrKey::~IfdStrKey() { 00142 //**************************************************************************** 00143 if (_onHeap) delete[] strVal; 00144 strVal=0; 00145 } 00146 00147 //**************************************************************************** 00148 IfdKey* 00149 IfdStrKey::clone(void) const { 00150 //**************************************************************************** 00151 return new IfdStrKey( strVal, _hashVal ); 00152 } 00153 00154 //**************************************************************************** 00155 int 00156 IfdStrKey::operator==( const IfdKey& k ) const { 00157 //**************************************************************************** 00158 00159 00160 if ( (strKey == k.getKeyKind()) && (_hashVal == k._hashVal) ) { 00161 00162 // Then they might actually match! Check the strings. 00163 // We used to use strcmp, but this is faster by x2.2. 00164 char* s1 = strVal; 00165 char* s2 = k.strVal; 00166 while (*s1 == *s2++) { 00167 if ( *s1++ == '\0') return 1; //NB: == in while => *s2 == \0 too. 00168 } 00169 } 00170 00171 return 0; 00172 } 00173 00174 00175 //**************************************************************************** 00176 int 00177 IfdStrKey::operator<( const IfdKey& k ) const { 00178 //**************************************************************************** 00179 return ( strKey == k.getKeyKind() ) && (strcmp(strVal, k.strVal) < 0); 00180 } 00181 00182 //**************************************************************************** 00183 void 00184 IfdStrKey::print( ostream &o) const { 00185 //**************************************************************************** 00186 o << "IfdStrKey(" << strVal << ")"; 00187 } 00188