|
activemq-cpp-3.4.0
|
00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one or more 00003 * contributor license agreements. See the NOTICE file distributed with 00004 * this work for additional information regarding copyright ownership. 00005 * The ASF licenses this file to You under the Apache License, Version 2.0 00006 * (the "License"); you may not use this file except in compliance with 00007 * the License. You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #ifndef _DECAF_INTERNAL_UTIL_HEXSTRINGPARSER_H_ 00019 #define _DECAF_INTERNAL_UTIL_HEXSTRINGPARSER_H_ 00020 00021 #include <decaf/util/Config.h> 00022 #include <string> 00023 00024 namespace decaf{ 00025 namespace internal{ 00026 namespace util{ 00027 00028 class HexStringParser { 00029 private: 00030 00031 static const unsigned int DOUBLE_EXPONENT_WIDTH = 11; 00032 static const unsigned int DOUBLE_MANTISSA_WIDTH = 52; 00033 static const unsigned int FLOAT_EXPONENT_WIDTH = 8; 00034 static const unsigned int FLOAT_MANTISSA_WIDTH = 23; 00035 static const unsigned int HEX_RADIX = 16; 00036 static const unsigned int MAX_SIGNIFICANT_LENGTH = 15; 00037 00038 static const std::string HEX_SIGNIFICANT; 00039 static const std::string BINARY_EXPONENT; 00040 static const std::string FLOAT_TYPE_SUFFIX; 00041 static const std::string HEX_PATTERN; 00042 00043 // TODO 00044 //static final Pattern PATTERN = Pattern.compile(HEX_PATTERN); 00045 00046 private: 00047 00048 int EXPONENT_WIDTH; 00049 int MANTISSA_WIDTH; 00050 long long EXPONENT_BASE; 00051 long long MAX_EXPONENT; 00052 long long MIN_EXPONENT; 00053 long long MANTISSA_MASK; 00054 long long sign; 00055 long long exponent; 00056 long long mantissa; 00057 std::string abandonedNumber; 00058 00059 public: 00060 00066 HexStringParser( int exponentWidth, int mantissaWidth ); 00067 00068 virtual ~HexStringParser() {} 00069 00077 long long parse( const std::string& hexString ); 00078 00079 private: 00080 00081 /* 00082 * Parses the sign field. 00083 * @param sign string to parse 00084 */ 00085 void parseHexSign( const std::string& signStr ) { 00086 this->sign = signStr.compare("-") == 0 ? 1 : 0; 00087 } 00088 00089 /* 00090 * Parses the exponent field. 00091 * @param exponent string to parse 00092 */ 00093 void parseExponent( const std::string& exponentStr ); 00094 00095 /* 00096 * Parses the mantissa field. 00097 * @param mantissa string to parse 00098 */ 00099 void parseMantissa( const std::string& significantStr ); 00100 00101 void setInfinite() { 00102 exponent = MAX_EXPONENT; 00103 mantissa = 0; 00104 } 00105 00106 void setZero() { 00107 exponent = 0; 00108 mantissa = 0; 00109 } 00110 00111 /* 00112 * Sets the exponent variable to Long::MAX_VALUE or -Long::MAX_VALUE if 00113 * overflow or underflow happens. 00114 * @param the offset to set 00115 */ 00116 void checkedAddExponent( long long offset ); 00117 00118 void processNormalNumber(); 00119 void processSubNormalNumber(); 00120 int countBitsLength( long long value ); 00121 00122 /* 00123 * Adjusts the mantissa to desired width for further analysis. 00124 */ 00125 void fitMantissaInDesiredWidth( int desiredWidth ); 00126 00127 /* 00128 * Stores the discarded bits to abandonedNumber. 00129 */ 00130 void discardTrailingBits( long long num ); 00131 00132 /* 00133 * The value is rounded up or down to the nearest infinitely precise result. 00134 * If the value is exactly halfway between two infinitely precise results, 00135 * then it should be rounded up to the nearest infinitely precise even. 00136 */ 00137 void round(); 00138 00139 /* 00140 * Returns the normalized significand after removing the leading zeros. 00141 */ 00142 std::string getNormalizedSignificand( const std::string& strIntegerPart, 00143 const std::string& strDecimalPart ); 00144 00145 /* 00146 * Calculates the offset between the normalized number and unnormalized 00147 * number. In a normalized representation, significand is represented by the 00148 * characters "0x1." followed by a lower-case hexadecimal representation of 00149 * the rest of the significand as a fraction. 00150 */ 00151 int getOffset( const std::string& strIntegerPart, 00152 const std::string& strDecimalPart ); 00153 00154 public: // Statics 00155 00156 /* 00157 * Parses the hex string to a double number. 00158 * @param hexString - string to parse 00159 * @returns the parsed double value 00160 */ 00161 static double parseDouble( const std::string& hexString ); 00162 00163 /* 00164 * Parses the hex string to a float number. 00165 * @param hexString - string to parse 00166 * @returns the parsed float value 00167 */ 00168 static float parseFloat( const std::string& hexString ); 00169 00170 00171 private: // Static 00172 00173 /* 00174 * Analyzes the hex string and extracts the sign and digit segments. 00175 * @param hexString - string to parse 00176 * @returns array of three strings holding the segments caller owns 00177 */ 00178 static std::string* getSegmentsFromHexString( const std::string& hexString ); 00179 00180 std::string& replaceFirst( std::string& target, 00181 const std::string& find, 00182 const std::string& replace ) { 00183 00184 std::string::size_type pos = std::string::npos; 00185 00186 if( ( pos = target.find_first_of( find, 0 ) ) != std::string::npos ) { 00187 return target.replace( pos, find.length(), replace ); 00188 } 00189 00190 return target; 00191 } 00192 00193 std::string& replaceAll( std::string& target, 00194 const std::string& find, 00195 const std::string& replace ) { 00196 00197 std::string::size_type pos = std::string::npos; 00198 while( ( pos = target.find( find ) ) != std::string::npos ) { 00199 target.replace( pos, find.length(), replace ); 00200 } 00201 00202 return target; 00203 } 00204 00205 }; 00206 00207 }}} 00208 00209 #endif /*_DECAF_INTERNAL_UTIL_HEXSTRINGPARSER_H_*/