package codec
import (
"hash/crc32"
"io"
"sync/atomic"
"github.com/go-faster/errors"
"github.com/gotd/td/bin"
)
type Full struct {
wSeqNo int64
rSeqNo int64
}
func (i *Full ) WriteHeader (w io .Writer ) (err error ) {
return nil
}
func (i *Full ) ReadHeader (r io .Reader ) (err error ) {
return nil
}
func (i *Full ) Write (w io .Writer , b *bin .Buffer ) error {
if err := checkOutgoingMessage (b ); err != nil {
return err
}
if err := writeFull (w , int (atomic .AddInt64 (&i .wSeqNo , 1 )-1 ), b ); err != nil {
return errors .Wrap (err , "write full" )
}
return nil
}
func (i *Full ) Read (r io .Reader , b *bin .Buffer ) error {
if err := readFull (r , int (atomic .AddInt64 (&i .rSeqNo , 1 )-1 ), b ); err != nil {
return errors .Wrap (err , "read full" )
}
return checkProtocolError (b )
}
func writeFull (w io .Writer , seqNo int , b *bin .Buffer ) error {
write := bin .Buffer {Buf : make ([]byte , 0 , 4 +4 +b .Len ()+4 )}
write .PutInt (4 + 4 + b .Len () + 4 )
write .PutInt (seqNo )
write .Put (b .Raw ())
crc := crc32 .ChecksumIEEE (write .Raw ())
write .PutUint32 (crc )
if _ , err := w .Write (write .Raw ()); err != nil {
return err
}
return nil
}
var errSeqNoMismatch = errors .New ("seq_no mismatch" )
var errCRCMismatch = errors .New ("crc mismatch" )
func readFull (r io .Reader , seqNo int , b *bin .Buffer ) error {
n , err := readLen (r , b )
if err != nil {
return errors .Wrap (err , "len" )
}
b .PutInt (n )
b .Expand (n - bin .Word )
inner := &bin .Buffer {Buf : b .Buf [bin .Word :n ]}
if _ , err := io .ReadFull (r , inner .Buf ); err != nil {
return errors .Wrap (err , "read seqno, buffer and crc" )
}
serverSeqNo , err := inner .Int ()
if err != nil {
return err
}
if serverSeqNo != seqNo {
return errSeqNoMismatch
}
payloadLength := n - 3 *bin .Word
inner .Skip (payloadLength )
crc , err := inner .Uint32 ()
if err != nil {
return err
}
clientCRC := crc32 .ChecksumIEEE (b .Buf [0 : n -bin .Word ])
if crc != clientCRC {
return errCRCMismatch
}
copy (b .Buf , b .Buf [2 *bin .Word :n -bin .Word ])
b .Buf = b .Buf [:payloadLength ]
return nil
}
The pages are generated with Golds v0.6.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .