Bug 1941128 - Turn off network.dns.native_https_query on Mac again
[gecko.git] / js / xpconnect / loader / ScriptPreloader-inl.h
blob5908600616c96ee6cac52a029d999d0986b2511d
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/. */
6 #ifndef ScriptPreloader_inl_h
7 #define ScriptPreloader_inl_h
9 #include "mozilla/Attributes.h"
10 #include "mozilla/Assertions.h"
11 #include "mozilla/CheckedInt.h"
12 #include "mozilla/EndianUtils.h"
13 #include "mozilla/EnumSet.h"
14 #include "mozilla/Range.h"
15 #include "mozilla/ResultExtensions.h"
16 #include "mozilla/Unused.h"
17 #include "mozilla/dom/ScriptSettings.h"
18 #include "nsString.h"
19 #include "nsTArray.h"
21 #include <prio.h>
23 namespace mozilla {
25 namespace loader {
27 using mozilla::dom::AutoJSAPI;
29 static inline Result<Ok, nsresult> Write(PRFileDesc* fd, const void* data,
30 int32_t len) {
31 if (PR_Write(fd, data, len) != len) {
32 return Err(NS_ERROR_FAILURE);
34 return Ok();
37 static inline Result<Ok, nsresult> WritePadding(PRFileDesc* fd,
38 uint8_t padding) {
39 static const char paddingBytes[8] = "PADBYTE";
40 MOZ_DIAGNOSTIC_ASSERT(padding <= sizeof(paddingBytes));
42 if (padding == 0) {
43 return Ok();
46 if (PR_Write(fd, static_cast<const void*>(paddingBytes), padding) !=
47 padding) {
48 return Err(NS_ERROR_FAILURE);
50 return Ok();
53 struct MOZ_RAII AutoSafeJSAPI : public AutoJSAPI {
54 AutoSafeJSAPI() { Init(); }
57 template <typename T>
58 struct Matcher;
60 // Wraps the iterator for a nsTHashTable so that it may be used as a range
61 // iterator. Each iterator result acts as a smart pointer to the hash element,
62 // and has a Remove() method which will remove the element from the hash.
64 // It also accepts an optional Matcher instance against which to filter the
65 // elements which should be iterated over.
67 // Example:
69 // for (auto& elem : HashElemIter<HashType>(hash)) {
70 // if (elem->IsDead()) {
71 // elem.Remove();
72 // }
73 // }
74 template <typename T>
75 class HashElemIter {
76 using Iterator = typename T::Iterator;
77 using ElemType = typename T::UserDataType;
79 T& hash_;
80 Matcher<ElemType>* matcher_;
81 Iterator iter_;
83 public:
84 explicit HashElemIter(T& hash, Matcher<ElemType>* matcher = nullptr)
85 : hash_(hash), matcher_(matcher), iter_(hash.Iter()) {}
87 class Elem {
88 friend class HashElemIter<T>;
90 HashElemIter<T>& iter_;
91 bool done_;
93 Elem(HashElemIter& iter, bool done) : iter_(iter), done_(done) {
94 skipNonMatching();
97 Iterator& iter() { return iter_.iter_; }
99 void skipNonMatching() {
100 if (iter_.matcher_) {
101 while (!done_ && !iter_.matcher_->Matches(get())) {
102 iter().Next();
103 done_ = iter().Done();
108 public:
109 Elem& operator*() { return *this; }
111 ElemType get() {
112 if (done_) {
113 return nullptr;
115 return iter().UserData();
118 const ElemType get() const { return const_cast<Elem*>(this)->get(); }
120 ElemType operator->() { return get(); }
122 const ElemType operator->() const { return get(); }
124 operator ElemType() { return get(); }
126 void Remove() { iter().Remove(); }
128 Elem& operator++() {
129 MOZ_ASSERT(!done_);
131 iter().Next();
132 done_ = iter().Done();
134 skipNonMatching();
135 return *this;
138 bool operator!=(Elem& other) const {
139 return done_ != other.done_ || this->get() != other.get();
143 Elem begin() { return Elem(*this, iter_.Done()); }
145 Elem end() { return Elem(*this, true); }
148 template <typename T>
149 HashElemIter<T> IterHash(T& hash,
150 Matcher<typename T::UserDataType>* matcher = nullptr) {
151 return HashElemIter<T>(hash, matcher);
154 template <typename T, typename F>
155 bool Find(T&& iter, F&& match) {
156 for (auto& elem : iter) {
157 if (match(elem)) {
158 return true;
161 return false;
164 }; // namespace loader
165 }; // namespace mozilla
167 #endif // ScriptPreloader_inl_h