package msgpack
import (
)
const (
minInternedStringLen = 3
maxDictLen = math.MaxUint16
)
var internedStringExtID = int8(math.MinInt8)
func () {
extTypes[internedStringExtID] = &extInfo{
Type: stringType,
Decoder: decodeInternedStringExt,
}
}
func ( *Decoder, reflect.Value, int) error {
, := .decodeInternedStringIndex()
if != nil {
return
}
, := .internedStringAtIndex()
if != nil {
return
}
.SetString()
return nil
}
func ( *Encoder, reflect.Value) error {
if .IsNil() {
return .EncodeNil()
}
= .Elem()
if .Kind() == reflect.String {
return .encodeInternedString(.String(), true)
}
return .EncodeValue()
}
func ( *Encoder, reflect.Value) error {
return .encodeInternedString(.String(), true)
}
func ( *Encoder) ( string, bool) error {
if len() >= minInternedStringLen {
if , := .dict[]; {
return .encodeInternedStringIndex()
}
if && len(.dict) < maxDictLen {
if .dict == nil {
.dict = make(map[string]int)
}
:= len(.dict)
.dict[] =
}
}
return .encodeNormalString()
}
func ( *Encoder) ( int) error {
if <= math.MaxUint8 {
if := .writeCode(msgpcode.FixExt1); != nil {
return
}
return .write1(byte(internedStringExtID), uint8())
}
if <= math.MaxUint16 {
if := .writeCode(msgpcode.FixExt2); != nil {
return
}
return .write2(byte(internedStringExtID), uint16())
}
if uint64() <= math.MaxUint32 {
if := .writeCode(msgpcode.FixExt4); != nil {
return
}
return .write4(byte(internedStringExtID), uint32())
}
return fmt.Errorf("msgpack: interned string index=%d is too large", )
}
func ( *Decoder, reflect.Value) error {
, := .decodeInternedString(true)
if == nil {
.Set(reflect.ValueOf())
return nil
}
if != nil {
if , := .(unexpectedCodeError); ! {
return
}
}
if := .s.UnreadByte(); != nil {
return
}
return decodeInterfaceValue(, )
}
func ( *Decoder, reflect.Value) error {
, := .decodeInternedString(true)
if != nil {
return
}
.SetString()
return nil
}
func ( *Decoder) ( bool) (string, error) {
, := .readCode()
if != nil {
return "",
}
if msgpcode.IsFixedString() {
:= int( & msgpcode.FixedStrMask)
return .decodeInternedStringWithLen(, )
}
switch {
case msgpcode.Nil:
return "", nil
case msgpcode.FixExt1, msgpcode.FixExt2, msgpcode.FixExt4:
, , := .extHeader()
if != nil {
return "",
}
if != internedStringExtID {
:= fmt.Errorf("msgpack: got ext type=%d, wanted %d",
, internedStringExtID)
return "",
}
, := .decodeInternedStringIndex()
if != nil {
return "",
}
return .internedStringAtIndex()
case msgpcode.Str8, msgpcode.Bin8:
, := .uint8()
if != nil {
return "",
}
return .decodeInternedStringWithLen(int(), )
case msgpcode.Str16, msgpcode.Bin16:
, := .uint16()
if != nil {
return "",
}
return .decodeInternedStringWithLen(int(), )
case msgpcode.Str32, msgpcode.Bin32:
, := .uint32()
if != nil {
return "",
}
return .decodeInternedStringWithLen(int(), )
}
return "", unexpectedCodeError{
code: ,
hint: "interned string",
}
}
func ( *Decoder) ( int) (int, error) {
switch {
case 1:
, := .uint8()
if != nil {
return 0,
}
return int(), nil
case 2:
, := .uint16()
if != nil {
return 0,
}
return int(), nil
case 4:
, := .uint32()
if != nil {
return 0,
}
return int(), nil
}
:= fmt.Errorf("msgpack: unsupported ext len=%d decoding interned string", )
return 0,
}
func ( *Decoder) ( int) (string, error) {
if >= len(.dict) {
:= fmt.Errorf("msgpack: interned string at index=%d does not exist", )
return "",
}
return .dict[], nil
}
func ( *Decoder) ( int, bool) (string, error) {
if <= 0 {
return "", nil
}
, := .stringWithLen()
if != nil {
return "",
}
if && len() >= minInternedStringLen && len(.dict) < maxDictLen {
.dict = append(.dict, )
}
return , nil
}