activemq-cpp-3.3.0

src/main/decaf/internal/util/HexStringParser.h

Go to the documentation of this file.
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_*/