2 * This file is part of the DOM implementation for KDE.
4 * (C) 1999 Lars Knoll (knoll@kde.org)
5 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
24 #include "PlatformString.h"
27 #include "DeprecatedString.h"
28 #include "TextEncoding.h"
29 #include <kjs/identifier.h>
30 #include <wtf/Vector.h>
33 using KJS::Identifier;
38 String::String(const UChar* str, unsigned len)
44 m_impl = StringImpl::empty();
46 m_impl = new StringImpl(str, len);
49 String::String(const UChar* str)
55 while (str[len] != UChar(0))
59 m_impl = StringImpl::empty();
61 m_impl = new StringImpl(str, len);
64 String::String(const DeprecatedString& str)
70 m_impl = StringImpl::empty();
72 m_impl = new StringImpl(reinterpret_cast<const UChar*>(str.unicode()), str.length());
75 String::String(const char* str)
82 m_impl = StringImpl::empty();
84 m_impl = new StringImpl(str, l);
87 String::String(const char* str, unsigned length)
93 m_impl = StringImpl::empty();
95 m_impl = new StringImpl(str, length);
98 void String::append(const String &str)
106 m_impl = m_impl->copy();
107 m_impl->append(str.m_impl.get());
111 void String::append(char c)
114 m_impl = new StringImpl(&c, 1);
116 m_impl = m_impl->copy();
121 void String::append(UChar c)
124 m_impl = new StringImpl(&c, 1);
126 m_impl = m_impl->copy();
131 String operator+(const String& a, const String& b)
142 String operator+(const String& s, const char* cs)
144 return s + String(cs);
147 String operator+(const char* cs, const String& s)
149 return String(cs) + s;
152 void String::insert(const String& str, unsigned pos)
155 m_impl = str.m_impl->copy();
157 m_impl->insert(str.m_impl.get(), pos);
160 UChar String::operator[](unsigned i) const
162 if (!m_impl || i >= m_impl->length())
164 return m_impl->characters()[i];
167 unsigned String::length() const
171 return m_impl->length();
174 void String::truncate(unsigned len)
177 m_impl->truncate(len);
180 void String::remove(unsigned pos, int len)
183 m_impl->remove(pos, len);
186 String String::substring(unsigned pos, unsigned len) const
190 return m_impl->substring(pos, len);
193 String String::split(unsigned pos)
197 return m_impl->split(pos);
200 String String::lower() const
204 return m_impl->lower();
207 String String::upper() const
211 return m_impl->upper();
214 String String::foldCase() const
218 return m_impl->foldCase();
221 bool String::percentage(int& result) const
223 if (!m_impl || !m_impl->length())
226 if ((*m_impl)[m_impl->length() - 1] != '%')
229 result = DeprecatedConstString(reinterpret_cast<const DeprecatedChar*>(m_impl->characters()), m_impl->length() - 1).string().toInt();
233 const UChar* String::characters() const
237 return m_impl->characters();
240 const UChar* String::charactersWithNullTermination()
244 return m_impl->charactersWithNullTermination();
247 DeprecatedString String::deprecatedString() const
250 return DeprecatedString::null;
251 if (!m_impl->characters())
252 return DeprecatedString("", 0);
253 return DeprecatedString(reinterpret_cast<const DeprecatedChar*>(m_impl->characters()), m_impl->length());
256 String String::sprintf(const char *format, ...)
259 va_start(args, format);
261 Vector<char, 256> buffer;
263 // Windows vsnprintf does not return the expected size on overflow
264 // So we just have to keep looping until our vsprintf call works!
268 buffer.resize(buffer.capacity() * 2);
269 result = vsnprintf(buffer.data(), buffer.capacity(), format, args);
270 // Windows vsnprintf returns -1 for both errors. Since there is no
271 // way to distinguish between "not enough room" and "invalid format"
272 // we just keep trying until we hit an arbitrary size and then stop.
273 } while (result < 0 && (buffer.capacity() * 2) < 2048);
278 unsigned len = result;
280 // Do the format once to get the length.
282 int result = vsnprintf(&ch, 1, format, args);
287 unsigned len = result;
288 buffer.resize(len + 1);
290 // Now do the formatting again, guaranteed to fit.
291 vsnprintf(buffer.data(), buffer.size(), format, args);
295 return new StringImpl(buffer.data(), len);
298 String String::number(int n)
300 return String::sprintf("%d", n);
303 String String::number(unsigned n)
305 return String::sprintf("%u", n);
308 String String::number(long n)
310 return String::sprintf("%ld", n);
313 String String::number(unsigned long n)
315 return String::sprintf("%lu", n);
318 String String::number(long long n)
321 return String::sprintf("%I64i", n);
323 return String::sprintf("%lli", n);
327 String String::number(unsigned long long n)
330 return String::sprintf("%I64u", n);
332 return String::sprintf("%llu", n);
336 String String::number(double n)
338 return String::sprintf("%.6lg", n);
341 int String::toInt(bool* ok) const
348 return m_impl->toInt(ok);
351 String String::copy() const
355 return m_impl->copy();
358 bool String::isEmpty() const
360 return !m_impl || !m_impl->length();
363 Length* String::toCoordsArray(int& len) const
365 return m_impl ? m_impl->toCoordsArray(len) : 0;
368 Length* String::toLengthArray(int& len) const
370 return m_impl ? m_impl->toLengthArray(len) : 0;
374 Vector<char> String::ascii() const
377 return m_impl->ascii();
379 const char* nullMsg = "(null impl)";
380 Vector<char> buffer(strlen(nullMsg) + 1);
381 for (int i = 0; nullMsg[i]; ++i) {
382 buffer.append(nullMsg[i]);
389 CString String::latin1() const
391 return TextEncoding(Latin1Encoding).fromUnicode(deprecatedString());
394 CString String::utf8() const
396 return TextEncoding(UTF8Encoding).fromUnicode(deprecatedString());
399 bool operator==(const String& a, const DeprecatedString& b)
401 unsigned l = a.length();
404 if (!memcmp(a.characters(), b.unicode(), l * sizeof(UChar)))
409 String::String(const Identifier& str)
415 m_impl = StringImpl::empty();
417 m_impl = new StringImpl(reinterpret_cast<const UChar*>(str.data()), str.size());
420 String::String(const UString& str)
426 m_impl = StringImpl::empty();
428 m_impl = new StringImpl(reinterpret_cast<const UChar*>(str.data()), str.size());
431 String::operator Identifier() const
435 return Identifier(reinterpret_cast<const KJS::UChar*>(m_impl->characters()), m_impl->length());
438 String::operator UString() const
442 return UString(reinterpret_cast<const KJS::UChar*>(m_impl->characters()), m_impl->length());
445 } // namespace WebCore
448 // For debugging only -- leaks memory
449 WebCore::String* string(const char* s)
451 return new WebCore::String(s);