14 Star 51 Fork 12

Hprose/hprose-go

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
reader.go 64.95 KB
一键复制 编辑 原始数据 按行查看 历史
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876
/**********************************************************\
| |
| hprose |
| |
| Official WebSite: http://www.hprose.com/ |
| http://www.hprose.org/ |
| |
\**********************************************************/
/**********************************************************\
* *
* hprose/reader.go *
* *
* hprose Reader for Go. *
* *
* LastModified: Jun 3, 2015 *
* Author: Ma Bingyao <andot@hprose.com> *
* *
\**********************************************************/
package hprose
import (
"container/list"
"errors"
"math"
"math/big"
"reflect"
"strconv"
"strings"
"sync"
"time"
"unicode/utf8"
)
// ErrNil is a error of nil
var ErrNil = errors.New("nil")
var errBadEncode = errors.New("bad utf-8 encoding")
var errRef = unexpectedTag(TagRef, nil)
var bigDigit = [...]*big.Int{
big.NewInt(0),
big.NewInt(1),
big.NewInt(2),
big.NewInt(3),
big.NewInt(4),
big.NewInt(5),
big.NewInt(6),
big.NewInt(7),
big.NewInt(8),
big.NewInt(9),
}
var bigTen = big.NewInt(10)
const timeStringFormat = "2006-01-02 15:04:05.999999999 -0700 MST"
var timeZero = time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)
var soMapType = reflect.TypeOf(map[string]interface{}(nil))
var ooMapType = reflect.TypeOf(map[interface{}]interface{}(nil))
var indexCache struct {
sync.RWMutex
cache map[reflect.Type]map[string][]int
}
// BufReader is buffer reader interface, Hprose Reader use it as input stream.
type BufReader interface {
Read(p []byte) (n int, err error)
ReadByte() (c byte, err error)
ReadRune() (r rune, size int, err error)
ReadString(delim byte) (line string, err error)
}
type readerRefer interface {
setRef(p interface{})
readRef(i int, err error) (interface{}, error)
resetRef()
}
type fakeReaderRefer struct{}
func (r fakeReaderRefer) setRef(p interface{}) {}
func (r fakeReaderRefer) readRef(i int, err error) (interface{}, error) {
return nil, errRef
}
func (r fakeReaderRefer) resetRef() {}
type realReaderRefer struct {
ref []interface{}
}
func (r *realReaderRefer) setRef(p interface{}) {
if r.ref == nil {
r.ref = make([]interface{}, 0)
}
r.ref = append(r.ref, p)
}
func (r *realReaderRefer) readRef(i int, err error) (interface{}, error) {
if err == nil {
return r.ref[i], nil
}
return nil, err
}
func (r *realReaderRefer) resetRef() {
if r.ref != nil {
r.ref = r.ref[:0]
}
}
// Reader is a fine-grained operation struct for Hprose unserialization
// when JSONCompatible is true, the Map data will unserialize to map[string]interface as the default type
type Reader struct {
*RawReader
classref []interface{}
fieldsref [][]string
readerRefer
JSONCompatible bool
}
// NewReader is the constructor for Hprose Reader
func NewReader(stream BufReader, simple bool) (reader *Reader) {
reader = new(Reader)
reader.RawReader = NewRawReader(stream)
if simple {
reader.readerRefer = fakeReaderRefer{}
} else {
reader.readerRefer = new(realReaderRefer)
}
return
}
// CheckTag the next byte in stream is the expected tag
func (r *Reader) CheckTag(expectTag byte) error {
tag, err := r.Stream.ReadByte()
if err == nil {
return unexpectedTag(tag, []byte{expectTag})
}
return err
}
// CheckTags the next byte in stream in the expected tags
func (r *Reader) CheckTags(expectTags []byte) (tag byte, err error) {
tag, err = r.Stream.ReadByte()
if err == nil {
if err = unexpectedTag(tag, expectTags); err == nil {
return tag, nil
}
}
return 0, err
}
// Unserialize a data from stream
func (r *Reader) Unserialize(p interface{}) (err error) {
switch p := p.(type) {
case nil:
return errors.New("argument p must be non-null pointer")
case *int:
if *p, err = r.ReadInt(); err == ErrNil {
err = nil
}
return err
case *uint:
if *p, err = r.ReadUint(); err == ErrNil {
err = nil
}
return err
case *int8:
if *p, err = r.ReadInt8(); err == ErrNil {
err = nil
}
return err
case *uint8:
if *p, err = r.ReadUint8(); err == ErrNil {
err = nil
}
return err
case *int16:
if *p, err = r.ReadInt16(); err == ErrNil {
err = nil
}
return err
case *uint16:
if *p, err = r.ReadUint16(); err == ErrNil {
err = nil
}
return err
case *int32:
if *p, err = r.ReadInt32(); err == ErrNil {
err = nil
}
return err
case *uint32:
if *p, err = r.ReadUint32(); err == ErrNil {
err = nil
}
return err
case *int64:
if *p, err = r.ReadInt64(); err == ErrNil {
err = nil
}
return err
case *uint64:
if *p, err = r.ReadUint64(); err == ErrNil {
err = nil
}
return err
case *big.Int:
if x, err := r.ReadBigInt(); err == ErrNil {
err = nil
*p = *x
} else {
*p = *x
}
return err
case *float32:
if *p, err = r.ReadFloat32(); err == ErrNil {
err = nil
}
return err
case *float64:
if *p, err = r.ReadFloat64(); err == ErrNil {
err = nil
}
return err
case *bool:
if *p, err = r.ReadBool(); err == ErrNil {
err = nil
}
return err
case *time.Time:
if *p, err = r.ReadDateTime(); err == ErrNil {
err = nil
}
return err
case *string:
if *p, err = r.ReadString(); err == ErrNil {
err = nil
}
return err
case *[]byte:
if x, err := r.ReadBytes(); err == ErrNil {
*p = *x
err = nil
} else {
*p = *x
}
return err
case *UUID:
if x, err := r.ReadUUID(); err == ErrNil {
*p = *x
err = nil
} else {
*p = *x
}
return err
case *list.List:
if x, err := r.ReadList(); err == ErrNil {
*p = *x
err = nil
} else {
*p = *x
}
return err
case **int:
if x, err := r.ReadInt(); err == ErrNil {
*p = nil
err = nil
} else {
*p = &x
}
return err
case **uint:
if x, err := r.ReadUint(); err == ErrNil {
*p = nil
err = nil
} else {
*p = &x
}
return err
case **int8:
if x, err := r.ReadInt8(); err == ErrNil {
*p = nil
err = nil
} else {
*p = &x
}
return err
case **uint8:
if x, err := r.ReadUint8(); err == ErrNil {
*p = nil
err = nil
} else {
*p = &x
}
return err
case **int16:
if x, err := r.ReadInt16(); err == ErrNil {
*p = nil
err = nil
} else {
*p = &x
}
return err
case **uint16:
if x, err := r.ReadUint16(); err == ErrNil {
*p = nil
err = nil
} else {
*p = &x
}
return err
case **int32:
if x, err := r.ReadInt32(); err == ErrNil {
*p = nil
err = nil
} else {
*p = &x
}
return err
case **uint32:
if x, err := r.ReadUint32(); err == ErrNil {
*p = nil
err = nil
} else {
*p = &x
}
return err
case **int64:
if x, err := r.ReadInt64(); err == ErrNil {
*p = nil
err = nil
} else {
*p = &x
}
return err
case **uint64:
if x, err := r.ReadUint64(); err == ErrNil {
*p = nil
err = nil
} else {
*p = &x
}
return err
case **big.Int:
if *p, err = r.ReadBigInt(); err == ErrNil {
*p = nil
err = nil
}
return err
case **float32:
if x, err := r.ReadFloat32(); err == ErrNil {
*p = nil
err = nil
} else {
*p = &x
}
return err
case **float64:
if x, err := r.ReadFloat64(); err == ErrNil {
*p = nil
err = nil
} else {
*p = &x
}
return err
case **bool:
if x, err := r.ReadBool(); err == ErrNil {
*p = nil
err = nil
} else {
*p = &x
}
return err
case **time.Time:
if x, err := r.ReadDateTime(); err == ErrNil {
*p = nil
err = nil
} else {
*p = &x
}
return err
case **string:
if x, err := r.ReadString(); err == ErrNil {
*p = nil
err = nil
} else {
*p = &x
}
return err
case **[]byte:
if *p, err = r.ReadBytes(); err == ErrNil {
*p = nil
err = nil
}
return err
case **UUID:
if *p, err = r.ReadUUID(); err == ErrNil {
*p = nil
err = nil
}
return err
case **list.List:
if *p, err = r.ReadList(); err == ErrNil {
*p = nil
err = nil
}
return err
case *interface{}:
if *p, err = r.readInterface(); err == ErrNil {
*p = nil
err = nil
}
return err
default:
v, err := r.checkPointer(p)
if err == nil {
return r.ReadValue(v.Elem())
}
}
return err
}
// ReadInteger from stream
func (r *Reader) ReadInteger(tag byte) (int, error) {
s := r.Stream
i := 0
b, err := s.ReadByte()
if err == nil && b == tag {
return i, nil
}
if err != nil {
return i, err
}
sign := 1
switch b {
case '-':
sign = -1
fallthrough
case '+':
b, err = s.ReadByte()
}
for b != tag && err == nil {
i *= 10
i += int(b-'0') * sign
b, err = s.ReadByte()
}
return i, err
}
// ReadUinteger from stream
func (r *Reader) ReadUinteger(tag byte) (uint, error) {
i, err := r.ReadInteger(tag)
return uint(i), err
}
// ReadInt from stream
func (r *Reader) ReadInt() (int, error) {
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return int(tag - '0'), nil
case TagInteger, TagLong:
return r.ReadIntWithoutTag()
case TagDouble:
f, err := r.ReadFloat64WithoutTag()
return int(f), err
case TagNull:
return 0, ErrNil
case TagEmpty, TagFalse:
return 0, nil
case TagTrue:
return 1, nil
case TagUTF8Char:
var str string
if str, err = r.readUTF8String(1); err == nil {
i, err := strconv.ParseInt(str, 10, 64)
return int(i), err
}
case TagString:
var str string
if str, err = r.ReadStringWithoutTag(); err == nil {
i, err := strconv.ParseInt(str, 10, 64)
return int(i), err
}
case TagRef:
var ref interface{}
if ref, err = r.readRef(r.ReadInteger(TagSemicolon)); err == nil {
if ref, ok := ref.(string); ok {
i, err := strconv.ParseInt(ref, 10, 64)
return int(i), err
}
return 0, errors.New("cannot convert type " +
reflect.TypeOf(ref).String() + " to type int")
}
default:
return 0, convertError(tag, "int")
}
}
return 0, err
}
// ReadIntWithoutTag from stream
func (r *Reader) ReadIntWithoutTag() (int, error) {
return r.ReadInteger(TagSemicolon)
}
// ReadUint from stream
func (r *Reader) ReadUint() (uint, error) {
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return uint(tag - '0'), nil
case TagInteger, TagLong:
return r.ReadUintWithoutTag()
case TagDouble:
f, err := r.ReadFloat64WithoutTag()
return uint(f), err
case TagNull:
return 0, ErrNil
case TagEmpty, TagFalse:
return 0, nil
case TagTrue:
return 1, nil
case TagUTF8Char:
var str string
if str, err = r.readUTF8String(1); err == nil {
i, err := strconv.ParseUint(str, 10, 64)
return uint(i), err
}
case TagString:
var str string
if str, err = r.ReadStringWithoutTag(); err == nil {
i, err := strconv.ParseUint(str, 10, 64)
return uint(i), err
}
case TagRef:
var ref interface{}
if ref, err = r.readRef(r.ReadInteger(TagSemicolon)); err == nil {
if ref, ok := ref.(string); ok {
i, err := strconv.ParseUint(ref, 10, 64)
return uint(i), err
}
return 0, errors.New("cannot convert type " +
reflect.TypeOf(ref).String() + " to type uint")
}
default:
return 0, convertError(tag, "uint")
}
}
return 0, err
}
// ReadUintWithoutTag from stream
func (r *Reader) ReadUintWithoutTag() (uint, error) {
return r.ReadUinteger(TagSemicolon)
}
// ReadInt64 from stream
func (r *Reader) ReadInt64() (int64, error) {
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return int64(tag - '0'), nil
case TagInteger, TagLong:
return r.ReadInt64WithoutTag()
case TagDouble:
f, err := r.ReadFloat64WithoutTag()
return int64(f), err
case TagNull:
return 0, ErrNil
case TagEmpty, TagFalse:
return 0, nil
case TagTrue:
return 1, nil
case TagUTF8Char:
var str string
if str, err = r.readUTF8String(1); err == nil {
return strconv.ParseInt(str, 10, 64)
}
case TagString:
var str string
if str, err = r.ReadStringWithoutTag(); err == nil {
return strconv.ParseInt(str, 10, 64)
}
case TagRef:
var ref interface{}
if ref, err = r.readRef(r.ReadInteger(TagSemicolon)); err == nil {
if ref, ok := ref.(string); ok {
return strconv.ParseInt(ref, 10, 64)
}
return 0, errors.New("cannot convert type " +
reflect.TypeOf(ref).String() + " to type int64")
}
default:
return 0, convertError(tag, "int64")
}
}
return 0, err
}
// ReadInt64WithoutTag from stream
func (r *Reader) ReadInt64WithoutTag() (int64, error) {
return r.readInt(TagSemicolon)
}
// ReadUint64 from stream
func (r *Reader) ReadUint64() (uint64, error) {
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return uint64(tag - '0'), nil
case TagInteger, TagLong:
return r.ReadUint64WithoutTag()
case TagDouble:
f, err := r.ReadFloat64WithoutTag()
return uint64(f), err
case TagNull:
return 0, ErrNil
case TagEmpty, TagFalse:
return 0, nil
case TagTrue:
return 1, nil
case TagUTF8Char:
var str string
if str, err = r.readUTF8String(1); err == nil {
return strconv.ParseUint(str, 10, 64)
}
case TagString:
var str string
if str, err = r.ReadStringWithoutTag(); err == nil {
return strconv.ParseUint(str, 10, 64)
}
case TagRef:
var ref interface{}
if ref, err = r.readRef(r.ReadInteger(TagSemicolon)); err == nil {
if ref, ok := ref.(string); ok {
return strconv.ParseUint(ref, 10, 64)
}
return 0, errors.New("cannot convert type " +
reflect.TypeOf(ref).String() + " to type uint64")
}
default:
return 0, convertError(tag, "uint64")
}
}
return 0, err
}
// ReadUint64WithoutTag from stream
func (r *Reader) ReadUint64WithoutTag() (uint64, error) {
return r.readUint(TagSemicolon)
}
// ReadInt8 from stream
func (r *Reader) ReadInt8() (int8, error) {
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return int8(tag - '0'), nil
case TagInteger, TagLong:
return r.ReadInt8WithoutTag()
case TagDouble:
f, err := r.ReadFloat64WithoutTag()
return int8(f), err
case TagNull:
return 0, ErrNil
case TagEmpty, TagFalse:
return 0, nil
case TagTrue:
return 1, nil
case TagUTF8Char:
var str string
if str, err = r.readUTF8String(1); err == nil {
i, err := strconv.ParseInt(str, 10, 64)
return int8(i), err
}
case TagString:
var str string
if str, err = r.ReadStringWithoutTag(); err == nil {
i, err := strconv.ParseInt(str, 10, 64)
return int8(i), err
}
case TagRef:
var ref interface{}
if ref, err = r.readRef(r.ReadInteger(TagSemicolon)); err == nil {
if ref, ok := ref.(string); ok {
i, err := strconv.ParseInt(ref, 10, 64)
return int8(i), err
}
return 0, errors.New("cannot convert type " +
reflect.TypeOf(ref).String() + " to type int8")
}
default:
return 0, convertError(tag, "int8")
}
}
return 0, err
}
// ReadInt8WithoutTag from stream
func (r *Reader) ReadInt8WithoutTag() (int8, error) {
return r.readInt8(TagSemicolon)
}
// ReadUint8 from stream
func (r *Reader) ReadUint8() (uint8, error) {
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return uint8(tag - '0'), nil
case TagInteger, TagLong:
return r.ReadUint8WithoutTag()
case TagDouble:
f, err := r.ReadFloat64WithoutTag()
return uint8(f), err
case TagNull:
return 0, ErrNil
case TagEmpty, TagFalse:
return 0, nil
case TagTrue:
return 1, nil
case TagUTF8Char:
var str string
if str, err = r.readUTF8String(1); err == nil {
i, err := strconv.ParseUint(str, 10, 64)
return uint8(i), err
}
case TagString:
var str string
if str, err = r.ReadStringWithoutTag(); err == nil {
i, err := strconv.ParseUint(str, 10, 64)
return uint8(i), err
}
case TagRef:
var ref interface{}
if ref, err = r.readRef(r.ReadInteger(TagSemicolon)); err == nil {
if ref, ok := ref.(string); ok {
i, err := strconv.ParseUint(ref, 10, 64)
return uint8(i), err
}
return 0, errors.New("cannot convert type " +
reflect.TypeOf(ref).String() + " to type uint8")
}
default:
return 0, convertError(tag, "uint8")
}
}
return 0, err
}
// ReadUint8WithoutTag from stream
func (r *Reader) ReadUint8WithoutTag() (uint8, error) {
return r.readUint8(TagSemicolon)
}
// ReadInt16 from stream
func (r *Reader) ReadInt16() (int16, error) {
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return int16(tag - '0'), nil
case TagInteger, TagLong:
return r.ReadInt16WithoutTag()
case TagDouble:
f, err := r.ReadFloat64WithoutTag()
return int16(f), err
case TagNull:
return 0, ErrNil
case TagEmpty, TagFalse:
return 0, nil
case TagTrue:
return 1, nil
case TagUTF8Char:
var str string
if str, err = r.readUTF8String(1); err == nil {
i, err := strconv.ParseInt(str, 10, 64)
return int16(i), err
}
case TagString:
var str string
if str, err = r.ReadStringWithoutTag(); err == nil {
i, err := strconv.ParseInt(str, 10, 64)
return int16(i), err
}
case TagRef:
var ref interface{}
if ref, err = r.readRef(r.ReadInteger(TagSemicolon)); err == nil {
if ref, ok := ref.(string); ok {
i, err := strconv.ParseInt(ref, 10, 64)
return int16(i), err
}
return 0, errors.New("cannot convert type " +
reflect.TypeOf(ref).String() + " to type int16")
}
default:
return 0, convertError(tag, "int16")
}
}
return 0, err
}
// ReadInt16WithoutTag from stream
func (r *Reader) ReadInt16WithoutTag() (int16, error) {
return r.readInt16(TagSemicolon)
}
// ReadUint16 from stream
func (r *Reader) ReadUint16() (uint16, error) {
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return uint16(tag - '0'), nil
case TagInteger, TagLong:
return r.ReadUint16WithoutTag()
case TagDouble:
f, err := r.ReadFloat64WithoutTag()
return uint16(f), err
case TagNull:
return 0, ErrNil
case TagEmpty, TagFalse:
return 0, nil
case TagTrue:
return 1, nil
case TagUTF8Char:
var str string
if str, err = r.readUTF8String(1); err == nil {
i, err := strconv.ParseUint(str, 10, 64)
return uint16(i), err
}
case TagString:
var str string
if str, err = r.ReadStringWithoutTag(); err == nil {
i, err := strconv.ParseUint(str, 10, 64)
return uint16(i), err
}
case TagRef:
var ref interface{}
if ref, err = r.readRef(r.ReadInteger(TagSemicolon)); err == nil {
if ref, ok := ref.(string); ok {
i, err := strconv.ParseUint(ref, 10, 64)
return uint16(i), err
}
return 0, errors.New("cannot convert type " +
reflect.TypeOf(ref).String() + " to type uint16")
}
default:
return 0, convertError(tag, "uint16")
}
}
return 0, err
}
// ReadUint16WithoutTag from stream
func (r *Reader) ReadUint16WithoutTag() (uint16, error) {
return r.readUint16(TagSemicolon)
}
// ReadInt32 from stream
func (r *Reader) ReadInt32() (int32, error) {
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return int32(tag - '0'), nil
case TagInteger, TagLong:
return r.ReadInt32WithoutTag()
case TagDouble:
f, err := r.ReadFloat64WithoutTag()
return int32(f), err
case TagNull:
return 0, ErrNil
case TagEmpty, TagFalse:
return 0, nil
case TagTrue:
return 1, nil
case TagUTF8Char:
var str string
if str, err = r.readUTF8String(1); err == nil {
i, err := strconv.ParseInt(str, 10, 64)
return int32(i), err
}
case TagString:
var str string
if str, err = r.ReadStringWithoutTag(); err == nil {
i, err := strconv.ParseInt(str, 10, 64)
return int32(i), err
}
case TagRef:
var ref interface{}
if ref, err = r.readRef(r.ReadInteger(TagSemicolon)); err == nil {
if ref, ok := ref.(string); ok {
i, err := strconv.ParseInt(ref, 10, 64)
return int32(i), err
}
return 0, errors.New("cannot convert type " +
reflect.TypeOf(ref).String() + " to type int32")
}
default:
return 0, convertError(tag, "int32")
}
}
return 0, err
}
// ReadInt32WithoutTag from stream
func (r *Reader) ReadInt32WithoutTag() (int32, error) {
return r.readInt32(TagSemicolon)
}
// ReadUint32 from stream
func (r *Reader) ReadUint32() (uint32, error) {
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return uint32(tag - '0'), nil
case TagInteger, TagLong:
return r.ReadUint32WithoutTag()
case TagDouble:
f, err := r.ReadFloat64WithoutTag()
return uint32(f), err
case TagNull:
return 0, ErrNil
case TagEmpty, TagFalse:
return 0, nil
case TagTrue:
return 1, nil
case TagUTF8Char:
var str string
if str, err = r.readUTF8String(1); err == nil {
i, err := strconv.ParseUint(str, 10, 64)
return uint32(i), err
}
case TagString:
var str string
if str, err = r.ReadStringWithoutTag(); err == nil {
i, err := strconv.ParseUint(str, 10, 64)
return uint32(i), err
}
case TagRef:
var ref interface{}
if ref, err = r.readRef(r.ReadInteger(TagSemicolon)); err == nil {
if ref, ok := ref.(string); ok {
i, err := strconv.ParseUint(ref, 10, 64)
return uint32(i), err
}
return 0, errors.New("cannot convert type " +
reflect.TypeOf(ref).String() + " to type uint32")
}
default:
return 0, convertError(tag, "uint32")
}
}
return 0, err
}
// ReadUint32WithoutTag from stream
func (r *Reader) ReadUint32WithoutTag() (uint32, error) {
return r.readUint32(TagSemicolon)
}
// ReadBigInt from stream
func (r *Reader) ReadBigInt() (*big.Int, error) {
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return big.NewInt(int64(tag - '0')), nil
case TagInteger, TagLong:
return r.ReadBigIntWithoutTag()
case TagDouble:
f, err := r.ReadFloat64WithoutTag()
return big.NewInt(int64(f)), err
case TagNull:
return big.NewInt(0), ErrNil
case TagEmpty, TagFalse:
return big.NewInt(0), nil
case TagTrue:
return big.NewInt(1), nil
case TagUTF8Char:
var str string
if str, err = r.readUTF8String(1); err == nil {
return stringToBigInt(str)
}
case TagString:
var str string
if str, err = r.ReadStringWithoutTag(); err == nil {
return stringToBigInt(str)
}
case TagRef:
var ref interface{}
if ref, err = r.readRef(r.ReadInteger(TagSemicolon)); err == nil {
if ref, ok := ref.(string); ok {
return stringToBigInt(ref)
}
return nil, errors.New("cannot convert type " +
reflect.TypeOf(ref).String() + " to type big.Int")
}
default:
return nil, convertError(tag, "big.Int")
}
}
return nil, err
}
// ReadBigIntWithoutTag from stream
func (r *Reader) ReadBigIntWithoutTag() (*big.Int, error) {
s := r.Stream
tag := TagSemicolon
i := big.NewInt(0)
b, err := s.ReadByte()
if err == nil && b == tag {
return i, nil
}
if err != nil {
return i, err
}
pos := true
switch b {
case '-':
pos = false
fallthrough
case '+':
b, err = s.ReadByte()
}
for b != tag && err == nil {
i = i.Mul(i, bigTen)
i = i.Add(i, bigDigit[b-'0'])
b, err = s.ReadByte()
}
if !pos {
i = i.Neg(i)
}
return i, err
}
// ReadFloat32 from stream
func (r *Reader) ReadFloat32() (float32, error) {
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return float32(tag - '0'), nil
case TagInteger, TagLong:
return r.readIntAsFloat32(TagSemicolon)
case TagDouble:
return r.ReadFloat32WithoutTag()
case TagNull:
return 0, ErrNil
case TagEmpty, TagFalse:
return 0, nil
case TagTrue:
return 1, nil
case TagNaN:
return float32(math.NaN()), nil
case TagInfinity:
f, err := r.readInfinity()
return float32(f), err
case TagUTF8Char:
var str string
if str, err = r.readUTF8String(1); err == nil {
f, err := strconv.ParseFloat(str, 32)
return float32(f), err
}
case TagString:
var str string
if str, err = r.ReadStringWithoutTag(); err == nil {
f, err := strconv.ParseFloat(str, 32)
return float32(f), err
}
case TagRef:
var ref interface{}
if ref, err = r.readRef(r.ReadInteger(TagSemicolon)); err == nil {
if ref, ok := ref.(string); ok {
f, err := strconv.ParseFloat(ref, 32)
return float32(f), err
}
return 0, errors.New("cannot convert type " +
reflect.TypeOf(ref).String() + " to type float32")
}
default:
return 0, convertError(tag, "float32")
}
}
return 0, err
}
// ReadFloat32WithoutTag from stream
func (r *Reader) ReadFloat32WithoutTag() (float32, error) {
str, err := r.readUntil(TagSemicolon)
if err != nil {
return float32(math.NaN()), err
}
f, _ := strconv.ParseFloat(str, 32)
return float32(f), nil
}
// ReadFloat64 from stream
func (r *Reader) ReadFloat64() (float64, error) {
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return float64(tag - '0'), nil
case TagInteger, TagLong:
return r.readIntAsFloat64(TagSemicolon)
case TagDouble:
return r.ReadFloat64WithoutTag()
case TagNull:
return 0, ErrNil
case TagEmpty, TagFalse:
return 0, nil
case TagTrue:
return 1, nil
case TagNaN:
return math.NaN(), nil
case TagInfinity:
return r.readInfinity()
case TagUTF8Char:
var str string
if str, err = r.readUTF8String(1); err == nil {
return strconv.ParseFloat(str, 64)
}
case TagString:
var str string
if str, err = r.ReadStringWithoutTag(); err == nil {
return strconv.ParseFloat(str, 64)
}
case TagRef:
var ref interface{}
if ref, err = r.readRef(r.ReadInteger(TagSemicolon)); err == nil {
if ref, ok := ref.(string); ok {
return strconv.ParseFloat(ref, 64)
}
return 0, errors.New("cannot convert type " +
reflect.TypeOf(ref).String() + " to type float64")
}
default:
return 0, convertError(tag, "float64")
}
}
return 0, err
}
// ReadFloat64WithoutTag from stream
func (r *Reader) ReadFloat64WithoutTag() (float64, error) {
str, err := r.readUntil(TagSemicolon)
if err != nil {
return math.NaN(), err
}
f, _ := strconv.ParseFloat(str, 64)
return f, nil
}
// ReadBool from stream
func (r *Reader) ReadBool() (bool, error) {
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case '0':
return false, nil
case '1', '2', '3', '4', '5', '6', '7', '8', '9':
return true, nil
case TagInteger, TagLong:
i, err := r.ReadInt64WithoutTag()
return i != 0, err
case TagDouble:
f, err := r.ReadFloat64WithoutTag()
return f != 0, err
case TagNull:
return false, ErrNil
case TagEmpty, TagFalse:
return false, nil
case TagTrue, TagNaN:
return true, nil
case TagInfinity:
_, err = r.readInfinity()
return true, err
case TagUTF8Char:
var str string
if str, err = r.readUTF8String(1); err == nil {
return strconv.ParseBool(str)
}
case TagString:
var str string
if str, err = r.ReadStringWithoutTag(); err == nil {
return strconv.ParseBool(str)
}
case TagRef:
var ref interface{}
if ref, err = r.readRef(r.ReadInteger(TagSemicolon)); err == nil {
if ref, ok := ref.(string); ok {
return strconv.ParseBool(ref)
}
return false, errors.New("cannot convert type " +
reflect.TypeOf(ref).String() + " to type bool")
}
default:
return false, convertError(tag, "bool")
}
}
return false, err
}
// ReadDateTime from stream
func (r *Reader) ReadDateTime() (time.Time, error) {
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case '0', TagEmpty:
return timeZero, nil
case TagNull:
return timeZero, ErrNil
case TagString:
var str string
if str, err = r.ReadStringWithoutTag(); err == nil {
return time.Parse(timeStringFormat, str)
}
case TagDate:
return r.ReadDateWithoutTag()
case TagTime:
return r.ReadTimeWithoutTag()
case TagRef:
var ref interface{}
if ref, err = r.readRef(r.ReadInteger(TagSemicolon)); err == nil {
switch ref := ref.(type) {
case time.Time:
return ref, nil
case string:
return time.Parse(timeStringFormat, ref)
default:
return timeZero, errors.New("cannot convert type " +
reflect.TypeOf(ref).String() + " to type time.Time")
}
}
default:
return timeZero, convertError(tag, "time.Time")
}
}
return timeZero, err
}
// ReadDateWithoutTag from stream
func (r *Reader) ReadDateWithoutTag() (time.Time, error) {
s := r.Stream
var year, month, day, hour, min, sec, nsec int
tag, err := s.ReadByte()
if err == nil {
year = int(tag - '0')
if tag, err = s.ReadByte(); err == nil {
year *= 10
year += int(tag - '0')
if tag, err = s.ReadByte(); err == nil {
year *= 10
year += int(tag - '0')
if tag, err = s.ReadByte(); err == nil {
year *= 10
year += int(tag - '0')
if tag, err = s.ReadByte(); err == nil {
month = int(tag - '0')
if tag, err = s.ReadByte(); err == nil {
month *= 10
month += int(tag - '0')
if tag, err = s.ReadByte(); err == nil {
day = int(tag - '0')
if tag, err = s.ReadByte(); err == nil {
day *= 10
day += int(tag - '0')
tag, err = s.ReadByte()
}
}
}
}
}
}
}
}
if err != nil {
return timeZero, err
}
if tag == TagTime {
if hour, min, sec, nsec, tag, err = r.readTime(); err != nil {
return timeZero, err
}
}
var loc *time.Location
if tag == TagUTC {
loc = time.UTC
} else if tag == TagSemicolon {
loc = time.Local
} else {
return timeZero, unexpectedTag(tag, []byte{TagUTC, TagSemicolon})
}
d := time.Date(year, time.Month(month), day, hour, min, sec, nsec, loc)
r.setRef(d)
return d, nil
}
// ReadTimeWithoutTag from stream
func (r *Reader) ReadTimeWithoutTag() (time.Time, error) {
hour, min, sec, nsec, tag, err := r.readTime()
if err != nil {
return timeZero, err
}
var loc *time.Location
if tag == TagUTC {
loc = time.UTC
} else if tag == TagSemicolon {
loc = time.Local
} else {
return timeZero, unexpectedTag(tag, []byte{TagUTC, TagSemicolon})
}
t := time.Date(1970, 1, 1, hour, min, sec, nsec, loc)
r.setRef(t)
return t, nil
}
// ReadString from stream
func (r *Reader) ReadString() (string, error) {
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return string([]byte{tag}), nil
case TagInteger, TagLong, TagDouble:
return r.readUntil(TagSemicolon)
case TagNull:
return "", ErrNil
case TagEmpty:
return "", nil
case TagTrue:
return "true", nil
case TagFalse:
return "false", nil
case TagNaN:
return "NaN", nil
case TagInfinity:
if sign, err := s.ReadByte(); err == nil {
return string([]byte{sign}) + "Inf", nil
}
return "Inf", err
case TagDate:
d, err := r.ReadDateWithoutTag()
return d.String(), err
case TagTime:
t, err := r.ReadTimeWithoutTag()
return t.String(), err
case TagUTF8Char:
return r.readUTF8String(1)
case TagString:
return r.ReadStringWithoutTag()
case TagGuid:
u, err := r.ReadUUIDWithoutTag()
return u.String(), err
case TagBytes:
if b, err := r.ReadBytesWithoutTag(); err == nil {
if !utf8.Valid(*b) {
err = errBadEncode
}
return string(*b), err
}
case TagRef:
var ref interface{}
if ref, err = r.readRef(r.ReadInteger(TagSemicolon)); err == nil {
if ref, ok := ref.(string); ok {
return ref, nil
}
return "", errors.New("cannot convert type " +
reflect.TypeOf(ref).String() + " to type string")
}
default:
return "", convertError(tag, "string")
}
}
return "", err
}
// ReadStringWithoutTag from stream
func (r *Reader) ReadStringWithoutTag() (str string, err error) {
if str, err = r.readStringWithoutTag(); err == nil {
r.setRef(str)
}
return str, err
}
// ReadBytes from stream
func (r *Reader) ReadBytes() (*[]byte, error) {
bytes := new([]byte)
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case TagNull:
return bytes, ErrNil
case TagEmpty:
return bytes, nil
case TagUTF8Char:
c, err := r.readUTF8String(1)
*bytes = []byte(c)
return bytes, err
case TagString:
str, err := r.ReadStringWithoutTag()
*bytes = []byte(str)
return bytes, err
case TagGuid:
u, err := r.ReadUUIDWithoutTag()
*bytes = []byte(*u)
return bytes, err
case TagBytes:
return r.ReadBytesWithoutTag()
case TagList:
err = r.ReadSliceWithoutTag(bytes)
return bytes, err
case TagRef:
var ref interface{}
if ref, err = r.readRef(r.ReadInteger(TagSemicolon)); err == nil {
if ref, ok := ref.(*[]byte); ok {
return ref, nil
}
return bytes, errors.New("cannot convert type " +
reflect.TypeOf(ref).String() + " to type bytes")
}
default:
return bytes, convertError(tag, "bytes")
}
}
return bytes, err
}
// ReadBytesWithoutTag from stream
func (r *Reader) ReadBytesWithoutTag() (*[]byte, error) {
s := r.Stream
length, err := r.ReadInteger(TagQuote)
if err != nil {
return new([]byte), err
}
b := make([]byte, length)
if _, err = s.Read(b); err == nil {
err = r.CheckTag(TagQuote)
}
r.setRef(&b)
return &b, err
}
// ReadUUID from stream
func (r *Reader) ReadUUID() (*UUID, error) {
uuid := new(UUID)
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case TagNull:
return uuid, ErrNil
case TagString:
str, err := r.ReadStringWithoutTag()
*uuid = ToUUID(str)
return uuid, err
case TagGuid:
return r.ReadUUIDWithoutTag()
case TagBytes:
if b, err := r.ReadBytesWithoutTag(); err == nil {
if len(*b) == 16 {
uuid = (*UUID)(b)
return uuid, nil
}
return uuid, convertError(TagBytes, "UUID")
}
return uuid, err
case TagRef:
var ref interface{}
if ref, err = r.readRef(r.ReadInteger(TagSemicolon)); err == nil {
if ref, ok := ref.(*UUID); ok {
return ref, nil
}
return uuid, errors.New("cannot convert type " +
reflect.TypeOf(ref).String() + " to type UUID")
}
default:
return uuid, convertError(tag, "UUID")
}
}
return uuid, err
}
// ReadUUIDWithoutTag from stream
func (r *Reader) ReadUUIDWithoutTag() (*UUID, error) {
s := r.Stream
err := r.CheckTag(TagOpenbrace)
if err == nil {
b := make([]byte, 36)
if _, err = s.Read(b); err == nil {
err = r.CheckTag(TagClosebrace)
u := ToUUID(string(b))
r.setRef(&u)
return &u, err
}
}
return new(UUID), err
}
// ReadList from stream
func (r *Reader) ReadList() (*list.List, error) {
l := list.New()
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case TagNull:
return l, ErrNil
case TagList:
return r.ReadListWithoutTag()
case TagRef:
var ref interface{}
if ref, err = r.readRef(r.ReadInteger(TagSemicolon)); err == nil {
if ref, ok := ref.(*list.List); ok {
return ref, nil
}
return l, errors.New("cannot convert type " +
reflect.TypeOf(ref).String() + " to type List")
}
default:
return l, convertError(tag, "List")
}
}
return l, err
}
// ReadListWithoutTag from stream
func (r *Reader) ReadListWithoutTag() (*list.List, error) {
l := list.New()
r.setRef(l)
length, err := r.ReadInteger(TagOpenbrace)
if err == nil {
for i := 0; i < length; i++ {
if e, err := r.readInterface(); err == nil {
l.PushBack(e)
} else {
return l, err
}
}
if err = r.CheckTag(TagClosebrace); err == nil {
return l, nil
}
}
return l, err
}
// ReadArray from stream
func (r *Reader) ReadArray(a []reflect.Value) error {
length := len(a)
r.setRef(&a)
for i := 0; i < length; i++ {
if err := r.ReadValue(a[i]); err != nil {
return err
}
}
return r.CheckTag(TagClosebrace)
}
// ReadSlice from stream
func (r *Reader) ReadSlice(p interface{}) error {
v, err := r.checkPointer(p)
if err == nil {
return r.readSlice(v.Elem())
}
return err
}
// ReadSliceWithoutTag from stream
func (r *Reader) ReadSliceWithoutTag(p interface{}) error {
v, err := r.checkPointer(p)
if err == nil {
return r.readSliceWithoutTag(v.Elem())
}
return err
}
// ReadMap from stream
func (r *Reader) ReadMap(p interface{}) error {
v, err := r.checkPointer(p)
if err == nil {
return r.readMap(v.Elem())
}
return err
}
// ReadMapWithoutTag from stream
func (r *Reader) ReadMapWithoutTag(p interface{}) error {
v, err := r.checkPointer(p)
if err == nil {
return r.readMapWithoutTag(v.Elem())
}
return err
}
// ReadObject from stream
func (r *Reader) ReadObject(p interface{}) error {
v, err := r.checkPointer(p)
if err == nil {
return r.readObject(v.Elem())
}
return err
}
// ReadObjectWithoutTag from stream
func (r *Reader) ReadObjectWithoutTag(p interface{}) error {
v, err := r.checkPointer(p)
if err == nil {
return r.readObjectWithoutTag(v.Elem())
}
return err
}
// Reset the serialize reference count
func (r *Reader) Reset() {
if r.classref != nil {
r.classref = r.classref[:0]
r.fieldsref = r.fieldsref[:0]
}
r.resetRef()
}
// ReadValue from stream
func (r *Reader) ReadValue(v reflect.Value) error {
t := v.Type()
switch t.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return r.readInt64(v)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return r.readUint64(v)
case reflect.Bool:
return r.readBool(v)
case reflect.Float32:
return r.readFloat32(v)
case reflect.Float64:
return r.readFloat64(v)
case reflect.String:
return r.readString(v)
case reflect.Slice:
if t.Name() == "UUID" {
return r.readUUID(v)
}
if t.Elem().Kind() == reflect.Uint8 {
return r.readBytes(v)
}
return r.readSlice(v)
case reflect.Map:
return r.readMap(v)
case reflect.Struct:
switch t.Name() {
case "Time":
return r.readDateTime(v)
case "Int":
return r.readBigInt(v)
case "List":
return r.readList(v)
}
return r.readObject(v)
case reflect.Interface:
p, err := r.readInterface()
if err == nil {
t := v.Type()
rv := reflect.ValueOf(&p).Elem()
rt := rv.Type()
if rt.AssignableTo(t) {
v.Set(rv)
} else if rt.ConvertibleTo(t) {
v.Set(rv.Convert(t))
}
}
return err
case reflect.Ptr:
switch t := t.Elem(); t.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return r.readInt64Pointer(v)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return r.readUint64Pointer(v)
case reflect.Bool:
return r.readBoolPointer(v)
case reflect.Float32:
return r.readFloat32Pointer(v)
case reflect.Float64:
return r.readFloat64Pointer(v)
case reflect.String:
return r.readStringPointer(v)
case reflect.Slice:
if t.Name() == "UUID" {
return r.readUUIDPointer(v)
}
if t.Elem().Kind() == reflect.Uint8 {
return r.readBytesPointer(v)
}
return r.readSlice(v)
case reflect.Map:
return r.readMap(v)
case reflect.Struct:
switch t.Name() {
case "Time":
return r.readDateTimePointer(v)
case "Int":
return r.readBigIntPointer(v)
case "List":
return r.readListPointer(v)
}
return r.readObject(v)
case reflect.Interface:
p, err := r.readInterface()
if err == nil {
t := v.Type()
rp := reflect.ValueOf(&p)
rt := rp.Type()
if rt.AssignableTo(t) {
v.Set(rp)
} else if rt.ConvertibleTo(t) {
v.Set(rp.Convert(t))
} else if rt.Elem().ConvertibleTo(t.Elem()) {
v.Set(reflect.New(t.Elem()))
v.Elem().Set(rp.Elem().Convert(t.Elem()))
}
}
return err
}
}
return errors.New("unsupported Type:" + t.String())
}
// private methods
func (r *Reader) checkPointer(p interface{}) (v reflect.Value, err error) {
v = reflect.ValueOf(p)
if v.Kind() != reflect.Ptr {
return v, errors.New("argument p must be a pointer")
}
return v, nil
}
func (r *Reader) readInterface() (interface{}, error) {
s := r.Stream
tag, err := s.ReadByte()
if err == nil {
switch tag {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return int(tag - '0'), nil
case TagInteger:
return r.ReadIntWithoutTag()
case TagLong:
return r.ReadBigIntWithoutTag()
case TagDouble:
return r.ReadFloat64WithoutTag()
case TagNull:
return nil, nil
case TagEmpty:
return "", nil
case TagTrue:
return true, nil
case TagFalse:
return false, nil
case TagNaN:
return math.NaN(), nil
case TagInfinity:
return r.readInfinity()
case TagDate:
return r.ReadDateWithoutTag()
case TagTime:
return r.ReadTimeWithoutTag()
case TagBytes:
return r.ReadBytesWithoutTag()
case TagUTF8Char:
return r.readUTF8String(1)
case TagString:
return r.ReadStringWithoutTag()
case TagGuid:
return r.ReadUUIDWithoutTag()
case TagList:
var e *[]interface{}
err := r.ReadSliceWithoutTag(&e)
return e, err
case TagMap:
if r.JSONCompatible {
var e *map[string]interface{}
err := r.ReadMapWithoutTag(&e)
return e, err
}
var e *map[interface{}]interface{}
err := r.ReadMapWithoutTag(&e)
return e, err
case TagClass:
err := r.readClass()
if err == nil {
var e interface{}
err := r.ReadObject(&e)
return e, err
}
return nil, err
case TagObject:
var e interface{}
err := r.ReadObjectWithoutTag(&e)
return e, err
case TagRef:
return r.readRef(r.ReadInteger(TagSemicolon))
}
return nil, unexpectedTag(tag, nil)
}
return nil, err
}
func (r *Reader) readUntil(tag byte) (string, error) {
s, err := r.Stream.ReadString(tag)
if err != nil {
return s, err
}
return s[:len(s)-1], nil
}
func (r *Reader) readInt(tag byte) (int64, error) {
s := r.Stream
i := int64(0)
b, err := s.ReadByte()
if err == nil && b == tag {
return i, nil
}
if err != nil {
return i, err
}
sign := int64(1)
switch b {
case '-':
sign = -1
fallthrough
case '+':
b, err = s.ReadByte()
}
for b != tag && err == nil {
i *= 10
i += int64(b-'0') * sign
b, err = s.ReadByte()
}
return i, err
}
func (r *Reader) readUint(tag byte) (uint64, error) {
i, err := r.readInt(tag)
return uint64(i), err
}
func (r *Reader) readInt8(tag byte) (int8, error) {
s := r.Stream
i := int8(0)
b, err := s.ReadByte()
if err == nil && b == tag {
return i, nil
}
if err != nil {
return i, err
}
sign := int8(1)
switch b {
case '-':
sign = -1
fallthrough
case '+':
b, err = s.ReadByte()
}
for b != tag && err == nil {
i *= 10
i += int8(b-'0') * sign
b, err = s.ReadByte()
}
return i, err
}
func (r *Reader) readUint8(tag byte) (uint8, error) {
i, err := r.readInt8(tag)
return uint8(i), err
}
func (r *Reader) readInt16(tag byte) (int16, error) {
s := r.Stream
i := int16(0)
b, err := s.ReadByte()
if err == nil && b == tag {
return i, nil
}
if err != nil {
return i, err
}
sign := int16(1)
switch b {
case '-':
sign = -1
fallthrough
case '+':
b, err = s.ReadByte()
}
for b != tag && err == nil {
i *= 10
i += int16(b-'0') * sign
b, err = s.ReadByte()
}
return i, err
}
func (r *Reader) readUint16(tag byte) (uint16, error) {
i, err := r.readInt16(tag)
return uint16(i), err
}
func (r *Reader) readInt32(tag byte) (int32, error) {
s := r.Stream
i := int32(0)
b, err := s.ReadByte()
if err == nil && b == tag {
return i, nil
}
if err != nil {
return i, err
}
sign := int32(1)
switch b {
case '-':
sign = -1
fallthrough
case '+':
b, err = s.ReadByte()
}
for b != tag && err == nil {
i *= 10
i += int32(b-'0') * sign
b, err = s.ReadByte()
}
return i, err
}
func (r *Reader) readUint32(tag byte) (uint32, error) {
i, err := r.readInt32(tag)
return uint32(i), err
}
func (r *Reader) readIntAsFloat64(tag byte) (float64, error) {
s := r.Stream
f := float64(0)
b, err := s.ReadByte()
if err == nil && b == tag {
return f, nil
}
if err != nil {
return f, err
}
sign := float64(1)
switch b {
case '-':
sign = -1
fallthrough
case '+':
b, err = s.ReadByte()
}
for b != tag && err == nil {
f *= 10
f += float64(b-'0') * sign
b, err = s.ReadByte()
}
return f, err
}
func (r *Reader) readIntAsFloat32(tag byte) (float32, error) {
f, err := r.readIntAsFloat64(tag)
return float32(f), err
}
func (r *Reader) readInfinity() (float64, error) {
if sign, err := r.Stream.ReadByte(); err == nil {
switch sign {
case '+':
return math.Inf(1), nil
case '-':
return math.Inf(-1), nil
default:
return math.NaN(), unexpectedTag(sign, []byte{'+', '-'})
}
} else {
return math.NaN(), err
}
}
func (r *Reader) readTime() (hour int, min int, sec int, nsec int, tag byte, err error) {
s := r.Stream
if tag, err = s.ReadByte(); err == nil {
hour = int(tag - '0')
if tag, err = s.ReadByte(); err == nil {
hour *= 10
hour += int(tag - '0')
if tag, err = s.ReadByte(); err == nil {
min = int(tag - '0')
if tag, err = s.ReadByte(); err == nil {
min *= 10
min += int(tag - '0')
if tag, err = s.ReadByte(); err == nil {
sec = int(tag - '0')
if tag, err = s.ReadByte(); err == nil {
sec *= 10
sec += int(tag - '0')
tag, err = s.ReadByte()
}
}
}
}
}
}
if err != nil {
return hour, min, sec, nsec, tag, err
}
if tag == TagPoint {
if tag, err = s.ReadByte(); err == nil {
nsec = int(tag - '0')
if tag, err = s.ReadByte(); err == nil {
nsec *= 10
nsec += int(tag - '0')
if tag, err = s.ReadByte(); err == nil {
nsec *= 10
nsec += int(tag - '0')
tag, err = s.ReadByte()
}
}
}
if err != nil {
return hour, min, sec, nsec, tag, err
}
if tag >= '0' && tag <= '9' {
nsec *= 10
nsec += int(tag - '0')
if tag, err = s.ReadByte(); err == nil {
nsec *= 10
nsec += int(tag - '0')
if tag, err = s.ReadByte(); err == nil {
nsec *= 10
nsec += int(tag - '0')
tag, err = s.ReadByte()
}
}
} else {
nsec *= 1000
}
if err != nil {
return hour, min, sec, nsec, tag, err
}
if tag >= '0' && tag <= '9' {
nsec *= 10
nsec += int(tag - '0')
if tag, err = s.ReadByte(); err == nil {
nsec *= 10
nsec += int(tag - '0')
if tag, err = s.ReadByte(); err == nil {
nsec *= 10
nsec += int(tag - '0')
tag, err = s.ReadByte()
}
}
} else {
nsec *= 1000
}
}
return hour, min, sec, nsec, tag, err
}
func (r *Reader) readStringWithoutTag() (str string, err error) {
var length int
if length, err = r.ReadInteger(TagQuote); err == nil {
if str, err = r.readUTF8String(length); err == nil {
err = r.CheckTag(TagQuote)
}
}
return str, err
}
func (r *Reader) readInt64(v reflect.Value) error {
x, err := r.ReadInt64()
if err == nil || err == ErrNil {
v.SetInt(x)
return nil
}
return err
}
func (r *Reader) readUint64(v reflect.Value) error {
x, err := r.ReadUint64()
if err == nil || err == ErrNil {
v.SetUint(x)
return nil
}
return err
}
func (r *Reader) readBool(v reflect.Value) error {
x, err := r.ReadBool()
if err == nil || err == ErrNil {
v.SetBool(x)
return nil
}
return err
}
func (r *Reader) readFloat32(v reflect.Value) error {
x, err := r.ReadFloat32()
if err == nil || err == ErrNil {
v.SetFloat(float64(x))
return nil
}
return err
}
func (r *Reader) readFloat64(v reflect.Value) error {
x, err := r.ReadFloat64()
if err == nil || err == ErrNil {
v.SetFloat(x)
return nil
}
return err
}
func (r *Reader) readBigInt(v reflect.Value) error {
x, err := r.ReadBigInt()
if err == nil || err == ErrNil {
v.Set(reflect.ValueOf(*x))
return nil
}
return err
}
func (r *Reader) readDateTime(v reflect.Value) error {
x, err := r.ReadDateTime()
if err == nil || err == ErrNil {
v.Set(reflect.ValueOf(x))
return nil
}
return err
}
func (r *Reader) readString(v reflect.Value) error {
x, err := r.ReadString()
if err == nil || err == ErrNil {
v.SetString(x)
return nil
}
return err
}
func (r *Reader) readBytes(v reflect.Value) error {
x, err := r.ReadBytes()
if err == nil || err == ErrNil {
v.Set(reflect.ValueOf(*x))
return nil
}
return err
}
func (r *Reader) readUUID(v reflect.Value) error {
x, err := r.ReadUUID()
if err == nil || err == ErrNil {
v.Set(reflect.ValueOf(*x))
return nil
}
return err
}
func (r *Reader) readList(v reflect.Value) error {
x, err := r.ReadList()
if err == nil || err == ErrNil {
v.Set(reflect.ValueOf(*x))
return nil
}
return err
}
func (r *Reader) getRef(v reflect.Value) error {
t := v.Type()
ref, err := r.readRef(r.ReadInteger(TagSemicolon))
if err != nil {
return err
}
refValue := reflect.ValueOf(ref)
refType := refValue.Type()
if refType.Kind() == reflect.Ptr {
if refType.AssignableTo(t) {
v.Set(refValue)
return nil
}
if refType.Elem().AssignableTo(t) {
v.Set(refValue.Elem())
return nil
}
}
return errors.New("cannot convert type " +
refType.String() + " to type " + t.String())
}
func (r *Reader) readSlice(v reflect.Value) error {
s := r.Stream
t := v.Type()
tag, err := s.ReadByte()
if err == nil {
switch tag {
case TagNull:
v.Set(reflect.Zero(t))
return nil
case TagList:
return r.readSliceWithoutTag(v)
case TagRef:
return r.getRef(v)
}
return convertError(tag, v.Type().String())
}
return err
}
func (r *Reader) readSliceWithoutTag(v reflect.Value) error {
t := v.Type()
switch t.Kind() {
case reflect.Slice:
case reflect.Interface:
t = reflect.TypeOf([]interface{}(nil))
case reflect.Ptr:
switch t = t.Elem(); t.Kind() {
case reflect.Slice:
case reflect.Interface:
t = reflect.TypeOf([]interface{}(nil))
default:
return errors.New("cannot convert slice to type " + t.String())
}
default:
return errors.New("cannot convert slice to type " + t.String())
}
slicePointer := reflect.New(t)
r.setRef(slicePointer.Interface())
slice := slicePointer.Elem()
length, err := r.ReadInteger(TagOpenbrace)
if err == nil {
slice.Set(reflect.MakeSlice(t, length, length))
for i := 0; i < length; i++ {
elem := slice.Index(i)
if err := r.ReadValue(elem); err != nil {
return err
}
}
if err = r.CheckTag(TagClosebrace); err == nil {
switch t := v.Type(); t.Kind() {
case reflect.Slice:
v.Set(slice)
case reflect.Interface:
v.Set(slicePointer)
case reflect.Ptr:
switch t.Elem().Kind() {
case reflect.Slice:
v.Set(slicePointer)
case reflect.Interface:
v.Set(reflect.New(t.Elem()))
v.Elem().Set(slicePointer)
}
}
return nil
}
}
return err
}
func (r *Reader) readSliceAsMap(v reflect.Value) error {
t := v.Type()
switch t.Kind() {
case reflect.Map:
break
case reflect.Interface:
if r.JSONCompatible {
t = soMapType
} else {
t = ooMapType
}
case reflect.Ptr:
switch t = t.Elem(); t.Kind() {
case reflect.Map:
break
case reflect.Interface:
if r.JSONCompatible {
t = soMapType
} else {
t = ooMapType
}
default:
return errors.New("cannot convert slice to type " + t.String())
}
default:
return errors.New("cannot convert slice to type " + t.String())
}
mPointer := reflect.New(t)
r.setRef(mPointer.Interface())
m := mPointer.Elem()
length, err := r.ReadInteger(TagOpenbrace)
if err == nil {
m.Set(reflect.MakeMap(t))
for i := 0; i < length; i++ {
key := reflect.New(t.Key()).Elem()
val := reflect.New(t.Elem()).Elem()
switch t.Key().Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
key.SetInt(int64(i))
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
key.SetUint(uint64(i))
case reflect.Float32, reflect.Float64:
key.SetFloat(float64(i))
case reflect.String:
key.SetString(strconv.Itoa(i))
case reflect.Interface:
key.Set(reflect.ValueOf(i))
default:
return errors.New("cannot convert int to type " + t.Key().String())
}
if err := r.ReadValue(val); err != nil {
return err
}
m.SetMapIndex(key, val)
}
if err = r.CheckTag(TagClosebrace); err == nil {
switch t := v.Type(); t.Kind() {
case reflect.Map:
v.Set(m)
case reflect.Interface:
v.Set(mPointer)
case reflect.Ptr:
switch t.Elem().Kind() {
case reflect.Map:
v.Set(mPointer)
case reflect.Interface:
v.Set(reflect.New(t.Elem()))
v.Elem().Set(mPointer)
}
}
return nil
}
}
return err
}
func (r *Reader) readMap(v reflect.Value) error {
s := r.Stream
t := v.Type()
tag, err := s.ReadByte()
if err == nil {
switch tag {
case TagNull:
v.Set(reflect.Zero(t))
return nil
case TagList:
return r.readSliceAsMap(v)
case TagMap:
return r.readMapWithoutTag(v)
case TagClass:
if err = r.readClass(); err == nil {
return r.readMap(v)
}
return err
case TagObject:
return r.readObjectWithoutTag(v)
case TagRef:
return r.getRef(v)
}
return convertError(tag, v.Type().String())
}
return err
}
func (r *Reader) readMapWithoutTag(v reflect.Value) error {
t := v.Type()
switch t.Kind() {
case reflect.Struct:
return r.readMapAsObject(v)
case reflect.Map:
break
case reflect.Interface:
if r.JSONCompatible {
t = soMapType
} else {
t = ooMapType
}
case reflect.Ptr:
switch t = t.Elem(); t.Kind() {
case reflect.Struct:
return r.readMapAsObject(v)
case reflect.Map:
break
case reflect.Interface:
if r.JSONCompatible {
t = soMapType
} else {
t = ooMapType
}
default:
return errors.New("cannot convert map to type " + t.String())
}
default:
return errors.New("cannot convert map to type " + t.String())
}
mPointer := reflect.New(t)
r.setRef(mPointer.Interface())
m := mPointer.Elem()
length, err := r.ReadInteger(TagOpenbrace)
if err == nil {
m.Set(reflect.MakeMap(t))
tk := t.Key()
tv := t.Elem()
for i := 0; i < length; i++ {
key := reflect.New(tk).Elem()
val := reflect.New(tv).Elem()
if err := r.ReadValue(key); err != nil {
return err
}
if err := r.ReadValue(val); err != nil {
return err
}
m.SetMapIndex(key, val)
}
if err = r.CheckTag(TagClosebrace); err == nil {
switch t := v.Type(); t.Kind() {
case reflect.Map:
v.Set(m)
case reflect.Interface:
v.Set(mPointer)
case reflect.Ptr:
switch t.Elem().Kind() {
case reflect.Map:
v.Set(mPointer)
case reflect.Interface:
v.Set(reflect.New(t.Elem()))
v.Elem().Set(mPointer)
}
}
return nil
}
}
return err
}
func (r *Reader) readMapAsObject(v reflect.Value) error {
t := v.Type()
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
objPointer := reflect.New(t)
r.setRef(objPointer.Interface())
obj := objPointer.Elem()
count, err := r.ReadInteger(TagOpenbrace)
if err == nil {
indexMap := getIndexCache(t)
for i := 0; i < count; i++ {
key, err := r.ReadString()
if err != nil {
return err
}
if index, ok := indexMap[strings.ToLower(key)]; ok {
f := obj.Field(index[0])
n := len(index)
for j := 1; j < n; j++ {
if f.Kind() == reflect.Ptr {
f.Set(reflect.New(f.Type().Elem()))
f = f.Elem()
}
f = f.Field(index[j])
}
err = r.ReadValue(f)
} else {
_, err = r.readInterface()
}
if err != nil {
return err
}
}
if err = r.CheckTag(TagClosebrace); err == nil {
switch t := v.Type(); t.Kind() {
case reflect.Struct:
v.Set(obj)
case reflect.Interface:
v.Set(objPointer)
case reflect.Ptr:
switch t.Elem().Kind() {
case reflect.Struct:
v.Set(objPointer)
case reflect.Interface:
v.Set(reflect.New(t.Elem()))
v.Elem().Set(objPointer)
}
}
return nil
}
}
return err
}
func (r *Reader) readObject(v reflect.Value) error {
s := r.Stream
t := v.Type()
tag, err := s.ReadByte()
if err == nil {
switch tag {
case TagNull:
v.Set(reflect.Zero(t))
return nil
case TagMap:
return r.readMapWithoutTag(v)
case TagClass:
if err = r.readClass(); err == nil {
return r.readObject(v)
}
return err
case TagObject:
return r.readObjectWithoutTag(v)
case TagRef:
return r.getRef(v)
}
return convertError(tag, v.Type().String())
}
return err
}
func (r *Reader) readObjectAsMap(v reflect.Value, index int) error {
t := soMapType
mPointer := reflect.New(t)
r.setRef(mPointer.Interface())
m := mPointer.Elem()
m.Set(reflect.MakeMap(t))
fields := r.fieldsref[index]
length := len(fields)
tk := t.Key()
tv := t.Elem()
for i := 0; i < length; i++ {
key := reflect.New(tk).Elem()
val := reflect.New(tv).Elem()
key.SetString(fields[i])
if err := r.ReadValue(val); err != nil {
return err
}
m.SetMapIndex(key, val)
}
err := r.CheckTag(TagClosebrace)
if err == nil {
switch t := v.Type(); t.Kind() {
case reflect.Map:
v.Set(m)
case reflect.Interface:
v.Set(mPointer)
case reflect.Ptr:
switch t.Elem().Kind() {
case reflect.Map:
v.Set(mPointer)
case reflect.Interface:
v.Set(reflect.New(t.Elem()))
v.Elem().Set(mPointer)
}
}
}
return err
}
func (r *Reader) readObjectWithoutTag(v reflect.Value) error {
t := v.Type()
kind := t.Kind()
index, err := r.ReadInteger(TagOpenbrace)
if err != nil {
return err
}
key := r.classref[index]
class, ok := key.(reflect.Type)
if !ok {
if kind == reflect.Struct {
class = t
} else if kind == reflect.Ptr && t.Elem().Kind() == reflect.Struct {
class = t.Elem()
} else {
class = soMapType
}
} else {
if t == soMapType || (kind == reflect.Ptr && t.Elem() == soMapType) {
class = soMapType
}
}
assignable := class.AssignableTo(t)
if kind == reflect.Ptr {
assignable = class.AssignableTo(t.Elem())
}
if !assignable {
return errors.New("cannot convert type " + class.String() + " to type " + t.String())
}
if class.Kind() == reflect.Map {
return r.readObjectAsMap(v, index)
}
objPointer := reflect.New(class)
r.setRef(objPointer.Interface())
obj := objPointer.Elem()
fields := r.fieldsref[index]
indexMap := getIndexCache(class)
count := len(fields)
for i := 0; i < count; i++ {
if index, ok := indexMap[strings.ToLower(fields[i])]; ok {
f := obj.Field(index[0])
n := len(index)
for j := 1; j < n; j++ {
if f.Kind() == reflect.Ptr {
f.Set(reflect.New(f.Type().Elem()))
f = f.Elem()
}
f = f.Field(index[j])
}
err = r.ReadValue(f)
} else {
_, err = r.readInterface()
}
if err != nil {
return err
}
}
if err = r.CheckTag(TagClosebrace); err == nil {
switch kind {
case reflect.Struct:
v.Set(obj)
case reflect.Interface:
v.Set(objPointer)
case reflect.Ptr:
switch t := t.Elem(); t.Kind() {
case reflect.Struct:
v.Set(objPointer)
case reflect.Interface:
v.Set(reflect.New(t))
v.Elem().Set(objPointer)
}
}
return nil
}
return err
}
func (r *Reader) readClass() error {
className, err := r.readStringWithoutTag()
if err != nil {
return err
}
count, err := r.ReadInteger(TagOpenbrace)
if err != nil {
return err
}
fields := make([]string, count)
for i := 0; i < count; i++ {
if fields[i], err = r.ReadString(); err != nil {
return err
}
}
if err = r.CheckTag(TagClosebrace); err != nil {
return err
}
class := ClassManager.GetClass(className)
if r.classref == nil {
r.classref = make([]interface{}, 0)
r.fieldsref = make([][]string, 0)
}
var key interface{} = class
if class == nil {
key = len(r.classref)
}
r.classref = append(r.classref, key)
r.fieldsref = append(r.fieldsref, fields)
return nil
}
func (r *Reader) readPointer(v reflect.Value, getValue func() (interface{}, error), setValue func(reflect.Value, interface{})) error {
if x, err := getValue(); err == nil {
if reflect.TypeOf(x).Kind() != reflect.Ptr {
v.Set(reflect.New(v.Type().Elem()))
setValue(v.Elem(), x)
} else {
setValue(v, x)
}
return nil
} else if err == ErrNil {
v.Set(reflect.Zero(v.Type()))
return nil
} else {
return err
}
}
func (r *Reader) getInt64() (interface{}, error) { return r.ReadInt64() }
func (r *Reader) setInt64(v reflect.Value, x interface{}) { v.SetInt(x.(int64)) }
func (r *Reader) readInt64Pointer(v reflect.Value) error {
return r.readPointer(v, r.getInt64, r.setInt64)
}
func (r *Reader) getUint64() (interface{}, error) { return r.ReadUint64() }
func (r *Reader) setUint64(v reflect.Value, x interface{}) { v.SetUint(x.(uint64)) }
func (r *Reader) readUint64Pointer(v reflect.Value) error {
return r.readPointer(v, r.getUint64, r.setUint64)
}
func (r *Reader) getBool() (interface{}, error) { return r.ReadBool() }
func (r *Reader) setBool(v reflect.Value, x interface{}) { v.SetBool(x.(bool)) }
func (r *Reader) readBoolPointer(v reflect.Value) error {
return r.readPointer(v, r.getBool, r.setBool)
}
func (r *Reader) getFloat32() (interface{}, error) { return r.ReadFloat32() }
func (r *Reader) setFloat32(v reflect.Value, x interface{}) { v.SetFloat(float64(x.(float32))) }
func (r *Reader) readFloat32Pointer(v reflect.Value) error {
return r.readPointer(v, r.getFloat32, r.setFloat32)
}
func (r *Reader) getFloat64() (interface{}, error) { return r.ReadFloat64() }
func (r *Reader) setFloat64(v reflect.Value, x interface{}) { v.SetFloat(x.(float64)) }
func (r *Reader) readFloat64Pointer(v reflect.Value) error {
return r.readPointer(v, r.getFloat64, r.setFloat64)
}
func (r *Reader) getBigInt() (interface{}, error) { return r.ReadBigInt() }
func (r *Reader) setBigInt(v reflect.Value, x interface{}) { v.Set(reflect.ValueOf(x)) }
func (r *Reader) readBigIntPointer(v reflect.Value) error {
return r.readPointer(v, r.getBigInt, r.setBigInt)
}
func (r *Reader) getDateTime() (interface{}, error) { return r.ReadDateTime() }
func (r *Reader) setDateTime(v reflect.Value, x interface{}) { v.Set(reflect.ValueOf(x)) }
func (r *Reader) readDateTimePointer(v reflect.Value) error {
return r.readPointer(v, r.getDateTime, r.setDateTime)
}
func (r *Reader) getString() (interface{}, error) { return r.ReadString() }
func (r *Reader) setString(v reflect.Value, x interface{}) { v.SetString(x.(string)) }
func (r *Reader) readStringPointer(v reflect.Value) error {
return r.readPointer(v, r.getString, r.setString)
}
func (r *Reader) getBytes() (interface{}, error) { return r.ReadBytes() }
func (r *Reader) setBytes(v reflect.Value, x interface{}) { v.Set(reflect.ValueOf(x)) }
func (r *Reader) readBytesPointer(v reflect.Value) error {
return r.readPointer(v, r.getBytes, r.setBytes)
}
func (r *Reader) getUUID() (interface{}, error) { return r.ReadUUID() }
func (r *Reader) setUUID(v reflect.Value, x interface{}) { v.Set(reflect.ValueOf(x)) }
func (r *Reader) readUUIDPointer(v reflect.Value) error {
return r.readPointer(v, r.getUUID, r.setUUID)
}
func (r *Reader) getList() (interface{}, error) { return r.ReadList() }
func (r *Reader) setList(v reflect.Value, x interface{}) { v.Set(reflect.ValueOf(x)) }
func (r *Reader) readListPointer(v reflect.Value) error {
return r.readPointer(v, r.getList, r.setList)
}
// private functions
func convertError(tag byte, dst string) error {
src, err := tagToString(tag)
if err == nil {
return errors.New("cannot convert type " + src + " to type " + dst)
}
return err
}
func tagToString(tag byte) (string, error) {
switch tag {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', TagInteger:
return "int", nil
case TagLong:
return "big.Int", nil
case TagDouble:
return "float64", nil
case TagNull:
return "nil", nil
case TagEmpty:
return "empty string", nil
case TagTrue:
return "bool true", nil
case TagFalse:
return "bool false", nil
case TagNaN:
return "NaN", nil
case TagInfinity:
return "Infinity", nil
case TagDate:
return "time.Time", nil
case TagTime:
return "time.Time", nil
case TagBytes:
return "[]byte", nil
case TagUTF8Char:
return "string", nil
case TagString:
return "string", nil
case TagGuid:
return "UUID", nil
case TagList:
return "slice", nil
case TagMap:
return "map", nil
case TagClass:
return "struct type", nil
case TagObject:
return "struct value", nil
case TagRef:
return "value reference", nil
case TagError:
return "error", nil
default:
return "unknown", unexpectedTag(tag, nil)
}
}
func stringToBigInt(str string) (*big.Int, error) {
if bigint, success := new(big.Int).SetString(str, 0); success {
return bigint, nil
}
return big.NewInt(0), errors.New(`cannot convert string "` + str + `" to type big.Int`)
}
func getIndexCache(class reflect.Type) map[string][]int {
indexCache.RLock()
indexMap, ok := indexCache.cache[class]
indexCache.RUnlock()
if !ok {
indexCache.Lock()
if indexCache.cache == nil {
indexCache.cache = make(map[reflect.Type]map[string][]int)
}
indexMap = make(map[string][]int)
getFieldsFunc(class, func(f *reflect.StructField) {
tag := ClassManager.GetTag(class)
if tag == "" {
indexMap[strings.ToLower(f.Name)] = f.Index
} else {
name := strings.SplitN(f.Tag.Get(tag), ",", 2)[0]
name = strings.TrimSpace(strings.SplitN(name, ">", 2)[0])
if name == "" {
indexMap[strings.ToLower(f.Name)] = f.Index
} else if name != "-" {
indexMap[strings.ToLower(name)] = f.Index
}
}
})
indexCache.cache[class] = indexMap
indexCache.Unlock()
}
return indexMap
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/andot/hprose-go.git
git@gitee.com:andot/hprose-go.git
andot
hprose-go
hprose-go
v1.5.1

搜索帮助