/usr/include/thunderbird/mozilla/dom/FakeString.h is in thunderbird-dev 1:52.8.0-1~deb8u1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_FakeString_h__
#define mozilla_dom_FakeString_h__
#include "nsString.h"
#include "nsStringBuffer.h"
#include "mozilla/RefPtr.h"
namespace mozilla {
namespace dom {
namespace binding_detail {
// A struct that has the same layout as an nsString but much faster
// constructor and destructor behavior. FakeString uses inline storage
// for small strings and a nsStringBuffer for longer strings.
struct FakeString {
FakeString() :
mFlags(nsString::F_TERMINATED)
{
}
~FakeString() {
if (mFlags & nsString::F_SHARED) {
nsStringBuffer::FromData(mData)->Release();
}
}
void Rebind(const nsString::char_type* aData, nsString::size_type aLength) {
MOZ_ASSERT(mFlags == nsString::F_TERMINATED);
mData = const_cast<nsString::char_type*>(aData);
mLength = aLength;
}
// Share aString's string buffer, if it has one; otherwise, make this string
// depend upon aString's data. aString should outlive this instance of
// FakeString.
void ShareOrDependUpon(const nsAString& aString) {
RefPtr<nsStringBuffer> sharedBuffer = nsStringBuffer::FromString(aString);
if (!sharedBuffer) {
Rebind(aString.Data(), aString.Length());
} else {
AssignFromStringBuffer(sharedBuffer.forget());
mLength = aString.Length();
}
}
void Truncate() {
MOZ_ASSERT(mFlags == nsString::F_TERMINATED);
mData = nsString::char_traits::sEmptyBuffer;
mLength = 0;
}
void SetIsVoid(bool aValue) {
MOZ_ASSERT(aValue,
"We don't support SetIsVoid(false) on FakeString!");
Truncate();
mFlags |= nsString::F_VOIDED;
}
const nsString::char_type* Data() const
{
return mData;
}
nsString::char_type* BeginWriting()
{
return mData;
}
nsString::size_type Length() const
{
return mLength;
}
// Reserve space to write aLength chars, not including null-terminator.
bool SetLength(nsString::size_type aLength, mozilla::fallible_t const&) {
// Use mInlineStorage for small strings.
if (aLength < sInlineCapacity) {
SetData(mInlineStorage);
} else {
RefPtr<nsStringBuffer> buf = nsStringBuffer::Alloc((aLength + 1) * sizeof(nsString::char_type));
if (MOZ_UNLIKELY(!buf)) {
return false;
}
AssignFromStringBuffer(buf.forget());
}
mLength = aLength;
mData[mLength] = char16_t(0);
return true;
}
// If this ever changes, change the corresponding code in the
// Optional<nsAString> specialization as well.
const nsAString* ToAStringPtr() const {
return reinterpret_cast<const nsString*>(this);
}
operator const nsAString& () const {
return *reinterpret_cast<const nsString*>(this);
}
private:
nsAString* ToAStringPtr() {
return reinterpret_cast<nsString*>(this);
}
nsString::char_type* mData;
nsString::size_type mLength;
uint32_t mFlags;
static const size_t sInlineCapacity = 64;
nsString::char_type mInlineStorage[sInlineCapacity];
FakeString(const FakeString& other) = delete;
void operator=(const FakeString& other) = delete;
void SetData(nsString::char_type* aData) {
MOZ_ASSERT(mFlags == nsString::F_TERMINATED);
mData = const_cast<nsString::char_type*>(aData);
}
void AssignFromStringBuffer(already_AddRefed<nsStringBuffer> aBuffer) {
SetData(static_cast<nsString::char_type*>(aBuffer.take()->Data()));
mFlags = nsString::F_SHARED | nsString::F_TERMINATED;
}
friend class NonNull<nsAString>;
// A class to use for our static asserts to ensure our object layout
// matches that of nsString.
class StringAsserter;
friend class StringAsserter;
class StringAsserter : public nsString {
public:
static void StaticAsserts() {
static_assert(offsetof(FakeString, mInlineStorage) ==
sizeof(nsString),
"FakeString should include all nsString members");
static_assert(offsetof(FakeString, mData) ==
offsetof(StringAsserter, mData),
"Offset of mData should match");
static_assert(offsetof(FakeString, mLength) ==
offsetof(StringAsserter, mLength),
"Offset of mLength should match");
static_assert(offsetof(FakeString, mFlags) ==
offsetof(StringAsserter, mFlags),
"Offset of mFlags should match");
}
};
};
} // namespace binding_detail
} // namespace dom
} // namespace mozilla
#endif /* mozilla_dom_FakeString_h__ */
|