package tctable; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; public class TCField { //Типы данных public static final int BD_NULL = 1000; //Столбец со значением всегда NULL public static final int BD_UINT1_B = 27; //1 байт без знаковый Boolean public static final int BD_UINT1 = 0; //1 байт без знаковый public static final int BD_UINT2 = 1; //2 байта без знаковый public static final int BD_UINT4 = 3; //4 байта без знаковый public static final int BD_UINT8 = 23; //8 байта без знаковый public static final int BD_SUINT8 = 24; //Почти тоже самое что и BD_UTF8_1 но с строке передаётся число public static final int BD_INT1 = 10; //1 байт со знаковый public static final int BD_INT2 = 11; //2 байта со знаковый public static final int BD_INT4 = 13; //4 байта со знаковый public static final int BD_INT8 = 17; //8 байт со знаковый public static final int BD_SINT8 = 25; //Почти тоже самое что и BD_UTF8_1 но с строке передаётся число public static final int BD_FLOAT4 = 20; //4 байта public static final int BD_FLOAT8 = 22; //8 байт double public static final int BD_SFLOAT8 = 26; //Почти тоже самое что и BD_UTF8_1 но с строке передаётся число public static final int BD_UTF8_1 = 100; //100 - utf8_1 string 1й байт размер строки в байтах public static final int BD_UTF8_1_UUID = 103; //103 - utf8_1 string 1й байт размер строки в байтах public static final int BD_UTF8_1_TIMESTAMP = 105; //103 - utf8_1 string 1й байт размер строки в байтах public static final int BD_UTF8_2 = 101; //101 - utf8_2 string 1х 2 байта размер строки в байтах public static final int BD_UTF8_4 = 102; //102 - utf8_4 string 1х 4 байта размер строки в байтах public static final int BD_UTF8_4_JSONB = 104; //102 - utf8_4 string 1х 4 байта размер строки в байтах public static final int BD_BLOB_2 = 141; public static final int BD_BLOB_4 = 143; //Двоичные данные uint4 количество байт public boolean u_exists=false; //Пользовательское поле (Для упрощения экспорта данных из базы в базу) public String u_type=""; //Пользовательское поле public String name=""; //Название столбца public int type=-1; //Тип данных public byte[] value=null; //Запакованые данные public TCField(String name, int type) { this.name=name; this.type=type; } public TCField(String name, String type) { this.name=name; //this.type=type; this.type= TCField.BD_UTF8_2; //Defalt type //From PostgreSQL and MySQL if(type.equals("null")) { this.type= TCField.BD_NULL; } else if(type.equals("bool")) { this.type= TCField.BD_UINT1_B; } else if(type.equals("tinyint")) { this.type= TCField.BD_UINT1; } else if(type.equals("int4") || type.equals("int") || type.equals("serial") || type.equals("bigint")) { this.type= TCField.BD_INT4; } else //bigint немного неправильно потому что это 64 бита но для андрод приложения не сделал if(type.equals("int8")) { this.type= TCField.BD_INT8; } else if(type.equals("float4") || type.equals("float")) { this.type= TCField.BD_FLOAT4; } else if(type.equals("float8") || type.equals("NUMBER")) { this.type= TCField.BD_FLOAT8; } else if(type.equals("varchar") || type.equals("VARCHAR2")) { this.type= TCField.BD_UTF8_2; } else if(type.equals("text")) { this.type= TCField.BD_UTF8_4; } else if(type.equals("jsonb")) { this.type= TCField.BD_UTF8_4_JSONB; } else if(type.equals("bytea") || type.equals("longblob")) { this.type= TCField.BD_BLOB_4; } else if(type.equals("timestamptz")) { this.type= TCField.BD_UTF8_1; } else if(type.equals("uuid")) { this.type= TCField.BD_UTF8_1_UUID; } else if(type.equals("timestamp")) { this.type= TCField.BD_UTF8_1_TIMESTAMP; } else if(type.equals("date")) { this.type= TCField.BD_UTF8_1; } } private int byteArrayToInt(byte[] b, int start, int length) { int dt = 0; if ((b[start] & 0x80) != 0) dt = Integer.MAX_VALUE; for (int i = 0; i < length; i++) dt = (dt << 8) + (b[start++] & 255); return dt; } /* private byte[] intToByteArray(int n, int byteCount) { byte[] res = new byte[byteCount]; for (int i = 0; i < byteCount; i++) res[byteCount - i - 1] = (byte) ((n >> i * 8) & 255); return res; } */ //Прочитать значение из потока в соответствии с типом public void ReadValue(InputStream fileHandle) throws IOException { if(this.type == TCField.BD_UINT1 || this.type == TCField.BD_UINT1_B) { value=new byte[1]; fileHandle.read(value); }else if(this.type== TCField.BD_UINT2) { value=new byte[2]; fileHandle.read(value); }else if(this.type== TCField.BD_UINT4) { value=new byte[4]; fileHandle.read(value); }else if(this.type== TCField.BD_UINT8) { value=new byte[8]; fileHandle.read(value); }else if(this.type== TCField.BD_INT1) { value=new byte[1]; fileHandle.read(value); }else if(this.type== TCField.BD_INT2) { value=new byte[2]; fileHandle.read(value); }else if(this.type== TCField.BD_INT4) { value=new byte[4]; fileHandle.read(value); }else if(this.type== TCField.BD_INT8) { value=new byte[8]; fileHandle.read(value); }else if(this.type== TCField.BD_FLOAT4) { value=new byte[4]; fileHandle.read(value); }else if(this.type== TCField.BD_FLOAT8) { value=new byte[8]; fileHandle.read(value); }else if(this.type== TCField.BD_UTF8_1 || this.type== TCField.BD_UTF8_1_UUID || this.type== TCField.BD_UTF8_1_TIMESTAMP || this.type== TCField.BD_SUINT8 || this.type== TCField.BD_SINT8 || this.type== TCField.BD_SFLOAT8) { byte[] s=new byte[1]; fileHandle.read(s); if(s[0]==0) value=null; else { value=new byte[s[0]]; fileHandle.read(value); } }else if(this.type== TCField.BD_UTF8_2) { int s=Tools.readUShort(fileHandle); if(s==0) value=null; else { value=new byte[s]; fileHandle.read(value); } }else if(this.type== TCField.BD_UTF8_4 || this.type== TCField.BD_UTF8_4_JSONB) { long s=Tools.readUInt(fileHandle); if(s==0) value=null; else { value=new byte[(int)s]; fileHandle.read(value); } }else if(this.type== TCField.BD_BLOB_4) { byte[] ss=new byte[4]; fileHandle.read(ss); int s=byteArrayToInt(ss, 0, 4); if(s==0) value=null; else { value=new byte[s]; fileHandle.read(value); } } } public String getStrVal() { String result=null; try { if(value==null) result = ""; if(type== TCField.BD_UINT1 || type== TCField.BD_UINT1_B) result = String.valueOf(getUByteVal()); if(type== TCField.BD_UINT4) result = String.valueOf(getUIntVal()); if(type== TCField.BD_UINT8) result = String.valueOf(getULongVal()); if(type== TCField.BD_INT4) result = String.valueOf(getIntVal()); if(type== TCField.BD_INT8) result = String.valueOf(getLongVal()); if(type== TCField.BD_FLOAT4) result = String.valueOf(getFloatVal()); if(type== TCField.BD_FLOAT8) result = String.valueOf(getDoubleVal()); if(type== TCField.BD_UTF8_1 || type== TCField.BD_UTF8_1_UUID || type== TCField.BD_UTF8_1_TIMESTAMP || type== TCField.BD_UTF8_2 || type== TCField.BD_UTF8_4 || type== TCField.BD_UTF8_4_JSONB || type== TCField.BD_SUINT8 || type== TCField.BD_SINT8 || type== TCField.BD_SFLOAT8) { result = new String(value, "UTF8"); } } catch (Exception e) {} return result; } public boolean getBoolVal(){ String result=getStrVal(); if(result==null) return false; else { result=result.toLowerCase(); if (result.equals("1") || result.equals("true") || result.equals("t")) return true; else return false; } } public int getIntVal() { int val=0; if(type==BD_INT4) { int i1 = value[0] & 0xff; int i2 = value[1] & 0xff; int i3 = value[2] & 0xff; int i4 = value[3] & 0xff; val = i4 << 24 | i3 << 16 | i2 << 8 | i1; }else{ String sVal = getStrVal(); if(sVal!=null) { try { val = Integer.valueOf(sVal); } catch (NumberFormatException e) { } } } return val; } public long getLongVal() { long val=0; if(type==BD_INT8) { long ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8; ch1 = value[0] & 0xff; ch2 = value[1] & 0xff; ch3 = value[2] & 0xff; ch4 = value[3] & 0xff; ch5 = value[4] & 0xff; ch6 = value[5] & 0xff; ch7 = value[6] & 0xff; ch8 = value[7] & 0xff; val = (ch8 << 56) | (ch7 << 48) | (ch6 << 40) | (ch5 << 32) | (ch4 << 24) | (ch3 << 16) | (ch2 << 8) | ch1; }else{ String sVal = getStrVal(); if(sVal!=null) { try { val = Long.valueOf(sVal); } catch (NumberFormatException e) { } } } return val; } /** Пока не использую но если буду использовать протестировать с большими числами */ public long getUIntVal() { long val=0; if(type==BD_UINT4) { long ch1, ch2, ch3, ch4; ch1 = value[0] & 0xff; ch2 = value[1] & 0xff; ch3 = value[2] & 0xff; ch4 = value[3] & 0xff; val = (ch4 << 24) | (ch3 << 16) | (ch2 << 8) | ch1; }else{ String sVal = getStrVal(); if(sVal!=null) { try { val = Long.valueOf(sVal); } catch (NumberFormatException e) { } } } return val; } public long getULongVal() { long val=0; if(type==BD_UINT8) { long ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8; ch1 = value[0] & 0xff; ch2 = value[1] & 0xff; ch3 = value[2] & 0xff; ch4 = value[3] & 0xff; ch5 = value[4] & 0xff; ch6 = value[5] & 0xff; ch7 = value[6] & 0xff; ch8 = value[7] & 0xff; val = (ch8 << 56) | (ch7 << 48) | (ch6 << 40) | (ch5 << 32) | (ch4 << 24) | (ch3 << 16) | (ch2 << 8) | ch1; }else{ String sVal = getStrVal(); if(sVal!=null) { try { val = Long.valueOf(sVal); } catch (NumberFormatException e) { } } } return val; } public short getUByteVal() { short val=0; if(type==BD_UINT1 || type==BD_UINT1_B) { val = (short) (value[0] & 0xff); }else{ String sVal = getStrVal(); if(sVal!=null) { try { val = Short.valueOf(sVal); } catch (NumberFormatException e) { } } } return val; } public float getFloatVal() { float val=0; if(type==BD_FLOAT4) { int ch1, ch2, ch3, ch4, count; ch1 = value[0] & 0xFF; ch2 = value[1] & 0xFF; ch3 = value[2] & 0xFF; ch4 = value[3] & 0xFF; count = (ch4 << 24) | (ch3 << 16) | (ch2 << 8) | ch1; val = Float.intBitsToFloat(count); }else{ String sVal = getStrVal(); if(sVal!=null) { try { val = Float.valueOf(sVal); } catch (NumberFormatException e) { } } } return val; } public double getDoubleVal() { double val=0; if(type==BD_FLOAT8) { int ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8; long count; ch1 = value[0] & 0xFF; ch2 = value[1] & 0xFF; ch3 = value[2] & 0xFF; ch4 = value[3] & 0xFF; ch5 = value[4] & 0xFF; ch6 = value[5] & 0xFF; ch7 = value[6] & 0xFF; ch8 = value[7] & 0xFF; count = ((long) ch8 << 56) | ((long) ch7 << 48) | ((long) ch6 << 40) | ((long) ch5 << 32) | ((long) ch4 << 24) | ((long) ch3 << 16) | ((long) ch2 << 8) | ch1; val = Double.longBitsToDouble(count); }else{ String sVal = getStrVal(); if(sVal!=null) { try { val = Double.valueOf(sVal); } catch (NumberFormatException e) { } } } return val; } public boolean setDoubleVal(Double v){ long iv= Double.doubleToLongBits(v); value=new byte[8]; value[0] = (byte)((iv & 0x00000000000000ffl)); value[1] = (byte)((iv & 0x000000000000ff00l) >> 8); value[2] = (byte)((iv & 0x0000000000ff0000l) >> 16); value[3] = (byte)((iv & 0x00000000ff000000l) >> 24); value[4] = (byte)((iv & 0x000000ff00000000l) >> 32); value[5] = (byte)((iv & 0x0000ff0000000000l) >> 40); value[6] = (byte)((iv & 0x00ff000000000000l) >> 48); value[7] = (byte)((iv & 0xff00000000000000l) >> 56); return true; } public boolean setValue(String val) { boolean result=true; if(val==null) { value=null; }else if(type== TCField.BD_UINT1 || type== TCField.BD_UINT1_B) { if(val.equals("f") || val.equals("false")) val="0"; else if(val.equals("t") || val.equals("true")) val="1"; int v= Integer.parseInt(val); if(v<0 || v>255) result=false; value=new byte[1]; value[0]=(byte)v; }else if(type== TCField.BD_UINT2) { int v= Integer.parseInt(val); if(v<0 || v>65535) result=false; value=new byte[2]; value[0] = (byte)((v & 0x000000ff)); value[1] = (byte)((v & 0x0000ff00) >> 8); }else if(type== TCField.BD_UINT4) { long v= Long.parseLong(val); value=new byte[4]; value[0] = (byte)((v & 0x000000ff)); value[1] = (byte)((v & 0x0000ff00) >> 8); value[2] = (byte)((v & 0x00ff0000) >> 16); value[3] = (byte)((v & 0xff000000) >> 24); }else if(type== TCField.BD_UINT8) { long v= Long.parseLong(val); value=new byte[8]; value[0] = (byte) (v & 0x00000000000000ffl); value[1] = (byte)((v & 0x000000000000ff00l) >> 8); value[2] = (byte)((v & 0x0000000000ff0000l) >> 16); value[3] = (byte)((v & 0x00000000ff000000l) >> 24); value[4] = (byte)((v & 0x000000ff00000000l) >> 32); value[5] = (byte)((v & 0x0000ff0000000000l) >> 40); value[6] = (byte)((v & 0x00ff000000000000l) >> 48); value[7] = (byte)((v & 0xff00000000000000l) >> 56); }else if(type== TCField.BD_INT1) { int v= Integer.parseInt(val); value=new byte[1]; value[0]=(byte)v; }else if(type== TCField.BD_INT2) { int v= Integer.parseInt(val); value=new byte[2]; value[0] = (byte)((v & 0x000000ff)); value[1] = (byte)((v & 0x0000ff00) >> 8); }else if(type== TCField.BD_INT4) { long v= Long.parseLong(val); value=new byte[4]; value[0] = (byte)((v & 0x000000ff)); value[1] = (byte)((v & 0x0000ff00) >> 8); value[2] = (byte)((v & 0x00ff0000) >> 16); value[3] = (byte)((v & 0xff000000) >> 24); }else if(type== TCField.BD_INT8) { long v= Long.parseLong(val); value=new byte[8]; value[0] = (byte) (v & 0x00000000000000ffl); value[1] = (byte)((v & 0x000000000000ff00l) >> 8); value[2] = (byte)((v & 0x0000000000ff0000l) >> 16); value[3] = (byte)((v & 0x00000000ff000000l) >> 24); value[4] = (byte)((v & 0x000000ff00000000l) >> 32); value[5] = (byte)((v & 0x0000ff0000000000l) >> 40); value[6] = (byte)((v & 0x00ff000000000000l) >> 48); value[7] = (byte)((v & 0xff00000000000000l) >> 56); }else if(type== TCField.BD_FLOAT4) { Float v= Float.parseFloat(val); int iv= Float.floatToIntBits(v); value=new byte[4]; value[0] = (byte)((iv & 0x000000ff)); value[1] = (byte)((iv & 0x0000ff00) >> 8); value[2] = (byte)((iv & 0x00ff0000) >> 16); value[3] = (byte)((iv & 0xff000000) >> 24); }else if(type== TCField.BD_FLOAT8) { setDoubleVal(Double.parseDouble(val)); }else if(type== TCField.BD_UTF8_1 || type== TCField.BD_UTF8_1_UUID || type== TCField.BD_UTF8_1_TIMESTAMP || this.type== TCField.BD_SUINT8 || this.type== TCField.BD_SINT8 || this.type== TCField.BD_SFLOAT8) { value=null; if(val!=null && !val.equals("")) { byte[] b=null; try { b = val.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { result=false; } if(b!=null) { int len=b.length; if(len>255) len=255; value=new byte[len+1]; value[0]=(byte)len; for(int i=0;i65535) len=65535; value=new byte[len+2]; value[0]=(byte) (len & 0x000000ff); value[1]=(byte)((len & 0x0000ff00) >> 8); for(int i=0;i> 8); value[2]=(byte)((len & 0x00ff0000) >> 16); value[3]=(byte)((len & 0xff000000) >> 24); for(int i=0;i