├── .gitignore ├── README.md ├── doc └── exception_response.txt └── src ├── client ├── request.go └── request_test.go ├── gohessian ├── encode.go ├── encode_test.go ├── hessisn.go ├── parse.go └── parse_test.go └── util └── util.go /.gitignore: -------------------------------------------------------------------------------- 1 | tmp 2 | doc/wanda.txt -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gohessian 2 | 3 | gohessian implements Hessian Protocol by golang 4 | -------------------------------------------------------------------------------- /doc/exception_response.txt: -------------------------------------------------------------------------------- 1 | r \x01\x00 2 | ----------------------------------------------- 3 | f 4 | S \x00\x04 code 5 | S \x00\x10 ServiceException 6 | S \x00\a message 7 | S \x00\xB0 Uncompilable source code - thorwException() in example.DataTypeImpl cannot implement thorwException() in example.DataType\n overridden method does not throw java.lang.Exception 8 | S \x00\x06 detail 9 | ----------------------------------------------- 10 | M 11 | t \x00\x1A java.lang.RuntimeException 12 | 13 | S \x00\r detailMessage 14 | S \x00\xB0 Uncompilable source code - thorwException() in example.DataTypeImpl cannot implement thorwException() in example.DataType\n overridden method does not throw java.lang.Exception 15 | 16 | S \x00\x05 cause 17 | R \x00\x00\x00\x00 18 | 19 | S \x00\n stackTrace 20 | ----------------------------------------------- 21 | V 22 | t \x00\x1C [java.lang.StackTraceElement 23 | l \x00\x00\x00\x14 ; list len is 20 24 | ----------------------------------------------- 25 | M 26 | t \x00\e java.lang.StackTraceElement 27 | S \x00\x0E declaringClass 28 | S \x00\x14 example.DataTypeImpl 29 | S \x00\n methodName 30 | S \x00\x0E thorwException 31 | S \x00\b fileName 32 | S \x00\x11 DataTypeImpl.java 33 | S \x00\n lineNumber 34 | I \x00\x00\x00A 35 | z 36 | ----------------------------------------------- 37 | M 38 | t \x00\e java.lang.StackTraceElement 39 | S \x00\x0E declaringClass 40 | S \x00% sun.reflect.GeneratedMethodAccessor43 41 | S \x00\n methodName 42 | S \x00\x06 invoke 43 | S \x00\b fileName 44 | N 45 | S \x00\n lineNumber 46 | I \xFF\xFF\xFF\xFF 47 | z 48 | ----------------------------------------------- 49 | M 50 | t \x00\e java.lang.StackTraceElement 51 | S \x00\x0E declaringClass 52 | S \x00( sun.reflect.DelegatingMethodAccessorImpl 53 | S \x00\n methodName 54 | S \x00\x06 invoke 55 | S \x00\b fileName 56 | S \x00! DelegatingMethodAccessorImpl.java 57 | S \x00\n lineNumber 58 | I \x00\x00\x00+ 59 | z 60 | ----------------------------------------------- 61 | M 62 | t \x00\e java.lang.StackTraceElement 63 | S \x00\x0E declaringClass 64 | S \x00\x18 java.lang.reflect.Method 65 | S \x00\n methodName 66 | S \x00\x06 invoke 67 | S \x00\b fileName 68 | S \x00\v Method.java 69 | S \x00\n lineNumber 70 | I \x00\x00\x02^ 71 | z 72 | ----------------------------------------------- 73 | M 74 | t \x00\e java.lang.StackTraceElement 75 | S \x00\x0E declaringClass 76 | S \x00) com.caucho.hessian.server.HessianSkeleton 77 | S \x00\n methodName 78 | S \x00\x06 invoke 79 | S \x00\b fileName 80 | S \x00\x14 HessianSkeleton.java 81 | S \x00\n lineNumber 82 | I \x00\x00\x01. 83 | z 84 | ----------------------------------------------- 85 | ----------------------------------------------- 86 | ................ 87 | M 88 | t \x00\e java.lang.StackTraceElement 89 | S \x00\x0E declaringClass 90 | S \x00) com.caucho.hessian.server.HessianSkeleton 91 | S \x00\n methodName 92 | S \x00\x06invokeS\x00\bfileNameS\x00\x14HessianSkeleton.javaS\x00\nlineNumberI\x00\x00\x00\xC6zMt\x00\ejava.lang.StackTraceElementS\x00\x0EdeclaringClassS\x00(com.caucho.hessian.server.HessianServletS\x00\nmethodNameS\x00\x06invokeS\x00\bfileNameS\x00\x13HessianServlet.javaS\x00\nlineNumberI\x00\x00\x01\x8FzMt\x00\ejava.lang.StackTraceElementS\x00\x0EdeclaringClassS\x00(com.caucho.hessian.server.HessianServletS\x00\nmethodNameS\x00\aserviceS\x00\bfileNameS\x00\x13HessianServlet.javaS\x00\nlineNumberI\x00\x00\x01{zMt\x00\ejava.lang.StackTraceElementS\x00\x0EdeclaringClassS\x00/org.apache.catalina.core.ApplicationFilterChainS\x00\nmethodNameS\x00\x10internalDoFilterS\x00\bfileNameS\x00\eApplicationFilterChain.javaS\x00\nlineNumberI\x00\x00\x01"zMt\x00\ejava.lang.StackTraceElementS\x00\x0EdeclaringClassS\x00/org.apache.catalina.core.ApplicationFilterChainS\x00\nmethodNameS\x00\bdoFilterS\x00\bfileNameS\x00\eApplicationFilterChain.javaS\x00\nlineNumberI\x00\x00\x00\xCEzMt\x00\ejava.lang.StackTraceElementS\x00\x0EdeclaringClassS\x00-org.apache.catalina.core.StandardWrapperValveS\x00\nmethodNameS\x00\x06invokeS\x00\bfileNameS\x00\x19StandardWrapperValve.javaS\x00\nlineNumberI\x00\x00\x00\xE9zMt\x00\ejava.lang.StackTraceElementS\x00\x0EdeclaringClassS\x00-org.apache.catalina.core.StandardContextValveS\x00\nmethodNameS\x00\x06invokeS\x00\bfileNameS\x00\x19StandardContextValve.javaS\x00\nlineNumberI\x00\x00\x00\xBFzMt\x00\ejava.lang.StackTraceElementS\x00\x0EdeclaringClassS\x00*org.apache.catalina.core.StandardHostValveS\x00\nmethodNameS\x00\x06invokeS\x00\bfileNameS\x00\x16StandardHostValve.javaS\x00\nlineNumberI\x00\x00\x00\x7FzMt\x00\ejava.lang.StackTraceElementS\x00\x0EdeclaringClassS\x00+org.apache.catalina.valves.ErrorReportValveS\x00\nmethodNameS\x00\x06invokeS\x00\bfileNameS\x00\x15ErrorReportValve.javaS\x00\nlineNumberI\x00\x00\x00gzMt\x00\ejava.lang.StackTraceElementS\x00\x0EdeclaringClassS\x00,org.apache.catalina.core.StandardEngineValveS\x00\nmethodNameS\x00\x06invokeS\x00\bfileNameS\x00\x18StandardEngineValve.javaS\x00\nlineNumberI\x00\x00\x00mzMt\x00\ejava.lang.StackTraceElementS\x00\x0EdeclaringClassS\x00+org.apache.catalina.connector.CoyoteAdapterS\x00\nmethodNameS\x00\aserviceS\x00\bfileNameS\x00\x12CoyoteAdapter.javaS\x00\nlineNumberI\x00\x00\x01%zMt\x00\ejava.lang.StackTraceElementS\x00\x0EdeclaringClassS\x00(org.apache.coyote.http11.Http11ProcessorS\x00\nmethodNameS\x00\aprocessS\x00\bfileNameS\x00\x14Http11Processor.javaS\x00\nlineNumberI\x00\x00\x03]zMt\x00\ejava.lang.StackTraceElementS\x00\x0EdeclaringClassS\x00?org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandlerS\x00\nmethodNameS\x00\aprocessS\x00\bfileNameS\x00\x13Http11Protocol.javaS\x00\nlineNumberI\x00\x00\x02^zMt\x00\ejava.lang.StackTraceElementS\x00\x0EdeclaringClassS\x00-org.apache.tomcat.util.net.JIoEndpoint$WorkerS\x00\nmethodNameS\x00\x03runS\x00\bfileNameS\x00\x10JIoEndpoint.javaS\x00\nlineNumberI\x00\x00\x01\xE9zMt\x00\ejava.lang.StackTraceElementS\x00\x0EdeclaringClassS\x00\x10java.lang.ThreadS\x00\nmethodNameS\x00\x03runS\x00\bfileNameS\x00\vThread.javaS\x00\nlineNumberI\x00\x00\x02\xE8zzS\x00\x14suppressedExceptionsVt\x00&java.util.Collections$UnmodifiableListl\x00\x00\x00\x00z 93 | ----------------------------------------------- 94 | z; V list 95 | z; M map 96 | z; Hessian end -------------------------------------------------------------------------------- /src/client/request.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "gohessian" 7 | "io" 8 | "io/ioutil" 9 | "net/http" 10 | "util" 11 | ) 12 | 13 | type hessian_request struct { 14 | body []byte 15 | } 16 | 17 | //向hessian服务发请求,并将解析结果返回 18 | //url string hessian 服务地址 19 | //method string hessian 公开的方法 20 | //params ...Any 请求参数 21 | func Request(url string, method string, params ...gohessian.Any) (interface{}, error) { 22 | r := &hessian_request{} 23 | r.pack_head(method) 24 | for _, v := range params { 25 | r.pack_param(v) 26 | } 27 | r.pack_end() 28 | 29 | resp, err := http_post(url, bytes.NewReader(r.body)) 30 | if err != nil { 31 | return nil, err 32 | } 33 | 34 | h := gohessian.NewHessian(bytes.NewReader(resp)) 35 | v, err := h.Parse() 36 | 37 | if err != nil { 38 | return nil, err 39 | } 40 | 41 | return v, nil 42 | } 43 | 44 | //http post 请求,返回body字节数组 45 | func http_post(url string, body io.Reader) (rb []byte, err error) { 46 | var resp *http.Response 47 | if resp, err = http.Post(url, "application/binary", body); err != nil { 48 | return nil, err 49 | } 50 | if resp.StatusCode != http.StatusOK { 51 | err = fmt.Errorf(resp.Status) 52 | return 53 | } 54 | defer resp.Body.Close() 55 | rb, err = ioutil.ReadAll(resp.Body) 56 | return 57 | } 58 | 59 | //封装 hessian 请求头 60 | func (h *hessian_request) pack_head(method string) { 61 | tmp_b, _ := util.PackUint16(uint16(len(method))) 62 | h.body = append(h.body, []byte{99, 0, 1, 109}...) 63 | h.body = append(h.body, tmp_b...) 64 | h.body = append(h.body, []byte(method)...) 65 | } 66 | 67 | //封装参数 68 | func (h *hessian_request) pack_param(p gohessian.Any) { 69 | tmp_b, err := gohessian.Encode(p) 70 | if err != nil { 71 | panic(err) 72 | } 73 | h.body = append(h.body, tmp_b...) 74 | } 75 | 76 | //封装包尾 77 | func (h *hessian_request) pack_end() { 78 | h.body = append(h.body, 'z') 79 | } 80 | -------------------------------------------------------------------------------- /src/client/request_test.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "bytes" 5 | "gohessian" 6 | "log" 7 | "testing" 8 | ) 9 | 10 | //GOPATH=/Users/weidewang/ownCloud/Workspace/go/gohessian go test -run=Test_* 11 | 12 | const ( 13 | MATH_H_URL = "http://localhost:8080/HessianTest/math" //整数四则运算hessian测试接口 14 | DT_H_URL = "http://localhost:8080/HessianTest/dt" //数据类型测试结果,传入参数,返回该参数的(响应)编码结果 15 | ) 16 | 17 | 18 | func Test_request_http_post(t *testing.T) { 19 | t.SkipNow() 20 | log.Println("Test_request") 21 | data := bytes.NewBuffer([]byte{0, 1, 3, 4}) 22 | rb, _ := http_post(DT_H_URL, bytes.NewReader(data.Bytes())) 23 | log.Println(rb) 24 | log.Println(string(rb)) 25 | } 26 | 27 | //整数 数学运算测试 28 | func Test_request_int_math(t *testing.T) { 29 | //Request(H_URL, "add", 100, 200, 101.5, true, false, []byte{1, 2, 3, 5}) 30 | Request(MATH_H_URL, "add", 100, 200) 31 | Request(MATH_H_URL, "sub", 100, 200) 32 | Request(MATH_H_URL, "mult", 100, 200) 33 | Request(MATH_H_URL, "div", 200, 50) 34 | } 35 | 36 | //数据类型测试 37 | func Test_request_data_type(t *testing.T) { 38 | Request(DT_H_URL, "dataBytes", []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) 39 | Request(DT_H_URL, "dataBoolean", true) 40 | Request(DT_H_URL, "dataBoolean", false) 41 | Request(DT_H_URL, "dataDouble", 1989.0604) 42 | 43 | list := []gohessian.Any{100, 10.001, "不厌其烦", []byte{0, 2, 4, 6, 8, 10}, true, nil, false} 44 | Request(DT_H_URL, "dataList", list) 45 | 46 | var hmap = make(map[gohessian.Any]gohessian.Any) 47 | hmap["你好"] = "哈哈哈" 48 | hmap[100] = "嘿嘿" 49 | hmap[100.1010] = 101910 50 | hmap[true] = true 51 | hmap[false] = true 52 | Request(DT_H_URL, "dataMap", hmap) 53 | 54 | Request(DT_H_URL, "dataMapNoParam") 55 | 56 | Request(DT_H_URL, "dataNull") 57 | 58 | Request(DT_H_URL, "dataString", "_BEGIN_兔兔你小姨子_END_") 59 | 60 | Request(DT_H_URL, "dataInt", 1000) 61 | 62 | } 63 | 64 | //异常测试,服务器已经抛出异常,但客户端看到的是200和空响应 65 | //curl -vvv --data-binary "c\x00\x01m\x00\adataIntz" -H "Content-Type: application/binary" http://localhost:8080/HessianTest/dt 66 | //curl -vvv --data-binary "c\x00\x01m\x00\x0EthorwExceptionz" -H "Content-Type: application/binary" http://localhost:8080/HessianTest/dt 67 | func Test_request_exception(t *testing.T) { 68 | // Request(DT_H_URL,"dataInt") 69 | Request(DT_H_URL, "thorwException") 70 | } 71 | 72 | -------------------------------------------------------------------------------- /src/gohessian/encode.go: -------------------------------------------------------------------------------- 1 | package gohessian 2 | 3 | import ( 4 | "bytes" 5 | "log" 6 | "runtime" 7 | "time" 8 | "unicode/utf8" 9 | "util" 10 | ) 11 | 12 | /* 13 | 对 基本数据进行 Hessian 编码 14 | 支持: 15 | int8 int16 int32 int64 16 | float64 17 | time.Time 18 | []byte 19 | []interface{} 20 | map[interface{}]interface{} 21 | nil 22 | bool 23 | */ 24 | 25 | type Encoder struct { 26 | } 27 | 28 | const ( 29 | CHUNK_SIZE = 0x8000 30 | ENCODER_DEBUG = false 31 | ) 32 | 33 | func init() { 34 | _, filename, _, _ := runtime.Caller(1) 35 | if ENCODER_DEBUG { 36 | log.SetPrefix(filename + "\n") 37 | } 38 | } 39 | 40 | func Encode(v interface{}) (b []byte, err error) { 41 | 42 | switch v.(type) { 43 | 44 | case []byte: 45 | b, err = encode_binary(v.([]byte)) 46 | 47 | case bool: 48 | b, err = encode_bool(v.(bool)) 49 | 50 | case time.Time: 51 | b, err = encode_time(v.(time.Time)) 52 | 53 | case float64: 54 | b, err = encode_float64(v.(float64)) 55 | 56 | case int: 57 | if v.(int) >= -2147483648 && v.(int) <= 2147483647 { 58 | b, err = encode_int32(int32(v.(int))) 59 | } else { 60 | b, err = encode_int64(int64(v.(int))) 61 | } 62 | 63 | case int32: 64 | b, err = encode_int32(v.(int32)) 65 | 66 | case int64: 67 | b, err = encode_int64(v.(int64)) 68 | 69 | case string: 70 | b, err = encode_string(v.(string)) 71 | 72 | case nil: 73 | b, err = encode_null(v) 74 | 75 | case []Any: 76 | b, err = encode_list(v.([]Any)) 77 | 78 | case map[Any]Any: 79 | b, err = encode_map(v.(map[Any]Any)) 80 | 81 | default: 82 | panic("unknow type") 83 | } 84 | if ENCODER_DEBUG { 85 | log.Println(util.SprintHex(b)) 86 | } 87 | return 88 | } 89 | 90 | //===================================== 91 | //对各种数据类型的编码 92 | //===================================== 93 | 94 | // binary 95 | func encode_binary(v []byte) (b []byte, err error) { 96 | var ( 97 | tag byte 98 | len_b []byte 99 | len_n int 100 | ) 101 | 102 | if len(v) == 0 { 103 | if len_b, err = util.PackUint16(0); err != nil { 104 | b = nil 105 | return 106 | } 107 | b = append(b, 'B') 108 | b = append(b, len_b...) 109 | return 110 | } 111 | 112 | r_buf := *bytes.NewBuffer(v) 113 | 114 | for r_buf.Len() > 0 { 115 | if r_buf.Len() > CHUNK_SIZE { 116 | tag = 'b' 117 | if len_b, err = util.PackUint16(uint16(CHUNK_SIZE)); err != nil { 118 | b = nil 119 | return 120 | } 121 | len_n = CHUNK_SIZE 122 | } else { 123 | tag = 'B' 124 | if len_b, err = util.PackUint16(uint16(r_buf.Len())); err != nil { 125 | b = nil 126 | return 127 | } 128 | len_n = r_buf.Len() 129 | } 130 | b = append(b, tag) 131 | b = append(b, len_b...) 132 | b = append(b, r_buf.Next(len_n)...) 133 | } 134 | return 135 | } 136 | 137 | // boolean 138 | func encode_bool(v bool) (b []byte, err error) { 139 | if v == true { 140 | b = append(b, 'T') 141 | } else { 142 | b = append(b, 'F') 143 | } 144 | return 145 | } 146 | 147 | // date 148 | func encode_time(v time.Time) (b []byte, err error) { 149 | var tmp_v []byte 150 | b = append(b, 'd') 151 | if tmp_v, err = util.PackInt64(v.UnixNano() / 1000000); err != nil { 152 | b = nil 153 | return 154 | } 155 | b = append(b, tmp_v...) 156 | return 157 | } 158 | 159 | // double 160 | func encode_float64(v float64) (b []byte, err error) { 161 | var tmp_v []byte 162 | if tmp_v, err = util.PackFloat64(v); err != nil { 163 | b = nil 164 | return 165 | } 166 | b = append(b, 'D') 167 | b = append(b, tmp_v...) 168 | return 169 | } 170 | 171 | // int 172 | func encode_int32(v int32) (b []byte, err error) { 173 | var tmp_v []byte 174 | if tmp_v, err = util.PackInt32(v); err != nil { 175 | b = nil 176 | return 177 | } 178 | b = append(b, 'I') 179 | b = append(b, tmp_v...) 180 | return 181 | } 182 | 183 | // long 184 | func encode_int64(v int64) (b []byte, err error) { 185 | var tmp_v []byte 186 | if tmp_v, err = util.PackInt64(v); err != nil { 187 | b = nil 188 | return 189 | } 190 | b = append(b, 'L') 191 | b = append(b, tmp_v...) 192 | return 193 | 194 | } 195 | 196 | // null 197 | func encode_null(v interface{}) (b []byte, err error) { 198 | b = append(b, 'N') 199 | return 200 | } 201 | 202 | // string 203 | func encode_string(v string) (b []byte, err error) { 204 | var ( 205 | len_b []byte 206 | s_buf = *bytes.NewBufferString(v) 207 | r_len = utf8.RuneCountInString(v) 208 | 209 | s_chunk = func(_len int) { 210 | for i := 0; i < _len; i++ { 211 | if r, s, err := s_buf.ReadRune(); s > 0 && err == nil { 212 | b = append(b, []byte(string(r))...) 213 | } 214 | } 215 | } 216 | ) 217 | 218 | if v == "" { 219 | if len_b, err = util.PackUint16(uint16(r_len)); err != nil { 220 | b = nil 221 | return 222 | } 223 | b = append(b, 'S') 224 | b = append(b, len_b...) 225 | b = append(b, []byte{}...) 226 | return 227 | } 228 | 229 | for { 230 | r_len = utf8.RuneCount(s_buf.Bytes()) 231 | if r_len == 0 { 232 | break 233 | } 234 | if r_len > CHUNK_SIZE { 235 | if len_b, err = util.PackUint16(uint16(CHUNK_SIZE)); err != nil { 236 | b = nil 237 | return 238 | } 239 | b = append(b, 's') 240 | b = append(b, len_b...) 241 | s_chunk(CHUNK_SIZE) 242 | } else { 243 | if len_b, err = util.PackUint16(uint16(r_len)); err != nil { 244 | b = nil 245 | return 246 | } 247 | b = append(b, 'S') 248 | b = append(b, len_b...) 249 | s_chunk(r_len) 250 | } 251 | } 252 | return 253 | } 254 | 255 | // list 256 | func encode_list(v []Any) (b []byte, err error) { 257 | list_len := len(v) 258 | var ( 259 | len_b []byte 260 | tmp_v []byte 261 | ) 262 | 263 | b = append(b, 'V') 264 | 265 | if len_b, err = util.PackInt32(int32(list_len)); err != nil { 266 | b = nil 267 | return 268 | } 269 | b = append(b, 'l') 270 | b = append(b, len_b...) 271 | 272 | for _, a := range v { 273 | if tmp_v, err = Encode(a); err != nil { 274 | b = nil 275 | return 276 | } 277 | b = append(b, tmp_v...) 278 | } 279 | b = append(b, 'z') 280 | return 281 | } 282 | 283 | // map 284 | func encode_map(v map[Any]Any) (b []byte, err error) { 285 | var ( 286 | tmp_k []byte 287 | tmp_v []byte 288 | ) 289 | b = append(b, 'M') 290 | for k, v := range v { 291 | if tmp_k, err = Encode(k); err != nil { 292 | b = nil 293 | return 294 | } 295 | if tmp_v, err = Encode(v); err != nil { 296 | b = nil 297 | return 298 | } 299 | b = append(b, tmp_k...) 300 | b = append(b, tmp_v...) 301 | } 302 | b = append(b, 'z') 303 | return 304 | } 305 | -------------------------------------------------------------------------------- /src/gohessian/encode_test.go: -------------------------------------------------------------------------------- 1 | package gohessian 2 | 3 | import ( 4 | "bytes" 5 | "log" 6 | "runtime" 7 | "testing" 8 | "time" 9 | ) 10 | 11 | func init() { 12 | _, filename, _, _ := runtime.Caller(1) 13 | log.SetPrefix(filename + "\n") 14 | time.Now() //do nothing 15 | } 16 | 17 | var check_result = func(want, got []byte, t *testing.T) { 18 | if !bytes.Equal(want, got) { 19 | t.Fatalf("want %v , got %v", want, got) 20 | } 21 | } 22 | 23 | func Test_encode_binary(t *testing.T) { 24 | b, err := Encode([]byte{}) 25 | if err != nil || b == nil { 26 | t.Fail() 27 | } 28 | 29 | want := []byte{0x42, 0x00, 0x00} 30 | check_result(b, want, t) 31 | 32 | raw := []byte{10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 'a', 'b', 'c', 'd'} 33 | b, err = Encode(raw) 34 | want = []byte{0x42, 0x00, 0x0e, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x61, 0x62, 0x63, 0x64} 35 | 36 | if err != nil || b == nil { 37 | t.Fail() 38 | } 39 | 40 | check_result(b, want, t) 41 | 42 | } 43 | 44 | func Test_encode_boolean(t *testing.T) { 45 | b, err := Encode(true) 46 | if err != nil || b[0] != 'T' { 47 | t.Fail() 48 | } 49 | want := []byte{0x54} 50 | check_result(want, b, t) 51 | 52 | b, err = Encode(false) 53 | if err != nil || b[0] != 'F' { 54 | t.Fail() 55 | } 56 | 57 | want = []byte{0x46} 58 | check_result(want, b, t) 59 | } 60 | 61 | func Test_encode_time(t *testing.T) { 62 | tz, _ := time.Parse("2006-01-02 15:04:05", "2014-02-09 06:15:23") 63 | b, err := Encode(tz) 64 | if err != nil || b == nil { 65 | t.Fail() 66 | } 67 | want := []byte{0x64, 0x00, 0x00, 0x01, 0x44, 0x15, 0x49, 0x34, 0x78} 68 | check_result(want, b, t) 69 | } 70 | 71 | func Test_encode_double(t *testing.T) { 72 | b, err := Encode(1989.0604) 73 | if err != nil || b == nil { 74 | t.Fail() 75 | } 76 | } 77 | 78 | func Test_encode_int_long(t *testing.T) { 79 | b, err := Encode(19890604) 80 | if err != nil || b == nil { 81 | t.Fail() 82 | } 83 | b, err = Encode(int32(19890604)) 84 | if err != nil || b == nil { 85 | t.Fail() 86 | } 87 | b, err = Encode(int64(19890604)) 88 | if err != nil || b == nil { 89 | t.Fail() 90 | } 91 | } 92 | 93 | func Test_encode_string(t *testing.T) { 94 | b, err := Encode("亡命之徒") 95 | if err != nil || b == nil { 96 | t.Fail() 97 | } 98 | } 99 | 100 | func Test_encode_nil(t *testing.T) { 101 | b, err := Encode(nil) 102 | if err != nil || b == nil { 103 | t.Fail() 104 | } 105 | } 106 | 107 | func Test_encode_list(t *testing.T) { 108 | list := []Any{100, 10.001, "不厌其烦", []byte{0, 2, 4, 6, 8, 10}, true, nil, false} 109 | 110 | b, err := Encode(list) 111 | if err != nil || b == nil { 112 | t.Fail() 113 | } 114 | } 115 | 116 | func Test_encode_map(t *testing.T) { 117 | var hmap = make(map[Any]Any) 118 | hmap["你好"] = "哈哈哈" 119 | hmap[100] = "嘿嘿" 120 | hmap[100.1010] = 101910 121 | hmap[true] = true 122 | hmap[false] = true 123 | b, err := Encode(hmap) 124 | if err != nil || b == nil { 125 | t.Fail() 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /src/gohessian/hessisn.go: -------------------------------------------------------------------------------- 1 | package gohessian 2 | 3 | import ( 4 | "bufio" 5 | ) 6 | 7 | // interface{} 的别名 8 | type Any interface{} 9 | 10 | //hessian 数据结构定义 11 | type Hessian struct { 12 | reader *bufio.Reader 13 | refs []Any 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/gohessian/parse.go: -------------------------------------------------------------------------------- 1 | package gohessian 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "time" 8 | "util" 9 | ) 10 | 11 | /* 12 | 对 Hessian 数据进行解码 13 | 具体用法见: parse_test.go 14 | */ 15 | const ( 16 | PARSE_DEBUG = true 17 | ) 18 | 19 | func NewHessian(r io.Reader) (h *Hessian) { 20 | return &Hessian{reader: bufio.NewReader(r)} 21 | } 22 | 23 | //读取当前字节,指针不前移 24 | func (h *Hessian) peek_byte() (b byte) { 25 | b = h.peek(1)[0] 26 | return 27 | } 28 | 29 | //添加引用 30 | func (h *Hessian) append_refs(v interface{}) { 31 | h.refs = append(h.refs, v) 32 | } 33 | 34 | //获取缓冲长度 35 | func (h *Hessian) len() (l int) { 36 | h.peek(1) //需要先读一下资源才能得到已缓冲的长度 37 | l = h.reader.Buffered() 38 | return 39 | } 40 | 41 | //读取 Hessian 结构中的一个字节,并后移一个字节 42 | func (h *Hessian) read_byte() (c byte, err error) { 43 | c, err = h.reader.ReadByte() 44 | return 45 | } 46 | 47 | //读取指定长度的字节,并后移N个字节 48 | func (h *Hessian) next(n int) (b []byte) { 49 | if n <= 0 { 50 | return 51 | } 52 | if n >= h.reader.Buffered() { 53 | n = h.reader.Buffered() 54 | } 55 | b = make([]byte, n) 56 | h.reader.Read(b) 57 | return 58 | } 59 | 60 | //读取指定长度字节,指针不后移 61 | func (h *Hessian) peek(n int) (b []byte) { 62 | b, _ = h.reader.Peek(n) 63 | return 64 | } 65 | 66 | //读取指定长度的 utf8 字符 67 | func (h *Hessian) next_rune(n int) (s []rune) { 68 | for i := 0; i < n; i++ { 69 | if r, ri, e := h.reader.ReadRune(); e == nil && ri > 0 { 70 | s = append(s, r) 71 | } 72 | } 73 | return 74 | } 75 | 76 | //读取数据类型描述,用于 list 和 map 77 | func (h *Hessian) read_type() string { 78 | if h.peek_byte() != 't' { 79 | return "" 80 | } 81 | t_len, _ := util.UnpackInt16(h.peek(3)[1:3]) // 取类型字符串长度 82 | t_name := h.next_rune(int(3 + t_len))[3:] //取类型名称 83 | return string(t_name) 84 | } 85 | 86 | //解析 hessian 数据包 87 | func (h *Hessian) Parse() (v interface{}, err error) { 88 | t, err := h.read_byte() 89 | if err == io.EOF { 90 | return 91 | } 92 | switch t { 93 | case 'r': //reply 94 | h.next(2) 95 | return h.Parse() 96 | 97 | case 'f': //fault 98 | h.Parse() //drop "code" 99 | code, _ := h.Parse() 100 | h.Parse() //drop "message" 101 | message, _ := h.Parse() 102 | v = nil 103 | err = fmt.Errorf("%s : %s", code, message) 104 | case 'N': //null 105 | v = nil 106 | 107 | case 'T': //true 108 | v = true 109 | 110 | case 'F': //false 111 | v = false 112 | 113 | case 'I': //int 114 | if v, err = util.UnpackInt32(h.next(4)); err != nil { 115 | panic(err) 116 | v = nil 117 | return 118 | } 119 | 120 | case 'L': //long 121 | if v, err = util.UnpackInt64(h.next(8)); err != nil { 122 | v = nil 123 | return 124 | } 125 | 126 | case 'D': //double 127 | if v, err = util.UnpackFloat64(h.next(8)); err != nil { 128 | v = nil 129 | return 130 | } 131 | 132 | case 'd': //date 133 | var ms int64 134 | if ms, err = util.UnpackInt64(h.next(8)); err != nil { 135 | v = nil 136 | return 137 | } 138 | v = time.Unix(ms/1000, ms%1000*10E5) 139 | 140 | case 'S', 's', 'X', 'x': //string,xml 141 | var str_chunks []rune 142 | var len int16 143 | for { //避免递归读取 Chunks 144 | if len, err = util.UnpackInt16(h.next(2)); err != nil { 145 | str_chunks = nil 146 | return 147 | } 148 | str_chunks = append(str_chunks, h.next_rune(int(len))...) 149 | if t == 'S' || t == 'X' { 150 | break 151 | } 152 | if t, err = h.read_byte(); err != nil { 153 | str_chunks = nil 154 | return 155 | } 156 | } 157 | v = string(str_chunks) 158 | 159 | case 'B', 'b': //binary 160 | var bin_chunks []byte //等同于 []uint8,在 反射判断类型的时候,会得到 []uint8 161 | var len int16 162 | for { //避免递归读取 Chunks 163 | if len, err = util.UnpackInt16(h.next(2)); err != nil { 164 | bin_chunks = nil 165 | return 166 | } 167 | bin_chunks = append(bin_chunks, h.next(int(len))...) 168 | if t == 'B' { 169 | break 170 | } 171 | if t, err = h.read_byte(); err != nil { 172 | bin_chunks = nil 173 | return 174 | } 175 | } 176 | v = bin_chunks 177 | 178 | case 'V': //list 179 | h.read_type() //TODO 类型怎么用? 180 | var list_chunks []Any 181 | if h.peek_byte() == 'l' { 182 | h.next(5) 183 | } 184 | for h.peek_byte() != 'z' { 185 | if _v, _e := h.Parse(); _e != nil { 186 | list_chunks = nil 187 | return 188 | } else { 189 | list_chunks = append(list_chunks, _v) 190 | } 191 | } 192 | h.read_byte() 193 | v = list_chunks 194 | h.append_refs(&list_chunks) 195 | 196 | case 'M': //map 197 | h.read_type() //TODO 类型怎么用? 198 | var map_chunks = make(map[Any]Any) 199 | for h.peek_byte() != 'z' { 200 | _kv, _ke := h.Parse() 201 | if _ke != nil { 202 | map_chunks = nil 203 | err = _ke 204 | return 205 | } 206 | _vv, _ve := h.Parse() 207 | if _ve != nil { 208 | map_chunks = nil 209 | err = _ve 210 | return 211 | } 212 | map_chunks[_kv] = _vv 213 | } 214 | h.read_byte() 215 | v = map_chunks 216 | h.append_refs(&map_chunks) 217 | 218 | case 'R': //ref 219 | var ref_idx int32 220 | if ref_idx, err = util.UnpackInt32(h.next(4)); err != nil { 221 | return 222 | } 223 | if len(h.refs) > int(ref_idx) { 224 | v = &h.refs[ref_idx] 225 | } 226 | 227 | default: 228 | err = fmt.Errorf("Invalid type: %v,>>%v<<<", string(t), h.peek(h.len())) 229 | } //switch 230 | return 231 | } // Parse end 232 | -------------------------------------------------------------------------------- /src/gohessian/parse_test.go: -------------------------------------------------------------------------------- 1 | package gohessian 2 | 3 | import ( 4 | "bytes" 5 | "log" 6 | "reflect" 7 | "testing" 8 | "time" 9 | "runtime" 10 | ) 11 | //GOPATH=/Users/weidewang/ownCloud/Workspace/go/gohessian go test -run=Test_* 12 | 13 | var data *bytes.Buffer 14 | var REPLY []byte = []byte{114, 1, 0} 15 | 16 | func init() { 17 | _, filename, _, _ := runtime.Caller(1) 18 | log.SetPrefix(filename+"\n") 19 | } 20 | 21 | func Test_parse_binary(t *testing.T) { 22 | b := []byte{114, 1, 0, 66, 4, 0, 72, 31, 158, 110, 182, 222, 60, 211, 253, 178, 168, 141, 216, 138, 23 | 38, 13, 108, 46, 61, 6, 3, 71, 155, 226, 59, 169, 181, 228, 144, 115, 89, 117, 33, 72, 200, 134, 24 | 72, 52, 241, 151, 148, 184, 184, 203, 58, 202, 233, 190, 106, 158, 84, 212, 148, 170, 65, 128, 25 | 159, 250, 0, 124, 130, 78, 104, 103, 168, 10, 217, 3, 112, 107, 63, 185, 237, 241, 12, 125, 29, 26 | 72, 25, 217, 99, 59, 176, 104, 87, 138, 136, 207, 106, 247, 56, 62, 100, 242, 176, 32, 74, 122, 27 | 233, 194, 100, 84, 162, 12, 9, 154, 28, 79, 38, 141, 50, 52, 120, 78, 209, 48, 77, 127, 159, 28 | 158, 160, 212, 107, 112, 185, 38, 111, 223, 248, 126, 235, 108, 143, 211, 133, 99, 16, 62, 27, 29 | 133, 82, 115, 222, 140, 139, 57, 44, 125, 234, 197, 39, 146, 168, 151, 212, 5, 150, 69, 93, 30 | 34, 168, 97, 214, 80, 16, 180, 121, 252, 202, 93, 187, 225, 112, 124, 2, 222, 195, 75, 65, 44, 31 | 152, 184, 177, 51, 207, 62, 87, 117, 37, 122, 244, 112, 210, 104, 40, 253, 56, 74, 252, 151, 32 | 39, 156, 116, 93, 164, 120, 54, 194, 12, 166, 75, 91, 51, 26, 127, 243, 197, 121, 41, 182, 34, 33 | 79, 6, 155, 243, 132, 79, 168, 16, 230, 6, 254, 185, 127, 47, 192, 230, 124, 216, 166, 148, 47, 34 | 56, 83, 140, 48, 84, 83, 29, 242, 169, 198, 97, 141, 137, 99, 13, 13, 203, 23, 208, 21, 198, 35 | 124, 53, 195, 120, 111, 129, 41, 57, 232, 80, 154, 214, 76, 230, 174, 97, 159, 210, 35, 168, 36 | 190, 70, 106, 180, 107, 37, 139, 24, 30, 105, 184, 39, 204, 246, 53, 158, 4, 148, 64, 154, 163, 37 | 117, 119, 118, 83, 124, 112, 145, 113, 189, 197, 158, 148, 75, 6, 190, 252, 196, 152, 189, 247, 38 | 253, 223, 40, 205, 122, 44, 87, 136, 148, 140, 249, 40, 255, 91, 98, 129, 249, 2, 192, 186, 32, 39 | 194, 162, 107, 126, 59, 225, 255, 119, 203, 0, 200, 97, 132, 13, 207, 227, 128, 218, 131, 200, 40 | 22, 226, 123, 45, 21, 235, 13, 254, 0, 173, 52, 30, 191, 8, 118, 0, 188, 122, 13, 79, 177, 35, 41 | 54, 162, 5, 236, 95, 118, 35, 132, 113, 204, 173, 189, 63, 2, 237, 244, 40, 159, 60, 172, 238, 42 | 64, 55, 3, 55, 135, 128, 92, 253, 98, 221, 47, 180, 125, 126, 54, 49, 31, 59, 108, 121, 15, 188, 43 | 96, 193, 198, 254, 56, 108, 230, 185, 97, 30, 241, 33, 187, 51, 220, 134, 176, 203, 72, 4, 169, 44 | 72, 229, 230, 43, 68, 236, 213, 145, 208, 85, 110, 202, 140, 132, 155, 172, 190, 79, 121, 18, 45 | 125, 3, 44, 165, 242, 94, 224, 4, 247, 158, 40, 182, 204, 128, 6, 91, 101, 142, 41, 123, 131, 46 | 53, 42, 83, 35, 138, 190, 192, 226, 75, 18, 84, 65, 41, 128, 21, 126, 126, 16, 91, 181, 135, 47 | 215, 147, 112, 43, 55, 161, 249, 219, 99, 109, 239, 155, 84, 195, 243, 235, 145, 107, 140, 189, 48 | 29, 37, 52, 122, 31, 84, 125, 65, 187, 84, 127, 38, 117, 97, 0, 114, 247, 78, 66, 78, 11, 158, 49 | 175, 72, 104, 12, 171, 0, 3, 46, 200, 127, 112, 184, 119, 245, 201, 179, 93, 193, 163, 215, 50 | 121, 37, 153, 155, 211, 25, 77, 92, 137, 133, 239, 255, 77, 77, 92, 158, 81, 226, 102, 135, 51 | 176, 222, 37, 125, 85, 247, 118, 109, 243, 172, 250, 194, 55, 49, 123, 213, 137, 150, 247, 214, 52 | 25, 194, 169, 141, 153, 148, 90, 147, 110, 242, 46, 137, 235, 26, 122, 45, 208, 198, 93, 66, 53 | 112, 195, 252, 143, 38, 123, 111, 131, 183, 147, 114, 244, 131, 107, 173, 51, 30, 87, 198, 43, 54 | 151, 82, 173, 124, 46, 232, 116, 238, 197, 10, 142, 38, 140, 93, 225, 247, 185, 56, 115, 232, 55 | 109, 113, 200, 113, 111, 139, 232, 187, 220, 167, 146, 84, 102, 106, 233, 204, 17, 240, 99, 202, 56 | 37, 78, 24, 118, 66, 225, 24, 249, 19, 34, 201, 120, 25, 192, 52, 43, 42, 78, 244, 92, 11, 230, 57 | 232, 49, 213, 99, 132, 166, 211, 78, 37, 16, 27, 132, 198, 118, 148, 79, 219, 213, 119, 246, 58 | 165, 67, 138, 200, 150, 21, 52, 137, 213, 206, 89, 77, 31, 232, 82, 175, 173, 255, 67, 21, 59 | 66, 97, 24, 126, 100, 40, 88, 184, 6, 230, 79, 244, 236, 53, 26, 4, 180, 3, 69, 47, 77, 7, 238, 60 | 103, 255, 28, 199, 127, 39, 250, 248, 199, 216, 120, 91, 118, 152, 165, 56, 193, 77, 86, 239, 61 | 98, 252, 71, 205, 162, 74, 225, 171, 221, 184, 255, 16, 148, 92, 235, 223, 75, 91, 209, 22, 222, 62 | 87, 245, 217, 135, 75, 151, 179, 37, 182, 46, 130, 9, 138, 232, 247, 4, 244, 77, 114, 79, 131, 63 | 38, 77, 135, 250, 66, 169, 78, 126, 198, 106, 71, 8, 175, 134, 49, 162, 124, 13, 48, 103, 58, 64 | 207, 182, 143, 54, 112, 65, 215, 193, 98, 232, 36, 94, 146, 200, 195, 238, 112, 8, 198, 188, 84, 65 | 226, 103, 101, 134, 217, 132, 201, 236, 68, 200, 170, 136, 186, 71, 220, 142, 164, 43, 166, 234, 66 | 47, 180, 171, 205, 51, 80, 187, 103, 186, 172, 119, 255, 3, 84, 205, 57, 70, 184, 29, 138, 88, 67 | 239, 143, 233, 107, 57, 157, 76, 44, 139, 11, 213, 76, 6, 247, 68, 120, 187, 119, 69, 237, 69, 68 | 173, 179, 244, 3, 74, 250, 37, 134, 22, 42, 116, 95, 128, 71, 161, 85, 233, 153, 11, 21, 232, 69 | 5, 143, 95, 126, 241, 153, 203, 202, 114, 236, 162, 94, 166, 113, 211, 218, 5, 135, 245, 70 | 124, 227, 54, 23, 10, 17, 58, 35, 7, 166, 40, 96, 7, 177, 234, 179, 223, 5, 110, 103, 22, 71 | 225, 69, 71, 40, 127, 42, 221, 7, 94, 94, 147, 210, 138, 80, 239, 198, 106} 72 | data = bytes.NewBuffer(b) 73 | h := NewHessian(bytes.NewReader(data.Bytes())) 74 | v, err := h.Parse() 75 | 76 | var binary_check []byte 77 | if reflect.TypeOf(v) != reflect.TypeOf(binary_check) { 78 | t.Fatalf("want []byte type,but got %v", reflect.TypeOf(v)) 79 | } 80 | if err != nil { 81 | t.Fatalf("error: %v", err) 82 | } 83 | } 84 | 85 | func Test_parse_null(t *testing.T) { 86 | data = bytes.NewBuffer(append(REPLY, 'N')) 87 | h := NewHessian(bytes.NewReader(data.Bytes())) 88 | v, err := h.Parse() 89 | if err != nil { 90 | t.Fatalf("error: %v", err) 91 | } 92 | if v != nil { 93 | t.Fatalf("wnat nil,but got %v", v) 94 | } 95 | } 96 | 97 | func Test_parse_bool_true(t *testing.T) { 98 | data = bytes.NewBuffer(append(REPLY, 'T')) 99 | h := NewHessian(bytes.NewReader(data.Bytes())) 100 | v, err := h.Parse() 101 | if err != nil { 102 | t.Fatalf("error: %v", err) 103 | } 104 | 105 | if reflect.TypeOf(v) != reflect.TypeOf(true) { 106 | t.Fatalf("want bool type,but got %v", reflect.TypeOf(v)) 107 | } 108 | 109 | if v != true { 110 | t.Fatalf("wnat true,but got %v", v) 111 | } 112 | } 113 | 114 | func Test_parse_bool_false(t *testing.T) { 115 | data = bytes.NewBuffer(append(REPLY, 'F')) 116 | h := NewHessian(bytes.NewReader(data.Bytes())) 117 | v, err := h.Parse() 118 | if err != nil { 119 | t.Fatalf("error: %v", err) 120 | } 121 | if reflect.TypeOf(v) != reflect.TypeOf(true) { 122 | t.Fatalf("want bool type,but got %v", reflect.TypeOf(v)) 123 | } 124 | if v != false { 125 | t.Fatalf("wnat false,but got %v", v) 126 | } 127 | } 128 | 129 | func Test_parse_int32_89(t *testing.T) { 130 | data = bytes.NewBuffer(append(REPLY, []byte{'I', 0, 0, 0, 89}...)) 131 | h := NewHessian(bytes.NewReader(data.Bytes())) 132 | v, err := h.Parse() 133 | if err != nil { 134 | t.Fatalf("error: %v", err) 135 | } 136 | if reflect.TypeOf(v) != reflect.TypeOf(int32(100)) { 137 | t.Fatalf("want int32 type,but got %v", reflect.TypeOf(v)) 138 | } 139 | if v != int32(89) { 140 | t.Fatalf("wnat 89,but got %v", v) 141 | } 142 | } 143 | 144 | func Test_parse_long_19890604(t *testing.T) { 145 | data = bytes.NewBuffer(append(REPLY, []byte{'L', 0, 0, 0, 0, 1, 47, 129, 172}...)) 146 | h := NewHessian(bytes.NewReader(data.Bytes())) 147 | v, err := h.Parse() 148 | if err != nil { 149 | t.Fatalf("error: %v", err) 150 | } 151 | if reflect.TypeOf(v) != reflect.TypeOf(int64(100)) { 152 | t.Fatalf("want int64 type,but got %v", reflect.TypeOf(v)) 153 | } 154 | if v != int64(19890604) { 155 | t.Fatalf("wnat 19890604,but got %v", v) 156 | } 157 | } 158 | 159 | func Test_parse_double_1989_0604(t *testing.T) { 160 | data = bytes.NewBuffer(append(REPLY, []byte{'D', 64, 159, 20, 61, 217, 127, 98, 183}...)) 161 | h := NewHessian(bytes.NewReader(data.Bytes())) 162 | v, err := h.Parse() 163 | if err != nil { 164 | t.Fatalf("error: %v", err) 165 | } 166 | if reflect.TypeOf(v) != reflect.TypeOf(float64(100)) { 167 | t.Fatalf("want float64 type,but got %v", reflect.TypeOf(v)) 168 | } 169 | if v != 1989.0604 { 170 | t.Fatalf("wnat 1989.0604,but got %v", v) 171 | } 172 | } 173 | 174 | func Test_parse_date(t *testing.T) { 175 | data = bytes.NewBuffer(append(REPLY, []byte{'d', 0, 0, 1, 67, 206, 0, 226, 40}...)) 176 | h := NewHessian(bytes.NewReader(data.Bytes())) 177 | v, err := h.Parse() 178 | if err != nil { 179 | t.Fatalf("error: %v", err) 180 | } 181 | if reflect.TypeOf(v) != reflect.TypeOf(time.Now()) { 182 | t.Fatalf("want time.Time type,but got %v", reflect.TypeOf(v)) 183 | } 184 | if v != time.Unix(1390730601, 0) { 185 | t.Fatalf("wnat 2014-01-26 18:03:21 +0800 CST,but got %v", v) 186 | } 187 | } 188 | 189 | func Test_parse_string(t *testing.T) { 190 | b := []byte{ 191 | 83, 0, 34, 95, 95, 66, 69, 71, 192 | 73, 78, 95, 95, 229, 133, 148, 193 | 229, 133, 148, 229, 146, 140, 194 | 229, 176, 143, 229, 167, 168, 195 | 229, 173, 144, 49, 50, 51, 196 | 52, 53, 54, 229, 133, 148, 197 | 229, 133, 148, 231, 170, 129, 198 | 231, 170, 129, 231, 170, 129, 199 | 46, 95, 95, 69, 78, 68, 95, 95} 200 | data = bytes.NewBuffer(append(REPLY, b...)) 201 | h := NewHessian(bytes.NewReader(data.Bytes())) 202 | v, err := h.Parse() 203 | if err != nil { 204 | t.Fatalf("error: %v", err) 205 | } 206 | if reflect.TypeOf(v) != reflect.TypeOf(string("")) { 207 | t.Fatalf("want string type,but got %v", reflect.TypeOf(v)) 208 | } 209 | want := "__BEGIN__兔兔和小姨子123456兔兔突突突.__END__" 210 | if v != want { 211 | t.Fatalf("wnat %s,but got %v", want, v) 212 | } 213 | } 214 | 215 | func Test_parse_list_without_type(t *testing.T) { 216 | b := []byte{ 217 | 114, 1, 0, 86, 108, 0, 0, 0, 0, 83, 0, 5, 104, 101, 108, 108, 111, 218 | 83, 0, 5, 119, 111, 114, 108, 100, 73, 0, 0, 0, 100, 84, 68, 64, 219 | 195, 136, 0, 0, 0, 0, 0, 68, 64, 81, 128, 3, 70, 220, 93, 100, 220 | 76, 0, 0, 0, 0, 0, 0, 3, 231, 100, 0, 0, 1, 67, 206, 150, 245, 230, 122} 221 | data = bytes.NewBuffer(b) 222 | h := NewHessian(bytes.NewReader(data.Bytes())) 223 | v, err := h.Parse() 224 | var list_check []Any 225 | if reflect.TypeOf(v) != reflect.TypeOf(list_check) { 226 | t.Fatalf("want []interface {} type,but got %v", reflect.TypeOf(v)) 227 | } 228 | if err != nil { 229 | t.Fatalf("error: %v", err) 230 | } 231 | } 232 | 233 | func Test_parse_list_with_type(t *testing.T) { 234 | b := []byte{ 235 | 114, 1, 0, 86, 116, 0, 6, 115, 116, 114, 105, 110, 103, 108, 0, 0, 0, 10, 236 | 83, 0, 5, 104, 101, 108, 108, 111, 83, 0, 5, 119, 111, 114, 108, 237 | 100, 73, 0, 0, 0, 100, 84, 68, 64, 195, 136, 0, 0, 0, 0, 0, 68, 238 | 64, 81, 128, 3, 70, 220, 93, 100, 76, 0, 0, 0, 0, 0, 0, 3, 231, 122} 239 | data = bytes.NewBuffer(b) 240 | h := NewHessian(bytes.NewReader(data.Bytes())) 241 | v, err := h.Parse() 242 | var list_check []Any 243 | if reflect.TypeOf(v) != reflect.TypeOf(list_check) { 244 | t.Fatalf("want []interface {} type,but got %v", reflect.TypeOf(v)) 245 | } 246 | if err != nil { 247 | t.Fatalf("error: %v", err) 248 | } 249 | } 250 | 251 | func Test_parse_map(t *testing.T) { 252 | b := []byte{114, 1, 0, 77, 116, 0, 5, 102, 108, 111, 97, 116, 73, 253 | 0, 0, 0, 10, 83, 0, 9, 109, 97, 112, 32, 118, 97, 108, 254 | 117, 101, 83, 0, 3, 107, 101, 121, 84, 122} 255 | 256 | data = bytes.NewBuffer(b) 257 | h := NewHessian(bytes.NewReader(data.Bytes())) 258 | v, err := h.Parse() 259 | 260 | var map_check map[Any]Any 261 | if reflect.TypeOf(v) != reflect.TypeOf(map_check) { 262 | t.Fatalf("want map[Any]Any type,but got %v", reflect.TypeOf(v)) 263 | } 264 | if err != nil { 265 | t.Fatalf("error: %v", err) 266 | } 267 | } 268 | -------------------------------------------------------------------------------- /src/util/util.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "bytes" 5 | "encoding/binary" 6 | "fmt" 7 | "strings" 8 | ) 9 | 10 | func PackInt8(v int8) (r []byte, err error) { 11 | buf := new(bytes.Buffer) 12 | err = binary.Write(buf, binary.BigEndian, v) 13 | if err != nil { 14 | return 15 | } 16 | r = buf.Bytes() 17 | return 18 | } 19 | 20 | //[10].pack('n').bytes => [0, 10] 21 | func PackInt16(v int16) (r []byte, err error) { 22 | buf := new(bytes.Buffer) 23 | err = binary.Write(buf, binary.BigEndian, v) 24 | if err != nil { 25 | return 26 | } 27 | r = buf.Bytes() 28 | return 29 | } 30 | 31 | //[10].pack('n').bytes => [0, 10] 32 | func PackUint16(v uint16) (r []byte, err error) { 33 | buf := new(bytes.Buffer) 34 | err = binary.Write(buf, binary.BigEndian, v) 35 | if err != nil { 36 | return 37 | } 38 | r = buf.Bytes() 39 | return 40 | } 41 | 42 | //[10].pack('N').bytes => [0, 0, 0, 10] 43 | func PackInt32(v int32) (r []byte, err error) { 44 | buf := new(bytes.Buffer) 45 | err = binary.Write(buf, binary.BigEndian, v) 46 | if err != nil { 47 | return 48 | } 49 | r = buf.Bytes() 50 | return 51 | } 52 | 53 | //[10].pack('q>').bytes => [0, 0, 0, 0, 0, 0, 0, 10] 54 | func PackInt64(v int64) (r []byte, err error) { 55 | buf := new(bytes.Buffer) 56 | err = binary.Write(buf, binary.BigEndian, v) 57 | if err != nil { 58 | return 59 | } 60 | r = buf.Bytes() 61 | return 62 | } 63 | 64 | //[10].pack('G').bytes => [64, 36, 0, 0, 0, 0, 0, 0] 65 | func PackFloat64(v float64) (r []byte, err error) { 66 | buf := new(bytes.Buffer) 67 | err = binary.Write(buf, binary.BigEndian, v) 68 | if err != nil { 69 | return 70 | } 71 | r = buf.Bytes() 72 | return 73 | } 74 | 75 | //(0,2).unpack('n') 76 | func UnpackInt16(b []byte) (pi int16, err error) { 77 | err = binary.Read(bytes.NewReader(b), binary.BigEndian, &pi) 78 | if err != nil { 79 | return 80 | } 81 | return 82 | } 83 | 84 | 85 | 86 | //(0,4).unpack('N') 87 | func UnpackInt32(b []byte) (pi int32, err error) { 88 | err = binary.Read(bytes.NewReader(b), binary.BigEndian, &pi) 89 | if err != nil { 90 | return 91 | } 92 | return 93 | } 94 | 95 | //long (0,8).unpack('q>') 96 | func UnpackInt64(b []byte) (pi int64, err error) { 97 | err = binary.Read(bytes.NewReader(b), binary.BigEndian, &pi) 98 | if err != nil { 99 | return 100 | } 101 | return 102 | } 103 | 104 | //Double (0,8).unpack('G) 105 | func UnpackFloat64(b []byte) (rs float64, err error) { 106 | err = binary.Read(bytes.NewReader(b), binary.BigEndian, &rs) 107 | if err != nil { 108 | return 109 | } 110 | return 111 | } 112 | 113 | //将字节数组格式化成 hex 114 | func SprintHex(b []byte) (rs string) { 115 | rs = fmt.Sprintf("[]byte{") 116 | for _, v := range b { 117 | rs += fmt.Sprintf("0x%02x,", v) 118 | } 119 | rs = strings.TrimSpace(rs) 120 | rs += fmt.Sprintf("}\n") 121 | return 122 | } 123 | 124 | 125 | --------------------------------------------------------------------------------