JDocCoverage Report - 21.04.2006 22:02:51

Namemethod, %comment, %TODO@see
smallsql.database.Utils275,4%   (433/7551)00

/* =============================================================
 * SmallSQL : a free Java DBMS library for the Java(tm) platform
 * =============================================================
 *
 * (C) Copyright 2004-2006, by Volker Berlin.
 *
 * Project Info:  http://www.smallsql.de/
 *
 * This library 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.1 of the License, or 
 * (at your option) any later version.
 *
 * This library 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 Street, Fifth Floor, Boston, MA  02110-1301, 
 * USA.  
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
 * in the United States and other countries.]
 *
 * ---------------
 * Utils.java
 * ---------------
 * Author: Volker Berlin
 * 
 */
package smallsql.database;

import java.sql.*;


class Utils {

	static final String MASTER_FILENAME = "smallsql.master";
	static final String TABLE_VIEW_EXTENTION = ".sdb";
	private static final String LOB_EXTENTION = ".lob";
	static final String IDX_EXTENTION = ".idx";
	private static final Integer[] integerCache = new Integer[260];
	private static final Short[]   shortCache   = new Short[260];
	static{
		for(int i=-4; i<256; i++){
			integerCache[ i+4 ] = new Integer(i);
			shortCache  [ i+4 ] = new Short((short)i);
		}
	}
	
    static SQLException createSQLException( String msg ){
        return new SmallSQLException( msg );
    }

    static SQLException createSQLException( Throwable e ){
        if(e instanceof SQLException) return (SQLException)e;
        return new SmallSQLException( e );
    }

    static String createTableViewFileName(Database database, String name){
        return database.getName() + '/' + name + TABLE_VIEW_EXTENTION;
    }

	static String createLobFileName(Database database, String name){
		return database.getName() + '/' + name + LOB_EXTENTION;
	}

	static String createIdxFileName(Database database, String name){
		return database.getName() + '/' + name + IDX_EXTENTION;
	}

	static boolean like(String value, String pattern){
		if(value == null || pattern == null) return false;
		if(pattern.length() == 0) return true;

		int mIdx = 0;//index in mask Array
		int sIdx = 0;//index in search Array
		boolean range = false;
		weiter:
		while(pattern.length() > mIdx && value.length() > sIdx) {
			char m = Character.toUpperCase(pattern.charAt(mIdx++));
			switch(m) {
				case '%':
					range = true;
					break;
				case '_':
					sIdx++;
					break;
				default:
					if(range) {//* wildcard ist aktiv
						for(; sIdx < value.length(); sIdx++) {
							if(Character.toUpperCase(value.charAt(sIdx)) == m) break;//Zähler darf nicht vor dem break erhöht werden
						}
						if(sIdx >= value.length()) return false;
						int lastmIdx = mIdx - 1;
						sIdx++;
						while(pattern.length() > mIdx && value.length() > sIdx) {
							m = Character.toUpperCase(pattern.charAt(mIdx++));
							if(Character.toUpperCase(value.charAt(sIdx)) != m) {
								if(m == '%' || m == '_') {
									mIdx--;
									break;
								}
								mIdx = lastmIdx;
								continue weiter;
							}
							sIdx++;
						}
						range = false;
					}else{
						if(Character.toUpperCase(value.charAt(sIdx)) != m) return false;
						sIdx++;
					}
					break;
			}
		}
		while(pattern.length() > mIdx) {
			//Suchmaske ist noch nicht zu ende es dürfen nur noch '*' enthalten sein
			if(Character.toUpperCase(pattern.charAt(mIdx++)) != '*') return false;
		}
		while(value.length() > sIdx && !range) return false;
		return true;
	}
	
	
	static int long2int(long value){
		if(value > Integer.MAX_VALUE)
			return Integer.MAX_VALUE;
		if(value < Integer.MIN_VALUE)
			return Integer.MIN_VALUE;
		return (int)value;
	}
	
	static long double2long(double value){
		if(value > Long.MAX_VALUE)
			return Long.MAX_VALUE;
		if(value < Long.MIN_VALUE)
			return Long.MIN_VALUE;
		return (long)value;
	}



    static float bytes2float( byte[] bytes ){
        return Float.intBitsToFloat( bytes2int( bytes ) );
    }

    static double bytes2double( byte[] bytes ){
        return Double.longBitsToDouble( bytes2long( bytes ) );
    }

