tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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