View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.shardingsphere.db.protocol.postgresql.payload;
19  
20  import io.netty.buffer.ByteBuf;
21  import lombok.Getter;
22  import lombok.RequiredArgsConstructor;
23  import org.apache.shardingsphere.db.protocol.payload.PacketPayload;
24  
25  import java.nio.charset.Charset;
26  
27  /**
28   * Payload operation for PostgreSQL packet data types.
29   *
30   * @see <a href="https://www.postgresql.org/docs/current/protocol-message-types.html">Message Data Types</a>
31   */
32  @RequiredArgsConstructor
33  @Getter
34  public final class PostgreSQLPacketPayload implements PacketPayload {
35      
36      private final ByteBuf byteBuf;
37      
38      private final Charset charset;
39      
40      /**
41       * Read 1 byte fixed length integer from byte buffers.
42       *
43       * @return 1 byte fixed length integer
44       */
45      public int readInt1() {
46          return byteBuf.readUnsignedByte();
47      }
48      
49      /**
50       * Write 1 byte fixed length integer to byte buffers.
51       *
52       * @param value 1 byte fixed length integer
53       */
54      public void writeInt1(final int value) {
55          byteBuf.writeByte(value);
56      }
57      
58      /**
59       * Read 2 byte fixed length integer from byte buffers.
60       *
61       * @return 2 byte fixed length integer
62       */
63      public int readInt2() {
64          return byteBuf.readUnsignedShort();
65      }
66      
67      /**
68       * Write 2 byte fixed length integer to byte buffers.
69       *
70       * @param value 2 byte fixed length integer
71       */
72      public void writeInt2(final int value) {
73          byteBuf.writeShort(value);
74      }
75      
76      /**
77       * Read 4 byte fixed length integer from byte buffers.
78       *
79       * @return 4 byte fixed length integer
80       */
81      public int readInt4() {
82          return byteBuf.readInt();
83      }
84      
85      /**
86       * Write 4 byte fixed length integer to byte buffers.
87       *
88       * @param value 4 byte fixed length integer
89       */
90      public void writeInt4(final int value) {
91          byteBuf.writeInt(value);
92      }
93      
94      /**
95       * Read 8 byte fixed length integer from byte buffers.
96       *
97       * @return 8 byte fixed length integer
98       */
99      public long readInt8() {
100         return byteBuf.readLong();
101     }
102     
103     /**
104      * Write 8 byte fixed length integer to byte buffers.
105      *
106      * @param value 8 byte fixed length integer
107      */
108     public void writeInt8(final long value) {
109         byteBuf.writeLong(value);
110     }
111     
112     /**
113      * Write variable length bytes to byte buffers.
114      * 
115      * @param value fixed length bytes
116      */
117     public void writeBytes(final byte[] value) {
118         byteBuf.writeBytes(value);
119     }
120     
121     /**
122      * Bytes before zero.
123      *
124      * @return the number of bytes before zero
125      */
126     public int bytesBeforeZero() {
127         return byteBuf.bytesBefore((byte) 0);
128     }
129     
130     /**
131      * Read null terminated string from byte buffers.
132      * 
133      * @return null terminated string
134      */
135     public String readStringNul() {
136         String result = byteBuf.readCharSequence(byteBuf.bytesBefore((byte) 0), charset).toString();
137         byteBuf.skipBytes(1);
138         return result;
139     }
140     
141     /**
142      * Write null terminated string to byte buffers.
143      * 
144      * @param value null terminated string
145      */
146     public void writeStringNul(final String value) {
147         byteBuf.writeBytes(value.getBytes(charset));
148         byteBuf.writeByte(0);
149     }
150     
151     /**
152      * Write rest of packet string to byte buffers.
153      * 
154      * @param value rest of packet string
155      */
156     public void writeStringEOF(final String value) {
157         byteBuf.writeBytes(value.getBytes(charset));
158     }
159     
160     /**
161      * Skip reserved from byte buffers.
162      * 
163      * @param length length of reserved
164      */
165     public void skipReserved(final int length) {
166         byteBuf.skipBytes(length);
167     }
168     
169     /**
170      * Check if there has complete packet in ByteBuf.
171      * PostgreSQL Message: (byte1) message type + (int4) length + (length - 4) payload
172      *
173      * @return has complete packet
174      */
175     public boolean hasCompletePacket() {
176         return byteBuf.readableBytes() >= 5 && byteBuf.readableBytes() - 1 >= byteBuf.getInt(byteBuf.readerIndex() + 1);
177     }
178 }