EMMA Coverage Report (generated Sun Mar 01 22:06:14 CET 2015)
[all classes][org.h2.value]

COVERAGE SUMMARY FOR SOURCE FILE [Transfer.java]

nameclass, %method, %block, %line, %
Transfer.java100% (1/1)100% (33/33)79%  (1087/1374)85%  (278.4/329)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Transfer100% (1/1)100% (33/33)79%  (1087/1374)85%  (278.4/329)
readValue (): Value 100% (1/1)69%  (330/477)76%  (79/104)
verifyLobMac (byte [], long): void 100% (1/1)69%  (9/13)75%  (3/4)
writeValue (Value): void 100% (1/1)76%  (420/550)81%  (105.8/130)
close (): void 100% (1/1)82%  (27/33)96%  (9.6/10)
Transfer (SessionInterface): void 100% (1/1)100% (6/6)100% (3/3)
calculateLobMac (long): byte [] 100% (1/1)100% (21/21)100% (6/6)
flush (): void 100% (1/1)100% (4/4)100% (2/2)
getSocket (): Socket 100% (1/1)100% (3/3)100% (1/1)
init (): void 100% (1/1)100% (28/28)100% (4/4)
isClosed (): boolean 100% (1/1)100% (11/11)100% (1/1)
openNewConnection (): Transfer 100% (1/1)100% (28/28)100% (7/7)
readBoolean (): boolean 100% (1/1)100% (9/9)100% (1/1)
readByte (): byte 100% (1/1)100% (4/4)100% (1/1)
readBytes (): byte [] 100% (1/1)100% (17/17)100% (6/6)
readBytes (byte [], int, int): void 100% (1/1)100% (7/7)100% (2/2)
readDouble (): double 100% (1/1)100% (4/4)100% (1/1)
readFloat (): float 100% (1/1)100% (4/4)100% (1/1)
readInt (): int 100% (1/1)100% (4/4)100% (1/1)
readLong (): long 100% (1/1)100% (4/4)100% (1/1)
readString (): String 100% (1/1)100% (35/35)100% (9/9)
setSSL (boolean): void 100% (1/1)100% (4/4)100% (2/2)
setSession (SessionInterface): void 100% (1/1)100% (4/4)100% (2/2)
setSocket (Socket): void 100% (1/1)100% (4/4)100% (2/2)
setVersion (int): void 100% (1/1)100% (4/4)100% (2/2)
writeBoolean (boolean): Transfer 100% (1/1)100% (11/11)100% (2/2)
writeByte (byte): Transfer 100% (1/1)100% (6/6)100% (2/2)
writeBytes (byte []): Transfer 100% (1/1)100% (18/18)100% (5/5)
writeBytes (byte [], int, int): Transfer 100% (1/1)100% (8/8)100% (2/2)
writeDouble (double): Transfer 100% (1/1)100% (6/6)100% (2/2)
writeFloat (float): Transfer 100% (1/1)100% (6/6)100% (2/2)
writeInt (int): Transfer 100% (1/1)100% (6/6)100% (2/2)
writeLong (long): Transfer 100% (1/1)100% (6/6)100% (2/2)
writeString (String): Transfer 100% (1/1)100% (29/29)100% (7/7)

