📄 string.cpp
字号:
/* * (C) 1999 Lars Knoll (knoll@kde.org) * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */#include "config.h"#include "PlatformString.h"#include "CString.h"#include "FloatConversion.h"#include "StringBuffer.h"#include "TextEncoding.h"#include <wtf/dtoa.h>#include <limits>#include <stdarg.h>#include <wtf/ASCIICType.h>#include <wtf/StringExtras.h>#include <wtf/Vector.h>#include <wtf/unicode/Unicode.h>#include <wtf/unicode/UTF8.h>#if USE(JSC)using JSC::Identifier;using JSC::UString;#endifusing namespace WTF;using namespace WTF::Unicode;namespace WebCore {String::String(const UChar* str, unsigned len){ if (!str) return; m_impl = StringImpl::create(str, len);}String::String(const UChar* str){ if (!str) return; int len = 0; while (str[len] != UChar(0)) len++; m_impl = StringImpl::create(str, len);}String::String(const char* str){ if (!str) return; m_impl = StringImpl::create(str);}String::String(const char* str, unsigned length){ if (!str) return; m_impl = StringImpl::create(str, length);}void String::append(const String& str){ // FIXME: This is extremely inefficient. So much so that we might want to take this // out of String's API. We can make it better by optimizing the case where exactly // one String is pointing at this StringImpl, but even then it's going to require a // call to fastMalloc every single time. if (str.m_impl) { if (m_impl) { StringBuffer buffer(m_impl->length() + str.length()); memcpy(buffer.characters(), m_impl->characters(), m_impl->length() * sizeof(UChar)); memcpy(buffer.characters() + m_impl->length(), str.characters(), str.length() * sizeof(UChar)); m_impl = StringImpl::adopt(buffer); } else m_impl = str.m_impl; }}void String::append(char c){ // FIXME: This is extremely inefficient. So much so that we might want to take this // out of String's API. We can make it better by optimizing the case where exactly // one String is pointing at this StringImpl, but even then it's going to require a // call to fastMalloc every single time. if (m_impl) { StringBuffer buffer(m_impl->length() + 1); memcpy(buffer.characters(), m_impl->characters(), m_impl->length() * sizeof(UChar)); buffer[m_impl->length()] = c; m_impl = StringImpl::adopt(buffer); } else m_impl = StringImpl::create(&c, 1);}void String::append(UChar c){ // FIXME: This is extremely inefficient. So much so that we might want to take this // out of String's API. We can make it better by optimizing the case where exactly // one String is pointing at this StringImpl, but even then it's going to require a // call to fastMalloc every single time. if (m_impl) { StringBuffer buffer(m_impl->length() + 1); memcpy(buffer.characters(), m_impl->characters(), m_impl->length() * sizeof(UChar)); buffer[m_impl->length()] = c; m_impl = StringImpl::adopt(buffer); } else m_impl = StringImpl::create(&c, 1);}String operator+(const String& a, const String& b){ if (a.isEmpty()) return b; if (b.isEmpty()) return a; String c = a; c += b; return c;}String operator+(const String& s, const char* cs){ return s + String(cs);}String operator+(const char* cs, const String& s){ return String(cs) + s;}void String::insert(const String& str, unsigned pos){ if (str.isEmpty()) { if (str.isNull()) return; if (isNull()) m_impl = str.impl(); return; } insert(str.characters(), str.length(), pos);}void String::append(const UChar* charactersToAppend, unsigned lengthToAppend){ if (!m_impl) { if (!charactersToAppend) return; m_impl = StringImpl::create(charactersToAppend, lengthToAppend); return; } if (!lengthToAppend) return; ASSERT(charactersToAppend); StringBuffer buffer(length() + lengthToAppend); memcpy(buffer.characters(), characters(), length() * sizeof(UChar)); memcpy(buffer.characters() + length(), charactersToAppend, lengthToAppend * sizeof(UChar)); m_impl = StringImpl::adopt(buffer);}void String::insert(const UChar* charactersToInsert, unsigned lengthToInsert, unsigned position){ if (position >= length()) { append(charactersToInsert, lengthToInsert); return; } ASSERT(m_impl); if (!lengthToInsert) return; ASSERT(charactersToInsert); StringBuffer buffer(length() + lengthToInsert); memcpy(buffer.characters(), characters(), position * sizeof(UChar)); memcpy(buffer.characters() + position, charactersToInsert, lengthToInsert * sizeof(UChar)); memcpy(buffer.characters() + position + lengthToInsert, characters() + position, (length() - position) * sizeof(UChar)); m_impl = StringImpl::adopt(buffer);}UChar String::operator[](unsigned i) const{ if (!m_impl || i >= m_impl->length()) return 0; return m_impl->characters()[i];}UChar32 String::characterStartingAt(unsigned i) const{ if (!m_impl || i >= m_impl->length()) return 0; return m_impl->characterStartingAt(i);}unsigned String::length() const{ if (!m_impl) return 0; return m_impl->length();}void String::truncate(unsigned position){ if (position >= length()) return; StringBuffer buffer(position); memcpy(buffer.characters(), characters(), position * sizeof(UChar)); m_impl = StringImpl::adopt(buffer);}void String::remove(unsigned position, int lengthToRemove){ if (lengthToRemove <= 0) return; if (position >= length()) return; if (static_cast<unsigned>(lengthToRemove) > length() - position) lengthToRemove = length() - position; StringBuffer buffer(length() - lengthToRemove); memcpy(buffer.characters(), characters(), position * sizeof(UChar)); memcpy(buffer.characters() + position, characters() + position + lengthToRemove, (length() - lengthToRemove - position) * sizeof(UChar)); m_impl = StringImpl::adopt(buffer);}String String::substring(unsigned pos, unsigned len) const{ if (!m_impl) return String(); return m_impl->substring(pos, len);}String String::substringCopy(unsigned pos, unsigned len) const{ if (!m_impl) return String(); return m_impl->substringCopy(pos, len);}String String::lower() const{ if (!m_impl) return String(); return m_impl->lower();}String String::upper() const{ if (!m_impl) return String(); return m_impl->upper();}String String::stripWhiteSpace() const{ if (!m_impl) return String(); return m_impl->stripWhiteSpace();}String String::simplifyWhiteSpace() const{ if (!m_impl) return String(); return m_impl->simplifyWhiteSpace();}String String::removeCharacters(CharacterMatchFunctionPtr findMatch) const{ if (!m_impl) return String(); return m_impl->removeCharacters(findMatch);}String String::foldCase() const{ if (!m_impl) return String(); return m_impl->foldCase();}bool String::percentage(int& result) const{ if (!m_impl || !m_impl->length()) return false; if ((*m_impl)[m_impl->length() - 1] != '%') return false; result = charactersToIntStrict(m_impl->characters(), m_impl->length() - 1); return true;}const UChar* String::characters() const{ if (!m_impl) return 0; return m_impl->characters();}const UChar* String::charactersWithNullTermination(){ if (!m_impl) return 0; if (m_impl->hasTerminatingNullCharacter()) return m_impl->characters(); m_impl = StringImpl::createWithTerminatingNullCharacter(*m_impl); return m_impl->characters();}String String::format(const char *format, ...){#if PLATFORM(QT) // Use QString::vsprintf to avoid the locale dependent formatting of vsnprintf. // https://bugs.webkit.org/show_bug.cgi?id=18994 va_list args; va_start(args, format); QString buffer; buffer.vsprintf(format, args); va_end(args); return buffer;#else va_list args; va_start(args, format); Vector<char, 256> buffer; // Do the format once to get the length.#if COMPILER(MSVC) int result = _vscprintf(format, args);#else char ch; int result = vsnprintf(&ch, 1, format, args); // We need to call va_end() and then va_start() again here, as the // contents of args is undefined after the call to vsnprintf // according to http://man.cx/snprintf(3) // // Not calling va_end/va_start here happens to work on lots of // systems, but fails e.g. on 64bit Linux. va_end(args); va_start(args, format);#endif if (result == 0) return String(""); if (result < 0) return String(); unsigned len = result; buffer.grow(len + 1); // Now do the formatting again, guaranteed to fit. vsnprintf(buffer.data(), buffer.size(), format, args); va_end(args); return StringImpl::create(buffer.data(), len);#endif}String String::number(short n){ return String::format("%hd", n);}String String::number(unsigned short n){ return String::format("%hu", n);}String String::number(int n){ return String::format("%d", n);}String String::number(unsigned n){ return String::format("%u", n);}String String::number(long n){ return String::format("%ld", n);}String String::number(unsigned long n){ return String::format("%lu", n);}String String::number(long long n){#if PLATFORM(WIN_OS) return String::format("%I64i", n);#else return String::format("%lli", n);#endif}String String::number(unsigned long long n){#if PLATFORM(WIN_OS) return String::format("%I64u", n);#else return String::format("%llu", n);#endif} String String::number(double n){ return String::format("%.6lg", n);}int String::toIntStrict(bool* ok, int base) const
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -