xpcom/ds/nsStringEnumerator.cpp

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.

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "nsStringEnumerator.h"
     8 #include "nsISimpleEnumerator.h"
     9 #include "nsSupportsPrimitives.h"
    10 #include "mozilla/Attributes.h"
    11 #include "nsTArray.h"
    13 //
    14 // nsStringEnumerator
    15 //
    17 class nsStringEnumerator MOZ_FINAL : public nsIStringEnumerator,
    18                                      public nsIUTF8StringEnumerator,
    19                                      public nsISimpleEnumerator
    20 {
    21 public:
    22     nsStringEnumerator(const nsTArray<nsString>* aArray, bool aOwnsArray) :
    23         mArray(aArray), mIndex(0), mOwnsArray(aOwnsArray), mIsUnicode(true)
    24     {}
    26     nsStringEnumerator(const nsTArray<nsCString>* aArray, bool aOwnsArray) :
    27         mCArray(aArray), mIndex(0), mOwnsArray(aOwnsArray), mIsUnicode(false)
    28     {}
    30     nsStringEnumerator(const nsTArray<nsString>* aArray, nsISupports* aOwner) :
    31         mArray(aArray), mIndex(0), mOwner(aOwner), mOwnsArray(false), mIsUnicode(true)
    32     {}
    34     nsStringEnumerator(const nsTArray<nsCString>* aArray, nsISupports* aOwner) :
    35         mCArray(aArray), mIndex(0), mOwner(aOwner), mOwnsArray(false), mIsUnicode(false)
    36     {}
    38     NS_DECL_ISUPPORTS
    39     NS_DECL_NSIUTF8STRINGENUMERATOR
    41     // have to declare nsIStringEnumerator manually, because of
    42     // overlapping method names
    43     NS_IMETHOD GetNext(nsAString& aResult);
    44     NS_DECL_NSISIMPLEENUMERATOR
    46 private:
    47     ~nsStringEnumerator() {
    48         if (mOwnsArray) {
    49             // const-casting is safe here, because the NS_New*
    50             // constructors make sure mOwnsArray is consistent with
    51             // the constness of the objects
    52             if (mIsUnicode)
    53                 delete const_cast<nsTArray<nsString>*>(mArray);
    54             else
    55                 delete const_cast<nsTArray<nsCString>*>(mCArray);
    56         }
    57     }
    59     union {
    60         const nsTArray<nsString>* mArray;
    61         const nsTArray<nsCString>* mCArray;
    62     };
    64     inline uint32_t Count() {
    65         return mIsUnicode ? mArray->Length() : mCArray->Length();
    66     }
    68     uint32_t mIndex;
    70     // the owner allows us to hold a strong reference to the object
    71     // that owns the array. Having a non-null value in mOwner implies
    72     // that mOwnsArray is false, because we rely on the real owner
    73     // to release the array
    74     nsCOMPtr<nsISupports> mOwner;
    75     bool mOwnsArray;
    76     bool mIsUnicode;
    77 };
    79 NS_IMPL_ISUPPORTS(nsStringEnumerator,
    80                   nsIStringEnumerator,
    81                   nsIUTF8StringEnumerator,
    82                   nsISimpleEnumerator)
    84 NS_IMETHODIMP
    85 nsStringEnumerator::HasMore(bool* aResult)
    86 {
    87     *aResult = mIndex < Count();
    88     return NS_OK;
    89 }
    91 NS_IMETHODIMP
    92 nsStringEnumerator::HasMoreElements(bool* aResult)
    93 {
    94     return HasMore(aResult);
    95 }
    97 NS_IMETHODIMP
    98 nsStringEnumerator::GetNext(nsISupports** aResult)
    99 {
   100     if (mIsUnicode) {
   101         nsSupportsStringImpl* stringImpl = new nsSupportsStringImpl();
   102         if (!stringImpl) return NS_ERROR_OUT_OF_MEMORY;
   104         stringImpl->SetData(mArray->ElementAt(mIndex++));
   105         *aResult = stringImpl;
   106     }
   107     else {
   108         nsSupportsCStringImpl* cstringImpl = new nsSupportsCStringImpl();
   109         if (!cstringImpl) return NS_ERROR_OUT_OF_MEMORY;
   111         cstringImpl->SetData(mCArray->ElementAt(mIndex++));
   112         *aResult = cstringImpl;
   113     }
   114     NS_ADDREF(*aResult);
   115     return NS_OK;
   116 }
   118 NS_IMETHODIMP
   119 nsStringEnumerator::GetNext(nsAString& aResult)
   120 {
   121     if (NS_WARN_IF(mIndex >= Count()))
   122         return NS_ERROR_UNEXPECTED;
   124     if (mIsUnicode)
   125         aResult = mArray->ElementAt(mIndex++);
   126     else
   127         CopyUTF8toUTF16(mCArray->ElementAt(mIndex++), aResult);
   129     return NS_OK;
   130 }
   132 NS_IMETHODIMP
   133 nsStringEnumerator::GetNext(nsACString& aResult)
   134 {
   135     if (NS_WARN_IF(mIndex >= Count()))
   136         return NS_ERROR_UNEXPECTED;
   138     if (mIsUnicode)
   139         CopyUTF16toUTF8(mArray->ElementAt(mIndex++), aResult);
   140     else
   141         aResult = mCArray->ElementAt(mIndex++);
   143     return NS_OK;
   144 }
   146 template<class T>
   147 static inline nsresult
   148 StringEnumeratorTail(T** aResult)
   149 {
   150     if (!*aResult)
   151         return NS_ERROR_OUT_OF_MEMORY;
   152     NS_ADDREF(*aResult);
   153     return NS_OK;
   154 }
   156 //
   157 // constructors
   158 //
   160 nsresult
   161 NS_NewStringEnumerator(nsIStringEnumerator** aResult,
   162                        const nsTArray<nsString>* aArray, nsISupports* aOwner)
   163 {
   164     if (NS_WARN_IF(!aResult) || NS_WARN_IF(!aArray))
   165         return NS_ERROR_INVALID_ARG;
   167     *aResult = new nsStringEnumerator(aArray, aOwner);
   168     return StringEnumeratorTail(aResult);
   169 }
   172 nsresult
   173 NS_NewUTF8StringEnumerator(nsIUTF8StringEnumerator** aResult,
   174                            const nsTArray<nsCString>* aArray, nsISupports* aOwner)
   175 {
   176     if (NS_WARN_IF(!aResult) || NS_WARN_IF(!aArray))
   177         return NS_ERROR_INVALID_ARG;
   179     *aResult = new nsStringEnumerator(aArray, aOwner);
   180     return StringEnumeratorTail(aResult);
   181 }
   183 nsresult
   184 NS_NewAdoptingStringEnumerator(nsIStringEnumerator** aResult,
   185                                nsTArray<nsString>* aArray)
   186 {
   187     if (NS_WARN_IF(!aResult) || NS_WARN_IF(!aArray))
   188         return NS_ERROR_INVALID_ARG;
   190     *aResult = new nsStringEnumerator(aArray, true);
   191     return StringEnumeratorTail(aResult);
   192 }
   194 nsresult
   195 NS_NewAdoptingUTF8StringEnumerator(nsIUTF8StringEnumerator** aResult,
   196                                    nsTArray<nsCString>* aArray)
   197 {
   198     if (NS_WARN_IF(!aResult) || NS_WARN_IF(!aArray))
   199         return NS_ERROR_INVALID_ARG;
   201     *aResult = new nsStringEnumerator(aArray, true);
   202     return StringEnumeratorTail(aResult);
   203 }
   205 // const ones internally just forward to the non-const equivalents
   206 nsresult
   207 NS_NewStringEnumerator(nsIStringEnumerator** aResult,
   208                        const nsTArray<nsString>* aArray)
   209 {
   210     if (NS_WARN_IF(!aResult) || NS_WARN_IF(!aArray))
   211         return NS_ERROR_INVALID_ARG;
   213     *aResult = new nsStringEnumerator(aArray, false);
   214     return StringEnumeratorTail(aResult);
   215 }
   217 nsresult
   218 NS_NewUTF8StringEnumerator(nsIUTF8StringEnumerator** aResult,
   219                            const nsTArray<nsCString>* aArray)
   220 {
   221     if (NS_WARN_IF(!aResult) || NS_WARN_IF(!aArray))
   222         return NS_ERROR_INVALID_ARG;
   224     *aResult = new nsStringEnumerator(aArray, false);
   225     return StringEnumeratorTail(aResult);
   226 }

mercurial