gecko-dev/toolkit/components/extensions/MatchGlob.h
Kris Maglione 186924219b Bug 1322235: Part 1 - Add native MatchPattern and MatchGlob bindings. r=billm,aswan
Bill, can you please review the binding code, and the general sanity of the
platform code. Andrew and zombie, can you please matching algorithms and
tests.

Change summary:

The existing JavaScript matching code works well overall, but it needs to be
called a lot, particularly from hot code paths. In most cases, the overhead of
the matching code on its own adds up enough to cause a problem. When we have
to call out to JavaScript via XPConnect to make a policy decision, it adds up
even more.

These classes solve both of these problems by a) being very fast, and b) being
accessible directly from C++. They are particularly optimized for the common
cases where only literal or prefix matches are required, and they take special
steps to avoid virtual calls wherever possible, and caching computed URL
values so that they can be reused across many match operations without
additional overhead.

MozReview-Commit-ID: BZzPZDQRnl

--HG--
rename : toolkit/modules/tests/xpcshell/test_MatchPattern.js => toolkit/components/extensions/test/xpcshell/test_MatchPattern.js
extra : rebase_source : c93c4c6c36460eb5ad0fc3aa86ad42a72e76bb6c
2017-05-24 14:57:29 -07:00

99 lines
3.0 KiB
C++

/* -*- Mode: C++; tab-width: 2; 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 mozilla_extensions_MatchGlob_h
#define mozilla_extensions_MatchGlob_h
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/MatchGlobBinding.h"
#include "jspubtd.h"
#include "js/RootingAPI.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsISupports.h"
#include "nsWrapperCache.h"
namespace mozilla {
namespace extensions {
class MatchPattern;
class MatchGlob final : public nsISupports
, public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MatchGlob)
static already_AddRefed<MatchGlob>
Constructor(dom::GlobalObject& aGlobal, const nsAString& aGlob, bool aAllowQuestion,
ErrorResult& aRv);
bool Matches(const nsAString& aString) const;
bool IsWildcard() const
{
return mIsPrefix && mPathLiteral.IsEmpty();
}
void GetGlob(nsAString& aGlob) const
{
aGlob = mGlob;
}
nsISupports* GetParentObject() const { return mParent; }
virtual JSObject* WrapObject(JSContext* aCx, JS::HandleObject aGivenProto) override;
protected:
virtual ~MatchGlob();
private:
friend class MatchPattern;
explicit MatchGlob(nsISupports* aParent) : mParent(aParent) {}
void Init(JSContext* aCx, const nsAString& aGlob, bool aAllowQuestion, ErrorResult& aRv);
nsCOMPtr<nsISupports> mParent;
// The original glob string that this glob object represents.
nsString mGlob;
// The literal path string to match against. If this contains a non-void
// value, the glob matches against this exact literal string, rather than
// performng a pattern match. If mIsPrefix is true, the literal must appear
// at the start of the matched string. If it is false, the the literal must
// be exactly equal to the matched string.
nsString mPathLiteral;
bool mIsPrefix = false;
// The regular expression object which is equivalent to this glob pattern.
// Used for matching if, and only if, mPathLiteral is non-void.
JS::Heap<JSObject*> mRegExp;
};
class MatchGlobSet final : public nsTArray<RefPtr<MatchGlob>>
{
public:
// Note: We can't use the nsTArray constructors directly, since the static
// analyzer doesn't handle their MOZ_IMPLICIT annotations correctly.
MatchGlobSet() {}
explicit MatchGlobSet(size_type aCapacity) : nsTArray(aCapacity) {}
explicit MatchGlobSet(const nsTArray& aOther) : nsTArray(aOther) {}
MOZ_IMPLICIT MatchGlobSet(nsTArray&& aOther) : nsTArray(mozilla::Move(aOther)) {}
MOZ_IMPLICIT MatchGlobSet(std::initializer_list<RefPtr<MatchGlob>> aIL) : nsTArray(aIL) {}
bool Matches(const nsAString& aValue) const;
};
} // namespace extensions
} // namespace mozilla
#endif // mozilla_extensions_MatchGlob_h