1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller ( mueller@kde.org )
5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
6 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 *
23 */
24
25 #include "config.h"
26 #include "Length.h"
27
28 #include "PlatformString.h"
29 #include "StringBuffer.h"
30 #include <wtf/ASCIICType.h>
31 #include <wtf/Assertions.h>
32
33 using namespace WTF;
34
35 namespace WebCore {
36
parseLength(const UChar * data,unsigned length)37 static Length parseLength(const UChar* data, unsigned length)
38 {
39 if (length == 0)
40 return Length(1, Relative);
41
42 unsigned i = 0;
43 while (i < length && isSpaceOrNewline(data[i]))
44 ++i;
45 if (i < length && (data[i] == '+' || data[i] == '-'))
46 ++i;
47 while (i < length && isASCIIDigit(data[i]))
48 ++i;
49 unsigned intLength = i;
50 while (i < length && (isASCIIDigit(data[i]) || data[i] == '.'))
51 ++i;
52 unsigned doubleLength = i;
53
54 // IE quirk: Skip whitespace between the number and the % character (20 % => 20%).
55 while (i < length && isSpaceOrNewline(data[i]))
56 ++i;
57
58 bool ok;
59 UChar next = (i < length) ? data[i] : ' ';
60 if (next == '%') {
61 // IE quirk: accept decimal fractions for percentages.
62 double r = charactersToDouble(data, doubleLength, &ok);
63 if (ok)
64 return Length(r, Percent);
65 return Length(1, Relative);
66 }
67 int r = charactersToIntStrict(data, intLength, &ok);
68 if (next == '*') {
69 if (ok)
70 return Length(r, Relative);
71 return Length(1, Relative);
72 }
73 if (ok)
74 return Length(r, Fixed);
75 return Length(0, Relative);
76 }
77
countCharacter(const UChar * data,unsigned length,UChar character)78 static int countCharacter(const UChar* data, unsigned length, UChar character)
79 {
80 int count = 0;
81 for (int i = 0; i < static_cast<int>(length); ++i)
82 count += data[i] == character;
83 return count;
84 }
85
newCoordsArray(const String & string,int & len)86 Length* newCoordsArray(const String& string, int& len)
87 {
88 unsigned length = string.length();
89 const UChar* data = string.characters();
90 StringBuffer spacified(length);
91 for (unsigned i = 0; i < length; i++) {
92 UChar cc = data[i];
93 if (cc > '9' || (cc < '0' && cc != '-' && cc != '*' && cc != '.'))
94 spacified[i] = ' ';
95 else
96 spacified[i] = cc;
97 }
98 RefPtr<StringImpl> str = StringImpl::adopt(spacified);
99
100 str = str->simplifyWhiteSpace();
101
102 len = countCharacter(str->characters(), str->length(), ' ') + 1;
103 Length* r = new Length[len];
104
105 int i = 0;
106 int pos = 0;
107 int pos2;
108
109 while ((pos2 = str->find(' ', pos)) != -1) {
110 r[i++] = parseLength(str->characters() + pos, pos2 - pos);
111 pos = pos2+1;
112 }
113 r[i] = parseLength(str->characters() + pos, str->length() - pos);
114
115 ASSERT(i == len - 1);
116
117 return r;
118 }
119
newLengthArray(const String & string,int & len)120 Length* newLengthArray(const String& string, int& len)
121 {
122 RefPtr<StringImpl> str = string.impl()->simplifyWhiteSpace();
123 if (!str->length()) {
124 len = 1;
125 return 0;
126 }
127
128 len = countCharacter(str->characters(), str->length(), ',') + 1;
129 Length* r = new Length[len];
130
131 int i = 0;
132 int pos = 0;
133 int pos2;
134
135 while ((pos2 = str->find(',', pos)) != -1) {
136 r[i++] = parseLength(str->characters() + pos, pos2 - pos);
137 pos = pos2+1;
138 }
139
140 ASSERT(i == len - 1);
141
142 // IE Quirk: If the last comma is the last char skip it and reduce len by one.
143 if (str->length()-pos > 0)
144 r[i] = parseLength(str->characters() + pos, str->length() - pos);
145 else
146 len--;
147
148 return r;
149 }
150
151 } // namespace WebCore
152