    static long bytes2long( byte[] bytes ){
        long result = 0;
        int length = Math.min( 8, bytes.length);
        for(int i=0; i<length; i++){
            result = (result << 8) | (bytes[i] & 0xFF);
        }
        return result;
    }

    static int bytes2int( byte[] bytes ){
        int result = 0;
        int length = Math.min( 4, bytes.length);
        for(int i=0; i<length; i++){
            result = (result << 8) | (bytes[i] & 0xFF);
        }
        return result;
    }

	static byte[] int2bytes( int value ){
		byte[] result = new byte[4];
		result[0] = (byte)(value >> 24);
		result[1] = (byte)(value >> 16);
		result[2] = (byte)(value >> 8);
		result[3] = (byte)(value);
		return result;
	}

    static String bytes2hex( byte[] bytes ){
        StringBuffer buf = new StringBuffer(bytes.length << 1);
        for(int i=0; i<bytes.length; i++){
            buf.append( digits[ (bytes[i] >> 4) & 0x0F ] );
            buf.append( digits[ (bytes[i]     ) & 0x0F ] );
        }
        return buf.toString();
    }

    static byte[] hex2bytes( char[] hex, int offset, int length) throws SQLException{
        try{
            byte[] bytes = new byte[length / 2];
            for(int i=0; i<bytes.length; i++){
                bytes[i] = (byte)((hexDigit2int( hex[ offset++ ] ) << 4)
                                | hexDigit2int( hex[ offset++ ] ));
            }
            return bytes;
        }catch(Exception e){
             throw new SQLException("Invalid hex sequense at " + offset/*, offset*/);
        }
    }

    private static int hexDigit2int(char digit){
        if(digit >= '0' && digit <= '9') return digit - '0';
        digit |= 0x20;
        if(digit >= 'a' && digit <= 'f') return digit - 'W'; // -'W'  ==  -'a' + 10
        throw new RuntimeException();
    }

    static byte[] unique2bytes( String unique ) throws SQLException{
        char[] chars = unique.toCharArray();
        byte[] daten = new byte[16];
        daten[3] = hex2byte( chars, 0 );
        daten[2] = hex2byte( chars, 2 );
        daten[1] = hex2byte( chars, 4 );
        daten[0] = hex2byte( chars, 6 );

        daten[5] = hex2byte( chars, 9 );
        daten[4] = hex2byte( chars, 11 );

        daten[7] = hex2byte( chars, 14 );
        daten[6] = hex2byte( chars, 16 );

        daten[8] = hex2byte( chars, 19 );
        daten[9] = hex2byte( chars, 21 );

        daten[10] = hex2byte( chars, 24 );
        daten[11] = hex2byte( chars, 26 );
        daten[12] = hex2byte( chars, 28 );
        daten[13] = hex2byte( chars, 30 );
        daten[14] = hex2byte( chars, 32 );
        daten[15] = hex2byte( chars, 34 );
        return daten;
    }

    private static byte hex2byte( char[] hex, int offset) throws SQLException{
        try{
                return (byte)((hexDigit2int( hex[ offset++ ] ) << 4)
                                | hexDigit2int( hex[ offset++ ] ));
        }catch(Exception e){
             throw new SQLException("Invalid hex sequense at position " + offset + " in '" + new String(hex) + '\'');
        }
    }

