net.sf.saxon.om.PrefixPool Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Saxon-HE Show documentation
Show all versions of Saxon-HE Show documentation
The XSLT and XQuery Processor
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2018-2023 Saxonica Limited
// 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/.
// This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
package net.sf.saxon.om;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* A prefix pool maintains a two-way mapping from namespace prefixes (as strings) to
* integer prefix codes. Prefix codes always fit in 11 bits, but are handled as ints.
*
* Until 9.8, prefixes were managed by the NamePool. The NamePool now only handles
* fingerprints, which are integer representations of the URI and local name parts of
* a QName. Prefix codes are now used only in the tinytree, and the table of codes
* is local to a document. For this reason, access is not synchronised.
*/
public class PrefixPool {
private final static int LIMIT = 2047;
String[] prefixes = new String[8];
int used = 0;
Map index = null;
public PrefixPool() {
prefixes[0] = "";
used = 1;
}
/**
* Get the prefix code corresponding to a given prefix, allocating a new code if necessary
* @param prefix the namespace prefix. If empty, the prefix code is always zero.
* @return the integer prefix code (always fits in 10 bits)
*/
public int obtainPrefixCode(String prefix) {
if (prefix.isEmpty()) {
return 0;
}
// Create an index if it's going to be useful
if (index == null && used > 8) {
makeIndex();
}
// See if the prefix is already known
if (index != null) {
int existing = index.getOrDefault(prefix, -1);
if (existing != -1) {
return existing;
}
} else {
for (int i=0; i LIMIT) {
throw new IllegalStateException("Too many namespace prefixes - limit is " + LIMIT + " per document");
}
if (used >= prefixes.length) {
prefixes = Arrays.copyOf(prefixes, used * 2);
}
prefixes[code] = prefix;
if (index != null) {
index.put(prefix, code);
}
return code;
}
private void makeIndex() {
index = new HashMap<>(used);
for (int i=0; i