/* Woodstox Lite ("wool") XML processor
 *
 * Copyright (c) 2006- Tatu Saloranta, tatu.saloranta@iki.fi
 *
 * Licensed under the License specified in the file LICENSE which is
 * included with the source code.
 * You may not use this file except in compliance with the License.
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.fasterxml.aalto.in;

import com.fasterxml.aalto.impl.ErrorConsts;

An alternate implementation of PName: instead of coming straight from byte contents, it is actually just built from a character array.

Note: one unfortunate result of this being a somewhat different PName is that equality comparison between this and other implementations will not work as expected. As such, these should only be used as temporary names.

/** * An alternate implementation of PName: instead of coming straight from * byte contents, it is actually just built from a character array. *<p> * Note: one unfortunate result of this being a somewhat different PName * is that equality comparison between this and other implementations will not * work as expected. As such, these should only be used as temporary names. */
public final class PNameC extends PName {
Since the hash may be calculated different from the way eventual String's hash will be (right now it is not), we better store "our" hash here.
/** * Since the hash may be calculated different from the way eventual * String's hash will be (right now it is not), we better store * "our" hash here. */
protected final int mHash; public PNameC(String pname, String prefix, String ln, int hash) { super(pname, prefix, ln); mHash = hash; } @Override public PName createBoundName(NsBinding nsb) { PNameC newName = new PNameC(_prefixedName, _prefix, _localName, mHash); newName._namespaceBinding = nsb; return newName; } public static PNameC construct(String pname) { return construct(pname, calcHash(pname)); } public static PNameC construct(String pname, int hash) { int colonIx = pname.indexOf(':'); if (colonIx < 0) { return new PNameC(pname, null, pname, hash); } /* !!! TODO: cache prefix intern() calls, since they are bound * to cluster nicely (and quite often within same thread too) */ return new PNameC(pname, pname.substring(0, colonIx).intern(), pname.substring(colonIx+1).intern(), hash); } /* ////////////////////////////////////////////////////////// // Sub-class API ////////////////////////////////////////////////////////// */ public boolean equalsPName(char[] buffer, int start, int len, int hash) { if (hash != mHash) { return false; } String pname = _prefixedName; int plen = pname.length(); if (len != plen) { return false; } for (int i = 0; i < len; ++i) { if (buffer[start+i] != pname.charAt(i)) { return false; } } return true; } public int getCustomHash() { return mHash; }
Implementation of a hashing method for variable length Strings. Most of the time intention is that this calculation is done by caller during parsing, not here; however, sometimes it needs to be done for parsed "String" too.
Params:
  • len – Length of String; has to be at least 1 (caller guarantees this pre-condition)
/** * Implementation of a hashing method for variable length * Strings. Most of the time intention is that this calculation * is done by caller during parsing, not here; however, sometimes * it needs to be done for parsed "String" too. * * @param len Length of String; has to be at least 1 (caller guarantees * this pre-condition) */
public static int calcHash(char[] buffer, int start, int len) { int hash = (int) buffer[0]; for (int i = 1; i < len; ++i) { hash = (hash * 31) + (int) buffer[i]; } return hash; } public static int calcHash(String key) { int hash = (int) key.charAt(0); for (int i = 1, len = key.length(); i < len; ++i) { hash = (hash * 31) + (int) key.charAt(i); } return hash; } /* ////////////////////////////////////////////////////////// // Methods for package/core parser ////////////////////////////////////////////////////////// */
This method should never get called on instances of this class, so let's throw an exception if that does happen.
/** * This method should never get called on instances of this class, * so let's throw an exception if that does happen. */
@Override public int sizeInQuads() { ErrorConsts.throwInternalError(); return 0; // never gets here } @Override public int getFirstQuad() { ErrorConsts.throwInternalError(); return 0; // never gets here } @Override public final int getLastQuad() { ErrorConsts.throwInternalError(); return 0; // never gets here } @Override public int getQuad(int index) { ErrorConsts.throwInternalError(); return 0; // never gets here } /* ////////////////////////////////////////////////////////// // Redefined standard methods ////////////////////////////////////////////////////////// */
Whether we should use internal hash, or the hash of prefixed name string itself is an open question. For now, let's use former.
/** * Whether we should use internal hash, or the hash of prefixed * name string itself is an open question. For now, let's use * former. */
@Override public int hashCode() { return mHash; } }