1/*
2 * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
3 * and the EPL 1.0 (http://h2database.com/html/license.html).
4 * Initial Developer: H2 Group
5 */
6package org.h2.value;
7 
8import java.io.BufferedInputStream;
9import java.io.BufferedOutputStream;
10import java.io.DataInputStream;
11import java.io.DataOutputStream;
12import java.io.IOException;
13import java.io.Reader;
14import java.math.BigDecimal;
15import java.net.InetAddress;
16import java.net.Socket;
17import java.sql.ResultSet;
18import java.sql.ResultSetMetaData;
19import java.sql.SQLException;
20import java.sql.Timestamp;
21 
22import org.h2.api.ErrorCode;
23import org.h2.engine.Constants;
24import org.h2.engine.SessionInterface;
25import org.h2.message.DbException;
26import org.h2.mvstore.DataUtils;
27import org.h2.security.SHA256;
28import org.h2.store.Data;
29import org.h2.store.DataReader;
30import org.h2.tools.SimpleResultSet;
31import org.h2.util.DateTimeUtils;
32import org.h2.util.IOUtils;
33import org.h2.util.JdbcUtils;
34import org.h2.util.MathUtils;
35import org.h2.util.NetUtils;
36import org.h2.util.StringUtils;
37import org.h2.util.Utils;
38 
39/**
40 * The transfer class is used to send and receive Value objects.
41 * It is used on both the client side, and on the server side.
42 */
43public class Transfer {
44 
45    private static final int BUFFER_SIZE = 64 * 1024;
46    private static final int LOB_MAGIC = 0x1234;
47    private static final int LOB_MAC_SALT_LENGTH = 16;
48 
49    private Socket socket;
50    private DataInputStream in;
51    private DataOutputStream out;
52    private SessionInterface session;
53    private boolean ssl;
54    private int version;
55    private byte[] lobMacSalt;
56 
57    /**
58     * Create a new transfer object for the specified session.
59     *
60     * @param session the session
61     */
62    public Transfer(SessionInterface session) {
63        this.session = session;
64    }
65 
66    /**
67     * Set the socket this object uses.
68     *
69     * @param s the socket
70     */
71    public void setSocket(Socket s) {
72        socket = s;
73    }
74 
75    /**
76     * Initialize the transfer object. This method will try to open an input and
77     * output stream.
78     */
79    public synchronized void init() throws IOException {
80        if (socket != null) {
81            in = new DataInputStream(
82                    new BufferedInputStream(
83                            socket.getInputStream(), Transfer.BUFFER_SIZE));
84            out = new DataOutputStream(
85                    new BufferedOutputStream(
86                            socket.getOutputStream(), Transfer.BUFFER_SIZE));
87        }
88    }
89 
90    /**
91     * Write pending changes.
92     */
93    public void flush() throws IOException {
94        out.flush();
95    }
96 
97    /**
98     * Write a boolean.
99     *
100     * @param x the value
101     * @return itself
102     */
103    public Transfer writeBoolean(boolean x) throws IOException {
104        out.writeByte((byte) (x ? 1 : 0));
105        return this;
106    }
107 
108    /**
109     * Read a boolean.
110     *
111     * @return the value
112     */
113    public boolean readBoolean() throws IOException {
114        return in.readByte() == 1;
115    }
116 
117    /**
118     * Write a byte.
119     *
120     * @param x the value
121     * @return itself
122     */
123    private Transfer writeByte(byte x) throws IOException {
124        out.writeByte(x);
125        return this;
126    }
127 
128    /**
129     * Read a byte.
130     *
131     * @return the value
132     */
133    private byte readByte() throws IOException {
134        return in.readByte();
135    }
136 
137    /**
138     * Write an int.
139     *
140     * @param x the value
141     * @return itself
142     */
143    public Transfer writeInt(int x) throws IOException {
144        out.writeInt(x);
145        return this;
146    }
147 
148    /**
149     * Read an int.
150     *
151     * @return the value
152     */
153    public int readInt() throws IOException {
154        return in.readInt();
155    }
156 
157    /**
158     * Write a long.
159     *
160     * @param x the value
161     * @return itself
162     */
163    public Transfer writeLong(long x) throws IOException {
164        out.writeLong(x);
165        return this;
166    }
167 
168    /**
169     * Read a long.
170     *
171     * @return the value
172     */
173    public long readLong() throws IOException {
174        return in.readLong();
175    }
176 
177    /**
178     * Write a double.
179     *
180     * @param i the value
181     * @return itself
182     */
183    private Transfer writeDouble(double i) throws IOException {
184        out.writeDouble(i);
185        return this;
186    }
187 
188    /**
189     * Write a float.
190     *
191     * @param i the value
192     * @return itself
193     */
194    private Transfer writeFloat(float i) throws IOException {
195        out.writeFloat(i);
196        return this;
197    }
198 
199    /**
200     * Read a double.
201     *
202     * @return the value
203     */
204    private double readDouble() throws IOException {
205        return in.readDouble();
206    }
207 
208    /**
209     * Read a float.
210     *
211     * @return the value
212     */
213    private float readFloat() throws IOException {
214        return in.readFloat();
215    }
216 
217    /**
218     * Write a string. The maximum string length is Integer.MAX_VALUE.
219     *
220     * @param s the value
221     * @return itself
222     */
223    public Transfer writeString(String s) throws IOException {
224        if (s == null) {
225            out.writeInt(-1);
226        } else {
227            int len = s.length();
228            out.writeInt(len);
229            for (int i = 0; i < len; i++) {
230                out.writeChar(s.charAt(i));
231            }
232        }
233        return this;
234    }
235 
236    /**
237     * Read a string.
238     *
239     * @return the value
240     */
241    public String readString() throws IOException {
242        int len = in.readInt();
243        if (len == -1) {
244            return null;
245        }
246        StringBuilder buff = new StringBuilder(len);
247        for (int i = 0; i < len; i++) {
248            buff.append(in.readChar());
249        }
250        String s = buff.toString();
251        s = StringUtils.cache(s);
252        return s;
253    }
254 
255    /**
256     * Write a byte array.
257     *
258     * @param data the value
259     * @return itself
260     */
261    public Transfer writeBytes(byte[] data) throws IOException {
262        if (data == null) {
263            writeInt(-1);
264        } else {
265            writeInt(data.length);
266            out.write(data);
267        }
268        return this;
269    }
270 
271    /**
272     * Write a number of bytes.
273     *
274     * @param buff the value
275     * @param off the offset
276     * @param len the length
277     * @return itself
278     */
279    public Transfer writeBytes(byte[] buff, int off, int len) throws IOException {
280        out.write(buff, off, len);
281        return this;
282    }
283 
284    /**
285     * Read a byte array.
286     *
287     * @return the value
288     */
289    public byte[] readBytes() throws IOException {
290        int len = readInt();
291        if (len == -1) {
292            return null;
293        }
294        byte[] b = DataUtils.newBytes(len);
295        in.readFully(b);
296        return b;
297    }
298 
299    /**
300     * Read a number of bytes.
301     *
302     * @param buff the target buffer
303     * @param off the offset
304     * @param len the number of bytes to read
305     */
306    public void readBytes(byte[] buff, int off, int len) throws IOException {
307        in.readFully(buff, off, len);
308    }
309 
310    /**
311     * Close the transfer object and the socket.
312     */
313    public synchronized void close() {
314        if (socket != null) {
315            try {
316                if (out != null) {
317                    out.flush();
318                }
319                if (socket != null) {
320                    socket.close();
321                }
322            } catch (IOException e) {
323                DbException.traceThrowable(e);
324            } finally {
325                socket = null;
326            }
327        }
328    }
329 
330    /**
331     * Write a value.
332     *
333     * @param v the value
334     */
335    public void writeValue(Value v) throws IOException {
336        int type = v.getType();
337        writeInt(type);
338        switch (type) {
339        case Value.NULL:
340            break;
341        case Value.BYTES:
342        case Value.JAVA_OBJECT:
343            writeBytes(v.getBytesNoCopy());
344            break;
345        case Value.UUID: {
346            ValueUuid uuid = (ValueUuid) v;
347            writeLong(uuid.getHigh());
348            writeLong(uuid.getLow());
349            break;
350        }
351        case Value.BOOLEAN:
352            writeBoolean(v.getBoolean().booleanValue());
353            break;
354        case Value.BYTE:
355            writeByte(v.getByte());
356            break;
357        case Value.TIME:
358            if (version >= Constants.TCP_PROTOCOL_VERSION_9) {
359                writeLong(((ValueTime) v).getNanos());
360            } else if (version >= Constants.TCP_PROTOCOL_VERSION_7) {
361                writeLong(DateTimeUtils.getTimeLocalWithoutDst(v.getTime()));
362            } else {
363                writeLong(v.getTime().getTime());
364            }
365            break;
366        case Value.DATE:
367            if (version >= Constants.TCP_PROTOCOL_VERSION_9) {
368                writeLong(((ValueDate) v).getDateValue());
369            } else if (version >= Constants.TCP_PROTOCOL_VERSION_7) {
370                writeLong(DateTimeUtils.getTimeLocalWithoutDst(v.getDate()));
371            } else {
372                writeLong(v.getDate().getTime());
373            }
374            break;
375        case Value.TIMESTAMP: {
376            if (version >= Constants.TCP_PROTOCOL_VERSION_9) {
377                ValueTimestamp ts = (ValueTimestamp) v;
378                writeLong(ts.getDateValue());
379                writeLong(ts.getTimeNanos());
380            } else if (version >= Constants.TCP_PROTOCOL_VERSION_7) {
381                Timestamp ts = v.getTimestamp();
382                writeLong(DateTimeUtils.getTimeLocalWithoutDst(ts));
383                writeInt(ts.getNanos() % 1000000);
384            } else {
385                Timestamp ts = v.getTimestamp();
386                writeLong(ts.getTime());
387                writeInt(ts.getNanos() % 1000000);
388            }
389            break;
390        }
391        case Value.DECIMAL:
392            writeString(v.getString());
393            break;
394        case Value.DOUBLE:
395            writeDouble(v.getDouble());
396            break;
397        case Value.FLOAT:
398            writeFloat(v.getFloat());
399            break;
400        case Value.INT:
401            writeInt(v.getInt());
402            break;
403        case Value.LONG:
404            writeLong(v.getLong());
405            break;
406        case Value.SHORT:
407            writeInt(v.getShort());
408            break;
409        case Value.STRING:
410        case Value.STRING_IGNORECASE:
411        case Value.STRING_FIXED:
412            writeString(v.getString());
413            break;
414        case Value.BLOB: {
415            if (version >= Constants.TCP_PROTOCOL_VERSION_11) {
416                if (v instanceof ValueLobDb) {
417                    ValueLobDb lob = (ValueLobDb) v;
418                    if (lob.isStored()) {
419                        writeLong(-1);
420                        writeInt(lob.getTableId());
421                        writeLong(lob.getLobId());
422                        if (version >= Constants.TCP_PROTOCOL_VERSION_12) {
423                            writeBytes(calculateLobMac(lob.getLobId()));
424                        }
425                        writeLong(lob.getPrecision());
426                        break;
427                    }
428                }
429            }
430            long length = v.getPrecision();
431            if (length < 0) {
432                throw DbException.get(
433                        ErrorCode.CONNECTION_BROKEN_1, "length=" + length);
434            }
435            writeLong(length);
436            long written = IOUtils.copyAndCloseInput(v.getInputStream(), out);
437            if (written != length) {
438                throw DbException.get(
439                        ErrorCode.CONNECTION_BROKEN_1, "length:" + length + " written:" + written);
440            }
441            writeInt(LOB_MAGIC);
442            break;
443        }
444        case Value.CLOB: {
445            if (version >= Constants.TCP_PROTOCOL_VERSION_11) {
446                if (v instanceof ValueLobDb) {
447                    ValueLobDb lob = (ValueLobDb) v;
448                    if (lob.isStored()) {
449                        writeLong(-1);
450                        writeInt(lob.getTableId());
451                        writeLong(lob.getLobId());
452                        if (version >= Constants.TCP_PROTOCOL_VERSION_12) {
453                            writeBytes(calculateLobMac(lob.getLobId()));
454                        }
455                        writeLong(lob.getPrecision());
456                        break;
457                    }
458                }
459            }
460            long length = v.getPrecision();
461            if (length < 0) {
462                throw DbException.get(
463                        ErrorCode.CONNECTION_BROKEN_1, "length=" + length);
464            }
465            writeLong(length);
466            Reader reader = v.getReader();
467            Data.copyString(reader, out);
468            writeInt(LOB_MAGIC);
469            break;
470        }
471        case Value.ARRAY: {
472            ValueArray va = (ValueArray) v;
473            Value[] list = va.getList();
474            int len = list.length;
475            Class<?> componentType = va.getComponentType();
476            if (componentType == Object.class) {
477                writeInt(len);
478            } else {
479                writeInt(-(len + 1));
480                writeString(componentType.getName());
481            }
482            for (Value value : list) {
483                writeValue(value);
484            }
485            break;
486        }
487        case Value.RESULT_SET: {
488            try {
489                ResultSet rs = ((ValueResultSet) v).getResultSet();
490                rs.beforeFirst();
491                ResultSetMetaData meta = rs.getMetaData();
492                int columnCount = meta.getColumnCount();
493                writeInt(columnCount);
494                for (int i = 0; i < columnCount; i++) {
495                    writeString(meta.getColumnName(i + 1));
496                    writeInt(meta.getColumnType(i + 1));
497                    writeInt(meta.getPrecision(i + 1));
498                    writeInt(meta.getScale(i + 1));
499                }
500                while (rs.next()) {
501                    writeBoolean(true);
502                    for (int i = 0; i < columnCount; i++) {
503                        int t = DataType.getValueTypeFromResultSet(meta, i + 1);
504                        Value val = DataType.readValue(session, rs, i + 1, t);
505                        writeValue(val);
506                    }
507                }
508                writeBoolean(false);
509                rs.beforeFirst();
510            } catch (SQLException e) {
511                throw DbException.convertToIOException(e);
512            }
513            break;
514        }
515        case Value.GEOMETRY:
516            if (version >= Constants.TCP_PROTOCOL_VERSION_14) {
517                writeBytes(v.getBytesNoCopy());
518            } else {
519                writeString(v.getString());
520            }
521            break;
522        default:
523            throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "type=" + type);
524        }
525    }
526 
527    /**
528     * Read a value.
529     *
530     * @return the value
531     */
532    public Value readValue() throws IOException {
533        int type = readInt();
534        switch(type) {
535        case Value.NULL:
536            return ValueNull.INSTANCE;
537        case Value.BYTES:
538            return ValueBytes.getNoCopy(readBytes());
539        case Value.UUID:
540            return ValueUuid.get(readLong(), readLong());
541        case Value.JAVA_OBJECT:
542            return ValueJavaObject.getNoCopy(null, readBytes(), session.getDataHandler());
543        case Value.BOOLEAN:
544            return ValueBoolean.get(readBoolean());
545        case Value.BYTE:
546            return ValueByte.get(readByte());
547        case Value.DATE:
548            if (version >= Constants.TCP_PROTOCOL_VERSION_9) {
549                return ValueDate.fromDateValue(readLong());
550            } else if (version >= Constants.TCP_PROTOCOL_VERSION_7) {
551                return ValueDate.fromMillis(DateTimeUtils.getTimeUTCWithoutDst(readLong()));
552            }
553            return ValueDate.fromMillis(readLong());
554        case Value.TIME:
555            if (version >= Constants.TCP_PROTOCOL_VERSION_9) {
556                return ValueTime.fromNanos(readLong());
557            } else if (version >= Constants.TCP_PROTOCOL_VERSION_7) {
558                return ValueTime.fromMillis(DateTimeUtils.getTimeUTCWithoutDst(readLong()));
559            }
560            return ValueTime.fromMillis(readLong());
561        case Value.TIMESTAMP: {
562            if (version >= Constants.TCP_PROTOCOL_VERSION_9) {
563                return ValueTimestamp.fromDateValueAndNanos(
564                        readLong(), readLong());
565            } else if (version >= Constants.TCP_PROTOCOL_VERSION_7) {
566                return ValueTimestamp.fromMillisNanos(
567                        DateTimeUtils.getTimeUTCWithoutDst(readLong()),
568                        readInt() % 1000000);
569            }
570            return ValueTimestamp.fromMillisNanos(readLong(),
571                    readInt() % 1000000);
572        }
573        case Value.DECIMAL:
574            return ValueDecimal.get(new BigDecimal(readString()));
575        case Value.DOUBLE:
576            return ValueDouble.get(readDouble());
577        case Value.FLOAT:
578            return ValueFloat.get(readFloat());
579        case Value.INT:
580            return ValueInt.get(readInt());
581        case Value.LONG:
582            return ValueLong.get(readLong());
583        case Value.SHORT:
584            return ValueShort.get((short) readInt());
585        case Value.STRING:
586            return ValueString.get(readString());
587        case Value.STRING_IGNORECASE:
588            return ValueStringIgnoreCase.get(readString());
589        case Value.STRING_FIXED:
590            return ValueStringFixed.get(readString());
591        case Value.BLOB: {
592            long length = readLong();
593            if (version >= Constants.TCP_PROTOCOL_VERSION_11) {
594                if (length == -1) {
595                    int tableId = readInt();
596                    long id = readLong();
597                    byte[] hmac;
598                    if (version >= Constants.TCP_PROTOCOL_VERSION_12) {
599                        hmac = readBytes();
600                    } else {
601                        hmac = null;
602                    }
603                    long precision = readLong();
604                    return ValueLobDb.create(
605                            Value.BLOB, session.getDataHandler(), tableId, id, hmac, precision);
606                }
607                int len = (int) length;
608                byte[] small = new byte[len];
609                IOUtils.readFully(in, small, len);
610                int magic = readInt();
611                if (magic != LOB_MAGIC) {
612                    throw DbException.get(
613                            ErrorCode.CONNECTION_BROKEN_1, "magic=" + magic);
614                }
615                return ValueLobDb.createSmallLob(Value.BLOB, small, length);
616            }
617            Value v = session.getDataHandler().getLobStorage().createBlob(in, length);
618            int magic = readInt();
619            if (magic != LOB_MAGIC) {
620                throw DbException.get(
621                        ErrorCode.CONNECTION_BROKEN_1, "magic=" + magic);
622            }
623            return v;
624        }
625        case Value.CLOB: {
626            long length = readLong();
627            if (version >= Constants.TCP_PROTOCOL_VERSION_11) {
628                if (length == -1) {
629                    int tableId = readInt();
630                    long id = readLong();
631                    byte[] hmac;
632                    if (version >= Constants.TCP_PROTOCOL_VERSION_12) {
633                        hmac = readBytes();
634                    } else {
635                        hmac = null;
636                    }
637                    long precision = readLong();
638                    return ValueLobDb.create(
639                            Value.CLOB, session.getDataHandler(), tableId, id, hmac, precision);
640                }
641                DataReader reader = new DataReader(in);
642                int len = (int) length;
643                char[] buff = new char[len];
644                IOUtils.readFully(reader, buff, len);
645                int magic = readInt();
646                if (magic != LOB_MAGIC) {
647                    throw DbException.get(
648                            ErrorCode.CONNECTION_BROKEN_1, "magic=" + magic);
649                }
650                byte[] small = new String(buff).getBytes(Constants.UTF8);
651                return ValueLobDb.createSmallLob(Value.CLOB, small, length);
652            }
653            Value v = session.getDataHandler().getLobStorage().
654                    createClob(new DataReader(in), length);
655            int magic = readInt();
656            if (magic != LOB_MAGIC) {
657                throw DbException.get(
658                        ErrorCode.CONNECTION_BROKEN_1, "magic=" + magic);
659            }
660            return v;
661        }
662        case Value.ARRAY: {
663            int len = readInt();
664            Class<?> componentType = Object.class;
665            if (len < 0) {
666                len = -(len + 1);
667                componentType = JdbcUtils.loadUserClass(readString());
668            }
669            Value[] list = new Value[len];
670            for (int i = 0; i < len; i++) {
671                list[i] = readValue();
672            }
673            return ValueArray.get(componentType, list);
674        }
675        case Value.RESULT_SET: {
676            SimpleResultSet rs = new SimpleResultSet();
677            rs.setAutoClose(false);
678            int columns = readInt();
679            for (int i = 0; i < columns; i++) {
680                rs.addColumn(readString(), readInt(), readInt(), readInt());
681            }
682            while (true) {
683                if (!readBoolean()) {
684                    break;
685                }
686                Object[] o = new Object[columns];
687                for (int i = 0; i < columns; i++) {
688                    o[i] = readValue().getObject();
689                }
690                rs.addRow(o);
691            }
692            return ValueResultSet.get(rs);
693        }
694        case Value.GEOMETRY:
695            if (version >= Constants.TCP_PROTOCOL_VERSION_14) {
696                return ValueGeometry.get(readBytes());
697            }
698            return ValueGeometry.get(readString());
699        default:
700            throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "type=" + type);
701        }
702    }
703 
704    /**
705     * Get the socket.
706     *
707     * @return the socket
708     */
709    public Socket getSocket() {
710        return socket;
711    }
712 
713    /**
714     * Set the session.
715     *
716     * @param session the session
717     */
718    public void setSession(SessionInterface session) {
719        this.session = session;
720    }
721 
722    /**
723     * Enable or disable SSL.
724     *
725     * @param ssl the new value
726     */
727    public void setSSL(boolean ssl) {
728        this.ssl = ssl;
729    }
730 
731    /**
732     * Open a new new connection to the same address and port as this one.
733     *
734     * @return the new transfer object
735     */
736    public Transfer openNewConnection() throws IOException {
737        InetAddress address = socket.getInetAddress();
738        int port = socket.getPort();
739        Socket s2 = NetUtils.createSocket(address, port, ssl);
740        Transfer trans = new Transfer(null);
741        trans.setSocket(s2);
742        trans.setSSL(ssl);
743        return trans;
744    }
745 
746    public void setVersion(int version) {
747        this.version = version;
748    }
749 
750    public synchronized boolean isClosed() {
751        return socket == null || socket.isClosed();
752    }
753 
754    /**
755     * Verify the HMAC.
756     *
757     * @param hmac the message authentication code
758     * @param lobId the lobId
759     * @throws DbException if the HMAC does not match
760     */
761    public void verifyLobMac(byte[] hmac, long lobId) {
762        byte[] result = calculateLobMac(lobId);
763        if (!Utils.compareSecure(hmac,  result)) {
764            throw DbException.get(ErrorCode.CONNECTION_BROKEN_1,
765                    "Invalid lob hmac; possibly the connection was re-opened internally");
766        }
767    }
768 
769    private byte[] calculateLobMac(long lobId) {
770        if (lobMacSalt == null) {
771            lobMacSalt = MathUtils.secureRandomBytes(LOB_MAC_SALT_LENGTH);
772        }
773        byte[] data = new byte[8];
774        Utils.writeLong(data, 0, lobId);
775        byte[] hmacData = SHA256.getHashWithSalt(data, lobMacSalt);
776        return hmacData;
777    }
778 
779}

[all classes][org.h2.value]
EMMA 2.0.5312 (C) Vladimir Roubtsov