1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2008 by Sun Microsystems, Inc. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * $RCSfile: table.hxx,v $ 10 * $Revision: 1.35 $ 11 * 12 * This file is part of OpenOffice.org. 13 * 14 * OpenOffice.org is free software: you can redistribute it and/or modify 15 * it under the terms of the GNU Lesser General Public License version 3 16 * only, as published by the Free Software Foundation. 17 * 18 * OpenOffice.org is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU Lesser General Public License version 3 for more details 22 * (a copy is included in the LICENSE file that accompanied this code). 23 * 24 * You should have received a copy of the GNU Lesser General Public License 25 * version 3 along with OpenOffice.org. If not, see 26 * <http://www.openoffice.org/license.html> 27 * for a copy of the LGPLv3 License. 28 * 29 ************************************************************************/ 30 31 // MARKER(update_precomp.py): autogen include statement, do not remove 32 #include "precompiled_sc.hxx" 33 34 // System - Includes ----------------------------------------------------- 35 36 #include "stringutil.hxx" 37 #include "rtl/ustrbuf.hxx" 38 #include "rtl/math.hxx" 39 40 using ::rtl::OUString; 41 using ::rtl::OUStringBuffer; 42 43 bool ScStringUtil::parseSimpleNumber( 44 const OUString& rStr, sal_Unicode dsep, sal_Unicode gsep, double& rVal) 45 { 46 if (gsep == 0x00A0) 47 // unicode space to ascii space 48 gsep = 0x0020; 49 50 OUStringBuffer aBuf; 51 sal_Int32 n = rStr.getLength(); 52 const sal_Unicode* p = rStr.getStr(); 53 sal_Int32 nPosDSep = -1, nPosGSep = -1; 54 sal_uInt32 nDigitCount = 0; 55 56 for (sal_Int32 i = 0; i < n; ++i) 57 { 58 sal_Unicode c = p[i]; 59 if (c == 0x00A0) 60 // unicode space to ascii space 61 c = 0x0020; 62 63 if (sal_Unicode('0') <= c && c <= sal_Unicode('9')) 64 { 65 // this is a digit. 66 aBuf.append(c); 67 ++nDigitCount; 68 } 69 else if (c == dsep) 70 { 71 // this is a decimal separator. 72 73 if (nPosDSep >= 0) 74 // a second decimal separator -> not a valid number. 75 return false; 76 77 if (nPosGSep >= 0 && i - nPosGSep != 4) 78 // the number has a group separator and the decimal sep is not 79 // positioned correctly. 80 return false; 81 82 nPosDSep = i; 83 nPosGSep = -1; 84 aBuf.append(c); 85 nDigitCount = 0; 86 } 87 else if (c == gsep) 88 { 89 // this is a group (thousand) separator. 90 91 if (i == 0) 92 // not allowed as the first character. 93 return false; 94 95 if (nPosDSep >= 0) 96 // not allowed after the decimal separator. 97 return false; 98 99 if (nPosGSep >= 0 && nDigitCount != 3) 100 // must be exactly 3 digits since the last group separator. 101 return false; 102 103 nPosGSep = i; 104 nDigitCount = 0; 105 } 106 else if (c == sal_Unicode('-') || c == sal_Unicode('+')) 107 { 108 // A sign must be the first character if it's given. 109 if (i == 0) 110 aBuf.append(c); 111 else 112 return false; 113 } 114 else 115 return false; 116 } 117 118 // finished parsing the number. 119 120 if (nPosGSep >= 0 && nDigitCount != 3) 121 // must be exactly 3 digits since the last group separator. 122 return false; 123 124 rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok; 125 sal_Int32 nParseEnd = 0; 126 rVal = ::rtl::math::stringToDouble(aBuf.makeStringAndClear(), dsep, gsep, &eStatus, &nParseEnd); 127 if (eStatus != rtl_math_ConversionStatus_Ok) 128 return false; 129 130 return true; 131 } 132