Mypal/dom/xslt/xslt/txKey.h
2019-03-11 13:26:37 +03:00

213 lines
5.7 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 txKey_h__
#define txKey_h__
#include "nsTHashtable.h"
#include "txNodeSet.h"
#include "txList.h"
#include "txXSLTPatterns.h"
#include "txXMLUtils.h"
class txPattern;
class Expr;
class txExecutionState;
class txKeyValueHashKey
{
public:
txKeyValueHashKey(const txExpandedName& aKeyName,
int32_t aRootIdentifier,
const nsAString& aKeyValue)
: mKeyName(aKeyName),
mKeyValue(aKeyValue),
mRootIdentifier(aRootIdentifier)
{
}
txExpandedName mKeyName;
nsString mKeyValue;
int32_t mRootIdentifier;
};
struct txKeyValueHashEntry : public PLDHashEntryHdr
{
public:
typedef const txKeyValueHashKey& KeyType;
typedef const txKeyValueHashKey* KeyTypePointer;
explicit txKeyValueHashEntry(KeyTypePointer aKey)
: mKey(*aKey),
mNodeSet(new txNodeSet(nullptr)) { }
txKeyValueHashEntry(const txKeyValueHashEntry& entry)
: mKey(entry.mKey),
mNodeSet(entry.mNodeSet) { }
bool KeyEquals(KeyTypePointer aKey) const;
static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
static PLDHashNumber HashKey(KeyTypePointer aKey);
enum { ALLOW_MEMMOVE = true };
txKeyValueHashKey mKey;
RefPtr<txNodeSet> mNodeSet;
};
typedef nsTHashtable<txKeyValueHashEntry> txKeyValueHash;
class txIndexedKeyHashKey
{
public:
txIndexedKeyHashKey(txExpandedName aKeyName,
int32_t aRootIdentifier)
: mKeyName(aKeyName),
mRootIdentifier(aRootIdentifier)
{
}
txExpandedName mKeyName;
int32_t mRootIdentifier;
};
struct txIndexedKeyHashEntry : public PLDHashEntryHdr
{
public:
typedef const txIndexedKeyHashKey& KeyType;
typedef const txIndexedKeyHashKey* KeyTypePointer;
explicit txIndexedKeyHashEntry(KeyTypePointer aKey)
: mKey(*aKey),
mIndexed(false) { }
txIndexedKeyHashEntry(const txIndexedKeyHashEntry& entry)
: mKey(entry.mKey),
mIndexed(entry.mIndexed) { }
bool KeyEquals(KeyTypePointer aKey) const;
static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
static PLDHashNumber HashKey(KeyTypePointer aKey);
enum { ALLOW_MEMMOVE = true };
txIndexedKeyHashKey mKey;
bool mIndexed;
};
typedef nsTHashtable<txIndexedKeyHashEntry> txIndexedKeyHash;
/**
* Class holding all <xsl:key>s of a particular expanded name in the
* stylesheet.
*/
class txXSLKey {
public:
explicit txXSLKey(const txExpandedName& aName) : mName(aName)
{
}
/**
* Adds a match/use pair.
* @param aMatch match-pattern
* @param aUse use-expression
* @return false if an error occurred, true otherwise
*/
bool addKey(nsAutoPtr<txPattern>&& aMatch, nsAutoPtr<Expr>&& aUse);
/**
* Indexes a subtree and adds it to the hash of key values
* @param aRoot Subtree root to index and add
* @param aKeyValueHash Hash to add values to
* @param aEs txExecutionState to use for XPath evaluation
*/
nsresult indexSubtreeRoot(const txXPathNode& aRoot,
txKeyValueHash& aKeyValueHash,
txExecutionState& aEs);
private:
/**
* Recursively searches a node, its attributes and its subtree for
* nodes matching any of the keys match-patterns.
* @param aNode Node to search
* @param aKey Key to use when adding into the hash
* @param aKeyValueHash Hash to add values to
* @param aEs txExecutionState to use for XPath evaluation
*/
nsresult indexTree(const txXPathNode& aNode, txKeyValueHashKey& aKey,
txKeyValueHash& aKeyValueHash, txExecutionState& aEs);
/**
* Tests one node if it matches any of the keys match-patterns. If
* the node matches its values are added to the index.
* @param aNode Node to test
* @param aKey Key to use when adding into the hash
* @param aKeyValueHash Hash to add values to
* @param aEs txExecutionState to use for XPath evaluation
*/
nsresult testNode(const txXPathNode& aNode, txKeyValueHashKey& aKey,
txKeyValueHash& aKeyValueHash, txExecutionState& aEs);
/**
* represents one match/use pair
*/
struct Key {
nsAutoPtr<txPattern> matchPattern;
nsAutoPtr<Expr> useExpr;
};
/**
* List of all match/use pairs. The items as |Key|s
*/
nsTArray<Key> mKeys;
/**
* Name of this key
*/
txExpandedName mName;
};
class txKeyHash
{
public:
explicit txKeyHash(const txOwningExpandedNameMap<txXSLKey>& aKeys)
: mKeyValues(4)
, mIndexedKeys(1)
, mKeys(aKeys)
{
}
nsresult init();
nsresult getKeyNodes(const txExpandedName& aKeyName,
const txXPathNode& aRoot,
const nsAString& aKeyValue,
bool aIndexIfNotFound,
txExecutionState& aEs,
txNodeSet** aResult);
private:
// Hash of all indexed key-values
txKeyValueHash mKeyValues;
// Hash showing which keys+roots has been indexed
txIndexedKeyHash mIndexedKeys;
// Map of txXSLKeys
const txOwningExpandedNameMap<txXSLKey>& mKeys;
// Empty nodeset returned if no key is found
RefPtr<txNodeSet> mEmptyNodeSet;
};
#endif //txKey_h__