Address issue #50.
[stompngo.git] / utils.go
blob3af2009b4f82f3f0b1da50ee791a04a6ffcde3c8
1 //
2 // Copyright © 2011-2019 Guy M. Allard
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
17 package stompngo
19 import (
20 "fmt"
21 "io"
22 "strings"
26 Encode a string per STOMP 1.1+ specifications.
28 func encode(s string) string {
29 r := s
30 for _, tr := range codecValues {
31 if strings.Index(r, tr.decoded) >= 0 {
32 r = strings.Replace(r, tr.decoded, tr.encoded, -1)
35 return r
39 Decode a string per STOMP 1.1+ specifications.
41 func decode(s string) string {
42 r := s
43 for _, tr := range codecValues {
44 if strings.Index(r, tr.encoded) >= 0 {
45 r = strings.Replace(r, tr.encoded, tr.decoded, -1)
48 return r
52 A network helper. Read from the wire until a 0x00 byte is encountered.
54 func readUntilNul(c *Connection) ([]uint8, error) {
55 c.setReadDeadline()
56 b, e := c.rdr.ReadBytes(0)
57 if c.checkReadError(e) != nil {
58 return b, e
60 if len(b) == 1 {
61 b = NULLBUFF
62 } else {
63 b = b[0 : len(b)-1]
65 return b, e
69 A network helper. Read a full message body with a known length that is
70 > 0. Then read the trailing 'null' byte expected for STOMP frames.
72 func readBody(c *Connection, l int) ([]uint8, error) {
73 b := make([]byte, l)
74 c.setReadDeadline()
75 n, e := io.ReadFull(c.rdr, b)
76 if n < l && n != 0 { // Short read, e is ErrUnexpectedEOF
77 c.log("SHORT READ", n, l, e)
78 return b[0 : n-1], e
80 if c.checkReadError(e) != nil { // Other erors
81 return b, e
83 c.setReadDeadline()
84 _, _ = c.rdr.ReadByte() // trailing NUL
85 if c.checkReadError(e) != nil { // Other erors
86 return b, e
88 return b, e
92 Common Header Validation.
94 func checkHeaders(h Headers, p string) error {
95 if h == nil {
96 return EHDRNIL
98 // Length check
99 if e := h.Validate(); e != nil {
100 return e
102 // Empty key / value check
103 for i := 0; i < len(h); i += 2 {
104 if h[i] == "" {
105 return EHDRMTK
107 if p == SPL_10 && h[i+1] == "" {
108 return EHDRMTV
111 // UTF8 check
112 if p != SPL_10 {
113 _, e := h.ValidateUTF8()
114 if e != nil {
115 return e
118 return nil
122 Internal function used by heartbeat initialization.
124 func max(a, b int64) int64 {
125 if a > b {
126 return a
128 return b
132 Debug helper. Get properly formatted destination.
134 func dumpmd(md MessageData) {
135 fmt.Printf("Command: %s\n", md.Message.Command)
136 fmt.Println("Headers:")
137 for i := 0; i < len(md.Message.Headers); i += 2 {
138 fmt.Printf("key:%s\t\tvalue:%s\n",
139 md.Message.Headers[i], md.Message.Headers[i+1])
141 fmt.Printf("Body: %s\n", string(md.Message.Body))
142 if md.Error != nil {
143 fmt.Printf("Error: %s\n", md.Error.Error())
144 } else {
145 fmt.Println("Error: nil")