-
Notifications
You must be signed in to change notification settings - Fork 114
/
int.go
123 lines (107 loc) · 3.44 KB
/
int.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package hessian
import (
"encoding/binary"
"io"
"reflect"
)
import (
perrors "github.com/pkg/errors"
)
/////////////////////////////////////////
// Int32
/////////////////////////////////////////
// # 32-bit signed integer
// ::= 'I' b3 b2 b1 b0
// ::= [x80-xbf] # -x10 to x3f
// ::= [xc0-xcf] b0 # -x800 to x7ff
// ::= [xd0-xd7] b1 b0 # -x40000 to x3ffff
func encInt32(b []byte, v int32) []byte {
if int32(INT_DIRECT_MIN) <= v && v <= int32(INT_DIRECT_MAX) {
return encByte(b, byte(v+int32(BC_INT_ZERO)))
} else if int32(INT_BYTE_MIN) <= v && v <= int32(INT_BYTE_MAX) {
return encByte(b, byte(int32(BC_INT_BYTE_ZERO)+v>>8), byte(v))
} else if int32(INT_SHORT_MIN) <= v && v <= int32(INT_SHORT_MAX) {
return encByte(b, byte(v>>16+int32(BC_INT_SHORT_ZERO)), byte(v>>8), byte(v))
}
return encByte(b, byte('I'), byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
}
/////////////////////////////////////////
// Int32
/////////////////////////////////////////
// # 32-bit signed integer
// ::= 'I' b3 b2 b1 b0
// ::= [x80-xbf] # -x10 to x3f
// ::= [xc0-xcf] b0 # -x800 to x7ff
// ::= [xd0-xd7] b1 b0 # -x40000 to x3ffff
func (d *Decoder) decInt32(flag int32) (int32, error) {
var (
err error
tag byte
)
if flag != TAG_READ {
tag = byte(flag)
} else {
tag, _ = d.ReadByte()
}
switch {
case tag >= 0x80 && tag <= 0xbf:
i8 := int8(tag - BC_INT_ZERO)
return int32(i8), nil
case tag >= 0xc0 && tag <= 0xcf:
buf := []byte{tag - BC_INT_BYTE_ZERO, 0}
_, err = io.ReadFull(d.reader, buf[1:])
if err != nil {
return 0, perrors.WithStack(err)
}
u16 := binary.BigEndian.Uint16(buf)
i16 := int16(u16)
return int32(i16), nil
case tag >= 0xd0 && tag <= 0xd7:
// Use int32 to represent int24.
buf := []byte{0, tag - BC_INT_SHORT_ZERO, 0, 0}
if buf[1]&0x80 != 0 {
buf[0] = 0xff
}
_, err = io.ReadFull(d.reader, buf[2:])
if err != nil {
return 0, perrors.WithStack(err)
}
u32 := binary.BigEndian.Uint32(buf)
return int32(u32), nil
case tag == BC_INT:
var i32 int32
err = binary.Read(d.reader, binary.BigEndian, &i32)
return i32, perrors.WithStack(err)
case tag == BC_NULL:
return int32(0), nil
default:
return 0, perrors.Errorf("decInt32 integer wrong tag:%#x", tag)
}
}
func (e *Encoder) encTypeInt32(b []byte, p interface{}) ([]byte, error) {
value := reflect.ValueOf(p)
if value.Kind() == reflect.Ptr && value.IsNil() || PackPtr(value).IsNil() {
return EncNull(b), nil
}
value = UnpackPtrValue(value)
if value.Kind() != reflect.Int32 {
return nil, perrors.Errorf("encode reflect Int32 integer wrong, it's not int32 pointer")
}
return encInt32(b, int32(value.Int())), nil
}