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/. */
5 
6 #include "txExpandedNameMap.h"
7 #include "txCore.h"
8 
9 class txMapItemComparator {
10  public:
Equals(const txExpandedNameMap_base::MapItem & aItem,const txExpandedName & aKey) const11   bool Equals(const txExpandedNameMap_base::MapItem& aItem,
12               const txExpandedName& aKey) const {
13     return aItem.mNamespaceID == aKey.mNamespaceID &&
14            aItem.mLocalName == aKey.mLocalName;
15   }
16 };
17 
18 /**
19  * Adds an item, if an item with this key already exists an error is
20  * returned
21  * @param  aKey   key for item to add
22  * @param  aValue value of item to add
23  * @return errorcode
24  */
addItem(const txExpandedName & aKey,void * aValue)25 nsresult txExpandedNameMap_base::addItem(const txExpandedName& aKey,
26                                          void* aValue) {
27   size_t pos = mItems.IndexOf(aKey, 0, txMapItemComparator());
28   if (pos != mItems.NoIndex) {
29     return NS_ERROR_XSLT_ALREADY_SET;
30   }
31 
32   MapItem* item = mItems.AppendElement();
33   NS_ENSURE_TRUE(item, NS_ERROR_OUT_OF_MEMORY);
34 
35   item->mNamespaceID = aKey.mNamespaceID;
36   item->mLocalName = aKey.mLocalName;
37   item->mValue = aValue;
38 
39   return NS_OK;
40 }
41 
42 /**
43  * Sets an item, if an item with this key already exists it is overwritten
44  * with the new value
45  * @param  aKey   key for item to set
46  * @param  aValue value of item to set
47  * @return errorcode
48  */
setItem(const txExpandedName & aKey,void * aValue,void ** aOldValue)49 nsresult txExpandedNameMap_base::setItem(const txExpandedName& aKey,
50                                          void* aValue, void** aOldValue) {
51   *aOldValue = nullptr;
52   size_t pos = mItems.IndexOf(aKey, 0, txMapItemComparator());
53   if (pos != mItems.NoIndex) {
54     *aOldValue = mItems[pos].mValue;
55     mItems[pos].mValue = aValue;
56     return NS_OK;
57   }
58 
59   MapItem* item = mItems.AppendElement();
60   NS_ENSURE_TRUE(item, NS_ERROR_OUT_OF_MEMORY);
61 
62   item->mNamespaceID = aKey.mNamespaceID;
63   item->mLocalName = aKey.mLocalName;
64   item->mValue = aValue;
65 
66   return NS_OK;
67 }
68 
69 /**
70  * Gets an item
71  * @param  aKey  key for item to get
72  * @return item with specified key, or null if no such item exists
73  */
getItem(const txExpandedName & aKey) const74 void* txExpandedNameMap_base::getItem(const txExpandedName& aKey) const {
75   size_t pos = mItems.IndexOf(aKey, 0, txMapItemComparator());
76   if (pos != mItems.NoIndex) {
77     return mItems[pos].mValue;
78   }
79 
80   return nullptr;
81 }
82 
83 /**
84  * Removes an item, deleting it if the map owns the values
85  * @param  aKey  key for item to remove
86  * @return item with specified key, or null if it has been deleted
87  *         or no such item exists
88  */
removeItem(const txExpandedName & aKey)89 void* txExpandedNameMap_base::removeItem(const txExpandedName& aKey) {
90   void* value = nullptr;
91   size_t pos = mItems.IndexOf(aKey, 0, txMapItemComparator());
92   if (pos != mItems.NoIndex) {
93     value = mItems[pos].mValue;
94     mItems.RemoveElementAt(pos);
95   }
96 
97   return value;
98 }
99