package gojay
import (
"unsafe"
)
func (dec *Decoder ) DecodeString (v *string ) error {
if dec .isPooled == 1 {
panic (InvalidUsagePooledDecoderError ("Invalid usage of pooled decoder" ))
}
return dec .decodeString (v )
}
func (dec *Decoder ) decodeString (v *string ) error {
for ; dec .cursor < dec .length || dec .read (); dec .cursor ++ {
switch dec .data [dec .cursor ] {
case ' ' , '\n' , '\t' , '\r' , ',' :
continue
case '"' :
dec .cursor ++
start , end , err := dec .getString ()
if err != nil {
return err
}
d := dec .data [start : end -1 ]
*v = *(*string )(unsafe .Pointer (&d ))
dec .cursor = end
return nil
case 'n' :
dec .cursor ++
err := dec .assertNull ()
if err != nil {
return err
}
return nil
default :
dec .err = dec .makeInvalidUnmarshalErr (v )
err := dec .skipData ()
if err != nil {
return err
}
return nil
}
}
return nil
}
func (dec *Decoder ) decodeStringNull (v **string ) error {
for ; dec .cursor < dec .length || dec .read (); dec .cursor ++ {
switch dec .data [dec .cursor ] {
case ' ' , '\n' , '\t' , '\r' , ',' :
continue
case '"' :
dec .cursor ++
start , end , err := dec .getString ()
if err != nil {
return err
}
if *v == nil {
*v = new (string )
}
d := dec .data [start : end -1 ]
**v = *(*string )(unsafe .Pointer (&d ))
dec .cursor = end
return nil
case 'n' :
dec .cursor ++
err := dec .assertNull ()
if err != nil {
return err
}
return nil
default :
dec .err = dec .makeInvalidUnmarshalErr (v )
err := dec .skipData ()
if err != nil {
return err
}
return nil
}
}
return nil
}
func (dec *Decoder ) parseEscapedString () error {
if dec .cursor >= dec .length && !dec .read () {
return dec .raiseInvalidJSONErr (dec .cursor )
}
switch dec .data [dec .cursor ] {
case '"' :
dec .data [dec .cursor ] = '"'
case '\\' :
dec .data [dec .cursor ] = '\\'
case '/' :
dec .data [dec .cursor ] = '/'
case 'b' :
dec .data [dec .cursor ] = '\b'
case 'f' :
dec .data [dec .cursor ] = '\f'
case 'n' :
dec .data [dec .cursor ] = '\n'
case 'r' :
dec .data [dec .cursor ] = '\r'
case 't' :
dec .data [dec .cursor ] = '\t'
case 'u' :
start := dec .cursor
dec .cursor ++
str , err := dec .parseUnicode ()
if err != nil {
return err
}
diff := dec .cursor - start
dec .data = append (append (dec .data [:start -1 ], str ...), dec .data [dec .cursor :]...)
dec .length = len (dec .data )
dec .cursor += len (str ) - diff - 1
return nil
default :
return dec .raiseInvalidJSONErr (dec .cursor )
}
dec .data = append (dec .data [:dec .cursor -1 ], dec .data [dec .cursor :]...)
dec .length --
return nil
}
func (dec *Decoder ) getString () (int , int , error ) {
var keyStart = dec .cursor
for dec .cursor < dec .length || dec .read () {
switch dec .data [dec .cursor ] {
case '"' :
dec .cursor = dec .cursor + 1
return keyStart , dec .cursor , nil
case '\\' :
dec .cursor = dec .cursor + 1
err := dec .parseEscapedString ()
if err != nil {
return 0 , 0 , err
}
default :
dec .cursor = dec .cursor + 1
continue
}
}
return 0 , 0 , dec .raiseInvalidJSONErr (dec .cursor )
}
func (dec *Decoder ) skipEscapedString () error {
start := dec .cursor
for ; dec .cursor < dec .length || dec .read (); dec .cursor ++ {
if dec .data [dec .cursor ] != '\\' {
d := dec .data [dec .cursor ]
dec .cursor = dec .cursor + 1
nSlash := dec .cursor - start
switch d {
case '"' :
if nSlash &1 != 1 {
return dec .raiseInvalidJSONErr (dec .cursor )
}
return nil
case 'u' :
if err := dec .skipString (); err != nil {
return err
}
dec .cursor --
return nil
case 'n' , 'r' , 't' , '/' , 'f' , 'b' :
return nil
default :
if nSlash &1 == 1 {
return dec .raiseInvalidJSONErr (dec .cursor )
}
return nil
}
}
}
return dec .raiseInvalidJSONErr (dec .cursor )
}
func (dec *Decoder ) skipString () error {
for dec .cursor < dec .length || dec .read () {
switch dec .data [dec .cursor ] {
case '"' :
dec .cursor = dec .cursor + 1
return nil
case '\\' :
dec .cursor = dec .cursor + 1
err := dec .skipEscapedString ()
if err != nil {
return err
}
default :
dec .cursor = dec .cursor + 1
continue
}
}
return dec .raiseInvalidJSONErr (len (dec .data ) - 1 )
}
func (dec *Decoder ) AddString (v *string ) error {
return dec .String (v )
}
func (dec *Decoder ) AddStringNull (v **string ) error {
return dec .StringNull (v )
}
func (dec *Decoder ) String (v *string ) error {
err := dec .decodeString (v )
if err != nil {
return err
}
dec .called |= 1
return nil
}
func (dec *Decoder ) StringNull (v **string ) error {
err := dec .decodeStringNull (v )
if err != nil {
return err
}
dec .called |= 1
return nil
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .