ScriptPreloader-inl.h (3914B)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ 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 #ifndef ScriptPreloader_inl_h 7 #define ScriptPreloader_inl_h 8 9 #include "mozilla/Attributes.h" 10 #include "mozilla/Assertions.h" 11 #include "mozilla/ResultExtensions.h" 12 #include "mozilla/dom/ScriptSettings.h" 13 #include "nsString.h" 14 #include "nsTArray.h" 15 16 #include <prio.h> 17 18 namespace mozilla { 19 20 namespace loader { 21 22 using mozilla::dom::AutoJSAPI; 23 24 static inline Result<Ok, nsresult> Write(PRFileDesc* fd, const void* data, 25 int32_t len) { 26 if (PR_Write(fd, data, len) != len) { 27 return Err(NS_ERROR_FAILURE); 28 } 29 return Ok(); 30 } 31 32 static inline Result<Ok, nsresult> WritePadding(PRFileDesc* fd, 33 uint8_t padding) { 34 static const char paddingBytes[8] = "PADBYTE"; 35 MOZ_DIAGNOSTIC_ASSERT(padding <= sizeof(paddingBytes)); 36 37 if (padding == 0) { 38 return Ok(); 39 } 40 41 if (PR_Write(fd, static_cast<const void*>(paddingBytes), padding) != 42 padding) { 43 return Err(NS_ERROR_FAILURE); 44 } 45 return Ok(); 46 } 47 48 struct MOZ_RAII AutoSafeJSAPI : public AutoJSAPI { 49 AutoSafeJSAPI() { Init(); } 50 }; 51 52 template <typename T> 53 struct Matcher; 54 55 // Wraps the iterator for a nsTHashTable so that it may be used as a range 56 // iterator. Each iterator result acts as a smart pointer to the hash element, 57 // and has a Remove() method which will remove the element from the hash. 58 // 59 // It also accepts an optional Matcher instance against which to filter the 60 // elements which should be iterated over. 61 // 62 // Example: 63 // 64 // for (auto& elem : HashElemIter<HashType>(hash)) { 65 // if (elem->IsDead()) { 66 // elem.Remove(); 67 // } 68 // } 69 template <typename T> 70 class HashElemIter { 71 using Iterator = typename T::Iterator; 72 using ElemType = typename T::UserDataType; 73 74 T& hash_; 75 Matcher<ElemType>* matcher_; 76 Iterator iter_; 77 78 public: 79 explicit HashElemIter(T& hash, Matcher<ElemType>* matcher = nullptr) 80 : hash_(hash), matcher_(matcher), iter_(hash.Iter()) {} 81 82 class Elem { 83 friend class HashElemIter<T>; 84 85 HashElemIter<T>& iter_; 86 bool done_; 87 88 Elem(HashElemIter& iter, bool done) : iter_(iter), done_(done) { 89 skipNonMatching(); 90 } 91 92 Iterator& iter() { return iter_.iter_; } 93 94 void skipNonMatching() { 95 if (iter_.matcher_) { 96 while (!done_ && !iter_.matcher_->Matches(get())) { 97 iter().Next(); 98 done_ = iter().Done(); 99 } 100 } 101 } 102 103 public: 104 Elem& operator*() { return *this; } 105 106 ElemType get() { 107 if (done_) { 108 return nullptr; 109 } 110 return iter().UserData(); 111 } 112 113 const ElemType get() const { return const_cast<Elem*>(this)->get(); } 114 115 ElemType operator->() { return get(); } 116 117 const ElemType operator->() const { return get(); } 118 119 operator ElemType() { return get(); } 120 121 void Remove() { iter().Remove(); } 122 123 Elem& operator++() { 124 MOZ_ASSERT(!done_); 125 126 iter().Next(); 127 done_ = iter().Done(); 128 129 skipNonMatching(); 130 return *this; 131 } 132 133 bool operator!=(Elem& other) const { 134 return done_ != other.done_ || this->get() != other.get(); 135 } 136 }; 137 138 Elem begin() { return Elem(*this, iter_.Done()); } 139 140 Elem end() { return Elem(*this, true); } 141 }; 142 143 template <typename T> 144 HashElemIter<T> IterHash(T& hash, 145 Matcher<typename T::UserDataType>* matcher = nullptr) { 146 return HashElemIter<T>(hash, matcher); 147 } 148 149 template <typename T, typename F> 150 bool Find(T&& iter, F&& match) { 151 for (auto& elem : iter) { 152 if (match(elem)) { 153 return true; 154 } 155 } 156 return false; 157 } 158 159 }; // namespace loader 160 }; // namespace mozilla 161 162 #endif // ScriptPreloader_inl_h