    static String bytes2unique( byte[] daten, int offset ){
    	if(daten.length-offset < 16){
    		byte[] temp = new byte[16];
    		System.arraycopy(daten, offset, temp, 0, daten.length-offset);
    		daten = temp;
    	}
        char[] chars = new char[36];
        chars[8] = chars[13] = chars[18] = chars[23] = '-';

        chars[0] = digits[ (daten[offset+3] >> 4) & 0x0F ];
        chars[1] = digits[ (daten[offset+3]     ) & 0x0F ];
        chars[2] = digits[ (daten[offset+2] >> 4) & 0x0F ];
        chars[3] = digits[ (daten[offset+2]     ) & 0x0F ];
        chars[4] = digits[ (daten[offset+1] >> 4) & 0x0F ];
        chars[5] = digits[ (daten[offset+1]     ) & 0x0F ];
        chars[6] = digits[ (daten[offset+0] >> 4) & 0x0F ];
        chars[7] = digits[ (daten[offset+0]     ) & 0x0F ];

        chars[ 9] = digits[ (daten[offset+5] >> 4) & 0x0F ];
        chars[10] = digits[ (daten[offset+5]     ) & 0x0F ];
        chars[11] = digits[ (daten[offset+4] >> 4) & 0x0F ];
        chars[12] = digits[ (daten[offset+4]     ) & 0x0F ];

        chars[14] = digits[ (daten[offset+7] >> 4) & 0x0F ];
        chars[15] = digits[ (daten[offset+7]     ) & 0x0F ];
        chars[16] = digits[ (daten[offset+6] >> 4) & 0x0F ];
        chars[17] = digits[ (daten[offset+6]     ) & 0x0F ];

        chars[19] = digits[ (daten[offset+8] >> 4) & 0x0F ];
        chars[20] = digits[ (daten[offset+8]     ) & 0x0F ];
        chars[21] = digits[ (daten[offset+9] >> 4) & 0x0F ];
        chars[22] = digits[ (daten[offset+9]     ) & 0x0F ];

        chars[24] = digits[ (daten[offset+10] >> 4) & 0x0F ];
        chars[25] = digits[ (daten[offset+10]     ) & 0x0F ];
        chars[26] = digits[ (daten[offset+11] >> 4) & 0x0F ];
        chars[27] = digits[ (daten[offset+11]     ) & 0x0F ];
        chars[28] = digits[ (daten[offset+12] >> 4) & 0x0F ];
        chars[29] = digits[ (daten[offset+12]     ) & 0x0F ];
        chars[30] = digits[ (daten[offset+13] >> 4) & 0x0F ];
        chars[31] = digits[ (daten[offset+13]     ) & 0x0F ];
        chars[32] = digits[ (daten[offset+14] >> 4) & 0x0F ];
        chars[33] = digits[ (daten[offset+14]     ) & 0x0F ];
        chars[34] = digits[ (daten[offset+15] >> 4) & 0x0F ];
        chars[35] = digits[ (daten[offset+15]     ) & 0x0F ];
        return new String(chars);
    }

    static boolean string2boolean( String val){
        try{
            return Double.parseDouble( val ) != 0;
        }catch(NumberFormatException e){}
        return "true".equalsIgnoreCase( val ) || "yes".equalsIgnoreCase( val ) || "t".equalsIgnoreCase( val );
    }
	
	
	static long doubleToMoney(double value){
		if(value < 0)
			return (long)(value * 10000 - 0.5);
		return (long)(value * 10000 + 0.5);
	}

    static int indexOf( char value, char[] str, int offset, int length ){
        value |= 0x20;
        for(int end = offset+length;offset < end; offset++){
            if((str[offset] | 0x20) == value) return offset;
        }
        return -1;
    }

    static int indexOf( int value, int[] list ){
        int offset = 0;
        for(int end = list.length; offset < end; offset++){
            if((list[offset]) == value) return offset;
        }
        return -1;
    }

    static int compareBytes( byte[] leftBytes, byte[] rightBytes){
        int length = Math.min( leftBytes.length, rightBytes.length );
        int comp = 0;
        for(int i=0; i<length; i++){
            if(leftBytes[i] != rightBytes[i]){
                comp = leftBytes[i] < rightBytes[i] ? -1 : 1;
                break;
            }
        }
        if(comp == 0 && leftBytes.length != rightBytes.length){
            comp = leftBytes.length < rightBytes.length ? -1 : 1;
        }
        return comp;
    }
	
    
    /**
     * 
     * @param colNames
     * @param data
     * @return
     * @throws SQLException
     */
    static CommandSelect createMemoryCommandSelect( SSConnection con, String[] colNames, Object[][] data) throws SQLException{
		MemoryResult source = new MemoryResult(data, colNames.length);
		CommandSelect cmd = new CommandSelect(con.log);
		for(int i=0; i<colNames.length; i++){
			ExpressionName expr = new ExpressionName(colNames[i]);
			cmd.addColumnExpression( expr );
			expr.setFrom( source, i, new Column());
		}
		cmd.setSource(source);
		return cmd;
    }
	

	// receycle Integer objects, this is faster as to garbage the objects
	static final Integer getInteger(int value){
		if(value >= -4 && value < 256){
			return integerCache[ value+4 ];		
		}else
			return new Integer(value);
	}
	
	// receycle Integer objects, this is faster as to garbage the objects
	static final Short getShort(int value){
		if(value >= -4 && value < 256){
			return shortCache[ value+4 ];		
		}else
			return new Short((short)value);
	}
	
    final static char[] digits = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
}