ttomcat-1778514358873.zip-extract/_dependencies/maven/com.h2database_h2-2.2.220/org/h2/value/Transfer.java

Path
ttomcat-1778514358873.zip-extract/_dependencies/maven/com.h2database_h2-2.2.220/org/h2/value/Transfer.java
Status
scanned
Type
file
Name
Transfer.java
Extension
.java
Programming language
Java
Mime type
text/x-java
File type
Java source, ASCII text
Tag

      
    
Rootfs path

      
    
Size
41454 (40.5 KB)
MD5
bbcafd07897689423737db40fc239436
SHA1
d0da11d0b3a0f5d26dec1600805ca25596608941
SHA256
45bc3ed554685a0c9fe06ae100f0c6ffb2686443294e2ba076dd006981b67789
SHA512

      
    
SHA1_git
5d9bf8c65155d477d2434d18015e58ad614f1f2b
Is binary

      
    
Is text
True
Is archive

      
    
Is media

      
    
Is legal

      
    
Is manifest

      
    
Is readme

      
    
Is top level

      
    
Is key file

      
    
Transfer.java | 40.5 KB |

/* * Copyright 2004-2023 H2 Group. Multiple-Licensed under the MPL 2.0, * and the EPL 1.0 (https://h2database.com/html/license.html). * Initial Developer: H2 Group */ package org.h2.value; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.Reader; import java.math.BigDecimal; import java.net.InetAddress; import java.net.Socket; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import org.h2.api.ErrorCode; import org.h2.api.IntervalQualifier; import org.h2.engine.Constants; import org.h2.engine.Session; import org.h2.message.DbException; import org.h2.security.SHA256; import org.h2.store.Data; import org.h2.store.DataReader; import org.h2.util.Bits; import org.h2.util.DateTimeUtils; import org.h2.util.IOUtils; import org.h2.util.MathUtils; import org.h2.util.NetUtils; import org.h2.util.StringUtils; import org.h2.util.Utils; import org.h2.value.lob.LobData; import org.h2.value.lob.LobDataDatabase; import org.h2.value.lob.LobDataFetchOnDemand; /** * The transfer class is used to send and receive Value objects. * It is used on both the client side, and on the server side. */ public final class Transfer { private static final int BUFFER_SIZE = 64 * 1024; private static final int LOB_MAGIC = 0x1234; private static final int LOB_MAC_SALT_LENGTH = 16; private static final int NULL = 0; private static final int BOOLEAN = 1; private static final int TINYINT = 2; private static final int SMALLINT = 3; private static final int INTEGER = 4; private static final int BIGINT = 5; private static final int NUMERIC = 6; private static final int DOUBLE = 7; private static final int REAL = 8; private static final int TIME = 9; private static final int DATE = 10; private static final int TIMESTAMP = 11; private static final int VARBINARY = 12; private static final int VARCHAR = 13; private static final int VARCHAR_IGNORECASE = 14; private static final int BLOB = 15; private static final int CLOB = 16; private static final int ARRAY = 17; private static final int JAVA_OBJECT = 19; private static final int UUID = 20; private static final int CHAR = 21; private static final int GEOMETRY = 22; // 1.4.192 private static final int TIMESTAMP_TZ = 24; // 1.4.195 private static final int ENUM = 25; // 1.4.198 private static final int INTERVAL = 26; private static final int ROW = 27; // 1.4.200 private static final int JSON = 28; private static final int TIME_TZ = 29; // 2.0.202 private static final int BINARY = 30; private static final int DECFLOAT = 31; private static final int[] VALUE_TO_TI = new int[Value.TYPE_COUNT + 1]; private static final int[] TI_TO_VALUE = new int[45]; static { addType(-1, Value.UNKNOWN); addType(NULL, Value.NULL); addType(BOOLEAN, Value.BOOLEAN); addType(TINYINT, Value.TINYINT); addType(SMALLINT, Value.SMALLINT); addType(INTEGER, Value.INTEGER); addType(BIGINT, Value.BIGINT); addType(NUMERIC, Value.NUMERIC); addType(DOUBLE, Value.DOUBLE); addType(REAL, Value.REAL); addType(TIME, Value.TIME); addType(DATE, Value.DATE); addType(TIMESTAMP, Value.TIMESTAMP); addType(VARBINARY, Value.VARBINARY); addType(VARCHAR, Value.VARCHAR); addType(VARCHAR_IGNORECASE, Value.VARCHAR_IGNORECASE); addType(BLOB, Value.BLOB); addType(CLOB, Value.CLOB); addType(ARRAY, Value.ARRAY); addType(JAVA_OBJECT, Value.JAVA_OBJECT); addType(UUID, Value.UUID); addType(CHAR, Value.CHAR); addType(GEOMETRY, Value.GEOMETRY); addType(TIMESTAMP_TZ, Value.TIMESTAMP_TZ); addType(ENUM, Value.ENUM); addType(26, Value.INTERVAL_YEAR); addType(27, Value.INTERVAL_MONTH); addType(28, Value.INTERVAL_DAY); addType(29, Value.INTERVAL_HOUR); addType(30, Value.INTERVAL_MINUTE); addType(31, Value.INTERVAL_SECOND); addType(32, Value.INTERVAL_YEAR_TO_MONTH); addType(33, Value.INTERVAL_DAY_TO_HOUR); addType(34, Value.INTERVAL_DAY_TO_MINUTE); addType(35, Value.INTERVAL_DAY_TO_SECOND); addType(36, Value.INTERVAL_HOUR_TO_MINUTE); addType(37, Value.INTERVAL_HOUR_TO_SECOND); addType(38, Value.INTERVAL_MINUTE_TO_SECOND); addType(39, Value.ROW); addType(40, Value.JSON); addType(41, Value.TIME_TZ); addType(42, Value.BINARY); addType(43, Value.DECFLOAT); } private static void addType(int typeInformationType, int valueType) { VALUE_TO_TI[valueType + 1] = typeInformationType; TI_TO_VALUE[typeInformationType + 1] = valueType; } private Socket socket; private DataInputStream in; private DataOutputStream out; private Session session; private boolean ssl; private int version; private byte[] lobMacSalt; /** * Create a new transfer object for the specified session. * * @param session the session * @param s the socket */ public Transfer(Session session, Socket s) { this.session = session; this.socket = s; } /** * Initialize the transfer object. This method will try to open an input and * output stream. * @throws IOException on failure */ public synchronized void init() throws IOException { if (socket != null) { in = new DataInputStream( new BufferedInputStream( socket.getInputStream(), Transfer.BUFFER_SIZE)); out = new DataOutputStream( new BufferedOutputStream( socket.getOutputStream(), Transfer.BUFFER_SIZE)); } } /** * Write pending changes. * @throws IOException on failure */ public void flush() throws IOException { out.flush(); } /** * Write a boolean. * * @param x the value * @return itself * @throws IOException on failure */ public Transfer writeBoolean(boolean x) throws IOException { out.writeByte((byte) (x ? 1 : 0)); return this; } /** * Read a boolean. * * @return the value * @throws IOException on failure */ public boolean readBoolean() throws IOException { return in.readByte() != 0; } /** * Write a byte. * * @param x the value * @return itself * @throws IOException on failure */ public Transfer writeByte(byte x) throws IOException { out.writeByte(x); return this; } /** * Read a byte. * * @return the value * @throws IOException on failure */ public byte readByte() throws IOException { return in.readByte(); } /** * Write a short. * * @param x the value * @return itself * @throws IOException on failure */ private Transfer writeShort(short x) throws IOException { out.writeShort(x); return this; } /** * Read a short. * * @return the value * @throws IOException on failure */ private short readShort() throws IOException { return in.readShort(); } /** * Write an int. * * @param x the value * @return itself * @throws IOException on failure */ public Transfer writeInt(int x) throws IOException { out.writeInt(x); return this; } /** * Read an int. * * @return the value * @throws IOException on failure */ public int readInt() throws IOException { return in.readInt(); } /** * Write a long. * * @param x the value * @return itself * @throws IOException on failure */ public Transfer writeLong(long x) throws IOException { out.writeLong(x); return this; } /** * Read a long. * * @return the value * @throws IOException on failure */ public long readLong() throws IOException { return in.readLong(); } /** * Write a double. * * @param i the value * @return itself * @throws IOException on failure */ private Transfer writeDouble(double i) throws IOException { out.writeDouble(i); return this; } /** * Write a float. * * @param i the value * @return itself */ private Transfer writeFloat(float i) throws IOException { out.writeFloat(i); return this; } /** * Read a double. * * @return the value * @throws IOException on failure */ private double readDouble() throws IOException { return in.readDouble(); } /** * Read a float. * * @return the value * @throws IOException on failure */ private float readFloat() throws IOException { return in.readFloat(); } /** * Write a string. The maximum string length is Integer.MAX_VALUE. * * @param s the value * @return itself * @throws IOException on failure */ public Transfer writeString(String s) throws IOException { if (s == null) { out.writeInt(-1); } else { out.writeInt(s.length()); out.writeChars(s); } return this; } /** * Read a string. * * @return the value * @throws IOException on failure */ public String readString() throws IOException { int len = in.readInt(); if (len == -1) { return null; } StringBuilder buff = new StringBuilder(len); for (int i = 0; i < len; i++) { buff.append(in.readChar()); } String s = buff.toString(); s = StringUtils.cache(s); return s; } /** * Write a byte array. * * @param data the value * @return itself * @throws IOException on failure */ public Transfer writeBytes(byte[] data) throws IOException { if (data == null) { writeInt(-1); } else { writeInt(data.length); out.write(data); } return this; } /** * Write a number of bytes. * * @param buff the value * @param off the offset * @param len the length * @return itself * @throws IOException on failure */ public Transfer writeBytes(byte[] buff, int off, int len) throws IOException { out.write(buff, off, len); return this; } /** * Read a byte array. * * @return the value * @throws IOException on failure */ public byte[] readBytes() throws IOException { int len = readInt(); if (len == -1) { return null; } byte[] b = Utils.newBytes(len); in.readFully(b); return b; } /** * Read a number of bytes. * * @param buff the target buffer * @param off the offset * @param len the number of bytes to read * @throws IOException on failure */ public void readBytes(byte[] buff, int off, int len) throws IOException { in.readFully(buff, off, len); } /** * Close the transfer object and the socket. */ public synchronized void close() { if (socket != null) { try { if (out != null) { out.flush(); } socket.close(); } catch (IOException e) { DbException.traceThrowable(e); } finally { socket = null; } } } /** * Write value type, precision, and scale. * * @param type data type information * @return itself * @throws IOException on failure */ public Transfer writeTypeInfo(TypeInfo type) throws IOException { if (version >= Constants.TCP_PROTOCOL_VERSION_20) { writeTypeInfo20(type); } else { writeTypeInfo19(type); } return this; } private void writeTypeInfo20(TypeInfo type) throws IOException { int valueType = type.getValueType(); writeInt(VALUE_TO_TI[valueType + 1]); switch (valueType) { case Value.UNKNOWN: case Value.NULL: case Value.BOOLEAN: case Value.TINYINT: case Value.SMALLINT: case Value.INTEGER: case Value.BIGINT: case Value.DATE: case Value.UUID: break; case Value.CHAR: case Value.VARCHAR: case Value.VARCHAR_IGNORECASE: case Value.BINARY: case Value.VARBINARY: case Value.DECFLOAT: case Value.JAVA_OBJECT: case Value.JSON: writeInt((int) type.getDeclaredPrecision()); break; case Value.CLOB: case Value.BLOB: writeLong(type.getDeclaredPrecision()); break; case Value.NUMERIC: writeInt((int) type.getDeclaredPrecision()); writeInt(type.getDeclaredScale()); writeBoolean(type.getExtTypeInfo() != null); break; case Value.REAL: case Value.DOUBLE: case Value.INTERVAL_YEAR: case Value.INTERVAL_MONTH: case Value.INTERVAL_DAY: case Value.INTERVAL_HOUR: case Value.INTERVAL_MINUTE: case Value.INTERVAL_YEAR_TO_MONTH: case Value.INTERVAL_DAY_TO_HOUR: case Value.INTERVAL_DAY_TO_MINUTE: case Value.INTERVAL_HOUR_TO_MINUTE: writeBytePrecisionWithDefault(type.getDeclaredPrecision()); break; case Value.TIME: case Value.TIME_TZ: case Value.TIMESTAMP: case Value.TIMESTAMP_TZ: writeByteScaleWithDefault(type.getDeclaredScale()); break; case Value.INTERVAL_SECOND: case Value.INTERVAL_DAY_TO_SECOND: case Value.INTERVAL_HOUR_TO_SECOND: case Value.INTERVAL_MINUTE_TO_SECOND: writeBytePrecisionWithDefault(type.getDeclaredPrecision()); writeByteScaleWithDefault(type.getDeclaredScale()); break; case Value.ENUM: writeTypeInfoEnum(type); break; case Value.GEOMETRY: writeTypeInfoGeometry(type); break; case Value.ARRAY: writeInt((int) type.getDeclaredPrecision()); writeTypeInfo((TypeInfo) type.getExtTypeInfo()); break; case Value.ROW: writeTypeInfoRow(type); break; default: throw DbException.getUnsupportedException("value type " + valueType); } } private void writeBytePrecisionWithDefault(long precision) throws IOException { writeByte(precision >= 0 ? (byte) precision : -1); } private void writeByteScaleWithDefault(int scale) throws IOException { writeByte(scale >= 0 ? (byte) scale : -1); } private void writeTypeInfoEnum(TypeInfo type) throws IOException { ExtTypeInfoEnum ext = (ExtTypeInfoEnum) type.getExtTypeInfo(); if (ext != null) { int c = ext.getCount(); writeInt(c); for (int i = 0; i < c; i++) { writeString(ext.getEnumerator(i)); } } else { writeInt(0); } } private void writeTypeInfoGeometry(TypeInfo type) throws IOException { ExtTypeInfoGeometry ext = (ExtTypeInfoGeometry) type.getExtTypeInfo(); if (ext == null) { writeByte((byte) 0); } else { int t = ext.getType(); Integer srid = ext.getSrid(); if (t == 0) { if (srid == null) { writeByte((byte) 0); } else { writeByte((byte) 2); writeInt(srid); } } else { if (srid == null) { writeByte((byte) 1); writeShort((short) t); } else { writeByte((byte) 3); writeShort((short) t); writeInt(srid); } } } } private void writeTypeInfoRow(TypeInfo type) throws IOException { Set<Map.Entry<String, TypeInfo>> fields = ((ExtTypeInfoRow) type.getExtTypeInfo()).getFields(); writeInt(fields.size()); for (Map.Entry<String, TypeInfo> field : fields) { writeString(field.getKey()).writeTypeInfo(field.getValue()); } } private void writeTypeInfo19(TypeInfo type) throws IOException { int valueType = type.getValueType(); switch (valueType) { case Value.BINARY: valueType = Value.VARBINARY; break; case Value.DECFLOAT: valueType = Value.NUMERIC; break; } writeInt(VALUE_TO_TI[valueType + 1]).writeLong(type.getPrecision()).writeInt(type.getScale()); } /** * Read a type information. * * @return the type information * @throws IOException on failure */ public TypeInfo readTypeInfo() throws IOException { if (version >= Constants.TCP_PROTOCOL_VERSION_20) { return readTypeInfo20(); } else { return readTypeInfo19(); } } private TypeInfo readTypeInfo20() throws IOException { int valueType = TI_TO_VALUE[readInt() + 1]; long precision = -1L; int scale = -1; ExtTypeInfo ext = null; switch (valueType) { case Value.UNKNOWN: case Value.NULL: case Value.BOOLEAN: case Value.TINYINT: case Value.SMALLINT: case Value.INTEGER: case Value.BIGINT: case Value.DATE: case Value.UUID: break; case Value.CHAR: case Value.VARCHAR: case Value.VARCHAR_IGNORECASE: case Value.BINARY: case Value.VARBINARY: case Value.DECFLOAT: case Value.JAVA_OBJECT: case Value.JSON: precision = readInt(); break; case Value.CLOB: case Value.BLOB: precision = readLong(); break; case Value.NUMERIC: precision = readInt(); scale = readInt(); if (readBoolean()) { ext = ExtTypeInfoNumeric.DECIMAL; } break; case Value.REAL: case Value.DOUBLE: case Value.INTERVAL_YEAR: case Value.INTERVAL_MONTH: case Value.INTERVAL_DAY: case Value.INTERVAL_HOUR: case Value.INTERVAL_MINUTE: case Value.INTERVAL_YEAR_TO_MONTH: case Value.INTERVAL_DAY_TO_HOUR: case Value.INTERVAL_DAY_TO_MINUTE: case Value.INTERVAL_HOUR_TO_MINUTE: precision = readByte(); break; case Value.TIME: case Value.TIME_TZ: case Value.TIMESTAMP: case Value.TIMESTAMP_TZ: scale = readByte(); break; case Value.INTERVAL_SECOND: case Value.INTERVAL_DAY_TO_SECOND: case Value.INTERVAL_HOUR_TO_SECOND: case Value.INTERVAL_MINUTE_TO_SECOND: precision = readByte(); scale = readByte(); break; case Value.ENUM: ext = readTypeInfoEnum(); break; case Value.GEOMETRY: ext = readTypeInfoGeometry(); break; case Value.ARRAY: precision = readInt(); ext = readTypeInfo(); break; case Value.ROW: ext = readTypeInfoRow(); break; default: throw DbException.getUnsupportedException("value type " + valueType); } return TypeInfo.getTypeInfo(valueType, precision, scale, ext); } private ExtTypeInfo readTypeInfoEnum() throws IOException { ExtTypeInfo ext; int c = readInt(); if (c > 0) { String[] enumerators = new String[c]; for (int i = 0; i < c; i++) { enumerators[i] = readString(); } ext = new ExtTypeInfoEnum(enumerators); } else { ext = null; } return ext; } private ExtTypeInfo readTypeInfoGeometry() throws IOException { ExtTypeInfo ext; int e = readByte(); switch (e) { case 0: ext = null; break; case 1: ext = new ExtTypeInfoGeometry(readShort(), null); break; case 2: ext = new ExtTypeInfoGeometry(0, readInt()); break; case 3: ext = new ExtTypeInfoGeometry(readShort(), readInt()); break; default: throw DbException.getUnsupportedException("GEOMETRY type encoding " + e); } return ext; } private ExtTypeInfo readTypeInfoRow() throws IOException { LinkedHashMap<String, TypeInfo> fields = new LinkedHashMap<>(); for (int i = 0, l = readInt(); i < l; i++) { String name = readString(); if (fields.putIfAbsent(name, readTypeInfo()) != null) { throw DbException.get(ErrorCode.DUPLICATE_COLUMN_NAME_1, name); } } return new ExtTypeInfoRow(fields); } private TypeInfo readTypeInfo19() throws IOException { return TypeInfo.getTypeInfo(TI_TO_VALUE[readInt() + 1], readLong(), readInt(), null); } /** * Write a value. * * @param v the value * @throws IOException on failure */ public void writeValue(Value v) throws IOException { int type = v.getValueType(); switch (type) { case Value.NULL: writeInt(NULL); break; case Value.BINARY: if (version >= Constants.TCP_PROTOCOL_VERSION_20) { writeInt(BINARY); writeBytes(v.getBytesNoCopy()); break; } //$FALL-THROUGH$ case Value.VARBINARY: writeInt(VARBINARY); writeBytes(v.getBytesNoCopy()); break; case Value.JAVA_OBJECT: writeInt(JAVA_OBJECT); writeBytes(v.getBytesNoCopy()); break; case Value.UUID: { writeInt(UUID); ValueUuid uuid = (ValueUuid) v; writeLong(uuid.getHigh()); writeLong(uuid.getLow()); break; } case Value.BOOLEAN: writeInt(BOOLEAN); writeBoolean(v.getBoolean()); break; case Value.TINYINT: writeInt(TINYINT); writeByte(v.getByte()); break; case Value.TIME: writeInt(TIME); writeLong(((ValueTime) v).getNanos()); break; case Value.TIME_TZ: { ValueTimeTimeZone t = (ValueTimeTimeZone) v; if (version >= Constants.TCP_PROTOCOL_VERSION_19) { writeInt(TIME_TZ); writeLong(t.getNanos()); writeInt(t.getTimeZoneOffsetSeconds()); } else { writeInt(TIME); /* * Don't call SessionRemote.currentTimestamp(), it may require * own remote call and old server will not return custom time * zone anyway. */ ValueTimestampTimeZone current = session.isRemote() ? DateTimeUtils.currentTimestamp(DateTimeUtils.getTimeZone()) : session.currentTimestamp(); writeLong(DateTimeUtils.normalizeNanosOfDay(t.getNanos() + (t.getTimeZoneOffsetSeconds() - current.getTimeZoneOffsetSeconds()) * DateTimeUtils.NANOS_PER_DAY)); } break; } case Value.DATE: writeInt(DATE); writeLong(((ValueDate) v).getDateValue()); break; case Value.TIMESTAMP: { writeInt(TIMESTAMP); ValueTimestamp ts = (ValueTimestamp) v; writeLong(ts.getDateValue()); writeLong(ts.getTimeNanos()); break; } case Value.TIMESTAMP_TZ: { writeInt(TIMESTAMP_TZ); ValueTimestampTimeZone ts = (ValueTimestampTimeZone) v; writeLong(ts.getDateValue()); writeLong(ts.getTimeNanos()); int timeZoneOffset = ts.getTimeZoneOffsetSeconds(); writeInt(version >= Constants.TCP_PROTOCOL_VERSION_19 // ? timeZoneOffset : timeZoneOffset / 60); break; } case Value.DECFLOAT: if (version >= Constants.TCP_PROTOCOL_VERSION_20) { writeInt(DECFLOAT); writeString(v.getString()); break; } //$FALL-THROUGH$ case Value.NUMERIC: writeInt(NUMERIC); writeString(v.getString()); break; case Value.DOUBLE: writeInt(DOUBLE); writeDouble(v.getDouble()); break; case Value.REAL: writeInt(REAL); writeFloat(v.getFloat()); break; case Value.INTEGER: writeInt(INTEGER); writeInt(v.getInt()); break; case Value.BIGINT: writeInt(BIGINT); writeLong(v.getLong()); break; case Value.SMALLINT: writeInt(SMALLINT); if (version >= Constants.TCP_PROTOCOL_VERSION_20) { writeShort(v.getShort()); } else { writeInt(v.getShort()); } break; case Value.VARCHAR: writeInt(VARCHAR); writeString(v.getString()); break; case Value.VARCHAR_IGNORECASE: writeInt(VARCHAR_IGNORECASE); writeString(v.getString()); break; case Value.CHAR: writeInt(CHAR); writeString(v.getString()); break; case Value.BLOB: { writeInt(BLOB); ValueBlob lob = (ValueBlob) v; LobData lobData = lob.getLobData(); long length = lob.octetLength(); if (lobData instanceof LobDataDatabase) { LobDataDatabase lobDataDatabase = (LobDataDatabase) lobData; writeLong(-1); writeInt(lobDataDatabase.getTableId()); writeLong(lobDataDatabase.getLobId()); writeBytes(calculateLobMac(lobDataDatabase.getLobId())); writeLong(length); break; } if (length < 0) { throw DbException.get( ErrorCode.CONNECTION_BROKEN_1, "length=" + length); } writeLong(length); long written = IOUtils.copyAndCloseInput(lob.getInputStream(), out); if (written != length) { throw DbException.get( ErrorCode.CONNECTION_BROKEN_1, "length:" + length + " written:" + written); } writeInt(LOB_MAGIC); break; } case Value.CLOB: { writeInt(CLOB); ValueClob lob = (ValueClob) v; LobData lobData = lob.getLobData(); long charLength = lob.charLength(); if (lobData instanceof LobDataDatabase) { LobDataDatabase lobDataDatabase = (LobDataDatabase) lobData; writeLong(-1); writeInt(lobDataDatabase.getTableId()); writeLong(lobDataDatabase.getLobId()); writeBytes(calculateLobMac(lobDataDatabase.getLobId())); if (version >= Constants.TCP_PROTOCOL_VERSION_20) { writeLong(lob.octetLength()); } writeLong(charLength); break; } if (charLength < 0) { throw DbException.get( ErrorCode.CONNECTION_BROKEN_1, "length=" + charLength); } writeLong(charLength); Reader reader = lob.getReader(); Data.copyString(reader, out); writeInt(LOB_MAGIC); break; } case Value.ARRAY: { writeInt(ARRAY); ValueArray va = (ValueArray) v; Value[] list = va.getList(); int len = list.length; writeInt(len); for (Value value : list) { writeValue(value); } break; } case Value.ROW: { writeInt(version >= Constants.TCP_PROTOCOL_VERSION_18 ? ROW : ARRAY); ValueRow va = (ValueRow) v; Value[] list = va.getList(); int len = list.length; writeInt(len); for (Value value : list) { writeValue(value); } break; } case Value.ENUM: { writeInt(ENUM); writeInt(v.getInt()); if (version < Constants.TCP_PROTOCOL_VERSION_20) { writeString(v.getString()); } break; } case Value.GEOMETRY: writeInt(GEOMETRY); writeBytes(v.getBytesNoCopy()); break; case Value.INTERVAL_YEAR: case Value.INTERVAL_MONTH: case Value.INTERVAL_DAY: case Value.INTERVAL_HOUR: case Value.INTERVAL_MINUTE: if (version >= Constants.TCP_PROTOCOL_VERSION_18) { ValueInterval interval = (ValueInterval) v; int ordinal = type - Value.INTERVAL_YEAR; if (interval.isNegative()) { ordinal = ~ordinal; } writeInt(INTERVAL); writeByte((byte) ordinal); writeLong(interval.getLeading()); } else { writeInt(VARCHAR); writeString(v.getString()); } break; case Value.INTERVAL_SECOND: case Value.INTERVAL_YEAR_TO_MONTH: case Value.INTERVAL_DAY_TO_HOUR: case Value.INTERVAL_DAY_TO_MINUTE: case Value.INTERVAL_DAY_TO_SECOND: case Value.INTERVAL_HOUR_TO_MINUTE: case Value.INTERVAL_HOUR_TO_SECOND: case Value.INTERVAL_MINUTE_TO_SECOND: if (version >= Constants.TCP_PROTOCOL_VERSION_18) { ValueInterval interval = (ValueInterval) v; int ordinal = type - Value.INTERVAL_YEAR; if (interval.isNegative()) { ordinal = ~ordinal; } writeInt(INTERVAL); writeByte((byte) ordinal); writeLong(interval.getLeading()); writeLong(interval.getRemaining()); } else { writeInt(VARCHAR); writeString(v.getString()); } break; case Value.JSON: { writeInt(JSON); writeBytes(v.getBytesNoCopy()); break; } default: throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "type=" + type); } } /** * Read a value. * * @param columnType the data type of value, or {@code null} * @return the value * @throws IOException on failure */ public Value readValue(TypeInfo columnType) throws IOException { int type = readInt(); switch (type) { case NULL: return ValueNull.INSTANCE; case VARBINARY: return ValueVarbinary.getNoCopy(readBytes()); case BINARY: return ValueBinary.getNoCopy(readBytes()); case UUID: return ValueUuid.get(readLong(), readLong()); case JAVA_OBJECT: return ValueJavaObject.getNoCopy(readBytes()); case BOOLEAN: return ValueBoolean.get(readBoolean()); case TINYINT: return ValueTinyint.get(readByte()); case DATE: return ValueDate.fromDateValue(readLong()); case TIME: return ValueTime.fromNanos(readLong()); case TIME_TZ: return ValueTimeTimeZone.fromNanos(readLong(), readInt()); case TIMESTAMP: return ValueTimestamp.fromDateValueAndNanos(readLong(), readLong()); case TIMESTAMP_TZ: { long dateValue = readLong(), timeNanos = readLong(); int timeZoneOffset = readInt(); return ValueTimestampTimeZone.fromDateValueAndNanos(dateValue, timeNanos, version >= Constants.TCP_PROTOCOL_VERSION_19 ? timeZoneOffset : timeZoneOffset * 60); } case NUMERIC: return ValueNumeric.get(new BigDecimal(readString())); case DOUBLE: return ValueDouble.get(readDouble()); case REAL: return ValueReal.get(readFloat()); case ENUM: { int ordinal = readInt(); if (version >= Constants.TCP_PROTOCOL_VERSION_20) { return ((ExtTypeInfoEnum) columnType.getExtTypeInfo()).getValue(ordinal, session); } return ValueEnumBase.get(readString(), ordinal); } case INTEGER: return ValueInteger.get(readInt()); case BIGINT: return ValueBigint.get(readLong()); case SMALLINT: if (version >= Constants.TCP_PROTOCOL_VERSION_20) { return ValueSmallint.get(readShort()); } else { return ValueSmallint.get((short) readInt()); } case VARCHAR: return ValueVarchar.get(readString()); case VARCHAR_IGNORECASE: return ValueVarcharIgnoreCase.get(readString()); case CHAR: return ValueChar.get(readString()); case BLOB: { long length = readLong(); if (length == -1) { // fetch-on-demand LOB int tableId = readInt(); long id = readLong(); byte[] hmac = readBytes(); long precision = readLong(); return new ValueBlob(new LobDataFetchOnDemand(session.getDataHandler(), tableId, id, hmac), precision); } Value v = session.getDataHandler().getLobStorage().createBlob(in, length); int magic = readInt(); if (magic != LOB_MAGIC) { throw DbException.get( ErrorCode.CONNECTION_BROKEN_1, "magic=" + magic); } return v; } case CLOB: { long charLength = readLong(); if (charLength == -1) { // fetch-on-demand LOB int tableId = readInt(); long id = readLong(); byte[] hmac = readBytes(); long octetLength = version >= Constants.TCP_PROTOCOL_VERSION_20 ? readLong() : -1L; charLength = readLong(); return new ValueClob(new LobDataFetchOnDemand(session.getDataHandler(), tableId, id, hmac), octetLength, charLength); } if (charLength < 0) { throw DbException.get( ErrorCode.CONNECTION_BROKEN_1, "length="+ charLength); } Value v = session.getDataHandler().getLobStorage(). createClob(new DataReader(in), charLength); int magic = readInt(); if (magic != LOB_MAGIC) { throw DbException.get( ErrorCode.CONNECTION_BROKEN_1, "magic=" + magic); } return v; } case ARRAY: { int len = readInt(); if (len < 0) { // Unlikely, but possible with H2 1.4.200 and older versions len = ~len; readString(); } if (columnType != null) { TypeInfo elementType = (TypeInfo) columnType.getExtTypeInfo(); return ValueArray.get(elementType, readArrayElements(len, elementType), session); } return ValueArray.get(readArrayElements(len, null), session); } case ROW: { int len = readInt(); Value[] list = new Value[len]; if (columnType != null) { ExtTypeInfoRow extTypeInfoRow = (ExtTypeInfoRow) columnType.getExtTypeInfo(); Iterator<Entry<String, TypeInfo>> fields = extTypeInfoRow.getFields().iterator(); for (int i = 0; i < len; i++) { list[i] = readValue(fields.next().getValue()); } return ValueRow.get(columnType, list); } for (int i = 0; i < len; i++) { list[i] = readValue(null); } return ValueRow.get(list); } case GEOMETRY: return ValueGeometry.get(readBytes()); case INTERVAL: { int ordinal = readByte(); boolean negative = ordinal < 0; if (negative) { ordinal = ~ordinal; } return ValueInterval.from(IntervalQualifier.valueOf(ordinal), negative, readLong(), ordinal < 5 ? 0 : readLong()); } case JSON: // Do not trust the value return ValueJson.fromJson(readBytes()); case DECFLOAT: { String s = readString(); switch (s) { case "-Infinity": return ValueDecfloat.NEGATIVE_INFINITY; case "Infinity": return ValueDecfloat.POSITIVE_INFINITY; case "NaN": return ValueDecfloat.NAN; default: return ValueDecfloat.get(new BigDecimal(s)); } } default: throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "type=" + type); } } private Value[] readArrayElements(int len, TypeInfo elementType) throws IOException { Value[] list = new Value[len]; for (int i = 0; i < len; i++) { list[i] = readValue(elementType); } return list; } /** * Read a row count. * * @return the row count * @throws IOException on failure */ public long readRowCount() throws IOException { return version >= Constants.TCP_PROTOCOL_VERSION_20 ? readLong() : readInt(); } /** * Write a row count. * * @param rowCount the row count * @return itself * @throws IOException on failure */ public Transfer writeRowCount(long rowCount) throws IOException { return version >= Constants.TCP_PROTOCOL_VERSION_20 ? writeLong(rowCount) : writeInt(rowCount < Integer.MAX_VALUE ? (int) rowCount : Integer.MAX_VALUE); } /** * Get the socket. * * @return the socket */ public Socket getSocket() { return socket; } /** * Set the session. * * @param session the session */ public void setSession(Session session) { this.session = session; } /** * Enable or disable SSL. * * @param ssl the new value */ public void setSSL(boolean ssl) { this.ssl = ssl; } /** * Open a new connection to the same address and port as this one. * * @return the new transfer object * @throws IOException on failure */ public Transfer openNewConnection() throws IOException { InetAddress address = socket.getInetAddress(); int port = socket.getPort(); Socket s2 = NetUtils.createSocket(address, port, ssl); Transfer trans = new Transfer(null, s2); trans.setSSL(ssl); return trans; } public void setVersion(int version) { this.version = version; } public int getVersion() { return version; } public synchronized boolean isClosed() { return socket == null || socket.isClosed(); } /** * Verify the HMAC. * * @param hmac the message authentication code * @param lobId the lobId * @throws DbException if the HMAC does not match */ public void verifyLobMac(byte[] hmac, long lobId) { byte[] result = calculateLobMac(lobId); if (!Utils.compareSecure(hmac, result)) { throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "Invalid lob hmac; possibly the connection was re-opened internally"); } } private byte[] calculateLobMac(long lobId) { if (lobMacSalt == null) { lobMacSalt = MathUtils.secureRandomBytes(LOB_MAC_SALT_LENGTH); } byte[] data = new byte[8]; Bits.writeLong(data, 0, lobId); return SHA256.getHashWithSalt(data, lobMacSalt); } }
Detected license expression

      
    
Detected license expression (SPDX)

      
    
Percentage of license text
0.29
Copyrights
- end_line: 2
  copyright: Copyright 2004-2023 H2 Group. Multiple-Licensed
  start_line: 2
Holders
- holder: H2 Group. Multiple-Licensed
  end_line: 2
  start_line: 2
Authors

      
    
License expression License clue details
(mpl-2.0 OR epl-1.0) AND proprietary-license {'score': 20.37, 'matcher': '3-seq', 'end_line': 3, 'rule_url': 'https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mpl-2.0_or_epl-1.0_and_proprietary-license_2.RULE', 'from_file': None, 'start_line': 2, 'matched_text': ' * Copyright 2004-2023 H2 Group. Multiple-Licensed under the MPL 2.0,\n * and the EPL 1.0 (https://h2database.com/html/license.html).', 'match_coverage': 20.37, 'matched_length': 11, 'rule_relevance': 100, 'rule_identifier': 'mpl-2.0_or_epl-1.0_and_proprietary-license_2.RULE', 'license_expression': '(mpl-2.0 OR epl-1.0) AND proprietary-license', 'license_expression_spdx': '(MPL-2.0 OR EPL-1.0) AND LicenseRef-scancode-proprietary-license'}
URL Start line End line
https://h2database.com/html/license.html 3 3
Package URL License Primary language
pkg:osgi/com.h2database.source@2.2.220