activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tab...@apache.org
Subject svn commit: r563092 - in /activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal: ./ util/ util/FloatingPointParser.cpp util/FloatingPointParser.h util/HexStringParser.cpp util/HexStringParser.h
Date Mon, 06 Aug 2007 10:17:05 GMT
Author: tabish
Date: Mon Aug  6 03:17:04 2007
New Revision: 563092

URL: http://svn.apache.org/viewvc?view=rev&rev=563092
Log:
http://issues.apache.org/activemq/browse/AMQCPP-103

Adding in more Types wrappers

Added:
    activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/
    activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/
    activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/FloatingPointParser.cpp
    activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/FloatingPointParser.h
    activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/HexStringParser.cpp
    activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/HexStringParser.h

Added: activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/FloatingPointParser.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/FloatingPointParser.cpp?view=auto&rev=563092
==============================================================================
--- activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/FloatingPointParser.cpp
(added)
+++ activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/FloatingPointParser.cpp
Mon Aug  6 03:17:04 2007
@@ -0,0 +1,460 @@
+/*
+ *  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.
+ */
+
+#include "FloatingPointParser.h"
+#include <decaf/lang/Math.h>
+#include <decaf/lang/Integer.h>
+#include <decaf/lang/Long.h>
+#include <decaf/lang/Float.h>
+#include <decaf/lang/Double.h>
+#include <decaf/lang/Character.h>
+#include <decaf/internal/util/HexStringParser.h>
+#include <apr_lib.h>
+
+using namespace std;
+using namespace decaf;
+using namespace decaf::lang;
+using namespace decaf::internal;
+using namespace decaf::internal::util;
+
+////////////////////////////////////////////////////////////////////////////////
+double FloatingPointParser::parseDblImpl( const std::string& value, int exp )
+    throw ( exceptions::NumberFormatException ) {
+
+    // assumes s is a null terminated string with at least one
+    // character in it
+    LONG_UNION def[17];
+    LONG_UNION defBackup[17];
+    LONG_UNION* f;
+    LONG_UNION* fNoOverflow;
+    unsigned long long* g;
+    unsigned long long* tempBackup;
+    unsigned int overflow = 0;
+    double result = 0.0;
+    int index = 1;
+    int unprocessedDigits = 0;
+    std::string::const_iterator valItr = value.begin();
+
+    f = def;
+    fNoOverflow = defBackup;
+    (*f).longValue = 0;
+    tempBackup = g = 0;
+
+    do {
+
+        if( *valItr >= '0' && *valItr <= '9' ) {
+
+            // Make a back up of f before appending, so that we can
+            // back out of it if there is no more room, i.e. index >
+            // MAX_ACCURACY_WIDTH.
+
+            memcpy( fNoOverflow, f, sizeof(unsigned long long) * index );
+            overflow = simpleAppendDecimalDigitHighPrecision( f, index, *valItr - '0' );
+//            if( overflow ) {
+//                f[index++] = overflow;
+//                /* There is an overflow, but there is no more room
+//                 * to store the result. We really only need the top 52
+//                 * bits anyway, so we must back out of the overflow,
+//                 * and ignore the rest of the string.
+//                 */
+//                if (index >= MAX_ACCURACY_WIDTH) {
+//                  index--;
+//                  memcpy (f, fNoOverflow, sizeof (U_64) * index);
+//                  break;
+//                }
+//
+//                if (tempBackup) {
+//                  fNoOverflow = tempBackup;
+//                }
+//            }
+//        } else {
+//            index = -1;
+//        }
+
+    } while( index > 0 && *(++valItr) != '\0' );
+//
+//    /* We've broken out of the parse loop either because we've reached
+//     * the end of the string or we've overflowed the maximum accuracy
+//     * limit of a double. If we still have unprocessed digits in the
+//     * given string, then there are three possible results:
+//     *   1. (unprocessed digits + e) == 0, in which case we simply
+//     *      convert the existing bits that are already parsed
+//     *   2. (unprocessed digits + e) < 0, in which case we simply
+//     *      convert the existing bits that are already parsed along
+//     *      with the given e
+//     *   3. (unprocessed digits + e) > 0 indicates that the value is
+//     *      simply too big to be stored as a double, so return Infinity
+//     */
+//    if( ( unprocessedDigits = strlen (s) ) > 0 ) {
+//
+//        e += unprocessedDigits;
+//        if( index > -1 ) {
+//
+//            if (e == 0) {
+//                result = toDoubleHighPrecision (f, index);
+//            }
+//            else if (e < 0) {
+//                result = createDouble1 (env, f, index, e);
+//            } else {
+//                DOUBLE_TO_LONGBITS (result) = INFINITE_LONGBITS;
+//            }
+//        } else {
+//
+//            LOW_I32_FROM_VAR( result ) = -1;
+//            HIGH_I32_FROM_VAR( result ) = -1;
+//        }
+//    } else {
+//
+//        if( index > -1 ) {
+//            if( e == 0 ) {
+//                result = toDoubleHighPrecision( f, index );
+//            } else {
+//                result = createDouble1( env, f, index, e );
+//            } else {
+//                LOW_I32_FROM_VAR( result ) = -1;
+//                HIGH_I32_FROM_VAR( result ) = -1;
+//            }
+//        }
+//    }
+
+    return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+float FloatingPointParser::parseFltImpl( const std::string& value, int exp )
+    throw ( exceptions::NumberFormatException ) {
+
+    return 0.0f;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+FloatingPointParser::StringExponentPair FloatingPointParser::initialParse(
+    const std::string& value, int length ) throw ( exceptions::NumberFormatException
){
+
+    std::string newValue = value;
+    bool negative = false;
+    char c;
+    int start = 0;
+    int end = 0;
+    int decimal = 0;
+    int e = 0;
+
+    if( length == 0 ) {
+        throw exceptions::NumberFormatException(
+            __FILE__, __LINE__,
+            "FloatingPointParser::initialParse - Invalid zero length string");
+    }
+
+    c = newValue[length - 1];
+    if( c == 'D' || c == 'd' || c == 'F' || c == 'f') {
+        length--;
+        if( length == 0 ) {
+            throw exceptions::NumberFormatException(
+                __FILE__, __LINE__,
+                "FloatingPointParser::initialParse - Invalid zero length string");
+        }
+    }
+
+    end = Math::max( (int)newValue.find_first_of( 'E' ),
+                     (int)newValue.find_first_of( 'e' ) );
+
+    if( end > -1 ) {
+
+        if( end + 1 == length ) {
+            if( length == 0 ) {
+                throw exceptions::NumberFormatException(
+                    __FILE__, __LINE__,
+                    "FloatingPointParser::initialParse - Invalid no data after e",
+                    newValue.c_str() );
+            }
+        }
+
+        int exponent_offset = end + 1;
+
+        if( newValue[exponent_offset] == '+' ) {
+            if( newValue[exponent_offset + 1] == '-' ) {
+                if( length == 0 ) {
+                    throw exceptions::NumberFormatException(
+                        __FILE__, __LINE__,
+                        "FloatingPointParser::initialParse - "
+                        "Invalid length string");
+                }
+            }
+            exponent_offset++; // skip the plus sign
+        }
+
+        try {
+            e = Integer::parseInt( newValue.substr( exponent_offset, length ) );
+        } catch( exceptions::NumberFormatException ex ) {
+            // ex contains the exponent substring only so throw a
+            // new exception with the correct string
+            throw exceptions::NumberFormatException(
+                __FILE__, __LINE__,
+                "FloatingPointParser::initialParse - "
+                "exponent string is not valid" );
+        }
+
+    } else {
+        end = length;
+    }
+
+    if( length == 0 ) {
+        throw exceptions::NumberFormatException(
+            __FILE__, __LINE__,
+            "FloatingPointParser::initialParse - "
+            "invalid length string", newValue.c_str() );
+    }
+
+    c = newValue[start];
+
+    if( c == '-') {
+        ++start;
+        --length;
+        negative = true;
+    } else if( c == '+' ) {
+        ++start;
+        --length;
+    }
+
+    if( length == 0 ) {
+        throw exceptions::NumberFormatException(
+            __FILE__, __LINE__,
+            "FloatingPointParser::initialParse - "
+            "invalid length string", newValue.c_str() );
+    }
+
+    decimal = newValue.find_first_of( '.' );
+    if( decimal > -1 ) {
+        e -= end - decimal - 1;
+        newValue = newValue.substr( start, decimal ) + newValue.substr( decimal + 1, end
);
+    } else {
+        newValue = newValue.substr( start, end );
+    }
+
+    if( ( length = newValue.length() ) == 0 ) {
+        throw exceptions::NumberFormatException(
+            __FILE__, __LINE__,
+            "FloatingPointParser::initialParse - "
+            "invalid length string", newValue.c_str() );
+    }
+
+    end = length;
+    while( end > 1 && newValue[end - 1] == '0' ) {
+        --end;
+    }
+
+    start = 0;
+    while( start < end - 1 && newValue[start] == '0' ) {
+        start++;
+    }
+
+    if( end != length || start != 0 ) {
+        e += length - end;
+        newValue = newValue.substr( start, end );
+    }
+
+    return StringExponentPair( newValue, e, negative );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+double FloatingPointParser::parseDblName(
+    const std::string& namedDouble, int length )
+        throw( exceptions::NumberFormatException ) {
+
+    // Valid strings are only +Nan, NaN, -Nan, +Infinity, Infinity,
+    // -Infinity.
+    if( (length != 3) && ( length != 4) && ( length != 8) && ( length
!= 9 ) ) {
+        throw exceptions::NumberFormatException(
+            __FILE__, __LINE__,
+            "FloatingPointParser::parseDblName - "
+            "invalid name string", namedDouble.c_str() );
+    }
+
+    bool negative = namedDouble.at(0) == '-' ? true : false;
+
+    if( namedDouble.find_first_of( "Infinity" ) != string::npos ) {
+        return negative ? Double::NEGATIVE_INFINITY : Float::POSITIVE_INFINITY;
+    }
+
+    if( namedDouble.find_first_of( "NaN" ) != string::npos ) {
+        return Double::NaN;
+    }
+
+    throw exceptions::NumberFormatException(
+        __FILE__, __LINE__,
+        "FloatingPointParser::parseDblName - "
+        "invalid name string", namedDouble.c_str() );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+float FloatingPointParser::parseFltName(
+    const std::string& namedFloat, int length )
+        throw( exceptions::NumberFormatException ) {
+
+    // Valid strings are only +Nan, NaN, -Nan, +Infinity, Infinity,
+    // -Infinity.
+    if( ( length != 3 ) && ( length != 4 ) && ( length != 8 ) &&
( length != 9 ) ) {
+        throw exceptions::NumberFormatException(
+            __FILE__, __LINE__,
+            "FloatingPointParser::parseFltName - "
+            "invalid name string", namedFloat.c_str() );
+    }
+
+    bool negative = namedFloat.at(0) == '-' ? true : false;
+
+    if( namedFloat.find_first_of( "Infinitiy" ) != string::npos ) {
+        return negative ? Float::NEGATIVE_INFINITY : Float::POSITIVE_INFINITY;
+    }
+
+    if( namedFloat.find_first_of( "NaN" ) != string::npos ) {
+        return Float::NaN;
+    }
+
+    throw exceptions::NumberFormatException(
+        __FILE__, __LINE__,
+        "FloatingPointParser::parseFltName - "
+        "invalid name string", namedFloat.c_str() );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+double FloatingPointParser::parseDouble( const std::string& value )
+    throw( exceptions::NumberFormatException ) {
+
+    std::string newValue = value;
+    FloatingPointParser::trim( newValue );
+    int length = newValue.length();
+
+    if( length == 0 ) {
+        throw exceptions::NumberFormatException(
+            __FILE__, __LINE__,
+            "FloatingPointParser::parseDouble - "
+            "invalid length string", value.c_str() );
+    }
+
+    // See if this could be a named double
+    char last = newValue[length - 1];
+
+    if( (last == 'y') || (last == 'N') ) {
+        return parseDblName( newValue, length );
+    }
+
+    // See if it could be a hexadecimal representation
+    if( toLowerCase( newValue ).find_first_of( "0x" ) != string::npos ) {
+        return HexStringParser::parseDouble(value);
+    }
+
+    StringExponentPair info = initialParse(value, length);
+
+    double result = parseDblImpl( info.value, info.exp );
+
+    if( info.negative ) {
+        result = -result;
+    }
+
+    return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+float FloatingPointParser::parseFloat( const std::string& value )
+    throw( exceptions::NumberFormatException ) {
+
+    std::string newValue = value;
+    FloatingPointParser::trim( newValue );
+
+    int length = newValue.length();
+
+    if( length == 0 ) {
+        throw exceptions::NumberFormatException(
+            __FILE__, __LINE__,
+            "FloatingPointParser::parseFloat - "
+            "invalid length string", value.c_str() );
+    }
+
+    // See if this could be a named float
+    char last = newValue[length - 1];
+    if( (last == 'y') || (last == 'N') ) {
+        return parseFltName( value, length );
+    }
+
+    // See if it could be a hexadecimal representation
+    if( toLowerCase( newValue ).find_first_of( "0x" ) != string::npos ) {
+        return HexStringParser::parseFloat( newValue );
+    }
+
+    StringExponentPair info = initialParse( newValue, length );
+
+    float result = parseFltImpl( info.value, info.exp );
+    if( info.negative ) {
+        result = -result;
+    }
+
+    return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+std::string& FloatingPointParser::trim( std::string& value ) {
+
+    char const* delims = " \t\r\n";
+
+    // trim leading whitespace
+    string::size_type notwhite = value.find_first_not_of( delims );
+    value.erase( 0, notwhite );
+
+    // trim trailing whitespace
+    notwhite = value.find_last_not_of( delims );
+    value.erase( notwhite+1 );
+
+    return value;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+std::string& FloatingPointParser::toLowerCase( std::string& value ) {
+
+    string::size_type index = 0;
+
+    for( ; index < value.size(); ++index ) {
+        if( Character::isLetter( value[index] ) ) {
+            value[index] = apr_tolower( value[index] );
+        }
+    }
+
+    return value;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+unsigned int FloatingPointParser::simpleAppendDecimalDigitHighPrecision(
+    LONG_UNION* arg1, int length, unsigned long long digit )
+{
+    // assumes digit is less than 32 bits
+    unsigned long long arg;
+    IDATA index = 0;
+
+    digit <<= 32;
+
+    do {
+        arg = LOW_IN_U64 (arg1[index]);
+        digit = HIGH_IN_U64 (digit) + TIMES_TEN (arg);
+        LOW_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (digit);
+
+        arg = HIGH_IN_U64 (arg1[index]);
+        digit = HIGH_IN_U64 (digit) + TIMES_TEN (arg);
+        HIGH_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (digit);
+    }
+    while( ++index < length );
+
+    return HIGH_U32_FROM_VAR( digit );
+}

Added: activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/FloatingPointParser.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/FloatingPointParser.h?view=auto&rev=563092
==============================================================================
--- activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/FloatingPointParser.h
(added)
+++ activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/FloatingPointParser.h
Mon Aug  6 03:17:04 2007
@@ -0,0 +1,164 @@
+/*
+ *  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_FLOATINGPOINTPARSER_H_
+#define _DECAF_INTERNAL_UTIL_FLOATINGPOINTPARSER_H_
+
+#include <decaf/util/Config.h>
+#include <decaf/lang/exceptions/NumberFormatException.h>
+#include <string>
+
+namespace decaf{
+namespace internal{
+namespace util{
+
+    /**
+     * Used to parse a string and return either a single or double precision
+     * floating point number.
+     */
+    class FloatingPointParser {
+    private:
+
+        class StringExponentPair {
+        public:
+
+            std::string value;
+            int exp;
+            bool negative;
+
+            StringExponentPair( const std::string value, int exp, bool negative ) {
+                this->value = value;
+                this->exp = exp;
+                this->negative = negative;
+            }
+        };
+
+        // Used to make masking easier
+        typedef union {
+            unsigned long long longValue;
+            unsigned int intValue[2];
+            double doubleValue;
+        } LONG_UNION;
+
+    public:
+
+        virtual ~FloatingPointParser() {}
+
+    public:
+
+        /**
+         * Returns the closest double value to the real number in the string.
+         * @param value - the String that will be parsed to a floating point
+         * @return the double closest to the real number
+         * @exception NumberFormatException if value is not a valid Number
+         */
+        static double parseDouble( const std::string& value )
+            throw ( lang::exceptions::NumberFormatException );
+
+        /**
+         * Returns the closest float value to the real number in the string.
+         * @param value - the String that will be parsed to a floating point
+         * @return the float closest to the real number
+         * @exception NumberFormatException if value is not a valid Number
+         */
+        static float parseFloat( const std::string& value )
+            throw ( lang::exceptions::NumberFormatException );
+
+    private:
+
+        /**
+         * Takes a String and an integer exponent. The String should hold a positive
+         * integer value (or zero). The exponent will be used to calculate the
+         * floating point number by taking the positive integer the String
+         * represents and multiplying by 10 raised to the power of the of the
+         * exponent. Returns the closest double value to the real number
+         * @param value - the String that will be parsed to a floating point
+         * @param exp - an int represent the 10 to part
+         * @return the double closest to the real number
+         * @exception NumberFormatException if string isn't a valid number
+         */
+        static double parseDblImpl( const std::string& value, int exp )
+            throw ( lang::exceptions::NumberFormatException );
+
+        /**
+         * Takes a String and an integer exponent. The String should hold a positive
+         * integer value (or zero). The exponent will be used to calculate the
+         * floating point number by taking the positive integer the String
+         * represents and multiplying by 10 raised to the power of the of the
+         * exponent. Returns the closest float value to the real number
+         * @param value - the String that will be parsed to a floating point
+         * @param exp - an int represent the 10 to part
+         * @return the float closest to the real number
+         * @exception NumberFormatException fi the string is not a valid number
+         */
+        static float parseFltImpl( const std::string& value, int exp )
+            throw ( lang::exceptions::NumberFormatException );
+
+        /**
+         * Takes a String and does some initial parsing. Should return a
+         * StringExponentPair containing a String with no leading or trailing white
+         * space and trailing zeroes eliminated. The exponent of the
+         * StringExponentPair will be used to calculate the floating point number by
+         * taking the positive integer the String represents and multiplying by 10
+         * raised to the power of the of the exponent.
+         * @param value - the String that will be parsed to a floating point
+         * @param length - the length of s
+         * @return a StringExponentPair with necessary values
+         * @exception NumberFormatException
+         */
+        static StringExponentPair initialParse( const std::string& value, int length
)
+            throw ( lang::exceptions::NumberFormatException );
+
+        /*
+         * Assumes the string is trimmed.
+         * @param value - the String that will be parsed to a floating point
+         * @param length - the length of s
+         * @return the parsed double
+         * @exception NumberFormatException
+         */
+        static double parseDblName( const std::string& namedDouble, int length )
+            throw ( lang::exceptions::NumberFormatException );
+
+        /*
+         * Assumes the string is trimmed.
+         * @param value - the String that will be parsed to a floating point
+         * @param length - the length of s
+         * @return the parsed double
+         * @exception NumberFormatException
+         */
+        static float parseFltName( const std::string& namedFloat, int length )
+            throw ( lang::exceptions::NumberFormatException );
+
+        /**
+         * Trims the leading and trailing whitespace from a string
+         * @param value - reference to the string to trim
+         * @param returns a reference to the string passed for chaining
+         */
+        static std::string& trim( std::string& value );
+
+        /**
+         * Turns all letters in the string into lowercase.
+         * @param value - reference to the string to trim
+         * @param returns a reference to the string passed for chaining
+         */
+        static std::string& toLowerCase( std::string& value );
+
+    };
+
+}}}
+
+#endif /*_DECAF_INTERNAL_UTIL_FLOATINGPOINTPARSER_H_*/

Added: activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/HexStringParser.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/HexStringParser.cpp?view=auto&rev=563092
==============================================================================
--- activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/HexStringParser.cpp
(added)
+++ activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/HexStringParser.cpp
Mon Aug  6 03:17:04 2007
@@ -0,0 +1,294 @@
+/*
+ *  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.
+ */
+
+#include "HexStringParser.h"
+
+#include <decaf/lang/Character.h>
+#include <decaf/lang/Integer.h>
+#include <decaf/lang/Long.h>
+#include <decaf/lang/Double.h>
+#include <decaf/lang/Float.h>
+#include <decaf/lang/exceptions/NumberFormatException.h>
+
+using namespace decaf;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+using namespace decaf::internal;
+using namespace decaf::internal::util;
+
+////////////////////////////////////////////////////////////////////////////////
+const std::string HexStringParser::HEX_SIGNIFICANT =
+    "0[xX](\\p{XDigit}+\\.?|\\p{XDigit}*\\.\\p{XDigit}+)";
+const std::string HexStringParser::BINARY_EXPONENT =
+    "[pP]([+-]?\\d+)";
+const std::string HexStringParser::FLOAT_TYPE_SUFFIX =
+    "[fFdD]?";
+const std::string HexStringParser::HEX_PATTERN =
+    "[\\x00-\\x20]*([+-]?)" + HEX_SIGNIFICANT + BINARY_EXPONENT + FLOAT_TYPE_SUFFIX + "[\\x00-\\x20]*";
+
+////////////////////////////////////////////////////////////////////////////////
+HexStringParser::HexStringParser( int exponentWidth, int mantissaWidth ) {
+
+    this->EXPONENT_WIDTH = exponentWidth;
+    this->MANTISSA_WIDTH = mantissaWidth;
+
+    this->EXPONENT_BASE = ~( -1 << (exponentWidth - 1) );
+    this->MAX_EXPONENT = ~( -1 << exponentWidth );
+    this->MIN_EXPONENT = -( MANTISSA_WIDTH + 1 );
+    this->MANTISSA_MASK = ~( -1 << mantissaWidth );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+double HexStringParser::parseDouble( const std::string& hexString ) {
+
+    HexStringParser parser( DOUBLE_EXPONENT_WIDTH, DOUBLE_MANTISSA_WIDTH );
+    long long result = parser.parse( hexString );
+    return Double::longBitsToDouble( result );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+float HexStringParser::parseFloat( const std::string& hexString ) {
+
+    HexStringParser parser( FLOAT_EXPONENT_WIDTH, FLOAT_MANTISSA_WIDTH );
+    int result = (int)parser.parse( hexString );
+    return Float::intBitsToFloat( result );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+long long HexStringParser::parse( const std::string& hexString ) {
+
+    std::string* hexSegments = getSegmentsFromHexString( hexString );
+    std::string signStr = hexSegments[0];
+    std::string significantStr = hexSegments[1];
+    std::string exponentStr = hexSegments[2];
+    delete hexSegments;
+
+    parseHexSign( signStr );
+    parseExponent( exponentStr );
+    parseMantissa( significantStr );
+
+    sign <<= ( MANTISSA_WIDTH + EXPONENT_WIDTH );
+    exponent <<= MANTISSA_WIDTH;
+    return sign | exponent | mantissa;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+std::string* HexStringParser::getSegmentsFromHexString( const std::string& hexString
) {
+
+    // TODO
+//    Matcher matcher = PATTERN.matcher(hexString);
+//    if( !matcher.matches() ) {
+//        throw NumberFormatException(
+//            __FILE__, __LINE__,
+//            "HexStringParser::getSegmentsFromHexString"
+//            "Invalid hex string:", hexString.c_str() );
+//    }
+//
+//    std::string* hexSegments = new std::string[3];
+//    hexSegments[0] = matcher.group(1);
+//    hexSegments[1] = matcher.group(2);
+//    hexSegments[2] = matcher.group(3);
+//
+//    return hexSegments;
+
+    return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HexStringParser::parseExponent(const std::string& exponentStr) {
+
+    std::string newExponentStr = exponentStr;
+
+    char leadingChar = newExponentStr.at(0);
+    int expSign = ( leadingChar == '-' ? -1 : 1 );
+    if( !Character::isDigit( leadingChar ) ) {
+        newExponentStr = newExponentStr.substr( 1, newExponentStr.size() );
+    }
+
+    try {
+        exponent = expSign * Long::parseLong( exponentStr );
+        checkedAddExponent( EXPONENT_BASE );
+    } catch( exceptions::NumberFormatException& e ) {
+        exponent = expSign * Long::MAX_VALUE;
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HexStringParser::parseMantissa(const std::string& significantStr) {
+
+    //TODO
+    std::string* strings = significantStr.split("\\.");
+    std::string strIntegerPart = strings[0];
+    std::string strDecimalPart = strings.length > 1 ? strings[1] : "";
+
+    std::string significand =
+        getNormalizedSignificand( strIntegerPart, strDecimalPart) ;
+
+    if( significand == "0" ) {
+        setZero();
+        return;
+    }
+
+    int offset = getOffset( strIntegerPart, strDecimalPart );
+    checkedAddExponent( offset );
+
+    if( exponent >= MAX_EXPONENT ) {
+        setInfinite();
+        return;
+    }
+
+    if( exponent <= MIN_EXPONENT ) {
+        setZero();
+        return;
+    }
+
+    if( significand.length() > MAX_SIGNIFICANT_LENGTH ) {
+        abandonedNumber = significand.substr( MAX_SIGNIFICANT_LENGTH );
+        significand = significand.substr( 0, MAX_SIGNIFICANT_LENGTH );
+    }
+
+    mantissa = Long::parseLong( significand, HEX_RADIX );
+
+    if( exponent >= 1 ) {
+        processNormalNumber();
+    } else{
+        processSubNormalNumber();
+    }
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HexStringParser::checkedAddExponent( long long offset ) {
+
+    long long result = exponent + offset;
+    int expSign = Long::signum( exponent );
+
+    if( expSign * Long::signum( offset ) > 0 &&
+        expSign * Long::signum( result ) < 0 ) {
+
+        exponent = expSign * Long::MAX_VALUE;
+    } else {
+        exponent = result;
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HexStringParser::processNormalNumber() {
+    int desiredWidth = MANTISSA_WIDTH + 2;
+    fitMantissaInDesiredWidth( desiredWidth );
+    round();
+    mantissa = mantissa & MANTISSA_MASK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HexStringParser::processSubNormalNumber() {
+    int desiredWidth = MANTISSA_WIDTH + 1;
+    desiredWidth += (int)exponent;//lends bit from mantissa to exponent
+    exponent = 0;
+    fitMantissaInDesiredWidth( desiredWidth );
+    round();
+    mantissa = mantissa & MANTISSA_MASK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HexStringParser::fitMantissaInDesiredWidth(int desiredWidth){
+    int bitLength = countBitsLength( mantissa );
+    if( bitLength > desiredWidth ) {
+        discardTrailingBits( bitLength - desiredWidth );
+    } else {
+        mantissa <<= ( desiredWidth - bitLength );
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HexStringParser::discardTrailingBits( long long num ) {
+    long long mask = ~( -1L << num );
+    abandonedNumber += ( mantissa & mask );
+    mantissa >>= 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 HexStringParser::round() {
+    std::string result = abandonedNumber.replaceAll( "0+", "" );
+    bool moreThanZero = ( result.length() > 0 ? true : false );
+
+    int lastDiscardedBit = (int)( mantissa & 1L );
+    mantissa >>= 1;
+    int tailBitInMantissa = (int)( mantissa & 1L );
+
+    if( lastDiscardedBit == 1 && ( moreThanZero || tailBitInMantissa == 1 ) ) {
+
+        int oldLength = countBitsLength( mantissa );
+        mantissa += 1L;
+        int newLength = countBitsLength( mantissa );
+
+        //Rounds up to exponent when whole bits of mantissa are one-bits.
+        if( oldLength >= MANTISSA_WIDTH && newLength > oldLength ) {
+            checkedAddExponent( 1 );
+        }
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+std::string HexStringParser::getNormalizedSignificand(
+    const std::string& strIntegerPart, const std::string& strDecimalPart ) {
+
+    std::string significand = strIntegerPart + strDecimalPart;
+    significand = significand.replaceFirst( "^0+", "" );
+    if( significand.length() == 0 ) {
+        significand = "0"; //$NON-NLS-1$
+    }
+    return significand;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int HexStringParser::getOffset(
+    const std::string& strIntegerPart, const std::string& strDecimalPart ) {
+
+    strIntegerPart = strIntegerPart.replaceFirst( "^0+", "" );
+
+    //If the Interger part is a nonzero number.
+    if( strIntegerPart.length() != 0 ) {
+        std::string leadingNumber = strIntegerPart.substr( 0, 1 );
+        return ( strIntegerPart.length() - 1) * 4 +
+               countBitsLength(Long::parseLong( leadingNumber,HEX_RADIX ) ) - 1;
+    }
+
+    //If the Interger part is a zero number.
+    int i;
+    for( i = 0; i < strDecimalPart.length() && strDecimalPart.at(i) == '0'; i++
);
+
+    if( i == strDecimalPart.length() ) {
+        return 0;
+    }
+
+    std::string leadingNumber = strDecimalPart.substr( i,i + 1 );
+
+    return (-i - 1) * 4 +
+        countBitsLength( Long::parseLong( leadingNumber, HEX_RADIX) ) - 1;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int HexStringParser::countBitsLength(long long value) {
+    int leadingZeros = Long::numberOfLeadingZeros( value );
+    return Long::SIZE - leadingZeros;
+}

Added: activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/HexStringParser.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/HexStringParser.h?view=auto&rev=563092
==============================================================================
--- activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/HexStringParser.h (added)
+++ activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/HexStringParser.h Mon
Aug  6 03:17:04 2007
@@ -0,0 +1,184 @@
+/*
+ *  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 EXPONENT_BASE;
+        long MAX_EXPONENT;
+        long MIN_EXPONENT;
+        long MANTISSA_MASK;
+        long sign;
+        long exponent;
+        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
+         * @returns 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 lowercase 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
+         * @returns the parsed double value
+         */
+        static double parseDouble( const std::string& hexString );
+
+        /*
+         * Parses the hex string to a float number.
+         * @param hexString - string to parse
+         * @returns 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
+         * @returns array of three strings holding the segments caller owns
+         */
+        static std::string* getSegmentsFromHexString( const std::string& hexString );
+
+    };
+
+}}}
+
+#endif /*_DECAF_INTERNAL_UTIL_HEXSTRINGPARSER_H_*/



Mime
View raw message