1/* 2 * Copyright (C) 2003, 2006, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 27#include "config.h" 28#include "CString.h" 29 30#include <string.h> 31 32using namespace std; 33 34namespace WTF { 35 36PassRefPtr<CStringBuffer> CStringBuffer::createUninitialized(size_t length) 37{ 38 RELEASE_ASSERT(length < (numeric_limits<unsigned>::max() - sizeof(CStringBuffer))); 39 40 // The +1 is for the terminating NUL character. 41 size_t size = sizeof(CStringBuffer) + length + 1; 42 CStringBuffer* stringBuffer = static_cast<CStringBuffer*>(fastMalloc(size)); 43 return adoptRef(new (NotNull, stringBuffer) CStringBuffer(length)); 44} 45 46CString::CString(const char* str) 47{ 48 if (!str) 49 return; 50 51 init(str, strlen(str)); 52} 53 54CString::CString(const char* str, size_t length) 55{ 56 if (!str) { 57 ASSERT(!length); 58 return; 59 } 60 61 init(str, length); 62} 63 64void CString::init(const char* str, size_t length) 65{ 66 ASSERT(str); 67 68 m_buffer = CStringBuffer::createUninitialized(length); 69 memcpy(m_buffer->mutableData(), str, length); 70 m_buffer->mutableData()[length] = '\0'; 71} 72 73char* CString::mutableData() 74{ 75 copyBufferIfNeeded(); 76 if (!m_buffer) 77 return 0; 78 return m_buffer->mutableData(); 79} 80 81CString CString::newUninitialized(size_t length, char*& characterBuffer) 82{ 83 CString result; 84 result.m_buffer = CStringBuffer::createUninitialized(length); 85 char* bytes = result.m_buffer->mutableData(); 86 bytes[length] = '\0'; 87 characterBuffer = bytes; 88 return result; 89} 90 91void CString::copyBufferIfNeeded() 92{ 93 if (!m_buffer || m_buffer->hasOneRef()) 94 return; 95 96 RefPtr<CStringBuffer> buffer = m_buffer.release(); 97 size_t length = buffer->length(); 98 m_buffer = CStringBuffer::createUninitialized(length); 99 memcpy(m_buffer->mutableData(), buffer->data(), length + 1); 100} 101 102bool CString::isSafeToSendToAnotherThread() const 103{ 104 return !m_buffer || m_buffer->hasOneRef(); 105} 106 107bool operator==(const CString& a, const CString& b) 108{ 109 if (a.isNull() != b.isNull()) 110 return false; 111 if (a.length() != b.length()) 112 return false; 113 return !memcmp(a.data(), b.data(), a.length()); 114} 115 116bool operator==(const CString& a, const char* b) 117{ 118 if (a.isNull() != !b) 119 return false; 120 if (!b) 121 return true; 122 return !strcmp(a.data(), b); 123} 124 125} // namespace WTF 126