dom/bindings/DOMString.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef mozilla_dom_DOMString_h
michael@0 7 #define mozilla_dom_DOMString_h
michael@0 8
michael@0 9 #include "nsStringGlue.h"
michael@0 10 #include "nsStringBuffer.h"
michael@0 11 #include "mozilla/Assertions.h"
michael@0 12 #include "mozilla/Attributes.h"
michael@0 13 #include "mozilla/Maybe.h"
michael@0 14 #include "nsDOMString.h"
michael@0 15 #include "nsIAtom.h"
michael@0 16
michael@0 17 namespace mozilla {
michael@0 18 namespace dom {
michael@0 19
michael@0 20 /**
michael@0 21 * A class for representing string return values. This can be either passed to
michael@0 22 * callees that have an nsString or nsAString out param or passed to a callee
michael@0 23 * that actually knows about this class and can work with it. Such a callee may
michael@0 24 * call SetStringBuffer or SetOwnedString or SetOwnedAtom on this object, but
michael@0 25 * only if it plans to keep holding a strong ref to the internal stringbuffer!
michael@0 26 *
michael@0 27 * The proper way to store a value in this class is to either to do nothing
michael@0 28 * (which leaves this as an empty string), to call SetStringBuffer with a
michael@0 29 * non-null stringbuffer, to call SetOwnedString, to call SetOwnedAtom, to call
michael@0 30 * SetNull(), or to call AsAString() and set the value in the resulting
michael@0 31 * nsString. These options are mutually exclusive! Don't do more than one of
michael@0 32 * them.
michael@0 33 *
michael@0 34 * The proper way to extract a value is to check IsNull(). If not null, then
michael@0 35 * check HasStringBuffer(). If that's true, check for a zero length, and if the
michael@0 36 * length is nonzero call StringBuffer(). If the length is zero this is the
michael@0 37 * empty string. If HasStringBuffer() returns false, call AsAString() and get
michael@0 38 * the value from that.
michael@0 39 */
michael@0 40 class MOZ_STACK_CLASS DOMString {
michael@0 41 public:
michael@0 42 DOMString()
michael@0 43 : mStringBuffer(nullptr)
michael@0 44 , mLength(0)
michael@0 45 , mIsNull(false)
michael@0 46 {}
michael@0 47 ~DOMString()
michael@0 48 {
michael@0 49 MOZ_ASSERT(mString.empty() || !mStringBuffer,
michael@0 50 "Shouldn't have both present!");
michael@0 51 }
michael@0 52
michael@0 53 operator nsString&()
michael@0 54 {
michael@0 55 return AsAString();
michael@0 56 }
michael@0 57
michael@0 58 nsString& AsAString()
michael@0 59 {
michael@0 60 MOZ_ASSERT(!mStringBuffer, "We already have a stringbuffer?");
michael@0 61 MOZ_ASSERT(!mIsNull, "We're already set as null");
michael@0 62 if (mString.empty()) {
michael@0 63 mString.construct();
michael@0 64 }
michael@0 65 return mString.ref();
michael@0 66 }
michael@0 67
michael@0 68 bool HasStringBuffer() const
michael@0 69 {
michael@0 70 MOZ_ASSERT(mString.empty() || !mStringBuffer,
michael@0 71 "Shouldn't have both present!");
michael@0 72 MOZ_ASSERT(!mIsNull, "Caller should have checked IsNull() first");
michael@0 73 return mString.empty();
michael@0 74 }
michael@0 75
michael@0 76 // Get the stringbuffer. This can only be called if HasStringBuffer()
michael@0 77 // returned true and StringBufferLength() is nonzero. If that's true, it will
michael@0 78 // never return null.
michael@0 79 nsStringBuffer* StringBuffer() const
michael@0 80 {
michael@0 81 MOZ_ASSERT(!mIsNull, "Caller should have checked IsNull() first");
michael@0 82 MOZ_ASSERT(HasStringBuffer(),
michael@0 83 "Don't ask for the stringbuffer if we don't have it");
michael@0 84 MOZ_ASSERT(StringBufferLength() != 0, "Why are you asking for this?");
michael@0 85 MOZ_ASSERT(mStringBuffer,
michael@0 86 "If our length is nonzero, we better have a stringbuffer.");
michael@0 87 return mStringBuffer;
michael@0 88 }
michael@0 89
michael@0 90 // Get the length of the stringbuffer. Can only be called if
michael@0 91 // HasStringBuffer().
michael@0 92 uint32_t StringBufferLength() const
michael@0 93 {
michael@0 94 MOZ_ASSERT(HasStringBuffer(), "Don't call this if there is no stringbuffer");
michael@0 95 return mLength;
michael@0 96 }
michael@0 97
michael@0 98 void SetStringBuffer(nsStringBuffer* aStringBuffer, uint32_t aLength)
michael@0 99 {
michael@0 100 MOZ_ASSERT(mString.empty(), "We already have a string?");
michael@0 101 MOZ_ASSERT(!mIsNull, "We're already set as null");
michael@0 102 MOZ_ASSERT(!mStringBuffer, "Setting stringbuffer twice?");
michael@0 103 MOZ_ASSERT(aStringBuffer, "Why are we getting null?");
michael@0 104 mStringBuffer = aStringBuffer;
michael@0 105 mLength = aLength;
michael@0 106 }
michael@0 107
michael@0 108 void SetOwnedString(const nsAString& aString)
michael@0 109 {
michael@0 110 MOZ_ASSERT(mString.empty(), "We already have a string?");
michael@0 111 MOZ_ASSERT(!mIsNull, "We're already set as null");
michael@0 112 MOZ_ASSERT(!mStringBuffer, "Setting stringbuffer twice?");
michael@0 113 nsStringBuffer* buf = nsStringBuffer::FromString(aString);
michael@0 114 if (buf) {
michael@0 115 SetStringBuffer(buf, aString.Length());
michael@0 116 } else if (aString.IsVoid()) {
michael@0 117 SetNull();
michael@0 118 } else if (!aString.IsEmpty()) {
michael@0 119 AsAString() = aString;
michael@0 120 }
michael@0 121 }
michael@0 122
michael@0 123 enum NullHandling
michael@0 124 {
michael@0 125 eTreatNullAsNull,
michael@0 126 eTreatNullAsEmpty,
michael@0 127 eNullNotExpected
michael@0 128 };
michael@0 129
michael@0 130 void SetOwnedAtom(nsIAtom* aAtom, NullHandling aNullHandling)
michael@0 131 {
michael@0 132 MOZ_ASSERT(mString.empty(), "We already have a string?");
michael@0 133 MOZ_ASSERT(!mIsNull, "We're already set as null");
michael@0 134 MOZ_ASSERT(!mStringBuffer, "Setting stringbuffer twice?");
michael@0 135 MOZ_ASSERT(aAtom || aNullHandling != eNullNotExpected);
michael@0 136 if (aNullHandling == eNullNotExpected || aAtom) {
michael@0 137 SetStringBuffer(aAtom->GetStringBuffer(), aAtom->GetLength());
michael@0 138 } else if (aNullHandling == eTreatNullAsNull) {
michael@0 139 SetNull();
michael@0 140 }
michael@0 141 }
michael@0 142
michael@0 143 void SetNull()
michael@0 144 {
michael@0 145 MOZ_ASSERT(!mStringBuffer, "Should have no stringbuffer if null");
michael@0 146 MOZ_ASSERT(mString.empty(), "Should have no string if null");
michael@0 147 mIsNull = true;
michael@0 148 }
michael@0 149
michael@0 150 bool IsNull() const
michael@0 151 {
michael@0 152 MOZ_ASSERT(!mStringBuffer || mString.empty(),
michael@0 153 "How could we have a stringbuffer and a nonempty string?");
michael@0 154 return mIsNull || (!mString.empty() && mString.ref().IsVoid());
michael@0 155 }
michael@0 156
michael@0 157 void ToString(nsAString& aString)
michael@0 158 {
michael@0 159 if (IsNull()) {
michael@0 160 SetDOMStringToNull(aString);
michael@0 161 } else if (HasStringBuffer()) {
michael@0 162 if (StringBufferLength() == 0) {
michael@0 163 aString.Truncate();
michael@0 164 } else {
michael@0 165 StringBuffer()->ToString(StringBufferLength(), aString);
michael@0 166 }
michael@0 167 } else {
michael@0 168 aString = AsAString();
michael@0 169 }
michael@0 170 }
michael@0 171
michael@0 172 private:
michael@0 173 // We need to be able to act like a string as needed
michael@0 174 Maybe<nsAutoString> mString;
michael@0 175
michael@0 176 // For callees that know we exist, we can be a stringbuffer/length/null-flag
michael@0 177 // triple.
michael@0 178 nsStringBuffer* mStringBuffer;
michael@0 179 uint32_t mLength;
michael@0 180 bool mIsNull;
michael@0 181 };
michael@0 182
michael@0 183 } // namespace dom
michael@0 184 } // namespace mozilla
michael@0 185
michael@0 186 #endif // mozilla_dom_DOMString_h

mercurial