Пример #1
0
//读取数据类型描述,用于 list 和 map
func (h *Hessian) read_type() string {
	if h.peek_byte() != 't' {
		return ""
	}
	t_len, _ := util.UnpackInt16(h.peek(3)[1:3]) // 取类型字符串长度
	t_name := h.next_rune(int(3 + t_len))[3:]    //取类型名称
	return string(t_name)
}
Пример #2
0
//解析 hessian 数据包
func (h *Hessian) Parse() (v interface{}, err error) {
	t, err := h.read_byte()
	if err == io.EOF {
		return
	}
	switch t {
	case 'r': //reply
		h.next(2)
		return h.Parse()

	case 'f': //fault
		h.Parse() //drop "code"
		code, _ := h.Parse()
		h.Parse() //drop "message"
		message, _ := h.Parse()
		v = nil
		err = fmt.Errorf("%s : %s", code, message)
	case 'N': //null
		v = nil

	case 'T': //true
		v = true

	case 'F': //false
		v = false

	case 'I': //int
		if v, err = util.UnpackInt32(h.next(4)); err != nil {
			panic(err)
			v = nil
			return
		}

	case 'L': //long
		if v, err = util.UnpackInt64(h.next(8)); err != nil {
			v = nil
			return
		}

	case 'D': //double
		if v, err = util.UnpackFloat64(h.next(8)); err != nil {
			v = nil
			return
		}

	case 'd': //date
		var ms int64
		if ms, err = util.UnpackInt64(h.next(8)); err != nil {
			v = nil
			return
		}
		v = time.Unix(ms/1000, ms%1000*10E5)

	case 'S', 's', 'X', 'x': //string,xml
		var str_chunks []rune
		var len int16
		for { //避免递归读取 Chunks
			if len, err = util.UnpackInt16(h.next(2)); err != nil {
				str_chunks = nil
				return
			}
			str_chunks = append(str_chunks, h.next_rune(int(len))...)
			if t == 'S' || t == 'X' {
				break
			}
			if t, err = h.read_byte(); err != nil {
				str_chunks = nil
				return
			}
		}
		v = string(str_chunks)

	case 'B', 'b': //binary
		var bin_chunks []byte //等同于 []uint8,在 反射判断类型的时候,会得到 []uint8
		var len int16
		for { //避免递归读取 Chunks
			if len, err = util.UnpackInt16(h.next(2)); err != nil {
				bin_chunks = nil
				return
			}
			bin_chunks = append(bin_chunks, h.next(int(len))...)
			if t == 'B' {
				break
			}
			if t, err = h.read_byte(); err != nil {
				bin_chunks = nil
				return
			}
		}
		v = bin_chunks

	case 'V': //list
		h.read_type() //TODO 类型怎么用?
		var list_chunks []Any
		if h.peek_byte() == 'l' {
			h.next(5)
		}
		for h.peek_byte() != 'z' {
			if _v, _e := h.Parse(); _e != nil {
				list_chunks = nil
				return
			} else {
				list_chunks = append(list_chunks, _v)
			}
		}
		h.read_byte()
		v = list_chunks
		h.append_refs(&list_chunks)

	case 'M': //map
		h.read_type() //TODO 类型怎么用?
		var map_chunks = make(map[Any]Any)
		for h.peek_byte() != 'z' {
			_kv, _ke := h.Parse()
			if _ke != nil {
				map_chunks = nil
				err = _ke
				return
			}
			_vv, _ve := h.Parse()
			if _ve != nil {
				map_chunks = nil
				err = _ve
				return
			}
			map_chunks[_kv] = _vv
		}
		h.read_byte()
		v = map_chunks
		h.append_refs(&map_chunks)

	case 'R': //ref
		var ref_idx int32
		if ref_idx, err = util.UnpackInt32(h.next(4)); err != nil {
			return
		}
		if len(h.refs) > int(ref_idx) {
			v = &h.refs[ref_idx]
		}

	default:
		err = fmt.Errorf("Invalid type: %v,>>%v<<<", string(t), h.peek(h.len()))
	} //switch
	return
} // Parse end