/* * eXist Open Source Native XML Database * Copyright (C) 2012 The eXist Project * http://exist-db.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * $Id$ */ package org.exist.storage; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; import org.exist.util.ByteConversion; import org.w3c.dom.Node; /** * Static methods to deal with the signature of a node stored * in the first byte of the node data in the persistent DOM. * * The bits in the signature are used as follows: * * <pre> * 8 4 2 1 8 4 2 1 * T T T N 0 0 I I * </pre> * * where T = node type, N = has-namespace flag, I = number of bytes used * to store the name of the node (local name for elements and attributes). */ public final class Signatures { private final static Logger LOG = LogManager.getLogger(Signatures.class); public final static int Char = 0x0; public final static int Elem = 0x1; public final static int Proc = 0x2; public final static int Comm = 0x3; public final static int Attr = 0x4; public final static int Cdata = 0x5; public final static int intContent = 0x1; public final static int byteContent = 0x3; public final static int noContent = 0x0; public final static int shortContent = 0x2; /** * Returns the storage size of the given type as * number of bytes required. */ public final static int getLength(int type) { switch (type) { case intContent: return 4; case shortContent: return 2; case byteContent: return 1; } //TODO : throw an exception there ? -pb return 0; } /** * Returns one of IntContent, ShortContent, ByteContent * or NoContent based on the number of bytes required * to store the integer value given in length. */ public final static byte getSizeType( int length ) { if (length > Short.MAX_VALUE) {return intContent;} else if (length > Byte.MAX_VALUE) {return shortContent;} else if (length > 0) {return byteContent;} else {return noContent;} } /** * From the signature in byte 0 of the node data, * extract the node type and return a constant * as defined in {@link Node}. */ public final static short getType(byte signature) { final byte type = (byte)((signature & 0xE0) >> 0x5); switch (type) { case Char: return Node.TEXT_NODE; case Elem: return Node.ELEMENT_NODE; case Attr: return Node.ATTRIBUTE_NODE; case Proc: return Node.PROCESSING_INSTRUCTION_NODE; case Comm: return Node.COMMENT_NODE; case Cdata: return Node.CDATA_SECTION_NODE; } //TODO : thorw exception here -pb LOG.error("Unknown node type : " + type); return -1; } public final static int read(int type, byte[] data, int pos) { switch ( type ) { case intContent: return (int) ByteConversion.byteToInt(data, pos); case shortContent: return (int) ByteConversion.byteToShort(data, pos); case byteContent: return (int) data[pos]; } return 0; } public final static void write( int type, int size, byte[] data, int pos ) { switch ( type ) { case intContent: ByteConversion.intToByte( size, data, pos ); break; case shortContent: ByteConversion.shortToByte( (short) size, data, pos ); break; case byteContent: data[pos] = (byte) size; break; } //TODO : throw exception here ? -pb } }