加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
binary.go 3.89 KB
一键复制 编辑 原始数据 按行查看 历史
老马 提交于 2019-12-14 11:02 . first
/*
* 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 (
"io"
)
import (
gxbytes "gitee.com/manangui/dubbogo-gost-xjie/bytes"
perrors "github.com/pkg/errors"
)
/////////////////////////////////////////
// Binary, []byte
/////////////////////////////////////////
// # 8-bit binary data split into 64k chunks
// ::= x41(A) b1 b0 <binary-data> binary # non-final chunk
// ::= x42(B) b1 b0 <binary-data> # final chunk
// ::= [x20-x2f] <binary-data> # binary data of length 0-15
// ::= [x34-x37] <binary-data> # binary data of length 0-1023
func encBinary(b []byte, v []byte) []byte {
var (
length uint16
vLength int
)
if v == nil {
return encByte(b, BC_NULL)
}
vLength = len(v)
for {
if vLength > CHUNK_SIZE {
length = CHUNK_SIZE
b = encByte(b, BC_BINARY_CHUNK, byte(length>>8), byte(length))
} else {
length = uint16(vLength)
if vLength <= int(BINARY_DIRECT_MAX) {
b = encByte(b, byte(int(BC_BINARY_DIRECT)+vLength))
} else if vLength <= int(BINARY_SHORT_MAX) {
b = encByte(b, byte(int(BC_BINARY_SHORT)+vLength>>8), byte(vLength))
} else {
b = encByte(b, BC_BINARY, byte(vLength>>8), byte(vLength))
}
}
b = append(b, v[:length]...)
v = v[length:]
vLength = len(v)
if vLength == 0 {
break
}
}
return b
}
/////////////////////////////////////////
// Binary, []byte
/////////////////////////////////////////
// # 8-bit binary data split into 64k chunks
// ::= x41('A') b1 b0 <binary-data> binary # non-final chunk
// ::= x42('B') b1 b0 <binary-data> # final chunk
// ::= [x20-x2f] <binary-data> # binary data of length 0-15
// ::= [x34-x37] <binary-data> # binary data of length 0-1023
func (d *Decoder) getBinaryLength(tag byte) (int, error) {
var (
err error
buf [2]byte
)
if tag >= BC_BINARY_DIRECT && tag <= INT_DIRECT_MAX { // [0x20, 0x2f]
return int(tag - BC_BINARY_DIRECT), nil
}
if tag >= BC_BINARY_SHORT && tag <= byte(0x37) { // [0x34, 0x37]
_, err = io.ReadFull(d.reader, buf[:1])
if err != nil {
return 0, perrors.WithStack(err)
}
return int(tag-BC_BINARY_SHORT)<<8 + int(buf[0]), nil
}
if tag != BC_BINARY_CHUNK && tag != BC_BINARY {
return 0, perrors.Errorf("illegal binary tag:%d", tag)
}
_, err = io.ReadFull(d.reader, buf[:2])
if err != nil {
return 0, perrors.WithStack(err)
}
return int(buf[0])<<8 + int(buf[1]), nil
}
func (d *Decoder) decBinary(flag int32) ([]byte, error) {
var (
err error
tag byte
length int
)
if flag != TAG_READ {
tag = byte(flag)
} else {
tag, err = d.readBufByte()
if err != nil {
return nil, perrors.WithStack(err)
}
}
if tag == BC_NULL {
return []byte(""), nil
}
data := make([]byte, 0, 128)
bufp := gxbytes.GetBytes(65546)
buf := *bufp
defer gxbytes.PutBytes(bufp)
for {
length, err = d.getBinaryLength(tag)
if err != nil {
return nil, perrors.WithStack(err)
}
_, err = io.ReadFull(d.reader, buf[:length])
if err != nil {
return nil, perrors.WithStack(err)
}
data = append(data, buf[:length]...)
if tag != BC_BINARY_CHUNK {
break
}
tag, err = d.readBufByte()
if err != nil {
return nil, perrors.WithStack(err)
}
}
return data, nil
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化