]> git.r.bdr.sh - rbdr/mobius/blobdiff - hotline/transaction.go
Move panic handler
[rbdr/mobius] / hotline / transaction.go
index 835d194b24e5c445bcc741013c8e1f587125ab32..9b0ac407f81e9c694f2d710f10416392b2eccc6b 100644 (file)
@@ -1,12 +1,12 @@
 package hotline
 
 import (
 package hotline
 
 import (
+       "bytes"
        "encoding/binary"
        "errors"
        "fmt"
        "github.com/jhalter/mobius/concat"
        "math/rand"
        "encoding/binary"
        "errors"
        "fmt"
        "github.com/jhalter/mobius/concat"
        "math/rand"
-       "net"
 )
 
 const (
 )
 
 const (
@@ -32,6 +32,7 @@ const (
        tranNotifyChatSubject    = 119
        tranSetChatSubject       = 120
        tranAgreed               = 121
        tranNotifyChatSubject    = 119
        tranSetChatSubject       = 120
        tranAgreed               = 121
+       tranServerBanner         = 122
        tranGetFileNameList      = 200
        tranDownloadFile         = 202
        tranUploadFile           = 203
        tranGetFileNameList      = 200
        tranDownloadFile         = 202
        tranUploadFile           = 203
@@ -40,18 +41,18 @@ const (
        tranGetFileInfo          = 206
        tranSetFileInfo          = 207
        tranMoveFile             = 208
        tranGetFileInfo          = 206
        tranSetFileInfo          = 207
        tranMoveFile             = 208
-       // tranMakeFileAlias        = 209 TODO: implement file alias command
-       tranDownloadFldr = 210
+       tranMakeFileAlias        = 209
+       tranDownloadFldr         = 210
        // tranDownloadInfo         = 211 TODO: implement file transfer queue
        // tranDownloadInfo         = 211 TODO: implement file transfer queue
-       // tranDownloadBanner     = 212 TODO: figure out what this is used for
-       tranUploadFldr        = 213
-       tranGetUserNameList   = 300
-       tranNotifyChangeUser  = 301
-       tranNotifyDeleteUser  = 302
-       tranGetClientInfoText = 303
-       tranSetClientUserInfo = 304
-       tranListUsers         = 348
-       // tranUpdateUser         = 349 TODO: implement user updates from the > 1.5 account editor
+       tranDownloadBanner     = 212
+       tranUploadFldr         = 213
+       tranGetUserNameList    = 300
+       tranNotifyChangeUser   = 301
+       tranNotifyDeleteUser   = 302
+       tranGetClientInfoText  = 303
+       tranSetClientUserInfo  = 304
+       tranListUsers          = 348
+       tranUpdateUser         = 349
        tranNewUser            = 350
        tranDeleteUser         = 351
        tranGetUser            = 352
        tranNewUser            = 350
        tranDeleteUser         = 351
        tranGetUser            = 352
@@ -131,46 +132,24 @@ func ReadTransaction(buf []byte) (*Transaction, int, error) {
        }, tranLen, nil
 }
 
        }, tranLen, nil
 }
 
-func readN(conn net.Conn, n int) ([]Transaction, error) {
-       buf := make([]byte, 1400)
-       i := 0
-       for {
-               readLen, err := conn.Read(buf)
-               if err != nil {
-                       return nil, err
-               }
-
-               transactions, _, err := readTransactions(buf[:readLen])
-               //              spew.Fdump(os.Stderr, transactions)
-               if err != nil {
-                       return nil, err
-               }
+const tranHeaderLen = 20 // fixed length of transaction fields before the variable length fields
 
 
-               i += len(transactions)
-
-               if n == i {
-                       return transactions, nil
-               }
+// transactionScanner implements bufio.SplitFunc for parsing incoming byte slices into complete tokens
+func transactionScanner(data []byte, _ bool) (advance int, token []byte, err error) {
+       // The bytes that contain the size of a transaction are from 12:16, so we need at least 16 bytes
+       if len(data) < 16 {
+               return 0, nil, nil
        }
        }
-}
 
 
-func readTransactions(buf []byte) ([]Transaction, int, error) {
-       var transactions []Transaction
+       totalSize := binary.BigEndian.Uint32(data[12:16])
 
 
-       bufLen := len(buf)
-
-       var bytesRead = 0
-       for bytesRead < bufLen {
-               t, tReadLen, err := ReadTransaction(buf[bytesRead:])
-               if err != nil {
-                       return transactions, bytesRead, err
-               }
-               bytesRead += tReadLen
-
-               transactions = append(transactions, *t)
+       // tranLen represents the length of bytes that are part of the transaction
+       tranLen := int(tranHeaderLen + totalSize)
+       if tranLen > len(data) {
+               return 0, nil, nil
        }
 
        }
 
-       return transactions, bytesRead, nil
+       return tranLen, data[0:tranLen], nil
 }
 
 const minFieldLen = 4
 }
 
 const minFieldLen = 4
@@ -214,7 +193,7 @@ func ReadFields(paramCount []byte, buf []byte) ([]Field, error) {
        return fields, nil
 }
 
        return fields, nil
 }
 
-func (t Transaction) MarshalBinary() (data []byte, err error) {
+func (t *Transaction) MarshalBinary() (data []byte, err error) {
        payloadSize := t.Size()
 
        fieldCount := make([]byte, 2)
        payloadSize := t.Size()
 
        fieldCount := make([]byte, 2)
@@ -238,7 +217,7 @@ func (t Transaction) MarshalBinary() (data []byte, err error) {
 }
 
 // Size returns the total size of the transaction payload
 }
 
 // Size returns the total size of the transaction payload
-func (t Transaction) Size() []byte {
+func (t *Transaction) Size() []byte {
        bs := make([]byte, 4)
 
        fieldSize := 0
        bs := make([]byte, 4)
 
        fieldSize := 0
@@ -251,7 +230,7 @@ func (t Transaction) Size() []byte {
        return bs
 }
 
        return bs
 }
 
-func (t Transaction) GetField(id int) Field {
+func (t *Transaction) GetField(id int) Field {
        for _, field := range t.Fields {
                if id == int(binary.BigEndian.Uint16(field.ID)) {
                        return field
        for _, field := range t.Fields {
                if id == int(binary.BigEndian.Uint16(field.ID)) {
                        return field
@@ -260,3 +239,7 @@ func (t Transaction) GetField(id int) Field {
 
        return Field{}
 }
 
        return Field{}
 }
+
+func (t *Transaction) IsError() bool {
+       return bytes.Compare(t.ErrorCode, []byte{0, 0, 0, 1}) == 0
+}