20
20
import io .netty .buffer .ByteBuf ;
21
21
import io .netty .buffer .Unpooled ;
22
22
import io .netty .handler .codec .DecoderException ;
23
+ import io .vertx .core .buffer .Buffer ;
23
24
import io .vertx .core .impl .logging .Logger ;
24
25
import io .vertx .core .impl .logging .LoggerFactory ;
25
26
import io .vertx .core .json .Json ;
26
- import io .vertx .sqlclient .Tuple ;
27
- import io .vertx .sqlclient .data .Numeric ;
28
- import io .vertx .pgclient .data .*;
29
- import io .vertx .pgclient .impl .util .UTF8StringEndDetector ;
30
- import io .vertx .core .buffer .Buffer ;
31
27
import io .vertx .core .json .JsonArray ;
32
28
import io .vertx .core .json .JsonObject ;
29
+ import io .vertx .pgclient .data .*;
30
+ import io .vertx .pgclient .impl .util .UTF8StringEndDetector ;
31
+ import io .vertx .sqlclient .Tuple ;
32
+ import io .vertx .sqlclient .data .Numeric ;
33
33
import io .vertx .sqlclient .impl .codec .CommonCodec ;
34
34
35
35
import java .net .Inet4Address ;
50
50
51
51
import static java .time .format .DateTimeFormatter .ISO_LOCAL_DATE ;
52
52
import static java .time .format .DateTimeFormatter .ISO_LOCAL_TIME ;
53
- import static java .util .concurrent .TimeUnit .* ;
53
+ import static java .util .concurrent .TimeUnit .NANOSECONDS ;
54
54
55
55
/**
56
56
* @author <a href="mailto:julien@julienviet.com">Julien Viet</a>
@@ -91,6 +91,8 @@ public class DataTypeCodec {
91
91
private static final OffsetDateTime OFFSET_DATE_TIME_EPOCH = LocalDateTime .of (2000 , 1 , 1 , 0 , 0 , 0 ).atOffset (ZoneOffset .UTC );
92
92
private static final Inet [] empty_inet_array = new Inet [0 ];
93
93
private static final Money [] empty_money_array = new Money [0 ];
94
+ private static final PgSQLXML [] empty_pgsqlxml_array = new PgSQLXML [0 ];
95
+
94
96
95
97
// Sentinel used when an object is refused by the data type
96
98
public static final Object REFUSED_SENTINEL = new Object ();
@@ -107,7 +109,7 @@ public class DataTypeCodec {
107
109
private static final IntFunction <OffsetTime []> OFFSETTIME_ARRAY_FACTORY = size -> size == 0 ? empty_offset_time_array : new OffsetTime [size ];
108
110
private static final IntFunction <LocalDateTime []> LOCALDATETIME_ARRAY_FACTORY = size -> size == 0 ? empty_local_date_time_array : new LocalDateTime [size ];
109
111
private static final IntFunction <OffsetDateTime []> OFFSETDATETIME_ARRAY_FACTORY = size -> size == 0 ? empty_offset_date_time_array : new OffsetDateTime [size ];
110
- private static final IntFunction <Buffer []> BUFFER_ARRAY_FACTORY =size -> size == 0 ? empty_buffer_array : new Buffer [size ];
112
+ private static final IntFunction <Buffer []> BUFFER_ARRAY_FACTORY = size -> size == 0 ? empty_buffer_array : new Buffer [size ];
111
113
private static final IntFunction <UUID []> UUID_ARRAY_FACTORY = size -> size == 0 ? empty_uuid_array : new UUID [size ];
112
114
private static final IntFunction <Object []> JSON_ARRAY_FACTORY = size -> size == 0 ? empty_json_array : new Object [size ];
113
115
private static final IntFunction <Numeric []> NUMERIC_ARRAY_FACTORY = size -> size == 0 ? empty_numeric_array : new Numeric [size ];
@@ -121,20 +123,18 @@ public class DataTypeCodec {
121
123
private static final IntFunction <Interval []> INTERVAL_ARRAY_FACTORY = size -> size == 0 ? empty_interval_array : new Interval [size ];
122
124
private static final IntFunction <Inet []> INET_ARRAY_FACTORY = size -> size == 0 ? empty_inet_array : new Inet [size ];
123
125
private static final IntFunction <Money []> MONEY_ARRAY_FACTORY = size -> size == 0 ? empty_money_array : new Money [size ];
124
-
126
+ private static final IntFunction < PgSQLXML []> PGSQLXML_ARRAY_FACTORY = size -> size == 0 ? empty_pgsqlxml_array : new PgSQLXML [ size ];
125
127
private static final java .time .format .DateTimeFormatter TIMETZ_FORMAT = new DateTimeFormatterBuilder ()
126
128
.parseCaseInsensitive ()
127
129
.append (ISO_LOCAL_TIME )
128
130
.appendOffset ("+HH:mm" , "00:00" )
129
131
.toFormatter ();
130
-
131
132
private static final java .time .format .DateTimeFormatter TIMESTAMP_FORMAT = new DateTimeFormatterBuilder ()
132
133
.parseCaseInsensitive ()
133
134
.append (ISO_LOCAL_DATE )
134
135
.appendLiteral (' ' )
135
136
.append (ISO_LOCAL_TIME )
136
137
.toFormatter ();
137
-
138
138
private static final java .time .format .DateTimeFormatter TIMESTAMPTZ_FORMAT = new DateTimeFormatterBuilder ()
139
139
.append (TIMESTAMP_FORMAT )
140
140
.appendOffset ("+HH:mm" , "00:00" )
@@ -360,6 +360,12 @@ public static void encodeBinary(DataType id, Object value, ByteBuf buff) {
360
360
case MONEY_ARRAY :
361
361
binaryEncodeArray ((Money []) value , DataType .MONEY , buff );
362
362
break ;
363
+ case XML :
364
+ binaryEncodePgXMLSQL ((PgSQLXML ) value , buff );
365
+ break ;
366
+ case XML_ARRAY :
367
+ binaryEncodeArray ((PgSQLXML []) value , DataType .XML , buff );
368
+ break ;
363
369
default :
364
370
logger .debug ("Data type " + id + " does not support binary encoding" );
365
371
defaultEncodeBinary (value , buff );
@@ -497,6 +503,10 @@ public static Object decodeBinary(DataType id, int index, int len, ByteBuf buff)
497
503
return binaryDecodeMoney (index , len , buff );
498
504
case MONEY_ARRAY :
499
505
return binaryDecodeArray (MONEY_ARRAY_FACTORY , DataType .MONEY , index , len , buff );
506
+ case XML :
507
+ return binaryDecodePgXMLSQL (index , len , buff );
508
+ case XML_ARRAY :
509
+ return binaryDecodeArray (PGSQLXML_ARRAY_FACTORY , DataType .XML , index , len , buff );
500
510
default :
501
511
logger .debug ("Data type " + id + " does not support binary decoding" );
502
512
return defaultDecodeBinary (index , len , buff );
@@ -669,7 +679,7 @@ private static Boolean binaryDecodeBOOL(int index, int len, ByteBuf buff) {
669
679
}
670
680
671
681
private static Boolean textDecodeBOOL (int index , int len , ByteBuf buff ) {
672
- if (buff .getByte (index ) == 't' ) {
682
+ if (buff .getByte (index ) == 't' ) {
673
683
return Boolean .TRUE ;
674
684
} else {
675
685
return Boolean .FALSE ;
@@ -770,7 +780,7 @@ private static Line textDecodeLine(int index, int len, ByteBuf buff) {
770
780
771
781
private static LineSegment textDecodeLseg (int index , int len , ByteBuf buff ) {
772
782
// Lseg representation: [p1,p2]
773
- int idxOfPointsSeparator = buff .indexOf (index , index + len , (byte ) ')' ) + 1 ;
783
+ int idxOfPointsSeparator = buff .indexOf (index , index + len , (byte ) ')' ) + 1 ;
774
784
int lenOfP1 = idxOfPointsSeparator - index - 1 ;
775
785
Point p1 = textDecodePOINT (index + 1 , lenOfP1 , buff );
776
786
Point p2 = textDecodePOINT (idxOfPointsSeparator + 1 , len - lenOfP1 - 3 , buff );
@@ -779,7 +789,7 @@ private static LineSegment textDecodeLseg(int index, int len, ByteBuf buff) {
779
789
780
790
private static Box textDecodeBox (int index , int len , ByteBuf buff ) {
781
791
// Box representation: p1,p2
782
- int idxOfPointsSeparator = buff .indexOf (index , index + len , (byte ) ')' ) + 1 ;
792
+ int idxOfPointsSeparator = buff .indexOf (index , index + len , (byte ) ')' ) + 1 ;
783
793
int lenOfUpperRightCornerPoint = idxOfPointsSeparator - index ;
784
794
Point upperRightCorner = textDecodePOINT (index , lenOfUpperRightCornerPoint , buff );
785
795
Point lowerLeftCorner = textDecodePOINT (idxOfPointsSeparator + 1 , len - lenOfUpperRightCornerPoint - 1 , buff );
@@ -905,7 +915,7 @@ private static Interval textDecodeINTERVAL(int index, int len, ByteBuf buff) {
905
915
: Integer .parseInt (timeChunk .substring (sidx ));
906
916
} else {
907
917
// seconds with microseconds
908
- seconds = isNeg ? -Integer .parseInt (timeChunk .substring (sidx ).substring (0 , m ))
918
+ seconds = isNeg ? -Integer .parseInt (timeChunk .substring (sidx ).substring (0 , m ))
909
919
: Integer .parseInt (timeChunk .substring (sidx ).substring (0 , m ));
910
920
microseconds = isNeg ? -Integer .parseInt (timeChunk .substring (sidx ).substring (m + 1 ))
911
921
: Integer .parseInt (timeChunk .substring (sidx ).substring (m + 1 ));
@@ -990,7 +1000,6 @@ private static String textDecodeNAME(int index, int len, ByteBuf buff) {
990
1000
return buff .getCharSequence (index , len , StandardCharsets .UTF_8 ).toString ();
991
1001
}
992
1002
993
-
994
1003
private static void binaryEncodeNAME (String value , ByteBuf buff ) {
995
1004
String s = String .valueOf (value );
996
1005
buff .writeCharSequence (s , StandardCharsets .UTF_8 );
@@ -1466,7 +1475,7 @@ private static void binaryEncodeMoney(Money money, ByteBuf buff) {
1466
1475
1467
1476
private static Money binaryDecodeMoney (int index , int len , ByteBuf buff ) {
1468
1477
long value = binaryDecodeINT8 (index , len , buff );
1469
- return new Money (value / 100 , Math .abs (((int )value % 100 )));
1478
+ return new Money (value / 100 , Math .abs (((int ) value % 100 )));
1470
1479
}
1471
1480
1472
1481
private static String binaryDecodeTsQuery (int index , int len , ByteBuf buff ) {
@@ -1477,6 +1486,14 @@ private static void binaryEncodeTsQuery(String value, ByteBuf buff) {
1477
1486
buff .writeCharSequence (String .valueOf (value ), StandardCharsets .UTF_8 );
1478
1487
}
1479
1488
1489
+ private static String binaryDecodePgXMLSQL (int index , int len , ByteBuf buff ) {
1490
+ return buff .getCharSequence (index , len , StandardCharsets .UTF_8 ).toString ();
1491
+ }
1492
+
1493
+ private static void binaryEncodePgXMLSQL (PgSQLXML value , ByteBuf buff ) {
1494
+ buff .writeCharSequence (value .toString (), StandardCharsets .UTF_8 );
1495
+ }
1496
+
1480
1497
private static String textDecodeTsVector (int index , int len , ByteBuf buff ) {
1481
1498
return buff .getCharSequence (index , len , StandardCharsets .UTF_8 ).toString ();
1482
1499
}
@@ -1535,7 +1552,7 @@ private static Money textDecodeMoney(int index, int len, ByteBuf buff) {
1535
1552
* Decode the specified {@code buff} formatted as an hex string starting at the buffer readable index
1536
1553
* with the specified {@code length} to a {@link Buffer}.
1537
1554
*
1538
- * @param len the hex string length
1555
+ * @param len the hex string length
1539
1556
* @param buff the byte buff to read from
1540
1557
* @return the decoded value as a Buffer
1541
1558
*/
@@ -1551,7 +1568,7 @@ private static Buffer decodeHexStringToBytes(int index, int len, ByteBuf buff) {
1551
1568
}
1552
1569
1553
1570
private static byte decodeHexChar (byte ch ) {
1554
- return (byte )(((ch & 0x1F ) + ((ch >> 6 ) * 0x19 ) - 0x10 ) & 0x0F );
1571
+ return (byte ) (((ch & 0x1F ) + ((ch >> 6 ) * 0x19 ) - 0x10 ) & 0x0F );
1555
1572
}
1556
1573
1557
1574
private static boolean isHexFormat (int index , int len , ByteBuf buff ) {
@@ -1619,7 +1636,7 @@ private static <T> T[] binaryDecodeArray(IntFunction<T[]> supplier, DataType typ
1619
1636
return array ;
1620
1637
}
1621
1638
1622
- private static <T > void binaryEncodeArray (T [] values , DataType type , ByteBuf buff ){
1639
+ private static <T > void binaryEncodeArray (T [] values , DataType type , ByteBuf buff ) {
1623
1640
int startIndex = buff .writerIndex ();
1624
1641
buff .writeInt (1 ); // ndim
1625
1642
buff .writeInt (0 ); // dataoffset
@@ -1681,7 +1698,7 @@ private static <T> T textDecodeArrayElement(DataType type, int index, int len, B
1681
1698
// Some escaping - improve that later...
1682
1699
String s = buff .toString (index + 1 , len - 2 , StandardCharsets .UTF_8 );
1683
1700
StringBuilder sb = new StringBuilder ();
1684
- for (int i = 0 ;i < s .length ();i ++) {
1701
+ for (int i = 0 ; i < s .length (); i ++) {
1685
1702
char c = s .charAt (i );
1686
1703
if (c == '\\' ) {
1687
1704
c = s .charAt (++i );
@@ -1696,7 +1713,7 @@ private static <T> T textDecodeArrayElement(DataType type, int index, int len, B
1696
1713
}
1697
1714
}
1698
1715
1699
- private static <T > void textEncodeArray (T [] values , DataType type , ByteBuf buff ){
1716
+ private static <T > void textEncodeArray (T [] values , DataType type , ByteBuf buff ) {
1700
1717
buff .writeByte ('{' );
1701
1718
int len = values .length ;
1702
1719
for (int i = 0 ; i < len ; i ++) {
0 commit comments