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

COVERAGE SUMMARY FOR SOURCE FILE [Data.java]

nameclass, %method, %block, %line, %
Data.java100% (1/1)98%  (41/42)88%  (2478/2832)87%  (556/637)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Data100% (1/1)98%  (41/42)88%  (2478/2832)87%  (556/637)
getHandler (): DataHandler 0%   (0/1)0%   (0/3)0%   (0/1)
truncate (int): void 100% (1/1)24%  (5/21)33%  (2/6)
getValueLen (Value, DataHandler): int 100% (1/1)81%  (479/591)81%  (113/139)
writeValue (Value): void 100% (1/1)81%  (610/749)83%  (168/202)
readValue (): Value 100% (1/1)82%  (384/468)85%  (90/106)
Data (DataHandler, byte []): void 100% (1/1)100% (9/9)100% (4/4)
checkCapacity (int): void 100% (1/1)100% (12/12)100% (3/3)
copyString (Reader, OutputStream): void 100% (1/1)100% (32/32)100% (10/10)
create (DataHandler, byte []): Data 100% (1/1)100% (6/6)100% (1/1)
create (DataHandler, int): Data 100% (1/1)100% (7/7)100% (1/1)
expand (int): void 100% (1/1)100% (22/22)100% (4/4)
fillAligned (): void 100% (1/1)100% (23/23)100% (5/5)
getBytes (): byte [] 100% (1/1)100% (3/3)100% (1/1)
getStringLen (String): int 100% (1/1)100% (10/10)100% (2/2)
getStringWithoutLengthLen (String, int): int 100% (1/1)100% (26/26)100% (8/8)
getValueLen (Value): int 100% (1/1)100% (5/5)100% (1/1)
getVarIntLen (int): int 100% (1/1)100% (26/26)100% (9/9)
getVarLongLen (long): int 100% (1/1)100% (14/14)100% (5/5)
length (): int 100% (1/1)100% (3/3)100% (1/1)
read (byte [], int, int): void 100% (1/1)100% (15/15)100% (3/3)
readByte (): byte 100% (1/1)100% (11/11)100% (1/1)
readInt (): int 100% (1/1)100% (49/49)100% (4/4)
readLong (): long 100% (1/1)100% (12/12)100% (1/1)
readShortInt (): short 100% (1/1)100% (30/30)100% (2/2)
readString (): String 100% (1/1)100% (7/7)100% (2/2)
readString (int): String 100% (1/1)100% (85/85)100% (12/12)
readVarInt (): int 100% (1/1)100% (20/20)100% (5/5)
readVarIntRest (int): int 100% (1/1)100% (112/112)100% (18/18)
readVarLong (): long 100% (1/1)100% (52/52)100% (9/9)
reset (): void 100% (1/1)100% (4/4)100% (2/2)
setInt (int, int): void 100% (1/1)100% (36/36)100% (6/6)
setPos (int): void 100% (1/1)100% (4/4)100% (2/2)
write (byte [], int, int): void 100% (1/1)100% (15/15)100% (3/3)
writeByte (byte): void 100% (1/1)100% (12/12)100% (2/2)
writeInt (int): void 100% (1/1)100% (46/46)100% (7/7)
writeLong (long): void 100% (1/1)100% (11/11)100% (3/3)
writeShortInt (int): void 100% (1/1)100% (28/28)100% (4/4)
writeString (String): void 100% (1/1)100% (11/11)100% (4/4)
writeStringWithoutLength (String, int): void 100% (1/1)100% (81/81)100% (14/14)
writeStringWithoutLength (char [], int): void 100% (1/1)100% (81/81)100% (14/14)
writeVarInt (int): void 100% (1/1)100% (38/38)100% (5/5)
writeVarLong (long): void 100% (1/1)100% (42/42)100% (5/5)

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 *
6 * The variable size number format code is a port from SQLite,
7 * but stored in reverse order (least significant bits in the first byte).
8 */
9package org.h2.store;
10 
11import java.io.IOException;
12import java.io.OutputStream;
13import java.io.Reader;
14import java.math.BigDecimal;
15import java.math.BigInteger;
16import java.sql.ResultSet;
17import java.sql.ResultSetMetaData;
18import java.sql.SQLException;
19import java.sql.Timestamp;
20 
21import org.h2.api.ErrorCode;
22import org.h2.engine.Constants;
23import org.h2.engine.SysProperties;
24import org.h2.message.DbException;
25import org.h2.mvstore.DataUtils;
26import org.h2.tools.SimpleResultSet;
27import org.h2.util.DateTimeUtils;
28import org.h2.util.MathUtils;
29import org.h2.value.DataType;
30import org.h2.value.Value;
31import org.h2.value.ValueArray;
32import org.h2.value.ValueBoolean;
33import org.h2.value.ValueByte;
34import org.h2.value.ValueBytes;
35import org.h2.value.ValueDate;
36import org.h2.value.ValueDecimal;
37import org.h2.value.ValueDouble;
38import org.h2.value.ValueFloat;
39import org.h2.value.ValueGeometry;
40import org.h2.value.ValueInt;
41import org.h2.value.ValueJavaObject;
42import org.h2.value.ValueLob;
43import org.h2.value.ValueLobDb;
44import org.h2.value.ValueLong;
45import org.h2.value.ValueNull;
46import org.h2.value.ValueResultSet;
47import org.h2.value.ValueShort;
48import org.h2.value.ValueString;
49import org.h2.value.ValueStringFixed;
50import org.h2.value.ValueStringIgnoreCase;
51import org.h2.value.ValueTime;
52import org.h2.value.ValueTimestamp;
53import org.h2.value.ValueUuid;
54 
55/**
56 * This class represents a byte buffer that contains persistent data of a page.
57 *
58 * @author Thomas Mueller
59 * @author Noel Grandin
60 * @author Nicolas Fortin, Atelier SIG, IRSTV FR CNRS 24888
61 */
62public class Data {
63 
64    /**
65     * The length of an integer value.
66     */
67    public static final int LENGTH_INT = 4;
68 
69    /**
70     * The length of a long value.
71     */
72    private static final int LENGTH_LONG = 8;
73 
74    private static final int INT_0_15 = 32;
75    private static final int LONG_0_7 = 48;
76    private static final int DECIMAL_0_1 = 56;
77    private static final int DECIMAL_SMALL_0 = 58;
78    private static final int DECIMAL_SMALL = 59;
79    private static final int DOUBLE_0_1 = 60;
80    private static final int FLOAT_0_1 = 62;
81    private static final int BOOLEAN_FALSE = 64;
82    private static final int BOOLEAN_TRUE = 65;
83    private static final int INT_NEG = 66;
84    private static final int LONG_NEG = 67;
85    private static final int STRING_0_31 = 68;
86    private static final int BYTES_0_31 = 100;
87    private static final int LOCAL_TIME = 132;
88    private static final int LOCAL_DATE = 133;
89    private static final int LOCAL_TIMESTAMP = 134;
90 
91    private static final long MILLIS_PER_MINUTE = 1000 * 60;
92 
93    /**
94     * The data itself.
95     */
96    private byte[] data;
97 
98    /**
99     * The current write or read position.
100     */
101    private int pos;
102 
103    /**
104     * The data handler responsible for lob objects.
105     */
106    private final DataHandler handler;
107 
108    private Data(DataHandler handler, byte[] data) {
109        this.handler = handler;
110        this.data = data;
111    }
112 
113    /**
114     * Update an integer at the given position.
115     * The current position is not change.
116     *
117     * @param pos the position
118     * @param x the value
119     */
120    public void setInt(int pos, int x) {
121        byte[] buff = data;
122        buff[pos] = (byte) (x >> 24);
123        buff[pos + 1] = (byte) (x >> 16);
124        buff[pos + 2] = (byte) (x >> 8);
125        buff[pos + 3] = (byte) x;
126    }
127 
128    /**
129     * Write an integer at the current position.
130     * The current position is incremented.
131     *
132     * @param x the value
133     */
134    public void writeInt(int x) {
135        byte[] buff = data;
136        buff[pos] = (byte) (x >> 24);
137        buff[pos + 1] = (byte) (x >> 16);
138        buff[pos + 2] = (byte) (x >> 8);
139        buff[pos + 3] = (byte) x;
140        pos += 4;
141    }
142 
143    /**
144     * Read an integer at the current position.
145     * The current position is incremented.
146     *
147     * @return the value
148     */
149    public int readInt() {
150        byte[] buff = data;
151        int x = (buff[pos] << 24) +
152                ((buff[pos+1] & 0xff) << 16) +
153                ((buff[pos+2] & 0xff) << 8) +
154                (buff[pos+3] & 0xff);
155        pos += 4;
156        return x;
157    }
158 
159    /**
160     * Get the length of a String. This includes the bytes required to encode
161     * the length.
162     *
163     * @param s the string
164     * @return the number of bytes required
165     */
166    public static int getStringLen(String s) {
167        int len = s.length();
168        return getStringWithoutLengthLen(s, len) + getVarIntLen(len);
169    }
170 
171    /**
172     * Calculate the length of String, excluding the bytes required to encode
173     * the length.
174     * <p>
175     * For performance reasons the internal representation of a String is
176     * similar to UTF-8, but not exactly UTF-8.
177     *
178     * @param s the string
179     * @param len the length of the string
180     * @return the number of bytes required
181     */
182    private static int getStringWithoutLengthLen(String s, int len) {
183        int plus = 0;
184        for (int i = 0; i < len; i++) {
185            char c = s.charAt(i);
186            if (c >= 0x800) {
187                plus += 2;
188            } else if (c >= 0x80) {
189                plus++;
190            }
191        }
192        return len + plus;
193    }
194 
195    /**
196     * Read a String value.
197     * The current position is incremented.
198     *
199     * @return the value
200     */
201    public String readString() {
202        int len = readVarInt();
203        return readString(len);
204    }
205 
206    /**
207     * Read a String from the byte array.
208     * <p>
209     * For performance reasons the internal representation of a String is
210     * similar to UTF-8, but not exactly UTF-8.
211     *
212     * @param len the length of the resulting string
213     * @return the String
214     */
215    private String readString(int len) {
216        byte[] buff = data;
217        int p = pos;
218        char[] chars = new char[len];
219        for (int i = 0; i < len; i++) {
220            int x = buff[p++] & 0xff;
221            if (x < 0x80) {
222                chars[i] = (char) x;
223            } else if (x >= 0xe0) {
224                chars[i] = (char) (((x & 0xf) << 12) +
225                        ((buff[p++] & 0x3f) << 6) +
226                        (buff[p++] & 0x3f));
227            } else {
228                chars[i] = (char) (((x & 0x1f) << 6) +
229                        (buff[p++] & 0x3f));
230            }
231        }
232        pos = p;
233        return new String(chars);
234    }
235 
236    /**
237     * Write a String.
238     * The current position is incremented.
239     *
240     * @param s the value
241     */
242    public void writeString(String s) {
243        int len = s.length();
244        writeVarInt(len);
245        writeStringWithoutLength(s, len);
246    }
247 
248    /**
249     * Write a String.
250     * <p>
251     * For performance reasons the internal representation of a String is
252     * similar to UTF-8, but not exactly UTF-8.
253     *
254     * @param s the string
255     * @param len the number of characters to write
256     */
257    private void writeStringWithoutLength(String s, int len) {
258        int p = pos;
259        byte[] buff = data;
260        for (int i = 0; i < len; i++) {
261            int c = s.charAt(i);
262            if (c < 0x80) {
263                buff[p++] = (byte) c;
264            } else if (c >= 0x800) {
265                buff[p++] = (byte) (0xe0 | (c >> 12));
266                buff[p++] = (byte) (((c >> 6) & 0x3f));
267                buff[p++] = (byte) (c & 0x3f);
268            } else {
269                buff[p++] = (byte) (0xc0 | (c >> 6));
270                buff[p++] = (byte) (c & 0x3f);
271            }
272        }
273        pos = p;
274    }
275 
276    private void writeStringWithoutLength(char[] chars, int len) {
277        int p = pos;
278        byte[] buff = data;
279        for (int i = 0; i < len; i++) {
280            int c = chars[i];
281            if (c < 0x80) {
282                buff[p++] = (byte) c;
283            } else if (c >= 0x800) {
284                buff[p++] = (byte) (0xe0 | (c >> 12));
285                buff[p++] = (byte) (((c >> 6) & 0x3f));
286                buff[p++] = (byte) (c & 0x3f);
287            } else {
288                buff[p++] = (byte) (0xc0 | (c >> 6));
289                buff[p++] = (byte) (c & 0x3f);
290            }
291        }
292        pos = p;
293    }
294 
295    /**
296     * Create a new buffer for the given handler. The
297     * handler will decide what type of buffer is created.
298     *
299     * @param handler the data handler
300     * @param capacity the initial capacity of the buffer
301     * @return the buffer
302     */
303    public static Data create(DataHandler handler, int capacity) {
304        return new Data(handler, new byte[capacity]);
305    }
306 
307    /**
308     * Create a new buffer using the given data for the given handler. The
309     * handler will decide what type of buffer is created.
310     *
311     * @param handler the data handler
312     * @param buff the data
313     * @return the buffer
314     */
315    public static Data create(DataHandler handler, byte[] buff) {
316        return new Data(handler, buff);
317    }
318 
319    /**
320     * Get the current write position of this buffer, which is the current
321     * length.
322     *
323     * @return the length
324     */
325    public int length() {
326        return pos;
327    }
328 
329    /**
330     * Get the byte array used for this page.
331     *
332     * @return the byte array
333     */
334    public byte[] getBytes() {
335        return data;
336    }
337 
338    /**
339     * Set the position to 0.
340     */
341    public void reset() {
342        pos = 0;
343    }
344 
345    /**
346     * Append a number of bytes to this buffer.
347     *
348     * @param buff the data
349     * @param off the offset in the data
350     * @param len the length in bytes
351     */
352    public void write(byte[] buff, int off, int len) {
353        System.arraycopy(buff, off, data, pos, len);
354        pos += len;
355    }
356 
357    /**
358     * Copy a number of bytes to the given buffer from the current position. The
359     * current position is incremented accordingly.
360     *
361     * @param buff the output buffer
362     * @param off the offset in the output buffer
363     * @param len the number of bytes to copy
364     */
365    public void read(byte[] buff, int off, int len) {
366        System.arraycopy(data, pos, buff, off, len);
367        pos += len;
368    }
369 
370    /**
371     * Append one single byte.
372     *
373     * @param x the value
374     */
375    public void writeByte(byte x) {
376        data[pos++] = x;
377    }
378 
379    /**
380     * Read one single byte.
381     *
382     * @return the value
383     */
384    public byte readByte() {
385        return data[pos++];
386    }
387 
388    /**
389     * Read a long value. This method reads two int values and combines them.
390     *
391     * @return the long value
392     */
393    public long readLong() {
394        return ((long) (readInt()) << 32) + (readInt() & 0xffffffffL);
395    }
396 
397    /**
398     * Append a long value. This method writes two int values.
399     *
400     * @param x the value
401     */
402    public void writeLong(long x) {
403        writeInt((int) (x >>> 32));
404        writeInt((int) x);
405    }
406 
407    /**
408     * Append a value.
409     *
410     * @param v the value
411     */
412    public void writeValue(Value v) {
413        int start = pos;
414        if (v == ValueNull.INSTANCE) {
415            data[pos++] = 0;
416            return;
417        }
418        int type = v.getType();
419        switch (type) {
420        case Value.BOOLEAN:
421            writeByte((byte) (v.getBoolean().booleanValue() ?
422                    BOOLEAN_TRUE : BOOLEAN_FALSE));
423            break;
424        case Value.BYTE:
425            writeByte((byte) type);
426            writeByte(v.getByte());
427            break;
428        case Value.SHORT:
429            writeByte((byte) type);
430            writeShortInt(v.getShort());
431            break;
432        case Value.INT: {
433            int x = v.getInt();
434            if (x < 0) {
435                writeByte((byte) INT_NEG);
436                writeVarInt(-x);
437            } else if (x < 16) {
438                writeByte((byte) (INT_0_15 + x));
439            } else {
440                writeByte((byte) type);
441                writeVarInt(x);
442            }
443            break;
444        }
445        case Value.LONG: {
446            long x = v.getLong();
447            if (x < 0) {
448                writeByte((byte) LONG_NEG);
449                writeVarLong(-x);
450            } else if (x < 8) {
451                writeByte((byte) (LONG_0_7 + x));
452            } else {
453                writeByte((byte) type);
454                writeVarLong(x);
455            }
456            break;
457        }
458        case Value.DECIMAL: {
459            BigDecimal x = v.getBigDecimal();
460            if (BigDecimal.ZERO.equals(x)) {
461                writeByte((byte) DECIMAL_0_1);
462            } else if (BigDecimal.ONE.equals(x)) {
463                writeByte((byte) (DECIMAL_0_1 + 1));
464            } else {
465                int scale = x.scale();
466                BigInteger b = x.unscaledValue();
467                int bits = b.bitLength();
468                if (bits <= 63) {
469                    if (scale == 0) {
470                        writeByte((byte) DECIMAL_SMALL_0);
471                        writeVarLong(b.longValue());
472                    } else {
473                        writeByte((byte) DECIMAL_SMALL);
474                        writeVarInt(scale);
475                        writeVarLong(b.longValue());
476                    }
477                } else {
478                    writeByte((byte) type);
479                    writeVarInt(scale);
480                    byte[] bytes = b.toByteArray();
481                    writeVarInt(bytes.length);
482                    write(bytes, 0, bytes.length);
483                }
484            }
485            break;
486        }
487        case Value.TIME:
488            if (SysProperties.STORE_LOCAL_TIME) {
489                writeByte((byte) LOCAL_TIME);
490                ValueTime t = (ValueTime) v;
491                long nanos = t.getNanos();
492                long millis = nanos / 1000000;
493                nanos -= millis * 1000000;
494                writeVarLong(millis);
495                writeVarLong(nanos);
496            } else {
497                writeByte((byte) type);
498                writeVarLong(DateTimeUtils.getTimeLocalWithoutDst(v.getTime()));
499            }
500            break;
501        case Value.DATE: {
502            if (SysProperties.STORE_LOCAL_TIME) {
503                writeByte((byte) LOCAL_DATE);
504                long x = ((ValueDate) v).getDateValue();
505                writeVarLong(x);
506            } else {
507                writeByte((byte) type);
508                long x = DateTimeUtils.getTimeLocalWithoutDst(v.getDate());
509                writeVarLong(x / MILLIS_PER_MINUTE);
510            }
511            break;
512        }
513        case Value.TIMESTAMP: {
514            if (SysProperties.STORE_LOCAL_TIME) {
515                writeByte((byte) LOCAL_TIMESTAMP);
516                ValueTimestamp ts = (ValueTimestamp) v;
517                long dateValue = ts.getDateValue();
518                writeVarLong(dateValue);
519                long nanos = ts.getTimeNanos();
520                long millis = nanos / 1000000;
521                nanos -= millis * 1000000;
522                writeVarLong(millis);
523                writeVarLong(nanos);
524            } else {
525                Timestamp ts = v.getTimestamp();
526                writeByte((byte) type);
527                writeVarLong(DateTimeUtils.getTimeLocalWithoutDst(ts));
528                writeVarInt(ts.getNanos() % 1000000);
529            }
530            break;
531        }
532        case Value.GEOMETRY:
533        case Value.JAVA_OBJECT: {
534            writeByte((byte) type);
535            byte[] b = v.getBytesNoCopy();
536            int len = b.length;
537            writeVarInt(len);
538            write(b, 0, len);
539            break;
540        }
541        case Value.BYTES: {
542            byte[] b = v.getBytesNoCopy();
543            int len = b.length;
544            if (len < 32) {
545                writeByte((byte) (BYTES_0_31 + len));
546                write(b, 0, len);
547            } else {
548                writeByte((byte) type);
549                writeVarInt(len);
550                write(b, 0, len);
551            }
552            break;
553        }
554        case Value.UUID: {
555            writeByte((byte) type);
556            ValueUuid uuid = (ValueUuid) v;
557            writeLong(uuid.getHigh());
558            writeLong(uuid.getLow());
559            break;
560        }
561        case Value.STRING: {
562            String s = v.getString();
563            int len = s.length();
564            if (len < 32) {
565                writeByte((byte) (STRING_0_31 + len));
566                writeStringWithoutLength(s, len);
567            } else {
568                writeByte((byte) type);
569                writeString(s);
570            }
571            break;
572        }
573        case Value.STRING_IGNORECASE:
574        case Value.STRING_FIXED:
575            writeByte((byte) type);
576            writeString(v.getString());
577            break;
578        case Value.DOUBLE: {
579            double x = v.getDouble();
580            if (x == 1.0d) {
581                writeByte((byte) (DOUBLE_0_1 + 1));
582            } else {
583                long d = Double.doubleToLongBits(x);
584                if (d == ValueDouble.ZERO_BITS) {
585                    writeByte((byte) DOUBLE_0_1);
586                } else {
587                    writeByte((byte) type);
588                    writeVarLong(Long.reverse(d));
589                }
590            }
591            break;
592        }
593        case Value.FLOAT: {
594            float x = v.getFloat();
595            if (x == 1.0f) {
596                writeByte((byte) (FLOAT_0_1 + 1));
597            } else {
598                int f = Float.floatToIntBits(x);
599                if (f == ValueFloat.ZERO_BITS) {
600                    writeByte((byte) FLOAT_0_1);
601                } else {
602                    writeByte((byte) type);
603                    writeVarInt(Integer.reverse(f));
604                }
605            }
606            break;
607        }
608        case Value.BLOB:
609        case Value.CLOB: {
610            writeByte((byte) type);
611            if (v instanceof ValueLob) {
612                ValueLob lob = (ValueLob) v;
613                lob.convertToFileIfRequired(handler);
614                byte[] small = lob.getSmall();
615                if (small == null) {
616                    int t = -1;
617                    if (!lob.isLinked()) {
618                        t = -2;
619                    }
620                    writeVarInt(t);
621                    writeVarInt(lob.getTableId());
622                    writeVarInt(lob.getObjectId());
623                    writeVarLong(lob.getPrecision());
624                    writeByte((byte) (lob.isCompressed() ? 1 : 0));
625                    if (t == -2) {
626                        writeString(lob.getFileName());
627                    }
628                } else {
629                    writeVarInt(small.length);
630                    write(small, 0, small.length);
631                }
632            } else {
633                ValueLobDb lob = (ValueLobDb) v;
634                byte[] small = lob.getSmall();
635                if (small == null) {
636                    writeVarInt(-3);
637                    writeVarInt(lob.getTableId());
638                    writeVarLong(lob.getLobId());
639                    writeVarLong(lob.getPrecision());
640                } else {
641                    writeVarInt(small.length);
642                    write(small, 0, small.length);
643                }
644            }
645            break;
646        }
647        case Value.ARRAY: {
648            writeByte((byte) type);
649            Value[] list = ((ValueArray) v).getList();
650            writeVarInt(list.length);
651            for (Value x : list) {
652                writeValue(x);
653            }
654            break;
655        }
656        case Value.RESULT_SET: {
657            writeByte((byte) type);
658            try {
659                ResultSet rs = ((ValueResultSet) v).getResultSet();
660                rs.beforeFirst();
661                ResultSetMetaData meta = rs.getMetaData();
662                int columnCount = meta.getColumnCount();
663                writeVarInt(columnCount);
664                for (int i = 0; i < columnCount; i++) {
665                    writeString(meta.getColumnName(i + 1));
666                    writeVarInt(meta.getColumnType(i + 1));
667                    writeVarInt(meta.getPrecision(i + 1));
668                    writeVarInt(meta.getScale(i + 1));
669                }
670                while (rs.next()) {
671                    writeByte((byte) 1);
672                    for (int i = 0; i < columnCount; i++) {
673                        int t = DataType.getValueTypeFromResultSet(meta, i + 1);
674                        Value val = DataType.readValue(null, rs, i + 1, t);
675                        writeValue(val);
676                    }
677                }
678                writeByte((byte) 0);
679                rs.beforeFirst();
680            } catch (SQLException e) {
681                throw DbException.convert(e);
682            }
683            break;
684        }
685        default:
686            DbException.throwInternalError("type=" + v.getType());
687        }
688        if (SysProperties.CHECK2) {
689            if (pos - start != getValueLen(v, handler)) {
690                throw DbException.throwInternalError(
691                            "value size error: got " + (pos - start) +
692                            " expected " + getValueLen(v, handler));
693            }
694        }
695    }
696 
697    /**
698     * Read a value.
699     *
700     * @return the value
701     */
702    public Value readValue() {
703        int type = data[pos++] & 255;
704        switch (type) {
705        case Value.NULL:
706            return ValueNull.INSTANCE;
707        case BOOLEAN_TRUE:
708            return ValueBoolean.get(true);
709        case BOOLEAN_FALSE:
710            return ValueBoolean.get(false);
711        case INT_NEG:
712            return ValueInt.get(-readVarInt());
713        case Value.INT:
714            return ValueInt.get(readVarInt());
715        case LONG_NEG:
716            return ValueLong.get(-readVarLong());
717        case Value.LONG:
718            return ValueLong.get(readVarLong());
719        case Value.BYTE:
720            return ValueByte.get(readByte());
721        case Value.SHORT:
722            return ValueShort.get(readShortInt());
723        case DECIMAL_0_1:
724            return (ValueDecimal) ValueDecimal.ZERO;
725        case DECIMAL_0_1 + 1:
726            return (ValueDecimal) ValueDecimal.ONE;
727        case DECIMAL_SMALL_0:
728            return ValueDecimal.get(BigDecimal.valueOf(readVarLong()));
729        case DECIMAL_SMALL: {
730            int scale = readVarInt();
731            return ValueDecimal.get(BigDecimal.valueOf(readVarLong(), scale));
732        }
733        case Value.DECIMAL: {
734            int scale = readVarInt();
735            int len = readVarInt();
736            byte[] buff = DataUtils.newBytes(len);
737            read(buff, 0, len);
738            BigInteger b = new BigInteger(buff);
739            return ValueDecimal.get(new BigDecimal(b, scale));
740        }
741        case LOCAL_DATE: {
742            return ValueDate.fromDateValue(readVarLong());
743        }
744        case Value.DATE: {
745            long x = readVarLong() * MILLIS_PER_MINUTE;
746            return ValueDate.fromMillis(DateTimeUtils.getTimeUTCWithoutDst(x));
747        }
748        case LOCAL_TIME: {
749            long nanos = readVarLong() * 1000000 + readVarLong();
750            return ValueTime.fromNanos(nanos);
751        }
752        case Value.TIME:
753            // need to normalize the year, month and day
754            return ValueTime.fromMillis(
755                    DateTimeUtils.getTimeUTCWithoutDst(readVarLong()));
756        case LOCAL_TIMESTAMP: {
757            long dateValue = readVarLong();
758            long nanos = readVarLong() * 1000000 + readVarLong();
759            return ValueTimestamp.fromDateValueAndNanos(dateValue, nanos);
760        }
761        case Value.TIMESTAMP: {
762            return ValueTimestamp.fromMillisNanos(
763                    DateTimeUtils.getTimeUTCWithoutDst(readVarLong()),
764                    readVarInt());
765        }
766        case Value.BYTES: {
767            int len = readVarInt();
768            byte[] b = DataUtils.newBytes(len);
769            read(b, 0, len);
770            return ValueBytes.getNoCopy(b);
771        }
772        case Value.GEOMETRY: {
773            int len = readVarInt();
774            byte[] b = DataUtils.newBytes(len);
775            read(b, 0, len);
776            return ValueGeometry.get(b);
777        }
778        case Value.JAVA_OBJECT: {
779            int len = readVarInt();
780            byte[] b = DataUtils.newBytes(len);
781            read(b, 0, len);
782            return ValueJavaObject.getNoCopy(null, b, handler);
783        }
784        case Value.UUID:
785            return ValueUuid.get(readLong(), readLong());
786        case Value.STRING:
787            return ValueString.get(readString());
788        case Value.STRING_IGNORECASE:
789            return ValueStringIgnoreCase.get(readString());
790        case Value.STRING_FIXED:
791            return ValueStringFixed.get(readString());
792        case FLOAT_0_1:
793            return ValueFloat.get(0);
794        case FLOAT_0_1 + 1:
795            return ValueFloat.get(1);
796        case DOUBLE_0_1:
797            return ValueDouble.get(0);
798        case DOUBLE_0_1 + 1:
799            return ValueDouble.get(1);
800        case Value.DOUBLE:
801            return ValueDouble.get(Double.longBitsToDouble(
802                    Long.reverse(readVarLong())));
803        case Value.FLOAT:
804            return ValueFloat.get(Float.intBitsToFloat(
805                    Integer.reverse(readVarInt())));
806        case Value.BLOB:
807        case Value.CLOB: {
808            int smallLen = readVarInt();
809            if (smallLen >= 0) {
810                byte[] small = DataUtils.newBytes(smallLen);
811                read(small, 0, smallLen);
812                return ValueLobDb.createSmallLob(type, small);
813            } else if (smallLen == -3) {
814                int tableId = readVarInt();
815                long lobId = readVarLong();
816                long precision = readVarLong();
817                ValueLobDb lob = ValueLobDb.create(type, handler, tableId,
818                        lobId, null, precision);
819                return lob;
820            } else {
821                int tableId = readVarInt();
822                int objectId = readVarInt();
823                long precision = 0;
824                boolean compression = false;
825                // -1: regular; -2: regular, but not linked (in this case:
826                // including file name)
827                if (smallLen == -1 || smallLen == -2) {
828                    precision = readVarLong();
829                    compression = readByte() == 1;
830                }
831                if (smallLen == -2) {
832                    String filename = readString();
833                    return ValueLob.openUnlinked(type, handler, tableId,
834                            objectId, precision, compression, filename);
835                }
836                return ValueLob.openLinked(type, handler, tableId,
837                        objectId, precision, compression);
838            }
839        }
840        case Value.ARRAY: {
841            int len = readVarInt();
842            Value[] list = new Value[len];
843            for (int i = 0; i < len; i++) {
844                list[i] = readValue();
845            }
846            return ValueArray.get(list);
847        }
848        case Value.RESULT_SET: {
849            SimpleResultSet rs = new SimpleResultSet();
850            rs.setAutoClose(false);
851            int columns = readVarInt();
852            for (int i = 0; i < columns; i++) {
853                rs.addColumn(readString(), readVarInt(), readVarInt(), readVarInt());
854            }
855            while (true) {
856                if (readByte() == 0) {
857                    break;
858                }
859                Object[] o = new Object[columns];
860                for (int i = 0; i < columns; i++) {
861                    o[i] = readValue().getObject();
862                }
863                rs.addRow(o);
864            }
865            return ValueResultSet.get(rs);
866        }
867        default:
868            if (type >= INT_0_15 && type < INT_0_15 + 16) {
869                return ValueInt.get(type - INT_0_15);
870            } else if (type >= LONG_0_7 && type < LONG_0_7 + 8) {
871                return ValueLong.get(type - LONG_0_7);
872            } else if (type >= BYTES_0_31 && type < BYTES_0_31 + 32) {
873                int len = type - BYTES_0_31;
874                byte[] b = DataUtils.newBytes(len);
875                read(b, 0, len);
876                return ValueBytes.getNoCopy(b);
877            } else if (type >= STRING_0_31 && type < STRING_0_31 + 32) {
878                return ValueString.get(readString(type - STRING_0_31));
879            }
880            throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "type: " + type);
881        }
882    }
883 
884    /**
885     * Calculate the number of bytes required to encode the given value.
886     *
887     * @param v the value
888     * @return the number of bytes required to store this value
889     */
890    public int getValueLen(Value v) {
891        return getValueLen(v, handler);
892    }
893 
894    /**
895     * Calculate the number of bytes required to encode the given value.
896     *
897     * @param v the value
898     * @param handler the data handler for lobs
899     * @return the number of bytes required to store this value
900     */
901    public static int getValueLen(Value v, DataHandler handler) {
902        if (v == ValueNull.INSTANCE) {
903            return 1;
904        }
905        switch (v.getType()) {
906        case Value.BOOLEAN:
907            return 1;
908        case Value.BYTE:
909            return 2;
910        case Value.SHORT:
911            return 3;
912        case Value.INT: {
913            int x = v.getInt();
914            if (x < 0) {
915                return 1 + getVarIntLen(-x);
916            } else if (x < 16) {
917                return 1;
918            } else {
919                return 1 + getVarIntLen(x);
920            }
921        }
922        case Value.LONG: {
923            long x = v.getLong();
924            if (x < 0) {
925                return 1 + getVarLongLen(-x);
926            } else if (x < 8) {
927                return 1;
928            } else {
929                return 1 + getVarLongLen(x);
930            }
931        }
932        case Value.DOUBLE: {
933            double x = v.getDouble();
934            if (x == 1.0d) {
935                return 1;
936            }
937            long d = Double.doubleToLongBits(x);
938            if (d == ValueDouble.ZERO_BITS) {
939                return 1;
940            }
941            return 1 + getVarLongLen(Long.reverse(d));
942        }
943        case Value.FLOAT: {
944            float x = v.getFloat();
945            if (x == 1.0f) {
946                return 1;
947            }
948            int f = Float.floatToIntBits(x);
949            if (f == ValueFloat.ZERO_BITS) {
950                return 1;
951            }
952            return 1 + getVarIntLen(Integer.reverse(f));
953        }
954        case Value.STRING: {
955            String s = v.getString();
956            int len = s.length();
957            if (len < 32) {
958                return 1 + getStringWithoutLengthLen(s, len);
959            }
960            return 1 + getStringLen(s);
961        }
962        case Value.STRING_IGNORECASE:
963        case Value.STRING_FIXED:
964            return 1 + getStringLen(v.getString());
965        case Value.DECIMAL: {
966            BigDecimal x = v.getBigDecimal();
967            if (BigDecimal.ZERO.equals(x)) {
968                return 1;
969            } else if (BigDecimal.ONE.equals(x)) {
970                return 1;
971            }
972            int scale = x.scale();
973            BigInteger b = x.unscaledValue();
974            int bits = b.bitLength();
975            if (bits <= 63) {
976                if (scale == 0) {
977                    return 1 + getVarLongLen(b.longValue());
978                }
979                return 1 + getVarIntLen(scale) + getVarLongLen(b.longValue());
980            }
981            byte[] bytes = b.toByteArray();
982            return 1 + getVarIntLen(scale) + getVarIntLen(bytes.length) + bytes.length;
983        }
984        case Value.TIME:
985            if (SysProperties.STORE_LOCAL_TIME) {
986                long nanos = ((ValueTime) v).getNanos();
987                long millis = nanos / 1000000;
988                nanos -= millis * 1000000;
989                return 1 + getVarLongLen(millis) + getVarLongLen(nanos);
990            }
991            return 1 + getVarLongLen(DateTimeUtils.getTimeLocalWithoutDst(v.getTime()));
992        case Value.DATE: {
993            if (SysProperties.STORE_LOCAL_TIME) {
994                long dateValue = ((ValueDate) v).getDateValue();
995                return 1 + getVarLongLen(dateValue);
996            }
997            long x = DateTimeUtils.getTimeLocalWithoutDst(v.getDate());
998            return 1 + getVarLongLen(x / MILLIS_PER_MINUTE);
999        }
1000        case Value.TIMESTAMP: {
1001            if (SysProperties.STORE_LOCAL_TIME) {
1002                ValueTimestamp ts = (ValueTimestamp) v;
1003                long dateValue = ts.getDateValue();
1004                long nanos = ts.getTimeNanos();
1005                long millis = nanos / 1000000;
1006                nanos -= millis * 1000000;
1007                return 1 + getVarLongLen(dateValue) + getVarLongLen(millis) +
1008                        getVarLongLen(nanos);
1009            }
1010            Timestamp ts = v.getTimestamp();
1011            return 1 + getVarLongLen(DateTimeUtils.getTimeLocalWithoutDst(ts)) +
1012                    getVarIntLen(ts.getNanos() % 1000000);
1013        }
1014        case Value.GEOMETRY:
1015        case Value.JAVA_OBJECT: {
1016            byte[] b = v.getBytesNoCopy();
1017            return 1 + getVarIntLen(b.length) + b.length;
1018        }
1019        case Value.BYTES: {
1020            byte[] b = v.getBytesNoCopy();
1021            int len = b.length;
1022            if (len < 32) {
1023                return 1 + b.length;
1024            }
1025            return 1 + getVarIntLen(b.length) + b.length;
1026        }
1027        case Value.UUID:
1028            return 1 + LENGTH_LONG + LENGTH_LONG;
1029        case Value.BLOB:
1030        case Value.CLOB: {
1031            int len = 1;
1032            if (v instanceof ValueLob) {
1033                ValueLob lob = (ValueLob) v;
1034                lob.convertToFileIfRequired(handler);
1035                byte[] small = lob.getSmall();
1036                if (small == null) {
1037                    int t = -1;
1038                    if (!lob.isLinked()) {
1039                        t = -2;
1040                    }
1041                    len += getVarIntLen(t);
1042                    len += getVarIntLen(lob.getTableId());
1043                    len += getVarIntLen(lob.getObjectId());
1044                    len += getVarLongLen(lob.getPrecision());
1045                    len += 1;
1046                    if (t == -2) {
1047                        len += getStringLen(lob.getFileName());
1048                    }
1049                } else {
1050                    len += getVarIntLen(small.length);
1051                    len += small.length;
1052                }
1053            } else {
1054                ValueLobDb lob = (ValueLobDb) v;
1055                byte[] small = lob.getSmall();
1056                if (small == null) {
1057                    len += getVarIntLen(-3);
1058                    len += getVarIntLen(lob.getTableId());
1059                    len += getVarLongLen(lob.getLobId());
1060                    len += getVarLongLen(lob.getPrecision());
1061                } else {
1062                    len += getVarIntLen(small.length);
1063                    len += small.length;
1064                }
1065            }
1066            return len;
1067        }
1068        case Value.ARRAY: {
1069            Value[] list = ((ValueArray) v).getList();
1070            int len = 1 + getVarIntLen(list.length);
1071            for (Value x : list) {
1072                len += getValueLen(x, handler);
1073            }
1074            return len;
1075        }
1076        case Value.RESULT_SET: {
1077            int len = 1;
1078            try {
1079                ResultSet rs = ((ValueResultSet) v).getResultSet();
1080                rs.beforeFirst();
1081                ResultSetMetaData meta = rs.getMetaData();
1082                int columnCount = meta.getColumnCount();
1083                len += getVarIntLen(columnCount);
1084                for (int i = 0; i < columnCount; i++) {
1085                    len += getStringLen(meta.getColumnName(i + 1));
1086                    len += getVarIntLen(meta.getColumnType(i + 1));
1087                    len += getVarIntLen(meta.getPrecision(i + 1));
1088                    len += getVarIntLen(meta.getScale(i + 1));
1089                }
1090                while (rs.next()) {
1091                    len++;
1092                    for (int i = 0; i < columnCount; i++) {
1093                        int t = DataType.getValueTypeFromResultSet(meta, i + 1);
1094                        Value val = DataType.readValue(null, rs, i + 1, t);
1095                        len += getValueLen(val, handler);
1096                    }
1097                }
1098                len++;
1099                rs.beforeFirst();
1100            } catch (SQLException e) {
1101                throw DbException.convert(e);
1102            }
1103            return len;
1104        }
1105        default:
1106            throw DbException.throwInternalError("type=" + v.getType());
1107        }
1108    }
1109 
1110    /**
1111     * Set the current read / write position.
1112     *
1113     * @param pos the new position
1114     */
1115    public void setPos(int pos) {
1116        this.pos = pos;
1117    }
1118 
1119    /**
1120     * Write a short integer at the current position.
1121     * The current position is incremented.
1122     *
1123     * @param x the value
1124     */
1125    public void writeShortInt(int x) {
1126        byte[] buff = data;
1127        buff[pos++] = (byte) (x >> 8);
1128        buff[pos++] = (byte) x;
1129    }
1130 
1131    /**
1132     * Read an short integer at the current position.
1133     * The current position is incremented.
1134     *
1135     * @return the value
1136     */
1137    public short readShortInt() {
1138        byte[] buff = data;
1139        return (short) (((buff[pos++] & 0xff) << 8) + (buff[pos++] & 0xff));
1140    }
1141 
1142    /**
1143     * Shrink the array to this size.
1144     *
1145     * @param size the new size
1146     */
1147    public void truncate(int size) {
1148        if (pos > size) {
1149            byte[] buff = new byte[size];
1150            System.arraycopy(data, 0, buff, 0, size);
1151            this.pos = size;
1152            data = buff;
1153        }
1154    }
1155 
1156    /**
1157     * The number of bytes required for a variable size int.
1158     *
1159     * @param x the value
1160     * @return the len
1161     */
1162    private static int getVarIntLen(int x) {
1163        if ((x & (-1 << 7)) == 0) {
1164            return 1;
1165        } else if ((x & (-1 << 14)) == 0) {
1166            return 2;
1167        } else if ((x & (-1 << 21)) == 0) {
1168            return 3;
1169        } else if ((x & (-1 << 28)) == 0) {
1170            return 4;
1171        }
1172        return 5;
1173    }
1174 
1175    /**
1176     * Write a variable size int.
1177     *
1178     * @param x the value
1179     */
1180    public void writeVarInt(int x) {
1181        while ((x & ~0x7f) != 0) {
1182            data[pos++] = (byte) (0x80 | (x & 0x7f));
1183            x >>>= 7;
1184        }
1185        data[pos++] = (byte) x;
1186    }
1187 
1188    /**
1189     * Read a variable size int.
1190     *
1191     * @return the value
1192     */
1193    public int readVarInt() {
1194        int b = data[pos];
1195        if (b >= 0) {
1196            pos++;
1197            return b;
1198        }
1199        // a separate function so that this one can be inlined
1200        return readVarIntRest(b);
1201    }
1202 
1203    private int readVarIntRest(int b) {
1204        int x = b & 0x7f;
1205        b = data[pos + 1];
1206        if (b >= 0) {
1207            pos += 2;
1208            return x | (b << 7);
1209        }
1210        x |= (b & 0x7f) << 7;
1211        b = data[pos + 2];
1212        if (b >= 0) {
1213            pos += 3;
1214            return x | (b << 14);
1215        }
1216        x |= (b & 0x7f) << 14;
1217        b = data[pos + 3];
1218        if (b >= 0) {
1219            pos += 4;
1220            return x | b << 21;
1221        }
1222        x |= ((b & 0x7f) << 21) | (data[pos + 4] << 28);
1223        pos += 5;
1224        return x;
1225    }
1226 
1227    /**
1228     * The number of bytes required for a variable size long.
1229     *
1230     * @param x the value
1231     * @return the len
1232     */
1233    public static int getVarLongLen(long x) {
1234        int i = 1;
1235        while (true) {
1236            x >>>= 7;
1237            if (x == 0) {
1238                return i;
1239            }
1240            i++;
1241        }
1242    }
1243 
1244    /**
1245     * Write a variable size long.
1246     *
1247     * @param x the value
1248     */
1249    public void writeVarLong(long x) {
1250        while ((x & ~0x7f) != 0) {
1251            data[pos++] = (byte) ((x & 0x7f) | 0x80);
1252            x >>>= 7;
1253        }
1254        data[pos++] = (byte) x;
1255    }
1256 
1257    /**
1258     * Read a variable size long.
1259     *
1260     * @return the value
1261     */
1262    public long readVarLong() {
1263        long x = data[pos++];
1264        if (x >= 0) {
1265            return x;
1266        }
1267        x &= 0x7f;
1268        for (int s = 7;; s += 7) {
1269            long b = data[pos++];
1270            x |= (b & 0x7f) << s;
1271            if (b >= 0) {
1272                return x;
1273            }
1274        }
1275    }
1276 
1277    /**
1278     * Check if there is still enough capacity in the buffer.
1279     * This method extends the buffer if required.
1280     *
1281     * @param plus the number of additional bytes required
1282     */
1283    public void checkCapacity(int plus) {
1284        if (pos + plus >= data.length) {
1285            // a separate method to simplify inlining
1286            expand(plus);
1287        }
1288    }
1289 
1290    private void expand(int plus) {
1291        byte[] d = DataUtils.newBytes((data.length + plus) * 2);
1292        // must copy everything, because pos could be 0 and data may be
1293        // still required
1294        System.arraycopy(data, 0, d, 0, data.length);
1295        data = d;
1296    }
1297 
1298    /**
1299     * Fill up the buffer with empty space and an (initially empty) checksum
1300     * until the size is a multiple of Constants.FILE_BLOCK_SIZE.
1301     */
1302    public void fillAligned() {
1303        // 0..6 > 8, 7..14 > 16, 15..22 > 24, ...
1304        int len = MathUtils.roundUpInt(pos + 2, Constants.FILE_BLOCK_SIZE);
1305        pos = len;
1306        if (data.length < len) {
1307            checkCapacity(len - data.length);
1308        }
1309    }
1310 
1311    /**
1312     * Copy a String from a reader to an output stream.
1313     *
1314     * @param source the reader
1315     * @param target the output stream
1316     */
1317    public static void copyString(Reader source, OutputStream target)
1318            throws IOException {
1319        char[] buff = new char[Constants.IO_BUFFER_SIZE];
1320        Data d = new Data(null, new byte[3 * Constants.IO_BUFFER_SIZE]);
1321        while (true) {
1322            int l = source.read(buff);
1323            if (l < 0) {
1324                break;
1325            }
1326            d.writeStringWithoutLength(buff, l);
1327            target.write(d.data, 0, d.pos);
1328            d.reset();
1329        }
1330    }
1331 
1332    public DataHandler getHandler() {
1333        return handler;
1334    }
1335 
1336}

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