📄 cqlutilities.cpp
字号:
//%2006//////////////////////////////////////////////////////////////////////////// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;// IBM Corp.; EMC Corporation, The Open Group.// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;// EMC Corporation; VERITAS Software Corporation; The Open Group.// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;// EMC Corporation; Symantec Corporation; The Open Group.//// Permission is hereby granted, free of charge, to any person obtaining a copy// of this software and associated documentation files (the "Software"), to// deal in the Software without restriction, including without limitation the// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or// sell copies of the Software, and to permit persons to whom the Software is// furnished to do so, subject to the following conditions:// // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.////==============================================================================//// Authors: David Rosckes (rosckes@us.ibm.com)// Bert Rivero (hurivero@us.ibm.com)// Chuck Carmack (carmack@us.ibm.com)// Brian Lucier (lucier@us.ibm.com)//// Modified By:// David Dillard, VERITAS Software Corp.// (david.dillard@veritas.com)////%/////////////////////////////////////////////////////////////////////////////#include <Pegasus/CQL/CQLUtilities.h>// Query includes#include <Pegasus/Query/QueryCommon/QueryException.h>// Pegasus Common includes#include <Pegasus/Common/Tracer.h>// standard includes#include <errno.h>// symbol defines#define PEGASUS_SINT64_MIN (PEGASUS_SINT64_LITERAL(0x8000000000000000))#define PEGASUS_UINT64_MAX PEGASUS_UINT64_LITERAL(0xFFFFFFFFFFFFFFFF)// required for the windows compile#ifndef _MSC_VER#define _MSC_VER 0#endifPEGASUS_NAMESPACE_BEGINinline Uint8 _CQLUtilities_hexCharToNumeric(Char16 c){ Uint8 n; if (isdigit(c)) n = (c - '0'); else if (isupper(c)) n = (c - 'A' + 10); else // if (islower(c)) n = (c - 'a' + 10); return n;}Uint64 CQLUtilities::stringToUint64(const String &stringNum){ PEG_METHOD_ENTER(TRC_CQL,"CQLUtilities::stringToUint64()"); Uint64 x = 0; const Char16* p = stringNum.getChar16Data(); const Char16* pStart = p; if (String::equal(stringNum, String::EMPTY)) { MessageLoaderParms mload(String("CQL.CQLUtilities.EMPTY_STRING"), String("Error converting string to $0. String cannot be $1."), String("Uint64"), String("empty")); throw CQLRuntimeException(mload); } if (!p) { MessageLoaderParms mload(String("CQL.CQLUtilities.EMPTY_STRING"), String("Error converting string to $0. String cannot be $1."), String("Uint64"), String("NULL")); throw CQLRuntimeException(mload); } // If the string is a real number, use stringToReal, then convert to a Uint64 if (isReal(stringNum)) { // Note: the cast will rip off any non-whole number precision. CQL spec // is silent on whether to round up, round down, throw an error, or allow // the platform to round as it sees fit. We chose the latter for now. return (Uint64) stringToReal64(stringNum); } // There cannot be a negative '-' sign if (*p == '-') { MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_NEG"), String("Error converting string to $0. String '$1' cannot begin with '-'."), String("Uint64"), stringNum); throw CQLRuntimeException(mload); } if (*p == '+') p++; // skip over the positive sign if (!((*p >= '0') && (*p <= '9'))) { MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_NUM_FORMAT"), String("Error converting string to $0. String '$1' is badly formed."), String("Uint64"), stringNum); throw CQLRuntimeException(mload); } // if hexidecimal if ( (*p == '0') && ((p[1] == 'x') || (p[1] == 'X')) ) { // Convert a hexadecimal string // Skip over the "0x" p+=2; // At least one hexadecimal digit is required if (!*p) { MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_HEX_FORMAT"), String("Error converting string to $0. String '$1' needs a hexadecimal digit character following '0x'"), String("Uint64"), stringNum); throw CQLRuntimeException(mload); } // Add on each digit, checking for overflow errors while (isascii(*p) && isxdigit(*p)) { // Make sure we won't overflow when we multiply by 16 if (x > PEGASUS_UINT64_MAX/16) { MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"), String("Error converting string to $0. String '$1' caused an overflow."), String("Uint64"), stringNum); throw CQLRuntimeException(mload); } x = x << 4; // We can't overflow when we add the next digit Uint64 newDigit = Uint64(_CQLUtilities_hexCharToNumeric(*p++)); if (PEGASUS_UINT64_MAX - x < newDigit) { MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"), String("Error converting string to $0. String '$1' caused an overflow."), String("Uint64"), stringNum); throw CQLRuntimeException(mload); } x = x + newDigit; } // If we found a non-hexadecimal digit, report an error if (*p) { MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_HEX_CHAR"), String("Error converting string to $0. Character '$1' in string '$2' is not a hexidecimal digit."), String("Uint64"), String(p, 1), stringNum); throw CQLRuntimeException(mload); } // return value from the hex string PEG_METHOD_EXIT(); return x; } // end if hexidecimal // if binary Uint32 endString = stringNum.size() - 1; if ( (pStart[endString] == 'b') || (pStart[endString] == 'B') ) { // Add on each digit, checking for overflow errors while ((*p == '0') || (*p == '1')) { // Make sure we won't overflow when we multiply by 2 if (x > PEGASUS_UINT64_MAX/2) { MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"), String("Error converting string to $0. String '$1' caused an overflow."), String("Uint64"), stringNum); throw CQLRuntimeException(mload); } x = x << 1; // We can't overflow when we add the next digit Uint64 newDigit = 0; if (*p++ == '1') newDigit = 1; if (PEGASUS_UINT64_MAX - x < newDigit) { MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"), String("Error converting string to $0. String '$1' caused an overflow."), String("Uint64"), stringNum); throw CQLRuntimeException(mload); } x = x + newDigit; } // If we found a non-binary digit before the terminating 'b', then report an error if (*p && (p-pStart < (Sint32)endString || (*p != 'b' && *p != 'B'))) { MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_BIN_CHAR"), String("Error converting string to $0. Character '$1' in string '$2' is not a binary digit."), String("Uint64"), String(p, 1), stringNum); throw CQLRuntimeException(mload); } // return value from the binary string PEG_METHOD_EXIT(); return x; } // end if binary // Expect a positive decimal digit: // Add on each digit, checking for overflow errors while ((*p >= '0') && (*p <= '9')) { // Make sure we won't overflow when we multiply by 10 if (x > PEGASUS_UINT64_MAX/10) { MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"), String("Error converting string to $0. String '$1' caused an overflow."), String("Uint64"), stringNum); throw CQLRuntimeException(mload); } x = 10 * x; // Make sure we won't overflow when we add the next digit Uint64 newDigit = (*p++ - '0'); if (PEGASUS_UINT64_MAX - x < newDigit) { MessageLoaderParms mload(String("CQL.CQLUtilities.OVERFLOW"), String("Error converting string to $0. String '$1' caused an overflow."), String("Uint64"), stringNum); throw CQLRuntimeException(mload); } x = x + newDigit; } // If we found a non-decimal digit, report an error if (*p) { MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_DECIMAL_CHAR"), String("Error converting string to $0. Character '$1' in string '$2' is not a decimal digit."), String("Uint64"), String(p, 1), stringNum); throw CQLRuntimeException(mload); } // return the value for the decimal string PEG_METHOD_EXIT(); return x;}Sint64 CQLUtilities::stringToSint64(const String &stringNum){ PEG_METHOD_ENTER(TRC_CQL,"CQLUtilities::stringToSint64()"); Sint64 x = 0; Boolean invert = false; const Char16* p = stringNum.getChar16Data(); const Char16* pStart = p; if (String::equal(stringNum, String::EMPTY)) { MessageLoaderParms mload(String("CQL.CQLUtilities.EMPTY_STRING"), String("Error converting string to $0. String cannot be $1."), String("Sint64"), String("empty")); throw CQLRuntimeException(mload); } if (!p) { MessageLoaderParms mload(String("CQL.CQLUtilities.EMPTY_STRING"), String("Error converting string to $0. String cannot be $1."), String("Sint64"), String("NULL")); throw CQLRuntimeException(mload); } // If the string is a real number, use stringToReal, then convert to a Sint64 if (isReal(stringNum)) { // Note: the cast will rip off any non-whole number precision. CQL spec // is silent on whether to round up, round down, throw an error, or allow // the platform to round as it sees fit. We chose the latter for now. return (Sint64) stringToReal64(stringNum); } // skip over the sign if there is one if (*p == '-') { invert = true; p++; } if (*p == '+') p++; if (!((*p >= '0') && (*p <= '9'))) { MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_NUM_FORMAT"), String("Error converting string to $0. String '$1' is badly formed."), String("Uint64"), stringNum); throw CQLRuntimeException(mload); } // ******************** // Build the Sint64 as a negative number, regardless of the // eventual sign (negative numbers can be bigger than positive ones) // ******************** // if hexidecimal if ( (*p == '0') && ((p[1] == 'x') || (p[1] == 'X')) ) { // Convert a hexadecimal string // Skip over the "0x" p+=2; // At least one hexidecimal digit is required if (!*p) { MessageLoaderParms mload(String("CQL.CQLUtilities.INVALID_HEX_FORMAT"), String("Error converting string to $0. String '$1' needs a hexadecimal digit character following '0x'."), String("Sint64"), stringNum); throw CQLRuntimeException(mload); } // Add on each digit, checking for overflow errors while (isascii(*p) && isxdigit(*p)) { // Make sure we won't overflow when we multiply by 16
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -