diff --git a/codegen/protocol/packets.tmpl b/codegen/protocol/packets.tmpl
index 804e42c676e61e629a848f7e433a9396b96ac7d9..93c31fab5ef8a09405c0b5ad7b38ac6aa0908710 100644
--- a/codegen/protocol/packets.tmpl
+++ b/codegen/protocol/packets.tmpl
@@ -164,6 +164,16 @@ import "io"
         fields Fields{{$name}}
     }
 
+    // Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+    func (T *{{$name}}) Read(reader io.Reader) (err error) {
+        var length int32
+        length, err = ReadInt32(reader)
+        if err != nil {
+            return
+        }
+        return T.fields.Read(int(length - 4), reader)
+    }
+
     func (T *{{$name}}) Write(writer io.Writer) (length int, err error) {
         // TODO replace with pool
         var buf bytes.Buffer
diff --git a/lib/gat/protocol/backend.go b/lib/gat/protocol/backend.go
index 97576ef21109a73cb7af0ead2dad2df9dded7d92..7d987b333697aca0fe967f1de5cadf5401ddc6ed 100644
--- a/lib/gat/protocol/backend.go
+++ b/lib/gat/protocol/backend.go
@@ -40,6 +40,16 @@ type Authentication struct {
 	fields FieldsAuthentication
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *Authentication) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *Authentication) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -100,6 +110,16 @@ type BackendKeyData struct {
 	fields FieldsBackendKeyData
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *BackendKeyData) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *BackendKeyData) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -140,6 +160,16 @@ type BindComplete struct {
 	fields FieldsBindComplete
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *BindComplete) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *BindComplete) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -180,6 +210,16 @@ type CloseComplete struct {
 	fields FieldsCloseComplete
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *CloseComplete) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *CloseComplete) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -230,6 +270,16 @@ type CommandComplete struct {
 	fields FieldsCommandComplete
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *CommandComplete) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *CommandComplete) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -305,6 +355,16 @@ type CopyBothResponse struct {
 	fields FieldsCopyBothResponse
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *CopyBothResponse) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *CopyBothResponse) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -380,6 +440,16 @@ type CopyInResponse struct {
 	fields FieldsCopyInResponse
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *CopyInResponse) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *CopyInResponse) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -455,6 +525,16 @@ type CopyOutResponse struct {
 	fields FieldsCopyOutResponse
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *CopyOutResponse) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *CopyOutResponse) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -558,6 +638,16 @@ type DataRow struct {
 	fields FieldsDataRow
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *DataRow) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *DataRow) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -598,6 +688,16 @@ type EmptyQueryResponse struct {
 	fields FieldsEmptyQueryResponse
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *EmptyQueryResponse) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *EmptyQueryResponse) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -658,6 +758,16 @@ type ErrorResponse struct {
 	fields FieldsErrorResponse
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *ErrorResponse) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *ErrorResponse) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -723,6 +833,16 @@ type FunctionCallResponse struct {
 	fields FieldsFunctionCallResponse
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *FunctionCallResponse) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *FunctionCallResponse) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -798,6 +918,16 @@ type NegotiateProtocolVersion struct {
 	fields FieldsNegotiateProtocolVersion
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *NegotiateProtocolVersion) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *NegotiateProtocolVersion) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -838,6 +968,16 @@ type NoData struct {
 	fields FieldsNoData
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *NoData) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *NoData) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -902,6 +1042,16 @@ type NoticeResponse struct {
 	fields FieldsNoticeResponse
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *NoticeResponse) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *NoticeResponse) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -972,6 +1122,16 @@ type NotificationResponse struct {
 	fields FieldsNotificationResponse
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *NotificationResponse) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *NotificationResponse) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -1037,6 +1197,16 @@ type ParameterDescription struct {
 	fields FieldsParameterDescription
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *ParameterDescription) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *ParameterDescription) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -1097,6 +1267,16 @@ type ParameterStatus struct {
 	fields FieldsParameterStatus
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *ParameterStatus) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *ParameterStatus) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -1137,6 +1317,16 @@ type ParseComplete struct {
 	fields FieldsParseComplete
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *ParseComplete) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *ParseComplete) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -1177,6 +1367,16 @@ type PortalSuspended struct {
 	fields FieldsPortalSuspended
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *PortalSuspended) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *PortalSuspended) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -1217,6 +1417,16 @@ type ReadForQuery struct {
 	fields FieldsReadForQuery
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *ReadForQuery) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *ReadForQuery) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -1365,6 +1575,16 @@ type RowDescription struct {
 	fields FieldsRowDescription
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *RowDescription) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *RowDescription) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
diff --git a/lib/gat/protocol/frontend.go b/lib/gat/protocol/frontend.go
index e152b4f2041396f728f4b5ae16154f62072d2d3b..af5cab316cdeaae99bddd268ca4d15931a364463 100644
--- a/lib/gat/protocol/frontend.go
+++ b/lib/gat/protocol/frontend.go
@@ -1,6 +1,9 @@
 package protocol
 
-import "io"
+import (
+	"bytes"
+	"io"
+)
 
 // codegen: modify for debug only
 
@@ -154,6 +157,16 @@ type Bind struct {
 	fields FieldsBind
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *Bind) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *Bind) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -224,6 +237,16 @@ type CancelRequest struct {
 	fields FieldsCancelRequest
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *CancelRequest) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *CancelRequest) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -284,6 +307,16 @@ type Close struct {
 	fields FieldsClose
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *Close) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *Close) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -334,6 +367,16 @@ type CopyFail struct {
 	fields FieldsCopyFail
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *CopyFail) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *CopyFail) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -394,6 +437,16 @@ type Describe struct {
 	fields FieldsDescribe
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *Describe) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *Describe) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -454,6 +507,16 @@ type Execute struct {
 	fields FieldsExecute
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *Execute) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *Execute) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -494,6 +557,16 @@ type Flush struct {
 	fields FieldsFlush
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *Flush) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *Flush) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -642,6 +715,16 @@ type FunctionCall struct {
 	fields FieldsFunctionCall
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *FunctionCall) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *FunctionCall) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -692,6 +775,16 @@ type GSSENCRequest struct {
 	fields FieldsGSSENCRequest
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *GSSENCRequest) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *GSSENCRequest) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -743,6 +836,16 @@ type GSSResponse struct {
 	fields FieldsGSSResponse
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *GSSResponse) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *GSSResponse) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -828,6 +931,16 @@ type Parse struct {
 	fields FieldsParse
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *Parse) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *Parse) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -878,6 +991,16 @@ type PasswordMessage struct {
 	fields FieldsPasswordMessage
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *PasswordMessage) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *PasswordMessage) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -928,6 +1051,16 @@ type Query struct {
 	fields FieldsQuery
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *Query) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *Query) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -1003,6 +1136,16 @@ type SASLInitialResponse struct {
 	fields FieldsSASLInitialResponse
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *SASLInitialResponse) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *SASLInitialResponse) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -1059,6 +1202,16 @@ type SASLResponse struct {
 	fields FieldsSASLResponse
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *SASLResponse) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *SASLResponse) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -1109,6 +1262,16 @@ type SSLRequest struct {
 	fields FieldsSSLRequest
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *SSLRequest) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *SSLRequest) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -1174,6 +1337,16 @@ type StartupMessage struct {
 	fields FieldsStartupMessage
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *StartupMessage) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *StartupMessage) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -1209,6 +1382,16 @@ type Sync struct {
 	fields FieldsSync
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *Sync) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *Sync) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -1249,6 +1432,16 @@ type Terminate struct {
 	fields FieldsTerminate
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *Terminate) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *Terminate) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
diff --git a/lib/gat/protocol/shared.go b/lib/gat/protocol/shared.go
index 8793b61fab4aca53f72dcb757fcdf331b9f9e22a..0ebf9dd420ceec40ffc6def470b3d625bdd5229a 100644
--- a/lib/gat/protocol/shared.go
+++ b/lib/gat/protocol/shared.go
@@ -1,6 +1,9 @@
 package protocol
 
-import "io"
+import (
+	"bytes"
+	"io"
+)
 
 // codegen: modify for debug only
 
@@ -37,6 +40,16 @@ type CopyData struct {
 	fields FieldsCopyData
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *CopyData) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *CopyData) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer
@@ -77,6 +90,16 @@ type CopyDone struct {
 	fields FieldsCopyDone
 }
 
+// Read reads all but the packet identifier. Be sure to read that beforehand (if it exists)
+func (T *CopyDone) Read(reader io.Reader) (err error) {
+	var length int32
+	length, err = ReadInt32(reader)
+	if err != nil {
+		return
+	}
+	return T.fields.Read(int(length-4), reader)
+}
+
 func (T *CopyDone) Write(writer io.Writer) (length int, err error) {
 	// TODO replace with pool
 	var buf bytes.Buffer