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