package org.exist.storage; 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 = no of bytes used to store * the name of the node (local name for elements and attributes). */ public final class Signatures { 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; } 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 ) { 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; } System.err.println( "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; } } }