| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef _DECAF_INTERNAL_UTIL_HEXSTRINGPARSER_H_ |
| #define _DECAF_INTERNAL_UTIL_HEXSTRINGPARSER_H_ |
| |
| #include <decaf/util/Config.h> |
| #include <string> |
| |
| namespace decaf { |
| namespace internal { |
| namespace util { |
| |
| class HexStringParser { |
| private: |
| |
| static const unsigned int DOUBLE_EXPONENT_WIDTH = 11; |
| static const unsigned int DOUBLE_MANTISSA_WIDTH = 52; |
| static const unsigned int FLOAT_EXPONENT_WIDTH = 8; |
| static const unsigned int FLOAT_MANTISSA_WIDTH = 23; |
| static const unsigned int HEX_RADIX = 16; |
| static const unsigned int MAX_SIGNIFICANT_LENGTH = 15; |
| |
| static const std::string HEX_SIGNIFICANT; |
| static const std::string BINARY_EXPONENT; |
| static const std::string FLOAT_TYPE_SUFFIX; |
| static const std::string HEX_PATTERN; |
| |
| // TODO |
| //static final Pattern PATTERN = Pattern.compile(HEX_PATTERN); |
| |
| private: |
| |
| int EXPONENT_WIDTH; |
| int MANTISSA_WIDTH; |
| long long EXPONENT_BASE; |
| long long MAX_EXPONENT; |
| long long MIN_EXPONENT; |
| long long MANTISSA_MASK; |
| long long sign; |
| long long exponent; |
| long long mantissa; |
| std::string abandonedNumber; |
| |
| public: |
| |
| /** |
| * Create a new HexParser |
| * @param exponentWidth - Width of the exponent for the type to parse |
| * @param mantissaWidth - Width of the mantissa for the type to parse |
| */ |
| HexStringParser(int exponentWidth, int mantissaWidth); |
| |
| virtual ~HexStringParser() { |
| } |
| |
| /** |
| * Parses a hex string using the specs given in the constructor |
| * and returns a long long with the bits of the parsed string, the |
| * caller can then convert those to a float or doulbe as needed. |
| * @param hexString - string to parse |
| * @return the bits parsed from the string |
| */ |
| long long parse(const std::string& hexString); |
| |
| private: |
| |
| /* |
| * Parses the sign field. |
| * @param sign string to parse |
| */ |
| void parseHexSign(const std::string& signStr) { |
| this->sign = signStr.compare("-") == 0 ? 1 : 0; |
| } |
| |
| /* |
| * Parses the exponent field. |
| * @param exponent string to parse |
| */ |
| void parseExponent(const std::string& exponentStr); |
| |
| /* |
| * Parses the mantissa field. |
| * @param mantissa string to parse |
| */ |
| void parseMantissa(const std::string& significantStr); |
| |
| void setInfinite() { |
| exponent = MAX_EXPONENT; |
| mantissa = 0; |
| } |
| |
| void setZero() { |
| exponent = 0; |
| mantissa = 0; |
| } |
| |
| /* |
| * Sets the exponent variable to Long::MAX_VALUE or -Long::MAX_VALUE if |
| * overflow or underflow happens. |
| * @param the offset to set |
| */ |
| void checkedAddExponent(long long offset); |
| |
| void processNormalNumber(); |
| void processSubNormalNumber(); |
| int countBitsLength(long long value); |
| |
| /* |
| * Adjusts the mantissa to desired width for further analysis. |
| */ |
| void fitMantissaInDesiredWidth(int desiredWidth); |
| |
| /* |
| * Stores the discarded bits to abandonedNumber. |
| */ |
| void discardTrailingBits(long long num); |
| |
| /* |
| * The value is rounded up or down to the nearest infinitely precise result. |
| * If the value is exactly halfway between two infinitely precise results, |
| * then it should be rounded up to the nearest infinitely precise even. |
| */ |
| void round(); |
| |
| /* |
| * Returns the normalized significand after removing the leading zeros. |
| */ |
| std::string getNormalizedSignificand(const std::string& strIntegerPart, const std::string& strDecimalPart); |
| |
| /* |
| * Calculates the offset between the normalized number and unnormalized |
| * number. In a normalized representation, significand is represented by the |
| * characters "0x1." followed by a lower-case hexadecimal representation of |
| * the rest of the significand as a fraction. |
| */ |
| int getOffset(const std::string& strIntegerPart, const std::string& strDecimalPart); |
| |
| public: |
| // Statics |
| |
| /* |
| * Parses the hex string to a double number. |
| * @param hexString - string to parse |
| * @return the parsed double value |
| */ |
| static double parseDouble(const std::string& hexString); |
| |
| /* |
| * Parses the hex string to a float number. |
| * @param hexString - string to parse |
| * @return the parsed float value |
| */ |
| static float parseFloat(const std::string& hexString); |
| |
| private: |
| // Static |
| |
| /* |
| * Analyzes the hex string and extracts the sign and digit segments. |
| * @param hexString - string to parse |
| * @return array of three strings holding the segments caller owns |
| */ |
| static std::string* getSegmentsFromHexString(const std::string& hexString); |
| |
| std::string& replaceFirst(std::string& target, const std::string& find, const std::string& replace) { |
| |
| std::string::size_type pos = std::string::npos; |
| |
| if ((pos = target.find_first_of(find, 0)) != std::string::npos) { |
| return target.replace(pos, find.length(), replace); |
| } |
| |
| return target; |
| } |
| |
| std::string& replaceAll(std::string& target, const std::string& find, const std::string& replace) { |
| |
| std::string::size_type pos = std::string::npos; |
| while ((pos = target.find(find)) != std::string::npos) { |
| target.replace(pos, find.length(), replace); |
| } |
| |
| return target; |
| } |
| |
| }; |
| |
| }}} |
| |
| #endif /*_DECAF_INTERNAL_UTIL_HEXSTRINGPARSER_H_*/ |