michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim:set ts=2 sw=2 sts=2 et cindent: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsStringBuffer_h__ michael@0: #define nsStringBuffer_h__ michael@0: michael@0: #include "mozilla/Atomics.h" michael@0: #include "mozilla/MemoryReporting.h" michael@0: michael@0: template struct already_AddRefed; michael@0: michael@0: /** michael@0: * This structure precedes the string buffers "we" allocate. It may be the michael@0: * case that nsTAString::mData does not point to one of these special michael@0: * buffers. The mFlags member variable distinguishes the buffer type. michael@0: * michael@0: * When this header is in use, it enables reference counting, and capacity michael@0: * tracking. NOTE: A string buffer can be modified only if its reference michael@0: * count is 1. michael@0: */ michael@0: class nsStringBuffer michael@0: { michael@0: private: michael@0: friend class CheckStaticAtomSizes; michael@0: michael@0: mozilla::Atomic mRefCount; michael@0: uint32_t mStorageSize; michael@0: michael@0: public: michael@0: michael@0: /** michael@0: * Allocates a new string buffer, with given size in bytes and a michael@0: * reference count of one. When the string buffer is no longer needed, michael@0: * it should be released via Release. michael@0: * michael@0: * It is up to the caller to set the bytes corresponding to the string michael@0: * buffer by calling the Data method to fetch the raw data pointer. Care michael@0: * must be taken to properly null terminate the character array. The michael@0: * storage size can be greater than the length of the actual string michael@0: * (i.e., it is not required that the null terminator appear in the last michael@0: * storage unit of the string buffer's data). michael@0: * michael@0: * @return new string buffer or null if out of memory. michael@0: */ michael@0: static already_AddRefed Alloc(size_t storageSize); michael@0: michael@0: /** michael@0: * Resizes the given string buffer to the specified storage size. This michael@0: * method must not be called on a readonly string buffer. Use this API michael@0: * carefully!! michael@0: * michael@0: * This method behaves like the ANSI-C realloc function. (i.e., If the michael@0: * allocation fails, null will be returned and the given string buffer michael@0: * will remain unmodified.) michael@0: * michael@0: * @see IsReadonly michael@0: */ michael@0: static nsStringBuffer* Realloc(nsStringBuffer* buf, size_t storageSize); michael@0: michael@0: /** michael@0: * Increment the reference count on this string buffer. michael@0: */ michael@0: void NS_FASTCALL AddRef(); michael@0: michael@0: /** michael@0: * Decrement the reference count on this string buffer. The string michael@0: * buffer will be destroyed when its reference count reaches zero. michael@0: */ michael@0: void NS_FASTCALL Release(); michael@0: michael@0: /** michael@0: * This method returns the string buffer corresponding to the given data michael@0: * pointer. The data pointer must have been returned previously by a michael@0: * call to the nsStringBuffer::Data method. michael@0: */ michael@0: static nsStringBuffer* FromData(void* data) michael@0: { michael@0: return reinterpret_cast (data) - 1; michael@0: } michael@0: michael@0: /** michael@0: * This method returns the data pointer for this string buffer. michael@0: */ michael@0: void* Data() const michael@0: { michael@0: return const_cast (reinterpret_cast (this + 1)); michael@0: } michael@0: michael@0: /** michael@0: * This function returns the storage size of a string buffer in bytes. michael@0: * This value is the same value that was originally passed to Alloc (or michael@0: * Realloc). michael@0: */ michael@0: uint32_t StorageSize() const michael@0: { michael@0: return mStorageSize; michael@0: } michael@0: michael@0: /** michael@0: * If this method returns false, then the caller can be sure that their michael@0: * reference to the string buffer is the only reference to the string michael@0: * buffer, and therefore it has exclusive access to the string buffer and michael@0: * associated data. However, if this function returns true, then other michael@0: * consumers may rely on the data in this buffer being immutable and michael@0: * other threads may access this buffer simultaneously. michael@0: */ michael@0: bool IsReadonly() const michael@0: { michael@0: return mRefCount > 1; michael@0: } michael@0: michael@0: /** michael@0: * The FromString methods return a string buffer for the given string michael@0: * object or null if the string object does not have a string buffer. michael@0: * The reference count of the string buffer is NOT incremented by these michael@0: * methods. If the caller wishes to hold onto the returned value, then michael@0: * the returned string buffer must have its reference count incremented michael@0: * via a call to the AddRef method. michael@0: */ michael@0: static nsStringBuffer* FromString(const nsAString &str); michael@0: static nsStringBuffer* FromString(const nsACString &str); michael@0: michael@0: /** michael@0: * The ToString methods assign this string buffer to a given string michael@0: * object. If the string object does not support sharable string michael@0: * buffers, then its value will be set to a copy of the given string michael@0: * buffer. Otherwise, these methods increment the reference count of the michael@0: * given string buffer. It is important to specify the length (in michael@0: * storage units) of the string contained in the string buffer since the michael@0: * length of the string may be less than its storage size. The string michael@0: * must have a null terminator at the offset specified by |len|. michael@0: * michael@0: * NOTE: storage size is measured in bytes even for wide strings; michael@0: * however, string length is always measured in storage units michael@0: * (2-byte units for wide strings). michael@0: */ michael@0: void ToString(uint32_t len, nsAString &str, michael@0: bool aMoveOwnership = false); michael@0: void ToString(uint32_t len, nsACString &str, michael@0: bool aMoveOwnership = false); michael@0: michael@0: /** michael@0: * This measures the size. It should only be used if the StringBuffer is michael@0: * unshared. This is checked. michael@0: */ michael@0: size_t SizeOfIncludingThisMustBeUnshared(mozilla::MallocSizeOf aMallocSizeOf) const; michael@0: michael@0: /** michael@0: * This measures the size only if the StringBuffer is unshared. michael@0: */ michael@0: size_t SizeOfIncludingThisIfUnshared(mozilla::MallocSizeOf aMallocSizeOf) const; michael@0: michael@0: /** michael@0: * This measures the size regardless of whether the StringBuffer is michael@0: * unshared. michael@0: * michael@0: * WARNING: Only use this if you really know what you are doing, because michael@0: * it can easily lead to double-counting strings. If you do use them, michael@0: * please explain clearly in a comment why it's safe and won't lead to michael@0: * double-counting. michael@0: */ michael@0: size_t SizeOfIncludingThisEvenIfShared(mozilla::MallocSizeOf aMallocSizeOf) const; michael@0: }; michael@0: michael@0: #endif /* !defined(nsStringBuffer_h__ */