mirror of
https://github.com/schollz/cowyo.git
synced 2023-08-10 21:13:00 +03:00
Update all dependencies to latest
This commit is contained in:
parent
ff420fb81d
commit
b4638476cc
32
Gopkg.lock
generated
32
Gopkg.lock
generated
@ -29,13 +29,13 @@
|
|||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/danielheath/gin-teeny-security"
|
name = "github.com/danielheath/gin-teeny-security"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "0bc769386cc5a75bd79ccdcceaf0f977eeb6990e"
|
revision = "5f00fb6ac0933c2b378c907a3e2a43667afc4289"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/garyburd/redigo"
|
name = "github.com/garyburd/redigo"
|
||||||
packages = ["internal","redis"]
|
packages = ["internal","redis"]
|
||||||
revision = "34a326de1fea52965fa5ad664d3fc7163dd4b0a1"
|
revision = "d1ed5c67e5794de818ea85e6b522fda02623a484"
|
||||||
version = "v1.2.0"
|
version = "v1.4.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
@ -65,7 +65,7 @@
|
|||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/golang/protobuf"
|
name = "github.com/golang/protobuf"
|
||||||
packages = ["proto"]
|
packages = ["proto"]
|
||||||
revision = "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9"
|
revision = "1e59b77b52bf8e4b449a57e6f79f21226d571845"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/gorilla/context"
|
name = "github.com/gorilla/context"
|
||||||
@ -107,7 +107,7 @@
|
|||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/microcosm-cc/bluemonday"
|
name = "github.com/microcosm-cc/bluemonday"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "68fecaef60268522d2ac3f0123cec9d3bcab7b6e"
|
revision = "542fd4642604d0d0c26112396ce5b1a9d01eee0b"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/russross/blackfriday"
|
name = "github.com/russross/blackfriday"
|
||||||
@ -137,19 +137,19 @@
|
|||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/sergi/go-diff"
|
name = "github.com/sergi/go-diff"
|
||||||
packages = ["diffmatchpatch"]
|
packages = ["diffmatchpatch"]
|
||||||
revision = "2fc9cd33b5f86077aa3e0f442fa0476a9fa9a1dc"
|
revision = "1744e2970ca51c86172c8190fadad617561ed6e7"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/shurcooL/github_flavored_markdown"
|
name = "github.com/shurcooL/github_flavored_markdown"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "cccd3ce4f8e394ae9f87de0bd8b37e00625913d9"
|
revision = "28433ea3fc83827d77424782fefdcd94703366cc"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/shurcooL/go"
|
name = "github.com/shurcooL/go"
|
||||||
packages = ["parserutil","printerutil","reflectfind","reflectsource"]
|
packages = ["parserutil","printerutil","reflectfind","reflectsource"]
|
||||||
revision = "c661e953e604ba4a84a3c4e458462a481bd6ce72"
|
revision = "004faa6b0118cf52635363b72b51cdcc297800a2"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
@ -161,7 +161,7 @@
|
|||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/shurcooL/graphql"
|
name = "github.com/shurcooL/graphql"
|
||||||
packages = ["ident"]
|
packages = ["ident"]
|
||||||
revision = "cf6db17b893acfad0ca1929ba6be45bf854790ed"
|
revision = "d0549edd16dceb6939e538fdb1b4f2ec7ee816cc"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
@ -179,7 +179,7 @@
|
|||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/shurcooL/octiconssvg"
|
name = "github.com/shurcooL/octiconssvg"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "8c9861b86a08c72d14e0285d0dc313bb6df52295"
|
revision = "38b02129bb6460858e11f90798a3832da1e502bd"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
@ -200,28 +200,28 @@
|
|||||||
revision = "bd320f5d308e1a3c4314c678d8227a0d72574ae7"
|
revision = "bd320f5d308e1a3c4314c678d8227a0d72574ae7"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
|
||||||
name = "github.com/ugorji/go"
|
name = "github.com/ugorji/go"
|
||||||
packages = ["codec"]
|
packages = ["codec"]
|
||||||
revision = "50189f05eaf5a0c17e5084eb8f7fb91e23699840"
|
revision = "9831f2c3ac1068a78f50999a30db84270f647af6"
|
||||||
|
version = "v1.1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "golang.org/x/crypto"
|
name = "golang.org/x/crypto"
|
||||||
packages = ["bcrypt","blowfish"]
|
packages = ["bcrypt","blowfish"]
|
||||||
revision = "bd6f299fb381e4c3393d1c4b1f0b94f5e77650c8"
|
revision = "39efaea5da11abd5e2b90a435b1f338cdb94619c"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "golang.org/x/net"
|
name = "golang.org/x/net"
|
||||||
packages = ["html","html/atom"]
|
packages = ["html","html/atom"]
|
||||||
revision = "01c190206fbdffa42f334f4b2bf2220f50e64920"
|
revision = "5ccada7d0a7ba9aeb5d3aca8d3501b4c2a509fec"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "golang.org/x/sys"
|
name = "golang.org/x/sys"
|
||||||
packages = ["unix"]
|
packages = ["unix"]
|
||||||
revision = "4fe5d7925040acd225bf9c7cee65e82d07f06bff"
|
revision = "af50095a40f9041b3b38960738837185c26e9419"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "gopkg.in/go-playground/validator.v8"
|
name = "gopkg.in/go-playground/validator.v8"
|
||||||
@ -245,7 +245,7 @@
|
|||||||
branch = "v2"
|
branch = "v2"
|
||||||
name = "gopkg.in/yaml.v2"
|
name = "gopkg.in/yaml.v2"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "eb3733d160e74a9c7e442f435eb3bea458e1d19f"
|
revision = "d670f9405373e636a5a2765eea47fac0c9bc91a4"
|
||||||
|
|
||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
|
140
vendor/github.com/danielheath/gin-teeny-security/gin-teeny-security.go
generated
vendored
140
vendor/github.com/danielheath/gin-teeny-security/gin-teeny-security.go
generated
vendored
@ -1,9 +1,14 @@
|
|||||||
// A GIN middleware providing low-fi security for personal stuff.
|
// A GIN middleware providing low-fi security for personal stuff.
|
||||||
|
|
||||||
package gin_teeny_security
|
package gin_teeny_security
|
||||||
|
|
||||||
import "github.com/gin-gonic/gin"
|
import "github.com/gin-gonic/gin"
|
||||||
import "github.com/gin-contrib/sessions"
|
import "github.com/gin-contrib/sessions"
|
||||||
import "net/http"
|
import "net/http"
|
||||||
|
import "net/url"
|
||||||
|
import "fmt"
|
||||||
|
import "io"
|
||||||
|
import "html/template"
|
||||||
|
|
||||||
// Forces you to a login page until you provide a secret code.
|
// Forces you to a login page until you provide a secret code.
|
||||||
// No CSRF protection, so any script on any page can log you
|
// No CSRF protection, so any script on any page can log you
|
||||||
@ -12,40 +17,122 @@ import "net/http"
|
|||||||
// net can inject stuff. If you're sending open CORS headers this
|
// net can inject stuff. If you're sending open CORS headers this
|
||||||
// would be particularly bad.
|
// would be particularly bad.
|
||||||
func RequiresSecretAccessCode(secretAccessCode, path string) gin.HandlerFunc {
|
func RequiresSecretAccessCode(secretAccessCode, path string) gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
cfg := &Config{
|
||||||
|
Path: path,
|
||||||
|
Secret: secretAccessCode,
|
||||||
|
}
|
||||||
|
|
||||||
|
return cfg.Middleware
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Path string // defaults to login
|
||||||
|
Secret string
|
||||||
|
RequireAuth func(*gin.Context) bool // defaults to always requiring auth if unset
|
||||||
|
Template *template.Template
|
||||||
|
SaveKeyToSession func(*gin.Context, string)
|
||||||
|
GetKeyFromSession func(*gin.Context) string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Config) saveKey(ctx *gin.Context, k string) {
|
||||||
|
if c.SaveKeyToSession == nil {
|
||||||
|
c.SaveKeyToSession = DefaultSetSession
|
||||||
|
}
|
||||||
|
c.SaveKeyToSession(ctx, k)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Config) getKey(ctx *gin.Context) string {
|
||||||
|
if c.GetKeyFromSession == nil {
|
||||||
|
c.GetKeyFromSession = DefaultGetSession
|
||||||
|
}
|
||||||
|
return c.GetKeyFromSession(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DefaultSetSession(c *gin.Context, secret string) {
|
||||||
session := sessions.Default(c)
|
session := sessions.Default(c)
|
||||||
if c.Request.URL.Path == path {
|
session.Set("secretAccessCode", secret)
|
||||||
|
session.Save()
|
||||||
|
}
|
||||||
|
|
||||||
|
func DefaultGetSession(c *gin.Context) string {
|
||||||
|
session := sessions.Default(c)
|
||||||
|
str, ok := session.Get("secretAccessCode").(string)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println(session.Get("secretAccessCode"))
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Config) path() string {
|
||||||
|
if c.Path == "" {
|
||||||
|
return "/login/"
|
||||||
|
}
|
||||||
|
return c.Path
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Config) requireAuth(ctx *gin.Context) bool {
|
||||||
|
if ctx.Request.Header.Get("Authorization") == c.Secret {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return c.RequireAuth == nil || c.RequireAuth(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Config) template() *template.Template {
|
||||||
|
if c.Template == nil {
|
||||||
|
return DEFAULT_LOGIN_PAGE
|
||||||
|
}
|
||||||
|
return c.Template
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c Config) ExecTemplate(w io.Writer, message, returnUrl string) error {
|
||||||
|
return c.template().Execute(w, LoginPageParams{
|
||||||
|
Message: message,
|
||||||
|
Path: c.path() + "?" + url.Values{"return": []string{returnUrl}}.Encode(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type LoginPageParams struct {
|
||||||
|
Message string
|
||||||
|
Path string
|
||||||
|
}
|
||||||
|
|
||||||
|
var DEFAULT_LOGIN_PAGE = template.Must(template.New("login").Parse(`
|
||||||
|
<h1>Login</h1>
|
||||||
|
{{ if .Message }}<h2>{{ .Message }}</h2>{{ end }}
|
||||||
|
<form action="{{.Path}}" method="POST">
|
||||||
|
<input name="secretAccessCode" />
|
||||||
|
<input type="submit" value="Login" />
|
||||||
|
</form>
|
||||||
|
`))
|
||||||
|
|
||||||
|
func (cfg *Config) Middleware(c *gin.Context) {
|
||||||
|
if c.Request.URL.Path == cfg.path() {
|
||||||
|
returnTo := c.Request.URL.Query().Get("return")
|
||||||
|
if returnTo == "" {
|
||||||
|
returnTo = "/"
|
||||||
|
}
|
||||||
|
|
||||||
if c.Request.Method == "POST" {
|
if c.Request.Method == "POST" {
|
||||||
c.Request.ParseForm()
|
c.Request.ParseForm()
|
||||||
|
|
||||||
if c.Request.PostForm.Get("secretAccessCode") == secretAccessCode {
|
fmt.Println(c.Request.PostForm.Get("secretAccessCode"))
|
||||||
c.Header("Location", "/")
|
if c.Request.PostForm.Get("secretAccessCode") == cfg.Secret {
|
||||||
session.Set("secretAccessCode", secretAccessCode)
|
|
||||||
session.Save()
|
c.Header("Location", returnTo)
|
||||||
|
cfg.saveKey(c, cfg.Secret)
|
||||||
|
|
||||||
c.AbortWithStatus(http.StatusFound)
|
c.AbortWithStatus(http.StatusFound)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
session.Set("secretAccessCode", "")
|
cfg.saveKey(c, "")
|
||||||
session.Save()
|
c.Writer.WriteHeader(http.StatusForbidden)
|
||||||
c.Data(http.StatusForbidden, "text/html", []byte(`
|
cfg.ExecTemplate(c.Writer, "Wrong Password", returnTo)
|
||||||
<h1>Login</h1>
|
|
||||||
<h2>Wrong password</h2>
|
|
||||||
<form action="`+path+`" method="POST">
|
|
||||||
<input name="secretAccessCode" />
|
|
||||||
<input type="submit" value="Login" />
|
|
||||||
</form>
|
|
||||||
`))
|
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if c.Request.Method == "GET" {
|
} else if c.Request.Method == "GET" {
|
||||||
c.Data(http.StatusOK, "text/html", []byte(`
|
cfg.ExecTemplate(c.Writer, "", returnTo)
|
||||||
<h1>Login</h1>
|
|
||||||
<form action="`+path+`" method="POST">
|
|
||||||
<input name="secretAccessCode" />
|
|
||||||
<input type="submit" value="Login" />
|
|
||||||
</form>
|
|
||||||
`))
|
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
@ -54,12 +141,11 @@ func RequiresSecretAccessCode(secretAccessCode, path string) gin.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
v := session.Get("secretAccessCode")
|
v := cfg.getKey(c)
|
||||||
if v != secretAccessCode {
|
if cfg.requireAuth(c) && (v != cfg.Secret) {
|
||||||
c.Header("Location", path)
|
c.Header("Location", cfg.Path+"?"+url.Values{"return": []string{c.Request.URL.RequestURI()}}.Encode())
|
||||||
c.AbortWithStatus(http.StatusTemporaryRedirect)
|
c.AbortWithStatus(http.StatusTemporaryRedirect)
|
||||||
} else {
|
} else {
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
109
vendor/github.com/danielheath/gin-teeny-security/gin-teeny-security_test.go
generated
vendored
Normal file
109
vendor/github.com/danielheath/gin-teeny-security/gin-teeny-security_test.go
generated
vendored
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
package gin_teeny_security
|
||||||
|
|
||||||
|
import "net/http/cookiejar"
|
||||||
|
import "strings"
|
||||||
|
import "net/http/httptest"
|
||||||
|
import "net/http"
|
||||||
|
import "net/url"
|
||||||
|
import "log"
|
||||||
|
import "io"
|
||||||
|
import "io/ioutil"
|
||||||
|
import "testing"
|
||||||
|
import "github.com/gin-gonic/gin"
|
||||||
|
import "github.com/gin-contrib/sessions"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
http.DefaultClient.Jar, _ = cookiejar.New(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SampleGinApp() *gin.Engine {
|
||||||
|
router := gin.Default()
|
||||||
|
store := sessions.NewCookieStore([]byte("tis a secret"))
|
||||||
|
router.Use(sessions.Sessions("mysession", store))
|
||||||
|
cfg := &Config{
|
||||||
|
Path: "/enter-password/",
|
||||||
|
Secret: "garden",
|
||||||
|
RequireAuth: func(c *gin.Context) bool {
|
||||||
|
return !strings.HasPrefix(c.Request.URL.Path, "/public")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
router.Use(cfg.Middleware)
|
||||||
|
|
||||||
|
router.GET("/private", func(c *gin.Context) {
|
||||||
|
c.Data(http.StatusOK, "application/html", []byte("private stuff"))
|
||||||
|
})
|
||||||
|
|
||||||
|
router.GET("/public", func(c *gin.Context) {
|
||||||
|
c.Data(http.StatusOK, "application/html", []byte("public stuff"))
|
||||||
|
})
|
||||||
|
|
||||||
|
return router
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAuth(t *testing.T) {
|
||||||
|
ts := httptest.NewServer(SampleGinApp())
|
||||||
|
|
||||||
|
// Check public stuff can be accessed
|
||||||
|
res, err := http.Get(ts.URL + "/public/")
|
||||||
|
die(err)
|
||||||
|
mustBe("public stuff", readString(res.Body))
|
||||||
|
|
||||||
|
// Check private stuff can't be accessed
|
||||||
|
res, err = http.Get(ts.URL + "/private/")
|
||||||
|
die(err)
|
||||||
|
|
||||||
|
// Check entering the password as an HTTP header instead of a cookie works
|
||||||
|
r, err := http.NewRequest("GET", ts.URL+"/private/", nil)
|
||||||
|
die(err)
|
||||||
|
r.Header.Set("Authorization", "garden")
|
||||||
|
res, err = http.DefaultClient.Do(r)
|
||||||
|
die(err)
|
||||||
|
mustBe("private stuff", readString(res.Body))
|
||||||
|
|
||||||
|
// Check entering the wrong password as an HTTP header instead of a cookie works
|
||||||
|
r, err = http.NewRequest("GET", ts.URL+"/private/", nil)
|
||||||
|
die(err)
|
||||||
|
r.Header.Set("Authorization", "wrong")
|
||||||
|
res, err = http.DefaultClient.Do(r)
|
||||||
|
die(err)
|
||||||
|
mustStartWith("<h1>Login</h1>\n\n<form action=\"/enter-password/?return=%2Fprivate\"", readString(res.Body))
|
||||||
|
|
||||||
|
res, err = http.Get(ts.URL + "/private/")
|
||||||
|
die(err)
|
||||||
|
mustStartWith("<h1>Login</h1>\n\n<form action=\"/enter-password/?return=%2Fprivate\"", readString(res.Body))
|
||||||
|
|
||||||
|
// Check entering a bad password gives you a message
|
||||||
|
res, err = http.PostForm(ts.URL+"/enter-password/", url.Values{"secretAccessCode": []string{"wrong"}})
|
||||||
|
die(err)
|
||||||
|
mustStartWith("<h1>Login</h1>\n<h2>Wrong Password</h2>", readString(res.Body))
|
||||||
|
|
||||||
|
// Check entering a good password lets you access things
|
||||||
|
res, err = http.PostForm(ts.URL+"/enter-password/?return=/private/", url.Values{"secretAccessCode": []string{"garden"}})
|
||||||
|
die(err)
|
||||||
|
mustBe("private stuff", readString(res.Body))
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustStartWith(expected, actual string) {
|
||||||
|
if !strings.HasPrefix(strings.TrimSpace(actual), expected) {
|
||||||
|
log.Panicf("Should have gotten content starting with '%s' but got '%s'", expected, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustBe(expected, actual string) {
|
||||||
|
if actual != expected {
|
||||||
|
log.Panicf("Should have gotten '%s' but got '%s'", expected, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func readString(r io.ReadCloser) string {
|
||||||
|
b, e := ioutil.ReadAll(r)
|
||||||
|
defer r.Close()
|
||||||
|
die(e)
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func die(e error) {
|
||||||
|
if e != nil {
|
||||||
|
log.Fatal(e)
|
||||||
|
}
|
||||||
|
}
|
1
vendor/github.com/garyburd/redigo/README.markdown
generated
vendored
1
vendor/github.com/garyburd/redigo/README.markdown
generated
vendored
@ -21,6 +21,7 @@ Documentation
|
|||||||
|
|
||||||
- [API Reference](http://godoc.org/github.com/garyburd/redigo/redis)
|
- [API Reference](http://godoc.org/github.com/garyburd/redigo/redis)
|
||||||
- [FAQ](https://github.com/garyburd/redigo/wiki/FAQ)
|
- [FAQ](https://github.com/garyburd/redigo/wiki/FAQ)
|
||||||
|
- [Examples](https://godoc.org/github.com/garyburd/redigo/redis#pkg-examples)
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
|
63
vendor/github.com/garyburd/redigo/redis/conn.go
generated
vendored
63
vendor/github.com/garyburd/redigo/redis/conn.go
generated
vendored
@ -29,9 +29,12 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ ConnWithTimeout = (*conn)(nil)
|
||||||
|
)
|
||||||
|
|
||||||
// conn is the low-level implementation of Conn
|
// conn is the low-level implementation of Conn
|
||||||
type conn struct {
|
type conn struct {
|
||||||
|
|
||||||
// Shared
|
// Shared
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
pending int
|
pending int
|
||||||
@ -73,6 +76,7 @@ type DialOption struct {
|
|||||||
type dialOptions struct {
|
type dialOptions struct {
|
||||||
readTimeout time.Duration
|
readTimeout time.Duration
|
||||||
writeTimeout time.Duration
|
writeTimeout time.Duration
|
||||||
|
dialer *net.Dialer
|
||||||
dial func(network, addr string) (net.Conn, error)
|
dial func(network, addr string) (net.Conn, error)
|
||||||
db int
|
db int
|
||||||
password string
|
password string
|
||||||
@ -95,17 +99,27 @@ func DialWriteTimeout(d time.Duration) DialOption {
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialConnectTimeout specifies the timeout for connecting to the Redis server.
|
// DialConnectTimeout specifies the timeout for connecting to the Redis server when
|
||||||
|
// no DialNetDial option is specified.
|
||||||
func DialConnectTimeout(d time.Duration) DialOption {
|
func DialConnectTimeout(d time.Duration) DialOption {
|
||||||
return DialOption{func(do *dialOptions) {
|
return DialOption{func(do *dialOptions) {
|
||||||
dialer := net.Dialer{Timeout: d}
|
do.dialer.Timeout = d
|
||||||
do.dial = dialer.Dial
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DialKeepAlive specifies the keep-alive period for TCP connections to the Redis server
|
||||||
|
// when no DialNetDial option is specified.
|
||||||
|
// If zero, keep-alives are not enabled. If no DialKeepAlive option is specified then
|
||||||
|
// the default of 5 minutes is used to ensure that half-closed TCP sessions are detected.
|
||||||
|
func DialKeepAlive(d time.Duration) DialOption {
|
||||||
|
return DialOption{func(do *dialOptions) {
|
||||||
|
do.dialer.KeepAlive = d
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialNetDial specifies a custom dial function for creating TCP
|
// DialNetDial specifies a custom dial function for creating TCP
|
||||||
// connections. If this option is left out, then net.Dial is
|
// connections, otherwise a net.Dialer customized via the other options is used.
|
||||||
// used. DialNetDial overrides DialConnectTimeout.
|
// DialNetDial overrides DialConnectTimeout and DialKeepAlive.
|
||||||
func DialNetDial(dial func(network, addr string) (net.Conn, error)) DialOption {
|
func DialNetDial(dial func(network, addr string) (net.Conn, error)) DialOption {
|
||||||
return DialOption{func(do *dialOptions) {
|
return DialOption{func(do *dialOptions) {
|
||||||
do.dial = dial
|
do.dial = dial
|
||||||
@ -155,11 +169,16 @@ func DialUseTLS(useTLS bool) DialOption {
|
|||||||
// address using the specified options.
|
// address using the specified options.
|
||||||
func Dial(network, address string, options ...DialOption) (Conn, error) {
|
func Dial(network, address string, options ...DialOption) (Conn, error) {
|
||||||
do := dialOptions{
|
do := dialOptions{
|
||||||
dial: net.Dial,
|
dialer: &net.Dialer{
|
||||||
|
KeepAlive: time.Minute * 5,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, option := range options {
|
for _, option := range options {
|
||||||
option.f(&do)
|
option.f(&do)
|
||||||
}
|
}
|
||||||
|
if do.dial == nil {
|
||||||
|
do.dial = do.dialer.Dial
|
||||||
|
}
|
||||||
|
|
||||||
netConn, err := do.dial(network, address)
|
netConn, err := do.dial(network, address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -167,7 +186,12 @@ func Dial(network, address string, options ...DialOption) (Conn, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if do.useTLS {
|
if do.useTLS {
|
||||||
tlsConfig := cloneTLSClientConfig(do.tlsConfig, do.skipVerify)
|
var tlsConfig *tls.Config
|
||||||
|
if do.tlsConfig == nil {
|
||||||
|
tlsConfig = &tls.Config{InsecureSkipVerify: do.skipVerify}
|
||||||
|
} else {
|
||||||
|
tlsConfig = cloneTLSConfig(do.tlsConfig)
|
||||||
|
}
|
||||||
if tlsConfig.ServerName == "" {
|
if tlsConfig.ServerName == "" {
|
||||||
host, _, err := net.SplitHostPort(address)
|
host, _, err := net.SplitHostPort(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -556,10 +580,17 @@ func (c *conn) Flush() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) Receive() (reply interface{}, err error) {
|
func (c *conn) Receive() (interface{}, error) {
|
||||||
if c.readTimeout != 0 {
|
return c.ReceiveWithTimeout(c.readTimeout)
|
||||||
c.conn.SetReadDeadline(time.Now().Add(c.readTimeout))
|
}
|
||||||
|
|
||||||
|
func (c *conn) ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error) {
|
||||||
|
var deadline time.Time
|
||||||
|
if timeout != 0 {
|
||||||
|
deadline = time.Now().Add(timeout)
|
||||||
}
|
}
|
||||||
|
c.conn.SetReadDeadline(deadline)
|
||||||
|
|
||||||
if reply, err = c.readReply(); err != nil {
|
if reply, err = c.readReply(); err != nil {
|
||||||
return nil, c.fatal(err)
|
return nil, c.fatal(err)
|
||||||
}
|
}
|
||||||
@ -582,6 +613,10 @@ func (c *conn) Receive() (reply interface{}, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) Do(cmd string, args ...interface{}) (interface{}, error) {
|
func (c *conn) Do(cmd string, args ...interface{}) (interface{}, error) {
|
||||||
|
return c.DoWithTimeout(c.readTimeout, cmd, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *conn) DoWithTimeout(readTimeout time.Duration, cmd string, args ...interface{}) (interface{}, error) {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
pending := c.pending
|
pending := c.pending
|
||||||
c.pending = 0
|
c.pending = 0
|
||||||
@ -605,9 +640,11 @@ func (c *conn) Do(cmd string, args ...interface{}) (interface{}, error) {
|
|||||||
return nil, c.fatal(err)
|
return nil, c.fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.readTimeout != 0 {
|
var deadline time.Time
|
||||||
c.conn.SetReadDeadline(time.Now().Add(c.readTimeout))
|
if readTimeout != 0 {
|
||||||
|
deadline = time.Now().Add(readTimeout)
|
||||||
}
|
}
|
||||||
|
c.conn.SetReadDeadline(deadline)
|
||||||
|
|
||||||
if cmd == "" {
|
if cmd == "" {
|
||||||
reply := make([]interface{}, pending)
|
reply := make([]interface{}, pending)
|
||||||
|
51
vendor/github.com/garyburd/redigo/redis/conn_test.go
generated
vendored
51
vendor/github.com/garyburd/redigo/redis/conn_test.go
generated
vendored
@ -34,14 +34,16 @@ import (
|
|||||||
type testConn struct {
|
type testConn struct {
|
||||||
io.Reader
|
io.Reader
|
||||||
io.Writer
|
io.Writer
|
||||||
|
readDeadline time.Time
|
||||||
|
writeDeadline time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*testConn) Close() error { return nil }
|
func (*testConn) Close() error { return nil }
|
||||||
func (*testConn) LocalAddr() net.Addr { return nil }
|
func (*testConn) LocalAddr() net.Addr { return nil }
|
||||||
func (*testConn) RemoteAddr() net.Addr { return nil }
|
func (*testConn) RemoteAddr() net.Addr { return nil }
|
||||||
func (*testConn) SetDeadline(t time.Time) error { return nil }
|
func (c *testConn) SetDeadline(t time.Time) error { c.readDeadline = t; c.writeDeadline = t; return nil }
|
||||||
func (*testConn) SetReadDeadline(t time.Time) error { return nil }
|
func (c *testConn) SetReadDeadline(t time.Time) error { c.readDeadline = t; return nil }
|
||||||
func (*testConn) SetWriteDeadline(t time.Time) error { return nil }
|
func (c *testConn) SetWriteDeadline(t time.Time) error { c.writeDeadline = t; return nil }
|
||||||
|
|
||||||
func dialTestConn(r string, w io.Writer) redis.DialOption {
|
func dialTestConn(r string, w io.Writer) redis.DialOption {
|
||||||
return redis.DialNetDial(func(network, addr string) (net.Conn, error) {
|
return redis.DialNetDial(func(network, addr string) (net.Conn, error) {
|
||||||
@ -764,7 +766,6 @@ func BenchmarkDoPing(b *testing.B) {
|
|||||||
var clientTLSConfig, serverTLSConfig tls.Config
|
var clientTLSConfig, serverTLSConfig tls.Config
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
||||||
// The certificate and key for testing TLS dial options was created
|
// The certificate and key for testing TLS dial options was created
|
||||||
// using the command
|
// using the command
|
||||||
//
|
//
|
||||||
@ -822,3 +823,45 @@ Bjqn3yoLHaoZVvbWOi0C2TCN4FjXjaLNZGifQPbIcaA=
|
|||||||
clientTLSConfig.RootCAs = x509.NewCertPool()
|
clientTLSConfig.RootCAs = x509.NewCertPool()
|
||||||
clientTLSConfig.RootCAs.AddCert(certificate)
|
clientTLSConfig.RootCAs.AddCert(certificate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWithTimeout(t *testing.T) {
|
||||||
|
for _, recv := range []bool{true, false} {
|
||||||
|
for _, defaultTimout := range []time.Duration{0, time.Minute} {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
nc := &testConn{Reader: strings.NewReader("+OK\r\n+OK\r\n+OK\r\n+OK\r\n+OK\r\n+OK\r\n+OK\r\n+OK\r\n+OK\r\n+OK\r\n"), Writer: &buf}
|
||||||
|
c, _ := redis.Dial("", "", redis.DialReadTimeout(defaultTimout), redis.DialNetDial(func(network, addr string) (net.Conn, error) { return nc, nil }))
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
var minDeadline, maxDeadline time.Time
|
||||||
|
|
||||||
|
// Alternate between default and specified timeout.
|
||||||
|
if i%2 == 0 {
|
||||||
|
if defaultTimout != 0 {
|
||||||
|
minDeadline = time.Now().Add(defaultTimout)
|
||||||
|
}
|
||||||
|
if recv {
|
||||||
|
c.Receive()
|
||||||
|
} else {
|
||||||
|
c.Do("PING")
|
||||||
|
}
|
||||||
|
if defaultTimout != 0 {
|
||||||
|
maxDeadline = time.Now().Add(defaultTimout)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
timeout := 10 * time.Minute
|
||||||
|
minDeadline = time.Now().Add(timeout)
|
||||||
|
if recv {
|
||||||
|
redis.ReceiveWithTimeout(c, timeout)
|
||||||
|
} else {
|
||||||
|
redis.DoWithTimeout(c, timeout, "PING")
|
||||||
|
}
|
||||||
|
maxDeadline = time.Now().Add(timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expect set deadline in expected range.
|
||||||
|
if nc.readDeadline.Before(minDeadline) || nc.readDeadline.After(maxDeadline) {
|
||||||
|
t.Errorf("recv %v, %d: do deadline error: %v, %v, %v", recv, i, minDeadline, nc.readDeadline, maxDeadline)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -4,11 +4,7 @@ package redis
|
|||||||
|
|
||||||
import "crypto/tls"
|
import "crypto/tls"
|
||||||
|
|
||||||
// similar cloneTLSClientConfig in the stdlib, but also honor skipVerify for the nil case
|
func cloneTLSConfig(cfg *tls.Config) *tls.Config {
|
||||||
func cloneTLSClientConfig(cfg *tls.Config, skipVerify bool) *tls.Config {
|
|
||||||
if cfg == nil {
|
|
||||||
return &tls.Config{InsecureSkipVerify: skipVerify}
|
|
||||||
}
|
|
||||||
return &tls.Config{
|
return &tls.Config{
|
||||||
Rand: cfg.Rand,
|
Rand: cfg.Rand,
|
||||||
Time: cfg.Time,
|
Time: cfg.Time,
|
8
vendor/github.com/garyburd/redigo/redis/go17.go
generated
vendored
8
vendor/github.com/garyburd/redigo/redis/go17.go
generated
vendored
@ -1,14 +1,10 @@
|
|||||||
// +build go1.7
|
// +build go1.7,!go1.8
|
||||||
|
|
||||||
package redis
|
package redis
|
||||||
|
|
||||||
import "crypto/tls"
|
import "crypto/tls"
|
||||||
|
|
||||||
// similar cloneTLSClientConfig in the stdlib, but also honor skipVerify for the nil case
|
func cloneTLSConfig(cfg *tls.Config) *tls.Config {
|
||||||
func cloneTLSClientConfig(cfg *tls.Config, skipVerify bool) *tls.Config {
|
|
||||||
if cfg == nil {
|
|
||||||
return &tls.Config{InsecureSkipVerify: skipVerify}
|
|
||||||
}
|
|
||||||
return &tls.Config{
|
return &tls.Config{
|
||||||
Rand: cfg.Rand,
|
Rand: cfg.Rand,
|
||||||
Time: cfg.Time,
|
Time: cfg.Time,
|
||||||
|
9
vendor/github.com/garyburd/redigo/redis/go18.go
generated
vendored
Normal file
9
vendor/github.com/garyburd/redigo/redis/go18.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// +build go1.8
|
||||||
|
|
||||||
|
package redis
|
||||||
|
|
||||||
|
import "crypto/tls"
|
||||||
|
|
||||||
|
func cloneTLSConfig(cfg *tls.Config) *tls.Config {
|
||||||
|
return cfg.Clone()
|
||||||
|
}
|
17
vendor/github.com/garyburd/redigo/redis/log.go
generated
vendored
17
vendor/github.com/garyburd/redigo/redis/log.go
generated
vendored
@ -18,6 +18,11 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ ConnWithTimeout = (*loggingConn)(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewLoggingConn returns a logging wrapper around a connection.
|
// NewLoggingConn returns a logging wrapper around a connection.
|
||||||
@ -104,6 +109,12 @@ func (c *loggingConn) Do(commandName string, args ...interface{}) (interface{},
|
|||||||
return reply, err
|
return reply, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *loggingConn) DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (interface{}, error) {
|
||||||
|
reply, err := DoWithTimeout(c.Conn, timeout, commandName, args...)
|
||||||
|
c.print("DoWithTimeout", commandName, args, reply, err)
|
||||||
|
return reply, err
|
||||||
|
}
|
||||||
|
|
||||||
func (c *loggingConn) Send(commandName string, args ...interface{}) error {
|
func (c *loggingConn) Send(commandName string, args ...interface{}) error {
|
||||||
err := c.Conn.Send(commandName, args...)
|
err := c.Conn.Send(commandName, args...)
|
||||||
c.print("Send", commandName, args, nil, err)
|
c.print("Send", commandName, args, nil, err)
|
||||||
@ -115,3 +126,9 @@ func (c *loggingConn) Receive() (interface{}, error) {
|
|||||||
c.print("Receive", "", nil, reply, err)
|
c.print("Receive", "", nil, reply, err)
|
||||||
return reply, err
|
return reply, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *loggingConn) ReceiveWithTimeout(timeout time.Duration) (interface{}, error) {
|
||||||
|
reply, err := ReceiveWithTimeout(c.Conn, timeout)
|
||||||
|
c.print("ReceiveWithTimeout", "", nil, reply, err)
|
||||||
|
return reply, err
|
||||||
|
}
|
||||||
|
33
vendor/github.com/garyburd/redigo/redis/pool.go
generated
vendored
33
vendor/github.com/garyburd/redigo/redis/pool.go
generated
vendored
@ -28,6 +28,11 @@ import (
|
|||||||
"github.com/garyburd/redigo/internal"
|
"github.com/garyburd/redigo/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ ConnWithTimeout = (*pooledConnection)(nil)
|
||||||
|
_ ConnWithTimeout = (*errorConnection)(nil)
|
||||||
|
)
|
||||||
|
|
||||||
var nowFunc = time.Now // for testing
|
var nowFunc = time.Now // for testing
|
||||||
|
|
||||||
// ErrPoolExhausted is returned from a pool connection method (Do, Send,
|
// ErrPoolExhausted is returned from a pool connection method (Do, Send,
|
||||||
@ -96,7 +101,7 @@ var (
|
|||||||
// return nil, err
|
// return nil, err
|
||||||
// }
|
// }
|
||||||
// return c, nil
|
// return c, nil
|
||||||
// }
|
// },
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// Use the TestOnBorrow function to check the health of an idle connection
|
// Use the TestOnBorrow function to check the health of an idle connection
|
||||||
@ -115,7 +120,6 @@ var (
|
|||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
type Pool struct {
|
type Pool struct {
|
||||||
|
|
||||||
// Dial is an application supplied function for creating and configuring a
|
// Dial is an application supplied function for creating and configuring a
|
||||||
// connection.
|
// connection.
|
||||||
//
|
//
|
||||||
@ -269,7 +273,6 @@ func (p *Pool) get() (Conn, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
|
||||||
// Get idle connection.
|
// Get idle connection.
|
||||||
|
|
||||||
for i, n := 0, p.idle.Len(); i < n; i++ {
|
for i, n := 0, p.idle.Len(); i < n; i++ {
|
||||||
@ -420,6 +423,16 @@ func (pc *pooledConnection) Do(commandName string, args ...interface{}) (reply i
|
|||||||
return pc.c.Do(commandName, args...)
|
return pc.c.Do(commandName, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pc *pooledConnection) DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (reply interface{}, err error) {
|
||||||
|
cwt, ok := pc.c.(ConnWithTimeout)
|
||||||
|
if !ok {
|
||||||
|
return nil, errTimeoutNotSupported
|
||||||
|
}
|
||||||
|
ci := internal.LookupCommandInfo(commandName)
|
||||||
|
pc.state = (pc.state | ci.Set) &^ ci.Clear
|
||||||
|
return cwt.DoWithTimeout(timeout, commandName, args...)
|
||||||
|
}
|
||||||
|
|
||||||
func (pc *pooledConnection) Send(commandName string, args ...interface{}) error {
|
func (pc *pooledConnection) Send(commandName string, args ...interface{}) error {
|
||||||
ci := internal.LookupCommandInfo(commandName)
|
ci := internal.LookupCommandInfo(commandName)
|
||||||
pc.state = (pc.state | ci.Set) &^ ci.Clear
|
pc.state = (pc.state | ci.Set) &^ ci.Clear
|
||||||
@ -434,11 +447,23 @@ func (pc *pooledConnection) Receive() (reply interface{}, err error) {
|
|||||||
return pc.c.Receive()
|
return pc.c.Receive()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pc *pooledConnection) ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error) {
|
||||||
|
cwt, ok := pc.c.(ConnWithTimeout)
|
||||||
|
if !ok {
|
||||||
|
return nil, errTimeoutNotSupported
|
||||||
|
}
|
||||||
|
return cwt.ReceiveWithTimeout(timeout)
|
||||||
|
}
|
||||||
|
|
||||||
type errorConnection struct{ err error }
|
type errorConnection struct{ err error }
|
||||||
|
|
||||||
func (ec errorConnection) Do(string, ...interface{}) (interface{}, error) { return nil, ec.err }
|
func (ec errorConnection) Do(string, ...interface{}) (interface{}, error) { return nil, ec.err }
|
||||||
|
func (ec errorConnection) DoWithTimeout(time.Duration, string, ...interface{}) (interface{}, error) {
|
||||||
|
return nil, ec.err
|
||||||
|
}
|
||||||
func (ec errorConnection) Send(string, ...interface{}) error { return ec.err }
|
func (ec errorConnection) Send(string, ...interface{}) error { return ec.err }
|
||||||
func (ec errorConnection) Err() error { return ec.err }
|
func (ec errorConnection) Err() error { return ec.err }
|
||||||
func (ec errorConnection) Close() error { return ec.err }
|
func (ec errorConnection) Close() error { return nil }
|
||||||
func (ec errorConnection) Flush() error { return ec.err }
|
func (ec errorConnection) Flush() error { return ec.err }
|
||||||
func (ec errorConnection) Receive() (interface{}, error) { return nil, ec.err }
|
func (ec errorConnection) Receive() (interface{}, error) { return nil, ec.err }
|
||||||
|
func (ec errorConnection) ReceiveWithTimeout(time.Duration) (interface{}, error) { return nil, ec.err }
|
||||||
|
20
vendor/github.com/garyburd/redigo/redis/pubsub.go
generated
vendored
20
vendor/github.com/garyburd/redigo/redis/pubsub.go
generated
vendored
@ -14,11 +14,13 @@
|
|||||||
|
|
||||||
package redis
|
package redis
|
||||||
|
|
||||||
import "errors"
|
import (
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
// Subscription represents a subscribe or unsubscribe notification.
|
// Subscription represents a subscribe or unsubscribe notification.
|
||||||
type Subscription struct {
|
type Subscription struct {
|
||||||
|
|
||||||
// Kind is "subscribe", "unsubscribe", "psubscribe" or "punsubscribe"
|
// Kind is "subscribe", "unsubscribe", "psubscribe" or "punsubscribe"
|
||||||
Kind string
|
Kind string
|
||||||
|
|
||||||
@ -31,7 +33,6 @@ type Subscription struct {
|
|||||||
|
|
||||||
// Message represents a message notification.
|
// Message represents a message notification.
|
||||||
type Message struct {
|
type Message struct {
|
||||||
|
|
||||||
// The originating channel.
|
// The originating channel.
|
||||||
Channel string
|
Channel string
|
||||||
|
|
||||||
@ -41,7 +42,6 @@ type Message struct {
|
|||||||
|
|
||||||
// PMessage represents a pmessage notification.
|
// PMessage represents a pmessage notification.
|
||||||
type PMessage struct {
|
type PMessage struct {
|
||||||
|
|
||||||
// The matched pattern.
|
// The matched pattern.
|
||||||
Pattern string
|
Pattern string
|
||||||
|
|
||||||
@ -106,7 +106,17 @@ func (c PubSubConn) Ping(data string) error {
|
|||||||
// or error. The return value is intended to be used directly in a type switch
|
// or error. The return value is intended to be used directly in a type switch
|
||||||
// as illustrated in the PubSubConn example.
|
// as illustrated in the PubSubConn example.
|
||||||
func (c PubSubConn) Receive() interface{} {
|
func (c PubSubConn) Receive() interface{} {
|
||||||
reply, err := Values(c.Conn.Receive())
|
return c.receiveInternal(c.Conn.Receive())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReceiveWithTimeout is like Receive, but it allows the application to
|
||||||
|
// override the connection's default timeout.
|
||||||
|
func (c PubSubConn) ReceiveWithTimeout(timeout time.Duration) interface{} {
|
||||||
|
return c.receiveInternal(ReceiveWithTimeout(c.Conn, timeout))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c PubSubConn) receiveInternal(replyArg interface{}, errArg error) interface{} {
|
||||||
|
reply, err := Values(replyArg, errArg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
165
vendor/github.com/garyburd/redigo/redis/pubsub_example_test.go
generated
vendored
Normal file
165
vendor/github.com/garyburd/redigo/redis/pubsub_example_test.go
generated
vendored
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
// Copyright 2012 Gary Burd
|
||||||
|
//
|
||||||
|
// Licensed 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.
|
||||||
|
|
||||||
|
// +build go1.7
|
||||||
|
|
||||||
|
package redis_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/garyburd/redigo/redis"
|
||||||
|
)
|
||||||
|
|
||||||
|
// listenPubSubChannels listens for messages on Redis pubsub channels. The
|
||||||
|
// onStart function is called after the channels are subscribed. The onMessage
|
||||||
|
// function is called for each message.
|
||||||
|
func listenPubSubChannels(ctx context.Context, redisServerAddr string,
|
||||||
|
onStart func() error,
|
||||||
|
onMessage func(channel string, data []byte) error,
|
||||||
|
channels ...string) error {
|
||||||
|
// A ping is set to the server with this period to test for the health of
|
||||||
|
// the connection and server.
|
||||||
|
const healthCheckPeriod = time.Minute
|
||||||
|
|
||||||
|
c, err := redis.Dial("tcp", redisServerAddr,
|
||||||
|
// Read timeout on server should be greater than ping period.
|
||||||
|
redis.DialReadTimeout(healthCheckPeriod+10*time.Second),
|
||||||
|
redis.DialWriteTimeout(10*time.Second))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer c.Close()
|
||||||
|
|
||||||
|
psc := redis.PubSubConn{Conn: c}
|
||||||
|
|
||||||
|
if err := psc.Subscribe(redis.Args{}.AddFlat(channels)...); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
done := make(chan error, 1)
|
||||||
|
|
||||||
|
// Start a goroutine to receive notifications from the server.
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
switch n := psc.Receive().(type) {
|
||||||
|
case error:
|
||||||
|
done <- n
|
||||||
|
return
|
||||||
|
case redis.Message:
|
||||||
|
if err := onMessage(n.Channel, n.Data); err != nil {
|
||||||
|
done <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case redis.Subscription:
|
||||||
|
switch n.Count {
|
||||||
|
case len(channels):
|
||||||
|
// Notify application when all channels are subscribed.
|
||||||
|
if err := onStart(); err != nil {
|
||||||
|
done <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case 0:
|
||||||
|
// Return from the goroutine when all channels are unsubscribed.
|
||||||
|
done <- nil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
ticker := time.NewTicker(healthCheckPeriod)
|
||||||
|
defer ticker.Stop()
|
||||||
|
loop:
|
||||||
|
for err == nil {
|
||||||
|
select {
|
||||||
|
case <-ticker.C:
|
||||||
|
// Send ping to test health of connection and server. If
|
||||||
|
// corresponding pong is not received, then receive on the
|
||||||
|
// connection will timeout and the receive goroutine will exit.
|
||||||
|
if err = psc.Ping(""); err != nil {
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
case <-ctx.Done():
|
||||||
|
break loop
|
||||||
|
case err := <-done:
|
||||||
|
// Return error from the receive goroutine.
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signal the receiving goroutine to exit by unsubscribing from all channels.
|
||||||
|
psc.Unsubscribe()
|
||||||
|
|
||||||
|
// Wait for goroutine to complete.
|
||||||
|
return <-done
|
||||||
|
}
|
||||||
|
|
||||||
|
func publish() {
|
||||||
|
c, err := dial()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer c.Close()
|
||||||
|
|
||||||
|
c.Do("PUBLISH", "c1", "hello")
|
||||||
|
c.Do("PUBLISH", "c2", "world")
|
||||||
|
c.Do("PUBLISH", "c1", "goodbye")
|
||||||
|
}
|
||||||
|
|
||||||
|
// This example shows how receive pubsub notifications with cancelation and
|
||||||
|
// health checks.
|
||||||
|
func ExamplePubSubConn() {
|
||||||
|
redisServerAddr, err := serverAddr()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
|
||||||
|
err = listenPubSubChannels(ctx,
|
||||||
|
redisServerAddr,
|
||||||
|
func() error {
|
||||||
|
// The start callback is a good place to backfill missed
|
||||||
|
// notifications. For the purpose of this example, a goroutine is
|
||||||
|
// started to send notifications.
|
||||||
|
go publish()
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
func(channel string, message []byte) error {
|
||||||
|
fmt.Printf("channel: %s, message: %s\n", channel, message)
|
||||||
|
|
||||||
|
// For the purpose of this example, cancel the listener's context
|
||||||
|
// after receiving last message sent by publish().
|
||||||
|
if string(message) == "goodbye" {
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
"c1", "c2")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// channel: c1, message: hello
|
||||||
|
// channel: c2, message: world
|
||||||
|
// channel: c1, message: goodbye
|
||||||
|
}
|
88
vendor/github.com/garyburd/redigo/redis/pubsub_test.go
generated
vendored
88
vendor/github.com/garyburd/redigo/redis/pubsub_test.go
generated
vendored
@ -15,93 +15,13 @@
|
|||||||
package redis_test
|
package redis_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/garyburd/redigo/redis"
|
"github.com/garyburd/redigo/redis"
|
||||||
)
|
)
|
||||||
|
|
||||||
func publish(channel, value interface{}) {
|
|
||||||
c, err := dial()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
c.Do("PUBLISH", channel, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Applications can receive pushed messages from one goroutine and manage subscriptions from another goroutine.
|
|
||||||
func ExamplePubSubConn() {
|
|
||||||
c, err := dial()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
wg.Add(2)
|
|
||||||
|
|
||||||
psc := redis.PubSubConn{Conn: c}
|
|
||||||
|
|
||||||
// This goroutine receives and prints pushed notifications from the server.
|
|
||||||
// The goroutine exits when the connection is unsubscribed from all
|
|
||||||
// channels or there is an error.
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
for {
|
|
||||||
switch n := psc.Receive().(type) {
|
|
||||||
case redis.Message:
|
|
||||||
fmt.Printf("Message: %s %s\n", n.Channel, n.Data)
|
|
||||||
case redis.PMessage:
|
|
||||||
fmt.Printf("PMessage: %s %s %s\n", n.Pattern, n.Channel, n.Data)
|
|
||||||
case redis.Subscription:
|
|
||||||
fmt.Printf("Subscription: %s %s %d\n", n.Kind, n.Channel, n.Count)
|
|
||||||
if n.Count == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case error:
|
|
||||||
fmt.Printf("error: %v\n", n)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
// This goroutine manages subscriptions for the connection.
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
|
|
||||||
psc.Subscribe("example")
|
|
||||||
psc.PSubscribe("p*")
|
|
||||||
|
|
||||||
// The following function calls publish a message using another
|
|
||||||
// connection to the Redis server.
|
|
||||||
publish("example", "hello")
|
|
||||||
publish("example", "world")
|
|
||||||
publish("pexample", "foo")
|
|
||||||
publish("pexample", "bar")
|
|
||||||
|
|
||||||
// Unsubscribe from all connections. This will cause the receiving
|
|
||||||
// goroutine to exit.
|
|
||||||
psc.Unsubscribe()
|
|
||||||
psc.PUnsubscribe()
|
|
||||||
}()
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
|
|
||||||
// Output:
|
|
||||||
// Subscription: subscribe example 1
|
|
||||||
// Subscription: psubscribe p* 2
|
|
||||||
// Message: example hello
|
|
||||||
// Message: example world
|
|
||||||
// PMessage: p* pexample foo
|
|
||||||
// PMessage: p* pexample bar
|
|
||||||
// Subscription: unsubscribe example 1
|
|
||||||
// Subscription: punsubscribe p* 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func expectPushed(t *testing.T, c redis.PubSubConn, message string, expected interface{}) {
|
func expectPushed(t *testing.T, c redis.PubSubConn, message string, expected interface{}) {
|
||||||
actual := c.Receive()
|
actual := c.Receive()
|
||||||
if !reflect.DeepEqual(actual, expected) {
|
if !reflect.DeepEqual(actual, expected) {
|
||||||
@ -145,4 +65,10 @@ func TestPushed(t *testing.T) {
|
|||||||
c.Conn.Send("PING")
|
c.Conn.Send("PING")
|
||||||
c.Conn.Flush()
|
c.Conn.Flush()
|
||||||
expectPushed(t, c, `Send("PING")`, redis.Pong{})
|
expectPushed(t, c, `Send("PING")`, redis.Pong{})
|
||||||
|
|
||||||
|
c.Ping("timeout")
|
||||||
|
got := c.ReceiveWithTimeout(time.Minute)
|
||||||
|
if want := (redis.Pong{Data: "timeout"}); want != got {
|
||||||
|
t.Errorf("recv /w timeout got %v, want %v", got, want)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
56
vendor/github.com/garyburd/redigo/redis/redis.go
generated
vendored
56
vendor/github.com/garyburd/redigo/redis/redis.go
generated
vendored
@ -14,6 +14,11 @@
|
|||||||
|
|
||||||
package redis
|
package redis
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
// Error represents an error returned in a command reply.
|
// Error represents an error returned in a command reply.
|
||||||
type Error string
|
type Error string
|
||||||
|
|
||||||
@ -59,3 +64,54 @@ type Scanner interface {
|
|||||||
// loss of information.
|
// loss of information.
|
||||||
RedisScan(src interface{}) error
|
RedisScan(src interface{}) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConnWithTimeout is an optional interface that allows the caller to override
|
||||||
|
// a connection's default read timeout. This interface is useful for executing
|
||||||
|
// the BLPOP, BRPOP, BRPOPLPUSH, XREAD and other commands that block at the
|
||||||
|
// server.
|
||||||
|
//
|
||||||
|
// A connection's default read timeout is set with the DialReadTimeout dial
|
||||||
|
// option. Applications should rely on the default timeout for commands that do
|
||||||
|
// not block at the server.
|
||||||
|
//
|
||||||
|
// All of the Conn implementations in this package satisfy the ConnWithTimeout
|
||||||
|
// interface.
|
||||||
|
//
|
||||||
|
// Use the DoWithTimeout and ReceiveWithTimeout helper functions to simplify
|
||||||
|
// use of this interface.
|
||||||
|
type ConnWithTimeout interface {
|
||||||
|
Conn
|
||||||
|
|
||||||
|
// Do sends a command to the server and returns the received reply.
|
||||||
|
// The timeout overrides the read timeout set when dialing the
|
||||||
|
// connection.
|
||||||
|
DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (reply interface{}, err error)
|
||||||
|
|
||||||
|
// Receive receives a single reply from the Redis server. The timeout
|
||||||
|
// overrides the read timeout set when dialing the connection.
|
||||||
|
ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
var errTimeoutNotSupported = errors.New("redis: connection does not support ConnWithTimeout")
|
||||||
|
|
||||||
|
// DoWithTimeout executes a Redis command with the specified read timeout. If
|
||||||
|
// the connection does not satisfy the ConnWithTimeout interface, then an error
|
||||||
|
// is returned.
|
||||||
|
func DoWithTimeout(c Conn, timeout time.Duration, cmd string, args ...interface{}) (interface{}, error) {
|
||||||
|
cwt, ok := c.(ConnWithTimeout)
|
||||||
|
if !ok {
|
||||||
|
return nil, errTimeoutNotSupported
|
||||||
|
}
|
||||||
|
return cwt.DoWithTimeout(timeout, cmd, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReceiveWithTimeout receives a reply with the specified read timeout. If the
|
||||||
|
// connection does not satisfy the ConnWithTimeout interface, then an error is
|
||||||
|
// returned.
|
||||||
|
func ReceiveWithTimeout(c Conn, timeout time.Duration) (interface{}, error) {
|
||||||
|
cwt, ok := c.(ConnWithTimeout)
|
||||||
|
if !ok {
|
||||||
|
return nil, errTimeoutNotSupported
|
||||||
|
}
|
||||||
|
return cwt.ReceiveWithTimeout(timeout)
|
||||||
|
}
|
||||||
|
71
vendor/github.com/garyburd/redigo/redis/redis_test.go
generated
vendored
Normal file
71
vendor/github.com/garyburd/redigo/redis/redis_test.go
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// Copyright 2017 Gary Burd
|
||||||
|
//
|
||||||
|
// Licensed 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 redis_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/garyburd/redigo/redis"
|
||||||
|
)
|
||||||
|
|
||||||
|
type timeoutTestConn int
|
||||||
|
|
||||||
|
func (tc timeoutTestConn) Do(string, ...interface{}) (interface{}, error) {
|
||||||
|
return time.Duration(-1), nil
|
||||||
|
}
|
||||||
|
func (tc timeoutTestConn) DoWithTimeout(timeout time.Duration, cmd string, args ...interface{}) (interface{}, error) {
|
||||||
|
return timeout, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tc timeoutTestConn) Receive() (interface{}, error) {
|
||||||
|
return time.Duration(-1), nil
|
||||||
|
}
|
||||||
|
func (tc timeoutTestConn) ReceiveWithTimeout(timeout time.Duration) (interface{}, error) {
|
||||||
|
return timeout, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tc timeoutTestConn) Send(string, ...interface{}) error { return nil }
|
||||||
|
func (tc timeoutTestConn) Err() error { return nil }
|
||||||
|
func (tc timeoutTestConn) Close() error { return nil }
|
||||||
|
func (tc timeoutTestConn) Flush() error { return nil }
|
||||||
|
|
||||||
|
func testTimeout(t *testing.T, c redis.Conn) {
|
||||||
|
r, err := c.Do("PING")
|
||||||
|
if r != time.Duration(-1) || err != nil {
|
||||||
|
t.Errorf("Do() = %v, %v, want %v, %v", r, err, time.Duration(-1), nil)
|
||||||
|
}
|
||||||
|
r, err = redis.DoWithTimeout(c, time.Minute, "PING")
|
||||||
|
if r != time.Minute || err != nil {
|
||||||
|
t.Errorf("DoWithTimeout() = %v, %v, want %v, %v", r, err, time.Minute, nil)
|
||||||
|
}
|
||||||
|
r, err = c.Receive()
|
||||||
|
if r != time.Duration(-1) || err != nil {
|
||||||
|
t.Errorf("Receive() = %v, %v, want %v, %v", r, err, time.Duration(-1), nil)
|
||||||
|
}
|
||||||
|
r, err = redis.ReceiveWithTimeout(c, time.Minute)
|
||||||
|
if r != time.Minute || err != nil {
|
||||||
|
t.Errorf("ReceiveWithTimeout() = %v, %v, want %v, %v", r, err, time.Minute, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConnTimeout(t *testing.T) {
|
||||||
|
testTimeout(t, timeoutTestConn(0))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPoolConnTimeout(t *testing.T) {
|
||||||
|
p := &redis.Pool{Dial: func() (redis.Conn, error) { return timeoutTestConn(0), nil }}
|
||||||
|
testTimeout(t, p.Get())
|
||||||
|
}
|
156
vendor/github.com/garyburd/redigo/redis/reply.go
generated
vendored
156
vendor/github.com/garyburd/redigo/redis/reply.go
generated
vendored
@ -243,34 +243,67 @@ func Values(reply interface{}, err error) ([]interface{}, error) {
|
|||||||
return nil, fmt.Errorf("redigo: unexpected type for Values, got type %T", reply)
|
return nil, fmt.Errorf("redigo: unexpected type for Values, got type %T", reply)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sliceHelper(reply interface{}, err error, name string, makeSlice func(int), assign func(int, interface{}) error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch reply := reply.(type) {
|
||||||
|
case []interface{}:
|
||||||
|
makeSlice(len(reply))
|
||||||
|
for i := range reply {
|
||||||
|
if reply[i] == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := assign(i, reply[i]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
case nil:
|
||||||
|
return ErrNil
|
||||||
|
case Error:
|
||||||
|
return reply
|
||||||
|
}
|
||||||
|
return fmt.Errorf("redigo: unexpected type for %s, got type %T", name, reply)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float64s is a helper that converts an array command reply to a []float64. If
|
||||||
|
// err is not equal to nil, then Float64s returns nil, err. Nil array items are
|
||||||
|
// converted to 0 in the output slice. Floats64 returns an error if an array
|
||||||
|
// item is not a bulk string or nil.
|
||||||
|
func Float64s(reply interface{}, err error) ([]float64, error) {
|
||||||
|
var result []float64
|
||||||
|
err = sliceHelper(reply, err, "Float64s", func(n int) { result = make([]float64, n) }, func(i int, v interface{}) error {
|
||||||
|
p, ok := v.([]byte)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("redigo: unexpected element type for Floats64, got type %T", v)
|
||||||
|
}
|
||||||
|
f, err := strconv.ParseFloat(string(p), 64)
|
||||||
|
result[i] = f
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
// Strings is a helper that converts an array command reply to a []string. If
|
// Strings is a helper that converts an array command reply to a []string. If
|
||||||
// err is not equal to nil, then Strings returns nil, err. Nil array items are
|
// err is not equal to nil, then Strings returns nil, err. Nil array items are
|
||||||
// converted to "" in the output slice. Strings returns an error if an array
|
// converted to "" in the output slice. Strings returns an error if an array
|
||||||
// item is not a bulk string or nil.
|
// item is not a bulk string or nil.
|
||||||
func Strings(reply interface{}, err error) ([]string, error) {
|
func Strings(reply interface{}, err error) ([]string, error) {
|
||||||
if err != nil {
|
var result []string
|
||||||
return nil, err
|
err = sliceHelper(reply, err, "Strings", func(n int) { result = make([]string, n) }, func(i int, v interface{}) error {
|
||||||
|
switch v := v.(type) {
|
||||||
|
case string:
|
||||||
|
result[i] = v
|
||||||
|
return nil
|
||||||
|
case []byte:
|
||||||
|
result[i] = string(v)
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("redigo: unexpected element type for Strings, got type %T", v)
|
||||||
}
|
}
|
||||||
switch reply := reply.(type) {
|
})
|
||||||
case []interface{}:
|
return result, err
|
||||||
result := make([]string, len(reply))
|
|
||||||
for i := range reply {
|
|
||||||
if reply[i] == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
p, ok := reply[i].([]byte)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("redigo: unexpected element type for Strings, got type %T", reply[i])
|
|
||||||
}
|
|
||||||
result[i] = string(p)
|
|
||||||
}
|
|
||||||
return result, nil
|
|
||||||
case nil:
|
|
||||||
return nil, ErrNil
|
|
||||||
case Error:
|
|
||||||
return nil, reply
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("redigo: unexpected type for Strings, got type %T", reply)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ByteSlices is a helper that converts an array command reply to a [][]byte.
|
// ByteSlices is a helper that converts an array command reply to a [][]byte.
|
||||||
@ -278,43 +311,64 @@ func Strings(reply interface{}, err error) ([]string, error) {
|
|||||||
// items are stay nil. ByteSlices returns an error if an array item is not a
|
// items are stay nil. ByteSlices returns an error if an array item is not a
|
||||||
// bulk string or nil.
|
// bulk string or nil.
|
||||||
func ByteSlices(reply interface{}, err error) ([][]byte, error) {
|
func ByteSlices(reply interface{}, err error) ([][]byte, error) {
|
||||||
if err != nil {
|
var result [][]byte
|
||||||
return nil, err
|
err = sliceHelper(reply, err, "ByteSlices", func(n int) { result = make([][]byte, n) }, func(i int, v interface{}) error {
|
||||||
}
|
p, ok := v.([]byte)
|
||||||
switch reply := reply.(type) {
|
|
||||||
case []interface{}:
|
|
||||||
result := make([][]byte, len(reply))
|
|
||||||
for i := range reply {
|
|
||||||
if reply[i] == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
p, ok := reply[i].([]byte)
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("redigo: unexpected element type for ByteSlices, got type %T", reply[i])
|
return fmt.Errorf("redigo: unexpected element type for ByteSlices, got type %T", v)
|
||||||
}
|
}
|
||||||
result[i] = p
|
result[i] = p
|
||||||
}
|
return nil
|
||||||
return result, nil
|
})
|
||||||
case nil:
|
return result, err
|
||||||
return nil, ErrNil
|
|
||||||
case Error:
|
|
||||||
return nil, reply
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("redigo: unexpected type for ByteSlices, got type %T", reply)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ints is a helper that converts an array command reply to a []int. If
|
// Int64s is a helper that converts an array command reply to a []int64.
|
||||||
// err is not equal to nil, then Ints returns nil, err.
|
// If err is not equal to nil, then Int64s returns nil, err. Nil array
|
||||||
|
// items are stay nil. Int64s returns an error if an array item is not a
|
||||||
|
// bulk string or nil.
|
||||||
|
func Int64s(reply interface{}, err error) ([]int64, error) {
|
||||||
|
var result []int64
|
||||||
|
err = sliceHelper(reply, err, "Int64s", func(n int) { result = make([]int64, n) }, func(i int, v interface{}) error {
|
||||||
|
switch v := v.(type) {
|
||||||
|
case int64:
|
||||||
|
result[i] = v
|
||||||
|
return nil
|
||||||
|
case []byte:
|
||||||
|
n, err := strconv.ParseInt(string(v), 10, 64)
|
||||||
|
result[i] = n
|
||||||
|
return err
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("redigo: unexpected element type for Int64s, got type %T", v)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ints is a helper that converts an array command reply to a []in.
|
||||||
|
// If err is not equal to nil, then Ints returns nil, err. Nil array
|
||||||
|
// items are stay nil. Ints returns an error if an array item is not a
|
||||||
|
// bulk string or nil.
|
||||||
func Ints(reply interface{}, err error) ([]int, error) {
|
func Ints(reply interface{}, err error) ([]int, error) {
|
||||||
var ints []int
|
var result []int
|
||||||
values, err := Values(reply, err)
|
err = sliceHelper(reply, err, "Ints", func(n int) { result = make([]int, n) }, func(i int, v interface{}) error {
|
||||||
if err != nil {
|
switch v := v.(type) {
|
||||||
return ints, err
|
case int64:
|
||||||
|
n := int(v)
|
||||||
|
if int64(n) != v {
|
||||||
|
return strconv.ErrRange
|
||||||
}
|
}
|
||||||
if err := ScanSlice(values, &ints); err != nil {
|
result[i] = n
|
||||||
return ints, err
|
return nil
|
||||||
|
case []byte:
|
||||||
|
n, err := strconv.Atoi(string(v))
|
||||||
|
result[i] = n
|
||||||
|
return err
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("redigo: unexpected element type for Ints, got type %T", v)
|
||||||
}
|
}
|
||||||
return ints, nil
|
})
|
||||||
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// StringMap is a helper that converts an array of strings (alternating key, value)
|
// StringMap is a helper that converts an array of strings (alternating key, value)
|
||||||
|
41
vendor/github.com/garyburd/redigo/redis/reply_test.go
generated
vendored
41
vendor/github.com/garyburd/redigo/redis/reply_test.go
generated
vendored
@ -37,24 +37,44 @@ var replyTests = []struct {
|
|||||||
expected valueError
|
expected valueError
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"ints([v1, v2])",
|
"ints([[]byte, []byte])",
|
||||||
ve(redis.Ints([]interface{}{[]byte("4"), []byte("5")}, nil)),
|
ve(redis.Ints([]interface{}{[]byte("4"), []byte("5")}, nil)),
|
||||||
ve([]int{4, 5}, nil),
|
ve([]int{4, 5}, nil),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ints([nt64, int64])",
|
||||||
|
ve(redis.Ints([]interface{}{int64(4), int64(5)}, nil)),
|
||||||
|
ve([]int{4, 5}, nil),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ints([[]byte, nil, []byte])",
|
||||||
|
ve(redis.Ints([]interface{}{[]byte("4"), nil, []byte("5")}, nil)),
|
||||||
|
ve([]int{4, 0, 5}, nil),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ints(nil)",
|
"ints(nil)",
|
||||||
ve(redis.Ints(nil, nil)),
|
ve(redis.Ints(nil, nil)),
|
||||||
ve([]int(nil), redis.ErrNil),
|
ve([]int(nil), redis.ErrNil),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"strings([v1, v2])",
|
"int64s([[]byte, []byte])",
|
||||||
|
ve(redis.Int64s([]interface{}{[]byte("4"), []byte("5")}, nil)),
|
||||||
|
ve([]int64{4, 5}, nil),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"int64s([int64, int64])",
|
||||||
|
ve(redis.Int64s([]interface{}{int64(4), int64(5)}, nil)),
|
||||||
|
ve([]int64{4, 5}, nil),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"strings([[]byte, []bytev2])",
|
||||||
ve(redis.Strings([]interface{}{[]byte("v1"), []byte("v2")}, nil)),
|
ve(redis.Strings([]interface{}{[]byte("v1"), []byte("v2")}, nil)),
|
||||||
ve([]string{"v1", "v2"}, nil),
|
ve([]string{"v1", "v2"}, nil),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"strings(nil)",
|
"strings([string, string])",
|
||||||
ve(redis.Strings(nil, nil)),
|
ve(redis.Strings([]interface{}{"v1", "v2"}, nil)),
|
||||||
ve([]string(nil), redis.ErrNil),
|
ve([]string{"v1", "v2"}, nil),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"byteslices([v1, v2])",
|
"byteslices([v1, v2])",
|
||||||
@ -62,9 +82,9 @@ var replyTests = []struct {
|
|||||||
ve([][]byte{[]byte("v1"), []byte("v2")}, nil),
|
ve([][]byte{[]byte("v1"), []byte("v2")}, nil),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"byteslices(nil)",
|
"float64s([v1, v2])",
|
||||||
ve(redis.ByteSlices(nil, nil)),
|
ve(redis.Float64s([]interface{}{[]byte("1.234"), []byte("5.678")}, nil)),
|
||||||
ve([][]byte(nil), redis.ErrNil),
|
ve([]float64{1.234, 5.678}, nil),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"values([v1, v2])",
|
"values([v1, v2])",
|
||||||
@ -120,6 +140,11 @@ func dial() (redis.Conn, error) {
|
|||||||
return redis.DialDefaultServer()
|
return redis.DialDefaultServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// serverAddr wraps DefaultServerAddr() with a more suitable function name for examples.
|
||||||
|
func serverAddr() (string, error) {
|
||||||
|
return redis.DefaultServerAddr()
|
||||||
|
}
|
||||||
|
|
||||||
func ExampleBool() {
|
func ExampleBool() {
|
||||||
c, err := dial()
|
c, err := dial()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
17
vendor/github.com/garyburd/redigo/redis/test_test.go
generated
vendored
17
vendor/github.com/garyburd/redigo/redis/test_test.go
generated
vendored
@ -38,6 +38,7 @@ var (
|
|||||||
ErrNegativeInt = errNegativeInt
|
ErrNegativeInt = errNegativeInt
|
||||||
|
|
||||||
serverPath = flag.String("redis-server", "redis-server", "Path to redis server binary")
|
serverPath = flag.String("redis-server", "redis-server", "Path to redis server binary")
|
||||||
|
serverAddress = flag.String("redis-address", "127.0.0.1", "The address of the server")
|
||||||
serverBasePort = flag.Int("redis-port", 16379, "Beginning of port range for test servers")
|
serverBasePort = flag.Int("redis-port", 16379, "Beginning of port range for test servers")
|
||||||
serverLogName = flag.String("redis-log", "", "Write Redis server logs to `filename`")
|
serverLogName = flag.String("redis-log", "", "Write Redis server logs to `filename`")
|
||||||
serverLog = ioutil.Discard
|
serverLog = ioutil.Discard
|
||||||
@ -126,28 +127,32 @@ func stopDefaultServer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// startDefaultServer starts the default server if not already running.
|
// DefaultServerAddr starts the test server if not already started and returns
|
||||||
func startDefaultServer() error {
|
// the address of that server.
|
||||||
|
func DefaultServerAddr() (string, error) {
|
||||||
defaultServerMu.Lock()
|
defaultServerMu.Lock()
|
||||||
defer defaultServerMu.Unlock()
|
defer defaultServerMu.Unlock()
|
||||||
|
addr := fmt.Sprintf("%v:%d", *serverAddress, *serverBasePort)
|
||||||
if defaultServer != nil || defaultServerErr != nil {
|
if defaultServer != nil || defaultServerErr != nil {
|
||||||
return defaultServerErr
|
return addr, defaultServerErr
|
||||||
}
|
}
|
||||||
defaultServer, defaultServerErr = NewServer(
|
defaultServer, defaultServerErr = NewServer(
|
||||||
"default",
|
"default",
|
||||||
"--port", strconv.Itoa(*serverBasePort),
|
"--port", strconv.Itoa(*serverBasePort),
|
||||||
|
"--bind", *serverAddress,
|
||||||
"--save", "",
|
"--save", "",
|
||||||
"--appendonly", "no")
|
"--appendonly", "no")
|
||||||
return defaultServerErr
|
return addr, defaultServerErr
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialDefaultServer starts the test server if not already started and dials a
|
// DialDefaultServer starts the test server if not already started and dials a
|
||||||
// connection to the server.
|
// connection to the server.
|
||||||
func DialDefaultServer() (Conn, error) {
|
func DialDefaultServer() (Conn, error) {
|
||||||
if err := startDefaultServer(); err != nil {
|
addr, err := DefaultServerAddr()
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
c, err := Dial("tcp", fmt.Sprintf(":%d", *serverBasePort), DialReadTimeout(1*time.Second), DialWriteTimeout(1*time.Second))
|
c, err := Dial("tcp", addr, DialReadTimeout(1*time.Second), DialWriteTimeout(1*time.Second))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
3
vendor/github.com/golang/protobuf/jsonpb/jsonpb.go
generated
vendored
3
vendor/github.com/golang/protobuf/jsonpb/jsonpb.go
generated
vendored
@ -193,8 +193,7 @@ func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent, typeU
|
|||||||
// "Generated output always contains 3, 6, or 9 fractional digits,
|
// "Generated output always contains 3, 6, or 9 fractional digits,
|
||||||
// depending on required precision."
|
// depending on required precision."
|
||||||
s, ns := s.Field(0).Int(), s.Field(1).Int()
|
s, ns := s.Field(0).Int(), s.Field(1).Int()
|
||||||
d := time.Duration(s)*time.Second + time.Duration(ns)*time.Nanosecond
|
x := fmt.Sprintf("%d.%09d", s, ns)
|
||||||
x := fmt.Sprintf("%.9f", d.Seconds())
|
|
||||||
x = strings.TrimSuffix(x, "000")
|
x = strings.TrimSuffix(x, "000")
|
||||||
x = strings.TrimSuffix(x, "000")
|
x = strings.TrimSuffix(x, "000")
|
||||||
out.write(`"`)
|
out.write(`"`)
|
||||||
|
1
vendor/github.com/golang/protobuf/jsonpb/jsonpb_test.go
generated
vendored
1
vendor/github.com/golang/protobuf/jsonpb/jsonpb_test.go
generated
vendored
@ -407,6 +407,7 @@ var marshalingTests = []struct {
|
|||||||
{"Any with WKT", marshaler, anyWellKnown, anyWellKnownJSON},
|
{"Any with WKT", marshaler, anyWellKnown, anyWellKnownJSON},
|
||||||
{"Any with WKT and indent", marshalerAllOptions, anyWellKnown, anyWellKnownPrettyJSON},
|
{"Any with WKT and indent", marshalerAllOptions, anyWellKnown, anyWellKnownPrettyJSON},
|
||||||
{"Duration", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 3}}, `{"dur":"3.000s"}`},
|
{"Duration", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 3}}, `{"dur":"3.000s"}`},
|
||||||
|
{"Duration", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 100000000, Nanos: 1}}, `{"dur":"100000000.000000001s"}`},
|
||||||
{"Struct", marshaler, &pb.KnownTypes{St: &stpb.Struct{
|
{"Struct", marshaler, &pb.KnownTypes{St: &stpb.Struct{
|
||||||
Fields: map[string]*stpb.Value{
|
Fields: map[string]*stpb.Value{
|
||||||
"one": {Kind: &stpb.Value_StringValue{"loneliest number"}},
|
"one": {Kind: &stpb.Value_StringValue{"loneliest number"}},
|
||||||
|
2
vendor/github.com/microcosm-cc/bluemonday/CREDITS.md
generated
vendored
2
vendor/github.com/microcosm-cc/bluemonday/CREDITS.md
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
|
1. Andrew Krasichkov @buglloc https://github.com/buglloc
|
||||||
1. John Graham-Cumming http://jgc.org/
|
1. John Graham-Cumming http://jgc.org/
|
||||||
1. Mike Samuel mikesamuel@gmail.com
|
1. Mike Samuel mikesamuel@gmail.com
|
||||||
1. Dmitri Shuralyov shurcooL@gmail.com
|
1. Dmitri Shuralyov shurcooL@gmail.com
|
||||||
|
2
vendor/github.com/microcosm-cc/bluemonday/README.md
generated
vendored
2
vendor/github.com/microcosm-cc/bluemonday/README.md
generated
vendored
@ -312,7 +312,7 @@ It is not the job of bluemonday to fix your bad HTML, it is merely the job of bl
|
|||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
* Add support for CSS sanitisation to allow some CSS properties based on a whitelist, possibly using the [Gorilla CSS3 scanner](http://www.gorillatoolkit.org/pkg/css/scanner)
|
* Add support for CSS sanitisation to allow some CSS properties based on a whitelist, possibly using the [Gorilla CSS3 scanner](http://www.gorillatoolkit.org/pkg/css/scanner) - PRs welcome so long as testing covers XSS and demonstrates safety first
|
||||||
* Investigate whether devs want to blacklist elements and attributes. This would allow devs to take an existing policy (such as the `bluemonday.UGCPolicy()` ) that encapsulates 90% of what they're looking for but does more than they need, and to remove the extra things they do not want to make it 100% what they want
|
* Investigate whether devs want to blacklist elements and attributes. This would allow devs to take an existing policy (such as the `bluemonday.UGCPolicy()` ) that encapsulates 90% of what they're looking for but does more than they need, and to remove the extra things they do not want to make it 100% what they want
|
||||||
* Investigate whether devs want a validating HTML mode, in which the HTML elements are not just transformed into a balanced tree (every start tag has a closing tag at the correct depth) but also that elements and character data appear only in their allowed context (i.e. that a `table` element isn't a descendent of a `caption`, that `colgroup`, `thead`, `tbody`, `tfoot` and `tr` are permitted, and that character data is not permitted)
|
* Investigate whether devs want a validating HTML mode, in which the HTML elements are not just transformed into a balanced tree (every start tag has a closing tag at the correct depth) but also that elements and character data appear only in their allowed context (i.e. that a `table` element isn't a descendent of a `caption`, that `colgroup`, `thead`, `tbody`, `tfoot` and `tr` are permitted, and that character data is not permitted)
|
||||||
|
|
||||||
|
1
vendor/github.com/microcosm-cc/bluemonday/cmd/sanitise_html_email/main.go
generated
vendored
1
vendor/github.com/microcosm-cc/bluemonday/cmd/sanitise_html_email/main.go
generated
vendored
@ -27,7 +27,6 @@ func main() {
|
|||||||
|
|
||||||
// HTML email is often displayed in iframes and needs to preserve core
|
// HTML email is often displayed in iframes and needs to preserve core
|
||||||
// structure
|
// structure
|
||||||
p.AllowDocType(true)
|
|
||||||
p.AllowElements("html", "head", "body", "title")
|
p.AllowElements("html", "head", "body", "title")
|
||||||
|
|
||||||
// There are not safe, and is only being done here to demonstrate how to
|
// There are not safe, and is only being done here to demonstrate how to
|
||||||
|
19
vendor/github.com/microcosm-cc/bluemonday/policy.go
generated
vendored
19
vendor/github.com/microcosm-cc/bluemonday/policy.go
generated
vendored
@ -47,9 +47,6 @@ type Policy struct {
|
|||||||
// exceptions
|
// exceptions
|
||||||
initialized bool
|
initialized bool
|
||||||
|
|
||||||
// Allows the <!DOCTYPE > tag to exist in the sanitized document
|
|
||||||
allowDocType bool
|
|
||||||
|
|
||||||
// If true then we add spaces when stripping tags, specifically the closing
|
// If true then we add spaces when stripping tags, specifically the closing
|
||||||
// tag is replaced by a space character.
|
// tag is replaced by a space character.
|
||||||
addSpaces bool
|
addSpaces bool
|
||||||
@ -369,21 +366,6 @@ func (p *Policy) AllowURLSchemeWithCustomPolicy(
|
|||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// AllowDocType states whether the HTML sanitised by the sanitizer is allowed to
|
|
||||||
// contain the HTML DocType tag: <!DOCTYPE HTML> or one of it's variants.
|
|
||||||
//
|
|
||||||
// The HTML spec only permits one doctype per document, and as you know how you
|
|
||||||
// are using the output of this, you know best as to whether we should ignore it
|
|
||||||
// (default) or not.
|
|
||||||
//
|
|
||||||
// If you are sanitizing a HTML fragment the default (false) is fine.
|
|
||||||
func (p *Policy) AllowDocType(allow bool) *Policy {
|
|
||||||
|
|
||||||
p.allowDocType = allow
|
|
||||||
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddSpaceWhenStrippingTag states whether to add a single space " " when
|
// AddSpaceWhenStrippingTag states whether to add a single space " " when
|
||||||
// removing tags that are not whitelisted by the policy.
|
// removing tags that are not whitelisted by the policy.
|
||||||
//
|
//
|
||||||
@ -498,6 +480,7 @@ func (p *Policy) addDefaultElementsWithoutAttrs() {
|
|||||||
p.setOfElementsAllowedWithoutAttrs["ruby"] = struct{}{}
|
p.setOfElementsAllowedWithoutAttrs["ruby"] = struct{}{}
|
||||||
p.setOfElementsAllowedWithoutAttrs["s"] = struct{}{}
|
p.setOfElementsAllowedWithoutAttrs["s"] = struct{}{}
|
||||||
p.setOfElementsAllowedWithoutAttrs["samp"] = struct{}{}
|
p.setOfElementsAllowedWithoutAttrs["samp"] = struct{}{}
|
||||||
|
p.setOfElementsAllowedWithoutAttrs["script"] = struct{}{}
|
||||||
p.setOfElementsAllowedWithoutAttrs["section"] = struct{}{}
|
p.setOfElementsAllowedWithoutAttrs["section"] = struct{}{}
|
||||||
p.setOfElementsAllowedWithoutAttrs["select"] = struct{}{}
|
p.setOfElementsAllowedWithoutAttrs["select"] = struct{}{}
|
||||||
p.setOfElementsAllowedWithoutAttrs["small"] = struct{}{}
|
p.setOfElementsAllowedWithoutAttrs["small"] = struct{}{}
|
||||||
|
24
vendor/github.com/microcosm-cc/bluemonday/sanitize.go
generated
vendored
24
vendor/github.com/microcosm-cc/bluemonday/sanitize.go
generated
vendored
@ -112,9 +112,13 @@ func (p *Policy) sanitize(r io.Reader) *bytes.Buffer {
|
|||||||
switch token.Type {
|
switch token.Type {
|
||||||
case html.DoctypeToken:
|
case html.DoctypeToken:
|
||||||
|
|
||||||
if p.allowDocType {
|
// DocType is not handled as there is no safe parsing mechanism
|
||||||
buff.WriteString(token.String())
|
// provided by golang.org/x/net/html for the content, and this can
|
||||||
}
|
// be misused to insert HTML tags that are not then sanitized
|
||||||
|
//
|
||||||
|
// One might wish to recursively sanitize here using the same policy
|
||||||
|
// but I will need to do some further testing before considering
|
||||||
|
// this.
|
||||||
|
|
||||||
case html.CommentToken:
|
case html.CommentToken:
|
||||||
|
|
||||||
@ -217,7 +221,7 @@ func (p *Policy) sanitize(r io.Reader) *bytes.Buffer {
|
|||||||
case html.TextToken:
|
case html.TextToken:
|
||||||
|
|
||||||
if !skipElementContent {
|
if !skipElementContent {
|
||||||
switch strings.ToLower(mostRecentlyStartedToken) {
|
switch mostRecentlyStartedToken {
|
||||||
case "script":
|
case "script":
|
||||||
// not encouraged, but if a policy allows JavaScript we
|
// not encouraged, but if a policy allows JavaScript we
|
||||||
// should not HTML escape it as that would break the output
|
// should not HTML escape it as that would break the output
|
||||||
@ -231,7 +235,6 @@ func (p *Policy) sanitize(r io.Reader) *bytes.Buffer {
|
|||||||
buff.WriteString(token.String())
|
buff.WriteString(token.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// A token that didn't exist in the html package when we wrote this
|
// A token that didn't exist in the html package when we wrote this
|
||||||
return &bytes.Buffer{}
|
return &bytes.Buffer{}
|
||||||
@ -490,13 +493,18 @@ func (p *Policy) allowNoAttrs(elementName string) bool {
|
|||||||
|
|
||||||
func (p *Policy) validURL(rawurl string) (string, bool) {
|
func (p *Policy) validURL(rawurl string) (string, bool) {
|
||||||
if p.requireParseableURLs {
|
if p.requireParseableURLs {
|
||||||
// URLs do not contain whitespace
|
// URLs are valid if when space is trimmed the URL is valid
|
||||||
if strings.Contains(rawurl, " ") ||
|
rawurl = strings.TrimSpace(rawurl)
|
||||||
|
|
||||||
|
// URLs cannot contain whitespace, unless it is a data-uri
|
||||||
|
if (strings.Contains(rawurl, " ") ||
|
||||||
strings.Contains(rawurl, "\t") ||
|
strings.Contains(rawurl, "\t") ||
|
||||||
strings.Contains(rawurl, "\n") {
|
strings.Contains(rawurl, "\n")) &&
|
||||||
|
!strings.HasPrefix(rawurl, `data:`) {
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// URLs are valid if they parse
|
||||||
u, err := url.Parse(rawurl)
|
u, err := url.Parse(rawurl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", false
|
return "", false
|
||||||
|
244
vendor/github.com/microcosm-cc/bluemonday/sanitize_test.go
generated
vendored
244
vendor/github.com/microcosm-cc/bluemonday/sanitize_test.go
generated
vendored
@ -92,39 +92,6 @@ func TestSignatureBehaviour(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAllowDocType(t *testing.T) {
|
|
||||||
p := NewPolicy()
|
|
||||||
p.AllowElements("b")
|
|
||||||
|
|
||||||
in := "<!DOCTYPE html>Hello, <b>World</b>!"
|
|
||||||
expected := "Hello, <b>World</b>!"
|
|
||||||
|
|
||||||
out := p.Sanitize(in)
|
|
||||||
if out != expected {
|
|
||||||
t.Errorf(
|
|
||||||
"test 1 failed;\ninput : %s\noutput : %s\nexpected: %s",
|
|
||||||
in,
|
|
||||||
out,
|
|
||||||
expected,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow the doctype and run the test again
|
|
||||||
p.AllowDocType(true)
|
|
||||||
|
|
||||||
expected = "<!DOCTYPE html>Hello, <b>World</b>!"
|
|
||||||
|
|
||||||
out = p.Sanitize(in)
|
|
||||||
if out != expected {
|
|
||||||
t.Errorf(
|
|
||||||
"test 1 failed;\ninput : %s\noutput : %s\nexpected: %s",
|
|
||||||
in,
|
|
||||||
out,
|
|
||||||
expected,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLinks(t *testing.T) {
|
func TestLinks(t *testing.T) {
|
||||||
|
|
||||||
tests := []test{
|
tests := []test{
|
||||||
@ -1506,3 +1473,214 @@ func TestTargetBlankNoOpener(t *testing.T) {
|
|||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIssue51(t *testing.T) {
|
||||||
|
// Whitespace in URLs is permitted within HTML according to:
|
||||||
|
// https://dev.w3.org/html5/spec-LC/urls.html#parsing-urls
|
||||||
|
//
|
||||||
|
// We were aggressively rejecting URLs that contained line feeds but these
|
||||||
|
// are permitted.
|
||||||
|
//
|
||||||
|
// This test ensures that we do not regress that fix.
|
||||||
|
p := NewPolicy()
|
||||||
|
p.AllowImages()
|
||||||
|
p.AllowDataURIImages()
|
||||||
|
|
||||||
|
input := `<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAIAAADajyQQAAAAhnpUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjadY5LCsNADEP3c4oewb+R7eOUkEBv0OPXZpKmm76FLIQRGvv7dYxHwyTDpgcSoMLSUp5lghZKxELct3RxXuVycsdDZRlkONn9aGd+MRWBw80dExs2qXbZlTVKu6hbqWfkT8l30Z/8WvEBQsUsKBcOhtYAAAoCaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA0LjQuMC1FeGl2MiI+CiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICBleGlmOlBpeGVsWERpbWVuc2lvbj0iNzIiCiAgIGV4aWY6UGl4ZWxZRGltZW5zaW9uPSI3MiIKICAgdGlmZjpJbWFnZVdpZHRoPSI3MiIKICAgdGlmZjpJbWFnZUhlaWdodD0iNzIiCiAgIHRpZmY6T3JpZW50YXRpb249IjEiLz4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Pq6cYi8AAAADc0JJVAgICNvhT+AAAAN7SURBVGje7dtRSBNhHADwfxJ3L96Le0kf1GD1sBDyO5ALbEkyMyY9bHswg+FDW5B7EKVhJSeElrQUcRIkFFHoi0toPriEVi8KbUQxKSYNk8HpYE5ot4e7e/l68NT08aTp6v9/25+P7+O3/3d3H3ffB7RooSSH7IQQYu0KS4qeeeEWyHbY+qLZvbbZiEcghBBHIJ43NhrQ4oYiRUU7sQ0lFJqPizbBEViUFCWfnOmyCp4ZaV/bfHLKIwiecLYUYJTSbLid2ALJX/E+q7VnUdGz0pSDOKakA39DQrQSd8RI0cqgCLEe8rZ55zb1X5oKwLAMywJoANpOI4ZhAEBdHnA6B5ZVPalqwHCckTGLAqvi69jPwZF36yrIK6GR4NrZjrbTbK2ziVsaeba0CaD+nAtOrtU6m6rY2qbazYWH08syqOtLwUcfoamjzpCsSPNPigy5bYQQIti7xuP6VaOshsV26052Uc/mE1M9DoEQQmxuMbyqGBvwBKUU/sUog380EIYwhCEMYQhD2DGMk4VCASuGMIQhDGEIQ9hxe0Af5eDyj7ejw5PRVAGgwnLNJ/qaK+HTnRZ/bF8rc9/s86umEoKpXyb8E+nWx7NP65nM+9HuB/5T5tc3zouzs/q7Ri0d6vdHLb5GU2lNxa0txuLq6aw3scDVNHZcrsjE0jKwnEmPQnQiVLg26KvnSmwqVjb3DjXvVC8djRVOtVbvGTbmh19utY55z7Cle/NQN94/8IcYl+iq2U19m55Mmb2d51ijnR45TP7yrPvmaME1NnZrrzjy1+mo1tBp6OI6DndF2Ji/f3s03Si+6r34p0FNRb5q50ULd4iuj7Bi8reR7uFUgzjYYYFcLpfL5WT9I0sm9l2rbjQfxnWEFcvFJsIZgEi/O3LgiaVmUluMubr8UN2fkGUZl1QIQxjCEIYwhCEMYYdbUuE+D4QhDGEIQxjC/luYvBK667zE8zx/oc0XXNK3B8vL0716tsX75IOe3fzwxNtyged5vuX6QGhFNThkUfakJ0Sb4H6RyFOqrIZ7rIInmqdUSQbsxDEez+5mI3lKpRm3YOuLSAql2fi4g9gDSUObZ4vy+o2tu/dmATiOBZA1UIEzcQDAMiaO+aPV9nbtKtfkwhWW4wBUWVOh3FTFsce2YnhSAk9K4EmJvxt4UgJPSuCSCmEIQxjCEAYAAL8BrebxGP8KiJcAAAAASUVORK5CYII=" alt="">`
|
||||||
|
out := p.Sanitize(input)
|
||||||
|
expected := `<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAIAAADajyQQAAAAhnpUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjadY5LCsNADEP3c4oewb+R7eOUkEBv0OPXZpKmm76FLIQRGvv7dYxHwyTDpgcSoMLSUp5lghZKxELct3RxXuVycsdDZRlkONn9aGd+MRWBw80dExs2qXbZlTVKu6hbqWfkT8l30Z/8WvEBQsUsKBcOhtYAAAoCaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA0LjQuMC1FeGl2MiI+CiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICBleGlmOlBpeGVsWERpbWVuc2lvbj0iNzIiCiAgIGV4aWY6UGl4ZWxZRGltZW5zaW9uPSI3MiIKICAgdGlmZjpJbWFnZVdpZHRoPSI3MiIKICAgdGlmZjpJbWFnZUhlaWdodD0iNzIiCiAgIHRpZmY6T3JpZW50YXRpb249IjEiLz4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Pq6cYi8AAAADc0JJVAgICNvhT+AAAAN7SURBVGje7dtRSBNhHADwfxJ3L96Le0kf1GD1sBDyO5ALbEkyMyY9bHswg+FDW5B7EKVhJSeElrQUcRIkFFHoi0toPriEVi8KbUQxKSYNk8HpYE5ot4e7e/l68NT08aTp6v9/25+P7+O3/3d3H3ffB7RooSSH7IQQYu0KS4qeeeEWyHbY+qLZvbbZiEcghBBHIJ43NhrQ4oYiRUU7sQ0lFJqPizbBEViUFCWfnOmyCp4ZaV/bfHLKIwiecLYUYJTSbLid2ALJX/E+q7VnUdGz0pSDOKakA39DQrQSd8RI0cqgCLEe8rZ55zb1X5oKwLAMywJoANpOI4ZhAEBdHnA6B5ZVPalqwHCckTGLAqvi69jPwZF36yrIK6GR4NrZjrbTbK2ziVsaeba0CaD+nAtOrtU6m6rY2qbazYWH08syqOtLwUcfoamjzpCsSPNPigy5bYQQIti7xuP6VaOshsV26052Uc/mE1M9DoEQQmxuMbyqGBvwBKUU/sUog380EIYwhCEMYQhD2DGMk4VCASuGMIQhDGEIQ9hxe0Af5eDyj7ejw5PRVAGgwnLNJ/qaK+HTnRZ/bF8rc9/s86umEoKpXyb8E+nWx7NP65nM+9HuB/5T5tc3zouzs/q7Ri0d6vdHLb5GU2lNxa0txuLq6aw3scDVNHZcrsjE0jKwnEmPQnQiVLg26KvnSmwqVjb3DjXvVC8djRVOtVbvGTbmh19utY55z7Cle/NQN94/8IcYl+iq2U19m55Mmb2d51ijnR45TP7yrPvmaME1NnZrrzjy1+mo1tBp6OI6DndF2Ji/f3s03Si+6r34p0FNRb5q50ULd4iuj7Bi8reR7uFUgzjYYYFcLpfL5WT9I0sm9l2rbjQfxnWEFcvFJsIZgEi/O3LgiaVmUluMubr8UN2fkGUZl1QIQxjCEIYwhCEMYYdbUuE+D4QhDGEIQxjC/luYvBK667zE8zx/oc0XXNK3B8vL0716tsX75IOe3fzwxNtyged5vuX6QGhFNThkUfakJ0Sb4H6RyFOqrIZ7rIInmqdUSQbsxDEez+5mI3lKpRm3YOuLSAql2fi4g9gDSUObZ4vy+o2tu/dmATiOBZA1UIEzcQDAMiaO+aPV9nbtKtfkwhWW4wBUWVOh3FTFsce2YnhSAk9K4EmJvxt4UgJPSuCSCmEIQxjCEAYAAL8BrebxGP8KiJcAAAAASUVORK5CYII=" alt="">`
|
||||||
|
if out != expected {
|
||||||
|
t.Errorf(
|
||||||
|
"test failed;\ninput : %s\noutput : %s\nexpected: %s",
|
||||||
|
input,
|
||||||
|
out,
|
||||||
|
expected)
|
||||||
|
}
|
||||||
|
|
||||||
|
input = `<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAIAAADajyQQAAAAhnpUWHRSYXcgcHJvZmlsZSB0
|
||||||
|
eXBlIGV4aWYAAHjadY5LCsNADEP3c4oewb+R7eOUkEBv0OPXZpKmm76FLIQRGvv7dYxHwyTD
|
||||||
|
pgcSoMLSUp5lghZKxELct3RxXuVycsdDZRlkONn9aGd+MRWBw80dExs2qXbZlTVKu6hbqWfk
|
||||||
|
T8l30Z/8WvEBQsUsKBcOhtYAAAoCaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNr
|
||||||
|
ZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBt
|
||||||
|
ZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA0LjQuMC1F
|
||||||
|
eGl2MiI+CiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIv
|
||||||
|
MjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAg
|
||||||
|
ICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgIHhtbG5z
|
||||||
|
OnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICBleGlmOlBpeGVsWERp
|
||||||
|
bWVuc2lvbj0iNzIiCiAgIGV4aWY6UGl4ZWxZRGltZW5zaW9uPSI3MiIKICAgdGlmZjpJbWFn
|
||||||
|
ZVdpZHRoPSI3MiIKICAgdGlmZjpJbWFnZUhlaWdodD0iNzIiCiAgIHRpZmY6T3JpZW50YXRp
|
||||||
|
b249IjEiLz4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAog
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
IAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Pq6cYi8A
|
||||||
|
AAADc0JJVAgICNvhT+AAAAN7SURBVGje7dtRSBNhHADwfxJ3L96Le0kf1GD1sBDyO5ALbEky
|
||||||
|
MyY9bHswg+FDW5B7EKVhJSeElrQUcRIkFFHoi0toPriEVi8KbUQxKSYNk8HpYE5ot4e7e/l6
|
||||||
|
8NT08aTp6v9/25+P7+O3/3d3H3ffB7RooSSH7IQQYu0KS4qeeeEWyHbY+qLZvbbZiEcghBBH
|
||||||
|
IJ43NhrQ4oYiRUU7sQ0lFJqPizbBEViUFCWfnOmyCp4ZaV/bfHLKIwiecLYUYJTSbLid2ALJ
|
||||||
|
X/E+q7VnUdGz0pSDOKakA39DQrQSd8RI0cqgCLEe8rZ55zb1X5oKwLAMywJoANpOI4ZhAEBd
|
||||||
|
HnA6B5ZVPalqwHCckTGLAqvi69jPwZF36yrIK6GR4NrZjrbTbK2ziVsaeba0CaD+nAtOrtU6
|
||||||
|
m6rY2qbazYWH08syqOtLwUcfoamjzpCsSPNPigy5bYQQIti7xuP6VaOshsV26052Uc/mE1M9
|
||||||
|
DoEQQmxuMbyqGBvwBKUU/sUog380EIYwhCEMYQhD2DGMk4VCASuGMIQhDGEIQ9hxe0Af5eDy
|
||||||
|
j7ejw5PRVAGgwnLNJ/qaK+HTnRZ/bF8rc9/s86umEoKpXyb8E+nWx7NP65nM+9HuB/5T5tc3
|
||||||
|
zouzs/q7Ri0d6vdHLb5GU2lNxa0txuLq6aw3scDVNHZcrsjE0jKwnEmPQnQiVLg26KvnSmwq
|
||||||
|
Vjb3DjXvVC8djRVOtVbvGTbmh19utY55z7Cle/NQN94/8IcYl+iq2U19m55Mmb2d51ijnR45
|
||||||
|
TP7yrPvmaME1NnZrrzjy1+mo1tBp6OI6DndF2Ji/f3s03Si+6r34p0FNRb5q50ULd4iuj7Bi
|
||||||
|
8reR7uFUgzjYYYFcLpfL5WT9I0sm9l2rbjQfxnWEFcvFJsIZgEi/O3LgiaVmUluMubr8UN2f
|
||||||
|
kGUZl1QIQxjCEIYwhCEMYYdbUuE+D4QhDGEIQxjC/luYvBK667zE8zx/oc0XXNK3B8vL0716
|
||||||
|
tsX75IOe3fzwxNtyged5vuX6QGhFNThkUfakJ0Sb4H6RyFOqrIZ7rIInmqdUSQbsxDEez+5m
|
||||||
|
I3lKpRm3YOuLSAql2fi4g9gDSUObZ4vy+o2tu/dmATiOBZA1UIEzcQDAMiaO+aPV9nbtKtfk
|
||||||
|
whWW4wBUWVOh3FTFsce2YnhSAk9K4EmJvxt4UgJPSuCSCmEIQxjCEAYAAL8BrebxGP8KiJcA
|
||||||
|
AAAASUVORK5CYII=" alt="">`
|
||||||
|
out = p.Sanitize(input)
|
||||||
|
expected = `<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAIAAADajyQQAAAAhnpUWHRSYXcgcHJvZmlsZSB0
|
||||||
|
eXBlIGV4aWYAAHjadY5LCsNADEP3c4oewb+R7eOUkEBv0OPXZpKmm76FLIQRGvv7dYxHwyTD
|
||||||
|
pgcSoMLSUp5lghZKxELct3RxXuVycsdDZRlkONn9aGd+MRWBw80dExs2qXbZlTVKu6hbqWfk
|
||||||
|
T8l30Z/8WvEBQsUsKBcOhtYAAAoCaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNr
|
||||||
|
ZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBt
|
||||||
|
ZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA0LjQuMC1F
|
||||||
|
eGl2MiI+CiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIv
|
||||||
|
MjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAg
|
||||||
|
ICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgIHhtbG5z
|
||||||
|
OnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICBleGlmOlBpeGVsWERp
|
||||||
|
bWVuc2lvbj0iNzIiCiAgIGV4aWY6UGl4ZWxZRGltZW5zaW9uPSI3MiIKICAgdGlmZjpJbWFn
|
||||||
|
ZVdpZHRoPSI3MiIKICAgdGlmZjpJbWFnZUhlaWdodD0iNzIiCiAgIHRpZmY6T3JpZW50YXRp
|
||||||
|
b249IjEiLz4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAog
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
|
||||||
|
IAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Pq6cYi8A
|
||||||
|
AAADc0JJVAgICNvhT+AAAAN7SURBVGje7dtRSBNhHADwfxJ3L96Le0kf1GD1sBDyO5ALbEky
|
||||||
|
MyY9bHswg+FDW5B7EKVhJSeElrQUcRIkFFHoi0toPriEVi8KbUQxKSYNk8HpYE5ot4e7e/l6
|
||||||
|
8NT08aTp6v9/25+P7+O3/3d3H3ffB7RooSSH7IQQYu0KS4qeeeEWyHbY+qLZvbbZiEcghBBH
|
||||||
|
IJ43NhrQ4oYiRUU7sQ0lFJqPizbBEViUFCWfnOmyCp4ZaV/bfHLKIwiecLYUYJTSbLid2ALJ
|
||||||
|
X/E+q7VnUdGz0pSDOKakA39DQrQSd8RI0cqgCLEe8rZ55zb1X5oKwLAMywJoANpOI4ZhAEBd
|
||||||
|
HnA6B5ZVPalqwHCckTGLAqvi69jPwZF36yrIK6GR4NrZjrbTbK2ziVsaeba0CaD+nAtOrtU6
|
||||||
|
m6rY2qbazYWH08syqOtLwUcfoamjzpCsSPNPigy5bYQQIti7xuP6VaOshsV26052Uc/mE1M9
|
||||||
|
DoEQQmxuMbyqGBvwBKUU/sUog380EIYwhCEMYQhD2DGMk4VCASuGMIQhDGEIQ9hxe0Af5eDy
|
||||||
|
j7ejw5PRVAGgwnLNJ/qaK+HTnRZ/bF8rc9/s86umEoKpXyb8E+nWx7NP65nM+9HuB/5T5tc3
|
||||||
|
zouzs/q7Ri0d6vdHLb5GU2lNxa0txuLq6aw3scDVNHZcrsjE0jKwnEmPQnQiVLg26KvnSmwq
|
||||||
|
Vjb3DjXvVC8djRVOtVbvGTbmh19utY55z7Cle/NQN94/8IcYl+iq2U19m55Mmb2d51ijnR45
|
||||||
|
TP7yrPvmaME1NnZrrzjy1+mo1tBp6OI6DndF2Ji/f3s03Si+6r34p0FNRb5q50ULd4iuj7Bi
|
||||||
|
8reR7uFUgzjYYYFcLpfL5WT9I0sm9l2rbjQfxnWEFcvFJsIZgEi/O3LgiaVmUluMubr8UN2f
|
||||||
|
kGUZl1QIQxjCEIYwhCEMYYdbUuE+D4QhDGEIQxjC/luYvBK667zE8zx/oc0XXNK3B8vL0716
|
||||||
|
tsX75IOe3fzwxNtyged5vuX6QGhFNThkUfakJ0Sb4H6RyFOqrIZ7rIInmqdUSQbsxDEez+5m
|
||||||
|
I3lKpRm3YOuLSAql2fi4g9gDSUObZ4vy+o2tu/dmATiOBZA1UIEzcQDAMiaO+aPV9nbtKtfk
|
||||||
|
whWW4wBUWVOh3FTFsce2YnhSAk9K4EmJvxt4UgJPSuCSCmEIQxjCEAYAAL8BrebxGP8KiJcA
|
||||||
|
AAAASUVORK5CYII=" alt="">`
|
||||||
|
if out != expected {
|
||||||
|
t.Errorf(
|
||||||
|
"test failed;\ninput : %s\noutput : %s\nexpected: %s",
|
||||||
|
input,
|
||||||
|
out,
|
||||||
|
expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIssue55ScriptTags(t *testing.T) {
|
||||||
|
p1 := NewPolicy()
|
||||||
|
p2 := UGCPolicy()
|
||||||
|
p3 := UGCPolicy().AllowElements("script")
|
||||||
|
|
||||||
|
in := `<SCRIPT>document.write('<h1><header/h1>')</SCRIPT>`
|
||||||
|
expected := ``
|
||||||
|
out := p1.Sanitize(in)
|
||||||
|
if out != expected {
|
||||||
|
t.Errorf(
|
||||||
|
"test failed;\ninput : %s\noutput : %s\nexpected: %s",
|
||||||
|
in,
|
||||||
|
out,
|
||||||
|
expected,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
expected = ``
|
||||||
|
out = p2.Sanitize(in)
|
||||||
|
if out != expected {
|
||||||
|
t.Errorf(
|
||||||
|
"test failed;\ninput : %s\noutput : %s\nexpected: %s",
|
||||||
|
in,
|
||||||
|
out,
|
||||||
|
expected,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
expected = `<script>document.write('<h1><header/h1>')</script>`
|
||||||
|
out = p3.Sanitize(in)
|
||||||
|
if out != expected {
|
||||||
|
t.Errorf(
|
||||||
|
"test failed;\ninput : %s\noutput : %s\nexpected: %s",
|
||||||
|
in,
|
||||||
|
out,
|
||||||
|
expected,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2
vendor/github.com/sergi/go-diff/.travis.yml
generated
vendored
2
vendor/github.com/sergi/go-diff/.travis.yml
generated
vendored
@ -5,8 +5,8 @@ os:
|
|||||||
- osx
|
- osx
|
||||||
|
|
||||||
go:
|
go:
|
||||||
- 1.7.x
|
|
||||||
- 1.8.x
|
- 1.8.x
|
||||||
|
- 1.9.x
|
||||||
|
|
||||||
sudo: false
|
sudo: false
|
||||||
|
|
||||||
|
24
vendor/github.com/shurcooL/github_flavored_markdown/main.go
generated
vendored
24
vendor/github.com/shurcooL/github_flavored_markdown/main.go
generated
vendored
@ -199,36 +199,16 @@ var gfmHTMLConfig = syntaxhighlight.HTMLConfig{
|
|||||||
Decimal: "m",
|
Decimal: "m",
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Support highlighting for more languages.
|
|
||||||
func highlightCode(src []byte, lang string) (highlightedCode []byte, ok bool) {
|
func highlightCode(src []byte, lang string) (highlightedCode []byte, ok bool) {
|
||||||
switch lang {
|
switch lang {
|
||||||
case "Go":
|
case "Go", "Go-unformatted":
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
err := highlight_go.Print(src, &buf, syntaxhighlight.HTMLPrinter(gfmHTMLConfig))
|
err := highlight_go.Print(src, &buf, syntaxhighlight.HTMLPrinter(gfmHTMLConfig))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
return buf.Bytes(), true
|
return buf.Bytes(), true
|
||||||
case "Go-old":
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := syntaxhighlight.Print(syntaxhighlight.NewScanner(src), &buf, syntaxhighlight.HTMLPrinter(gfmHTMLConfig))
|
|
||||||
if err != nil {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
return buf.Bytes(), true
|
|
||||||
case "diff":
|
case "diff":
|
||||||
switch 2 {
|
|
||||||
default:
|
|
||||||
var buf bytes.Buffer
|
|
||||||
err := highlight_diff.Print(highlight_diff.NewScanner(src), &buf)
|
|
||||||
if err != nil {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
return buf.Bytes(), true
|
|
||||||
case 1:
|
|
||||||
lines := bytes.Split(src, []byte("\n"))
|
|
||||||
return bytes.Join(lines, []byte("\n")), true
|
|
||||||
case 2:
|
|
||||||
anns, err := highlight_diff.Annotate(src)
|
anns, err := highlight_diff.Annotate(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false
|
return nil, false
|
||||||
@ -304,9 +284,7 @@ func highlightCode(src []byte, lang string) (highlightedCode []byte, ok bool) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
return out, true
|
return out, true
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
1
vendor/github.com/shurcooL/go/README.md
generated
vendored
1
vendor/github.com/shurcooL/go/README.md
generated
vendored
@ -17,7 +17,6 @@ Directories
|
|||||||
|
|
||||||
| Path | Synopsis |
|
| Path | Synopsis |
|
||||||
|-------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|-------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| [analysis](https://godoc.org/github.com/shurcooL/go/analysis) | Package analysis provides a routine that determines if a file is generated or handcrafted. |
|
|
||||||
| [browser](https://godoc.org/github.com/shurcooL/go/browser) | Package browser provides utilities for interacting with users' browsers. |
|
| [browser](https://godoc.org/github.com/shurcooL/go/browser) | Package browser provides utilities for interacting with users' browsers. |
|
||||||
| [ctxhttp](https://godoc.org/github.com/shurcooL/go/ctxhttp) | Package ctxhttp provides helper functions for performing context-aware HTTP requests. |
|
| [ctxhttp](https://godoc.org/github.com/shurcooL/go/ctxhttp) | Package ctxhttp provides helper functions for performing context-aware HTTP requests. |
|
||||||
| [gddo](https://godoc.org/github.com/shurcooL/go/gddo) | Package gddo is a simple client library for accessing the godoc.org API. |
|
| [gddo](https://godoc.org/github.com/shurcooL/go/gddo) | Package gddo is a simple client library for accessing the godoc.org API. |
|
||||||
|
51
vendor/github.com/shurcooL/go/analysis/generated_detection.go
generated
vendored
51
vendor/github.com/shurcooL/go/analysis/generated_detection.go
generated
vendored
@ -1,51 +0,0 @@
|
|||||||
// Package analysis provides a routine that determines if a file is generated or handcrafted.
|
|
||||||
//
|
|
||||||
// Deprecated: Use github.com/shurcooL/go/generated package instead. This implementation
|
|
||||||
// was done ad-hoc before a standard was proposed.
|
|
||||||
package analysis
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IsFileGenerated returns true if the specified file is generated, or false if it's handcrafted.
|
|
||||||
// rootDir is the filepath of root directory, but name is a '/'-separated path to file.
|
|
||||||
//
|
|
||||||
// It considers vendored files as "generated", in the sense that they are not the canonical
|
|
||||||
// version of a file. This behavior would ideally be factored out into a higher level utility,
|
|
||||||
// since it has nothing to do with generated comments.
|
|
||||||
//
|
|
||||||
// Deprecated: Use generated.ParseFile instead, which is more well defined because it
|
|
||||||
// implements a specification.
|
|
||||||
func IsFileGenerated(rootDir, name string) (bool, error) {
|
|
||||||
// Detect from name.
|
|
||||||
switch {
|
|
||||||
case strings.HasPrefix(name, "vendor/") || strings.Contains(name, "/vendor/"):
|
|
||||||
return true, nil
|
|
||||||
case strings.HasPrefix(name, "Godeps/"):
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detect from file contents.
|
|
||||||
f, err := os.Open(filepath.Join(rootDir, filepath.FromSlash(name)))
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
r := bufio.NewReader(f)
|
|
||||||
s, err := r.ReadString('\n')
|
|
||||||
if err == io.EOF {
|
|
||||||
// Empty file or exactly 1 line is not considered to be generated.
|
|
||||||
return false, nil
|
|
||||||
} else if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if strings.Contains(s, "Code generated by") { // Consistent with https://golang.org/cl/15073.
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
return (strings.Contains(s, "GENERATED") || strings.Contains(s, "generated")) && strings.Contains(s, "DO NOT EDIT"), nil
|
|
||||||
}
|
|
28
vendor/github.com/shurcooL/go/analysis/generated_detection_test.go
generated
vendored
28
vendor/github.com/shurcooL/go/analysis/generated_detection_test.go
generated
vendored
@ -1,28 +0,0 @@
|
|||||||
package analysis_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/shurcooL/go/analysis"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ExampleIsFileGenerated() {
|
|
||||||
cwd, err := os.Getwd()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(analysis.IsFileGenerated(cwd, "testdata/generated_0.go.txt"))
|
|
||||||
fmt.Println(analysis.IsFileGenerated(cwd, "testdata/handcrafted_0.go.txt"))
|
|
||||||
fmt.Println(analysis.IsFileGenerated(cwd, "testdata/handcrafted_1.go.txt"))
|
|
||||||
fmt.Println(analysis.IsFileGenerated(cwd, "vendor/github.com/shurcooL/go/analysis/file.go"))
|
|
||||||
fmt.Println(analysis.IsFileGenerated(cwd, "subpkg/vendor/math/math.go"))
|
|
||||||
|
|
||||||
// Output:
|
|
||||||
// true <nil>
|
|
||||||
// false <nil>
|
|
||||||
// false <nil>
|
|
||||||
// true <nil>
|
|
||||||
// true <nil>
|
|
||||||
}
|
|
32
vendor/github.com/shurcooL/go/analysis/testdata/generated_0.go.txt
generated
vendored
32
vendor/github.com/shurcooL/go/analysis/testdata/generated_0.go.txt
generated
vendored
@ -1,32 +0,0 @@
|
|||||||
// generated by vfsgen; DO NOT EDIT
|
|
||||||
|
|
||||||
// +build !dev
|
|
||||||
|
|
||||||
package issues
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"compress/gzip"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
pathpkg "path"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Assets statically implements the virtual filesystem given to vfsgen as input.
|
|
||||||
var Assets = func() http.FileSystem {
|
|
||||||
mustUnmarshalTextTime := func(text string) time.Time {
|
|
||||||
var t time.Time
|
|
||||||
err := t.UnmarshalText([]byte(text))
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
fs := _vfsgen_fs{
|
|
||||||
...
|
|
||||||
}
|
|
||||||
}
|
|
9
vendor/github.com/shurcooL/go/analysis/testdata/handcrafted_0.go.txt
generated
vendored
9
vendor/github.com/shurcooL/go/analysis/testdata/handcrafted_0.go.txt
generated
vendored
@ -1,9 +0,0 @@
|
|||||||
// Package foo offers bar.
|
|
||||||
package foo
|
|
||||||
|
|
||||||
import "strings"
|
|
||||||
|
|
||||||
// Bar is bar.
|
|
||||||
func Bar() string {
|
|
||||||
return strings.Title("bar")
|
|
||||||
}
|
|
1
vendor/github.com/shurcooL/go/analysis/testdata/handcrafted_1.go.txt
generated
vendored
1
vendor/github.com/shurcooL/go/analysis/testdata/handcrafted_1.go.txt
generated
vendored
@ -1 +0,0 @@
|
|||||||
// Code generated by protoc-gen-gogo. Actually it isn't, because it's only 1 line.
|
|
4
vendor/github.com/shurcooL/graphql/README.md
generated
vendored
4
vendor/github.com/shurcooL/graphql/README.md
generated
vendored
@ -24,7 +24,7 @@ Usage
|
|||||||
Construct a GraphQL client, specifying the GraphQL server URL. Then, you can use it to make GraphQL queries and mutations.
|
Construct a GraphQL client, specifying the GraphQL server URL. Then, you can use it to make GraphQL queries and mutations.
|
||||||
|
|
||||||
```Go
|
```Go
|
||||||
client := graphql.NewClient("https://example.com/graphql", nil, nil)
|
client := graphql.NewClient("https://example.com/graphql", nil)
|
||||||
// Use client...
|
// Use client...
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ func main() {
|
|||||||
)
|
)
|
||||||
httpClient := oauth2.NewClient(context.Background(), src)
|
httpClient := oauth2.NewClient(context.Background(), src)
|
||||||
|
|
||||||
client := graphql.NewClient("https://example.com/graphql", httpClient, nil)
|
client := graphql.NewClient("https://example.com/graphql", httpClient)
|
||||||
// Use client...
|
// Use client...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
2
vendor/github.com/shurcooL/graphql/example/graphqldev/main.go
generated
vendored
2
vendor/github.com/shurcooL/graphql/example/graphqldev/main.go
generated
vendored
@ -38,7 +38,7 @@ func run() error {
|
|||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.Handle("/query", &relay.Handler{Schema: schema})
|
mux.Handle("/query", &relay.Handler{Schema: schema})
|
||||||
|
|
||||||
client := graphql.NewClient("/query", &http.Client{Transport: localRoundTripper{handler: mux}}, nil)
|
client := graphql.NewClient("/query", &http.Client{Transport: localRoundTripper{handler: mux}})
|
||||||
|
|
||||||
/*
|
/*
|
||||||
query {
|
query {
|
||||||
|
15
vendor/github.com/shurcooL/graphql/graphql.go
generated
vendored
15
vendor/github.com/shurcooL/graphql/graphql.go
generated
vendored
@ -6,7 +6,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"github.com/shurcooL/go/ctxhttp"
|
"github.com/shurcooL/go/ctxhttp"
|
||||||
"github.com/shurcooL/graphql/internal/jsonutil"
|
"github.com/shurcooL/graphql/internal/jsonutil"
|
||||||
@ -16,25 +15,17 @@ import (
|
|||||||
type Client struct {
|
type Client struct {
|
||||||
url string // GraphQL server URL.
|
url string // GraphQL server URL.
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
|
|
||||||
qctx *queryContext
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClient creates a GraphQL client targeting the specified GraphQL server URL.
|
// NewClient creates a GraphQL client targeting the specified GraphQL server URL.
|
||||||
// If httpClient is nil, then http.DefaultClient is used.
|
// If httpClient is nil, then http.DefaultClient is used.
|
||||||
// scalars optionally specifies types that are scalars (this matters
|
func NewClient(url string, httpClient *http.Client) *Client {
|
||||||
// when constructing queries from types, scalars are never expanded).
|
|
||||||
func NewClient(url string, httpClient *http.Client, scalars []reflect.Type) *Client {
|
|
||||||
if httpClient == nil {
|
if httpClient == nil {
|
||||||
httpClient = http.DefaultClient
|
httpClient = http.DefaultClient
|
||||||
}
|
}
|
||||||
return &Client{
|
return &Client{
|
||||||
url: url,
|
url: url,
|
||||||
httpClient: httpClient,
|
httpClient: httpClient,
|
||||||
|
|
||||||
qctx: &queryContext{
|
|
||||||
Scalars: scalars,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,9 +48,9 @@ func (c *Client) do(ctx context.Context, op operationType, v interface{}, variab
|
|||||||
var query string
|
var query string
|
||||||
switch op {
|
switch op {
|
||||||
case queryOperation:
|
case queryOperation:
|
||||||
query = constructQuery(c.qctx, v, variables)
|
query = constructQuery(v, variables)
|
||||||
case mutationOperation:
|
case mutationOperation:
|
||||||
query = constructMutation(c.qctx, v, variables)
|
query = constructMutation(v, variables)
|
||||||
}
|
}
|
||||||
in := struct {
|
in := struct {
|
||||||
Query string `json:"query"`
|
Query string `json:"query"`
|
||||||
|
18
vendor/github.com/shurcooL/graphql/ident/ident.go
generated
vendored
18
vendor/github.com/shurcooL/graphql/ident/ident.go
generated
vendored
@ -131,6 +131,10 @@ func (n Name) ToMixedCaps() string {
|
|||||||
n[i] = initialism
|
n[i] = initialism
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if brand, ok := isBrand(word); ok {
|
||||||
|
n[i] = brand
|
||||||
|
continue
|
||||||
|
}
|
||||||
r, size := utf8.DecodeRuneInString(word)
|
r, size := utf8.DecodeRuneInString(word)
|
||||||
n[i] = string(unicode.ToUpper(r)) + strings.ToLower(word[size:])
|
n[i] = string(unicode.ToUpper(r)) + strings.ToLower(word[size:])
|
||||||
}
|
}
|
||||||
@ -220,3 +224,17 @@ var initialisms = map[string]struct{}{
|
|||||||
// Additional common initialisms.
|
// Additional common initialisms.
|
||||||
"RSS": {},
|
"RSS": {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isBrand reports whether word is a brand.
|
||||||
|
func isBrand(word string) (string, bool) {
|
||||||
|
brand, ok := brands[strings.ToLower(word)]
|
||||||
|
return brand, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// brands is the map of brands in the MixedCaps naming convention;
|
||||||
|
// see https://dmitri.shuralyov.com/idiomatic-go#for-brands-or-words-with-more-than-1-capital-letter-lowercase-all-letters.
|
||||||
|
// Key is the lower case version of the brand, value is the canonical brand spelling.
|
||||||
|
// Only add entries that are highly unlikely to be non-brands.
|
||||||
|
var brands = map[string]string{
|
||||||
|
"github": "GitHub",
|
||||||
|
}
|
||||||
|
5
vendor/github.com/shurcooL/graphql/ident/ident_test.go
generated
vendored
5
vendor/github.com/shurcooL/graphql/ident/ident_test.go
generated
vendored
@ -81,13 +81,14 @@ func TestParseScreamingSnakeCase(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWords_ToMixedCaps(t *testing.T) {
|
func TestName_ToMixedCaps(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
in ident.Name
|
in ident.Name
|
||||||
want string
|
want string
|
||||||
}{
|
}{
|
||||||
{in: ident.Name{"client", "Mutation", "Id"}, want: "ClientMutationID"},
|
{in: ident.Name{"client", "Mutation", "Id"}, want: "ClientMutationID"},
|
||||||
{in: ident.Name{"CLIENT", "MUTATION", "ID"}, want: "ClientMutationID"},
|
{in: ident.Name{"CLIENT", "MUTATION", "ID"}, want: "ClientMutationID"},
|
||||||
|
{in: ident.Name{"github", "logo"}, want: "GitHubLogo"},
|
||||||
}
|
}
|
||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
got := tc.in.ToMixedCaps()
|
got := tc.in.ToMixedCaps()
|
||||||
@ -97,7 +98,7 @@ func TestWords_ToMixedCaps(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWords_ToLowerCamelCase(t *testing.T) {
|
func TestName_ToLowerCamelCase(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
in ident.Name
|
in ident.Name
|
||||||
want string
|
want string
|
||||||
|
93
vendor/github.com/shurcooL/graphql/query.go
generated
vendored
93
vendor/github.com/shurcooL/graphql/query.go
generated
vendored
@ -2,6 +2,7 @@ package graphql
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
@ -9,16 +10,16 @@ import (
|
|||||||
"github.com/shurcooL/graphql/ident"
|
"github.com/shurcooL/graphql/ident"
|
||||||
)
|
)
|
||||||
|
|
||||||
func constructQuery(qctx *queryContext, v interface{}, variables map[string]interface{}) string {
|
func constructQuery(v interface{}, variables map[string]interface{}) string {
|
||||||
query := qctx.Query(v)
|
query := query(v)
|
||||||
if variables != nil {
|
if variables != nil {
|
||||||
return "query(" + queryArguments(variables) + ")" + query
|
return "query(" + queryArguments(variables) + ")" + query
|
||||||
}
|
}
|
||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
func constructMutation(qctx *queryContext, v interface{}, variables map[string]interface{}) string {
|
func constructMutation(v interface{}, variables map[string]interface{}) string {
|
||||||
query := qctx.Query(v)
|
query := query(v)
|
||||||
if variables != nil {
|
if variables != nil {
|
||||||
return "mutation(" + queryArguments(variables) + ")" + query
|
return "mutation(" + queryArguments(variables) + ")" + query
|
||||||
}
|
}
|
||||||
@ -29,63 +30,79 @@ func constructMutation(qctx *queryContext, v interface{}, variables map[string]i
|
|||||||
//
|
//
|
||||||
// E.g., map[string]interface{}{"a": Int(123), "b": NewBoolean(true)} -> "$a:Int!$b:Boolean".
|
// E.g., map[string]interface{}{"a": Int(123), "b": NewBoolean(true)} -> "$a:Int!$b:Boolean".
|
||||||
func queryArguments(variables map[string]interface{}) string {
|
func queryArguments(variables map[string]interface{}) string {
|
||||||
sorted := make([]string, 0, len(variables))
|
// Sort keys in order to produce deterministic output for testing purposes.
|
||||||
|
// TODO: If tests can be made to work with non-deterministic output, then no need to sort.
|
||||||
|
keys := make([]string, 0, len(variables))
|
||||||
for k := range variables {
|
for k := range variables {
|
||||||
sorted = append(sorted, k)
|
keys = append(keys, k)
|
||||||
}
|
}
|
||||||
sort.Strings(sorted)
|
sort.Strings(keys)
|
||||||
var s string
|
|
||||||
for _, k := range sorted {
|
var buf bytes.Buffer
|
||||||
v := variables[k]
|
for _, k := range keys {
|
||||||
s += "$" + k + ":"
|
io.WriteString(&buf, "$")
|
||||||
t := reflect.TypeOf(v)
|
io.WriteString(&buf, k)
|
||||||
|
io.WriteString(&buf, ":")
|
||||||
|
writeArgumentType(&buf, reflect.TypeOf(variables[k]), true)
|
||||||
|
// Don't insert a comma here.
|
||||||
|
// Commas in GraphQL are insignificant, and we want minified output.
|
||||||
|
// See https://facebook.github.io/graphql/October2016/#sec-Insignificant-Commas.
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// writeArgumentType writes a minified GraphQL type for t to w.
|
||||||
|
// value indicates whether t is a value (required) type or pointer (optional) type.
|
||||||
|
// If value is true, then "!" is written at the end of t.
|
||||||
|
func writeArgumentType(w io.Writer, t reflect.Type, value bool) {
|
||||||
|
if t.Kind() == reflect.Ptr {
|
||||||
|
// Pointer is an optional type, so no "!" at the end of the pointer's underlying type.
|
||||||
|
writeArgumentType(w, t.Elem(), false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch t.Kind() {
|
switch t.Kind() {
|
||||||
case reflect.Slice, reflect.Array:
|
case reflect.Slice, reflect.Array:
|
||||||
// TODO: Support t.Elem() being a pointer, if needed. Probably want to do this recursively.
|
// List. E.g., "[Int]".
|
||||||
s += "[" + t.Elem().Name() + "!]" // E.g., "[IssueState!]".
|
io.WriteString(w, "[")
|
||||||
case reflect.Ptr:
|
writeArgumentType(w, t.Elem(), true)
|
||||||
// Pointer is an optional type, so no "!" at the end.
|
io.WriteString(w, "]")
|
||||||
s += t.Elem().Name() // E.g., "Int".
|
|
||||||
default:
|
default:
|
||||||
|
// Named type. E.g., "Int".
|
||||||
name := t.Name()
|
name := t.Name()
|
||||||
if name == "string" { // HACK: Workaround for https://github.com/shurcooL/githubql/issues/12.
|
if name == "string" { // HACK: Workaround for https://github.com/shurcooL/githubql/issues/12.
|
||||||
name = "ID"
|
name = "ID"
|
||||||
}
|
}
|
||||||
|
io.WriteString(w, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if value {
|
||||||
// Value is a required type, so add "!" to the end.
|
// Value is a required type, so add "!" to the end.
|
||||||
s += name + "!" // E.g., "Int!".
|
io.WriteString(w, "!")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type queryContext struct {
|
// query uses writeQuery to recursively construct
|
||||||
// Scalars are Go types that map to GraphQL scalars, and therefore we don't want to expand them.
|
|
||||||
Scalars []reflect.Type
|
|
||||||
}
|
|
||||||
|
|
||||||
// Query uses writeQuery to recursively construct
|
|
||||||
// a minified query string from the provided struct v.
|
// a minified query string from the provided struct v.
|
||||||
//
|
//
|
||||||
// E.g., struct{Foo Int, BarBaz *Boolean} -> "{foo,barBaz}".
|
// E.g., struct{Foo Int, BarBaz *Boolean} -> "{foo,barBaz}".
|
||||||
func (c *queryContext) Query(v interface{}) string {
|
func query(v interface{}) string {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
c.writeQuery(&buf, reflect.TypeOf(v), false)
|
writeQuery(&buf, reflect.TypeOf(v), false)
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeQuery writes a minified query for t to w. If inline is true,
|
// writeQuery writes a minified query for t to w.
|
||||||
// the struct fields of t are inlined into parent struct.
|
// If inline is true, the struct fields of t are inlined into parent struct.
|
||||||
func (c *queryContext) writeQuery(w io.Writer, t reflect.Type, inline bool) {
|
func writeQuery(w io.Writer, t reflect.Type, inline bool) {
|
||||||
switch t.Kind() {
|
switch t.Kind() {
|
||||||
case reflect.Ptr, reflect.Slice:
|
case reflect.Ptr, reflect.Slice:
|
||||||
c.writeQuery(w, t.Elem(), false)
|
writeQuery(w, t.Elem(), false)
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
// Special handling of scalar struct types. Don't expand them.
|
// If the type implements json.Unmarshaler, it's a scalar. Don't expand it.
|
||||||
for _, scalar := range c.Scalars {
|
if reflect.PtrTo(t).Implements(jsonUnmarshaler) {
|
||||||
if t == scalar {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if !inline {
|
if !inline {
|
||||||
io.WriteString(w, "{")
|
io.WriteString(w, "{")
|
||||||
}
|
}
|
||||||
@ -103,10 +120,12 @@ func (c *queryContext) writeQuery(w io.Writer, t reflect.Type, inline bool) {
|
|||||||
io.WriteString(w, ident.ParseMixedCaps(f.Name).ToLowerCamelCase())
|
io.WriteString(w, ident.ParseMixedCaps(f.Name).ToLowerCamelCase())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.writeQuery(w, f.Type, inlineField)
|
writeQuery(w, f.Type, inlineField)
|
||||||
}
|
}
|
||||||
if !inline {
|
if !inline {
|
||||||
io.WriteString(w, "}")
|
io.WriteString(w, "}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var jsonUnmarshaler = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
|
||||||
|
58
vendor/github.com/shurcooL/graphql/query_test.go
generated
vendored
58
vendor/github.com/shurcooL/graphql/query_test.go
generated
vendored
@ -2,7 +2,6 @@ package graphql
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"reflect"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -217,15 +216,20 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
}(),
|
}(),
|
||||||
want: `{actor{login,avatarUrl,url},createdAt,... on IssueComment{body},currentTitle,previousTitle,label{name,color}}`,
|
want: `{actor{login,avatarUrl,url},createdAt,... on IssueComment{body},currentTitle,previousTitle,label{name,color}}`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
inV: struct {
|
||||||
|
Viewer struct {
|
||||||
|
Login string
|
||||||
|
CreatedAt time.Time
|
||||||
|
ID interface{}
|
||||||
|
DatabaseID int
|
||||||
}
|
}
|
||||||
for _, tc := range tests {
|
}{},
|
||||||
qctx := &queryContext{
|
want: `{viewer{login,createdAt,id,databaseId}}`,
|
||||||
Scalars: []reflect.Type{
|
|
||||||
reflect.TypeOf(DateTime{}),
|
|
||||||
reflect.TypeOf(URI{}),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
got := constructQuery(qctx, tc.inV, tc.inVariables)
|
for _, tc := range tests {
|
||||||
|
got := constructQuery(tc.inV, tc.inVariables)
|
||||||
if got != tc.want {
|
if got != tc.want {
|
||||||
t.Errorf("\ngot: %q\nwant: %q\n", got, tc.want)
|
t.Errorf("\ngot: %q\nwant: %q\n", got, tc.want)
|
||||||
}
|
}
|
||||||
@ -260,7 +264,7 @@ func TestConstructMutation(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
got := constructMutation(&queryContext{}, tc.inV, tc.inVariables)
|
got := constructMutation(tc.inV, tc.inVariables)
|
||||||
if got != tc.want {
|
if got != tc.want {
|
||||||
t.Errorf("\ngot: %q\nwant: %q\n", got, tc.want)
|
t.Errorf("\ngot: %q\nwant: %q\n", got, tc.want)
|
||||||
}
|
}
|
||||||
@ -269,7 +273,6 @@ func TestConstructMutation(t *testing.T) {
|
|||||||
|
|
||||||
func TestQueryArguments(t *testing.T) {
|
func TestQueryArguments(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
|
||||||
in map[string]interface{}
|
in map[string]interface{}
|
||||||
want string
|
want string
|
||||||
}{
|
}{
|
||||||
@ -278,26 +281,43 @@ func TestQueryArguments(t *testing.T) {
|
|||||||
want: "$a:Int!$b:Boolean",
|
want: "$a:Int!$b:Boolean",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
in: map[string]interface{}{"states": []IssueState{IssueStateOpen, IssueStateClosed}},
|
in: map[string]interface{}{
|
||||||
want: "$states:[IssueState!]",
|
"required": []IssueState{IssueStateOpen, IssueStateClosed},
|
||||||
|
"optional": &[]IssueState{IssueStateOpen, IssueStateClosed},
|
||||||
|
},
|
||||||
|
want: "$optional:[IssueState!]$required:[IssueState!]!",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
in: map[string]interface{}{"states": []IssueState(nil)},
|
in: map[string]interface{}{
|
||||||
want: "$states:[IssueState!]",
|
"required": []IssueState(nil),
|
||||||
|
"optional": (*[]IssueState)(nil),
|
||||||
|
},
|
||||||
|
want: "$optional:[IssueState!]$required:[IssueState!]!",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
in: map[string]interface{}{"states": [...]IssueState{IssueStateOpen, IssueStateClosed}},
|
in: map[string]interface{}{
|
||||||
want: "$states:[IssueState!]",
|
"required": [...]IssueState{IssueStateOpen, IssueStateClosed},
|
||||||
|
"optional": &[...]IssueState{IssueStateOpen, IssueStateClosed},
|
||||||
|
},
|
||||||
|
want: "$optional:[IssueState!]$required:[IssueState!]!",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
in: map[string]interface{}{"id": ID("someid")},
|
in: map[string]interface{}{"id": ID("someID")},
|
||||||
want: "$id:ID!",
|
want: "$id:ID!",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
in: map[string]interface{}{"ids": []ID{"someID", "anotherID"}},
|
||||||
|
want: `$ids:[ID!]!`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: map[string]interface{}{"ids": &[]ID{"someID", "anotherID"}},
|
||||||
|
want: `$ids:[ID!]`,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range tests {
|
for i, tc := range tests {
|
||||||
got := queryArguments(tc.in)
|
got := queryArguments(tc.in)
|
||||||
if got != tc.want {
|
if got != tc.want {
|
||||||
t.Errorf("%s: got: %q, want: %q", tc.name, got, tc.want)
|
t.Errorf("test case %d:\n got: %q\nwant: %q", i, got, tc.want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -311,6 +331,8 @@ type (
|
|||||||
URI struct{ *url.URL }
|
URI struct{ *url.URL }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (u *URI) UnmarshalJSON(data []byte) error { panic("mock implementation") }
|
||||||
|
|
||||||
// IssueState represents the possible states of an issue.
|
// IssueState represents the possible states of an issue.
|
||||||
type IssueState string
|
type IssueState string
|
||||||
|
|
||||||
|
36
vendor/github.com/shurcooL/octiconssvg/generate.go
generated
vendored
36
vendor/github.com/shurcooL/octiconssvg/generate.go
generated
vendored
@ -7,7 +7,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/format"
|
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
@ -55,6 +54,8 @@ func run() error {
|
|||||||
fmt.Fprint(&buf, `package octiconssvg
|
fmt.Fprint(&buf, `package octiconssvg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"golang.org/x/net/html"
|
"golang.org/x/net/html"
|
||||||
"golang.org/x/net/html/atom"
|
"golang.org/x/net/html/atom"
|
||||||
)
|
)
|
||||||
@ -71,14 +72,18 @@ func Icon(name string) *html.Node {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`)
|
|
||||||
for _, name := range names {
|
|
||||||
processOcticon(&buf, octicons, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := format.Source(buf.Bytes())
|
// SetSize sets size of icon, and returns a reference to it.
|
||||||
if err != nil {
|
func SetSize(icon *html.Node, size int) *html.Node {
|
||||||
return fmt.Errorf("error from format.Source(): %v", err)
|
icon.Attr[`, widthAttrIndex, `].Val = strconv.Itoa(size)
|
||||||
|
icon.Attr[`, heightAttrIndex, `].Val = strconv.Itoa(size)
|
||||||
|
return icon
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
// Write all individual Octicon functions.
|
||||||
|
for _, name := range names {
|
||||||
|
generateAndWriteOcticon(&buf, octicons, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
var w io.Writer
|
var w io.Writer
|
||||||
@ -94,7 +99,7 @@ func Icon(name string) *html.Node {
|
|||||||
w = f
|
w = f
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = w.Write(b)
|
_, err = w.Write(buf.Bytes())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,10 +109,10 @@ type octicon struct {
|
|||||||
Height int `json:",string"`
|
Height int `json:",string"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func processOcticon(w io.Writer, octicons map[string]octicon, name string) {
|
func generateAndWriteOcticon(w io.Writer, octicons map[string]octicon, name string) {
|
||||||
svgXML := generateOcticon(octicons[name])
|
svgXML := generateOcticon(octicons[name])
|
||||||
svg := parseOcticon(svgXML)
|
|
||||||
|
|
||||||
|
svg := parseOcticon(svgXML)
|
||||||
// Clear these fields to remove cycles in the data structure, since go-goon
|
// Clear these fields to remove cycles in the data structure, since go-goon
|
||||||
// cannot print those in a way that's valid Go code. The generated data structure
|
// cannot print those in a way that's valid Go code. The generated data structure
|
||||||
// is not a proper *html.Node with all fields set, but it's enough for rendering
|
// is not a proper *html.Node with all fields set, but it's enough for rendering
|
||||||
@ -129,10 +134,19 @@ func generateOcticon(o octicon) (svgXML string) {
|
|||||||
// Skip fill-rule, if present. It has no effect on displayed SVG, but takes up space.
|
// Skip fill-rule, if present. It has no effect on displayed SVG, but takes up space.
|
||||||
path = `<path ` + path[len(`<path fill-rule="evenodd" `):]
|
path = `<path ` + path[len(`<path fill-rule="evenodd" `):]
|
||||||
}
|
}
|
||||||
|
// Note, SetSize relies on the absolute position of the width, height attributes.
|
||||||
|
// Keep them in sync with widthAttrIndex and heightAttrIndex.
|
||||||
return fmt.Sprintf(`<svg xmlns="http://www.w3.org/2000/svg" width="%d" height="%d" viewBox="0 0 %d %d">%s</svg>`,
|
return fmt.Sprintf(`<svg xmlns="http://www.w3.org/2000/svg" width="%d" height="%d" viewBox="0 0 %d %d">%s</svg>`,
|
||||||
o.Width, o.Height, o.Width, o.Height, path)
|
o.Width, o.Height, o.Width, o.Height, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// These constants are used during generation of SetSize function.
|
||||||
|
// Keep them in sync with generateOcticon.
|
||||||
|
const (
|
||||||
|
widthAttrIndex = 1
|
||||||
|
heightAttrIndex = 2
|
||||||
|
)
|
||||||
|
|
||||||
func parseOcticon(svgXML string) *html.Node {
|
func parseOcticon(svgXML string) *html.Node {
|
||||||
e, err := html.ParseFragment(strings.NewReader(svgXML), nil)
|
e, err := html.ParseFragment(strings.NewReader(svgXML), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
375
vendor/github.com/shurcooL/octiconssvg/octicons.go
generated
vendored
375
vendor/github.com/shurcooL/octiconssvg/octicons.go
generated
vendored
File diff suppressed because it is too large
Load Diff
14
vendor/github.com/shurcooL/octiconssvg/octicons_test.go
generated
vendored
14
vendor/github.com/shurcooL/octiconssvg/octicons_test.go
generated
vendored
@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func Example() {
|
func Example() {
|
||||||
var w io.Writer = os.Stdout // Or, e.g., http.ResponseWriter in your handler, etc.
|
var w io.Writer = os.Stdout // Or, e.g., http.ResponseWriter in your HTTP handler, etc.
|
||||||
|
|
||||||
err := html.Render(w, octiconssvg.Alert())
|
err := html.Render(w, octiconssvg.Alert())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -20,3 +20,15 @@ func Example() {
|
|||||||
// Output:
|
// Output:
|
||||||
// <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" style="fill: currentColor; vertical-align: top;"><path d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"></path></svg>
|
// <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" style="fill: currentColor; vertical-align: top;"><path d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"></path></svg>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleSetSize() {
|
||||||
|
var w io.Writer = os.Stdout // Or, e.g., http.ResponseWriter in your HTTP handler, etc.
|
||||||
|
|
||||||
|
err := html.Render(w, octiconssvg.SetSize(octiconssvg.MarkGitHub(), 24))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 16 16" style="fill: currentColor; vertical-align: top;"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg>
|
||||||
|
}
|
||||||
|
1
vendor/github.com/ugorji/go/.travis.yml
generated
vendored
1
vendor/github.com/ugorji/go/.travis.yml
generated
vendored
@ -1,6 +1,7 @@
|
|||||||
language: go
|
language: go
|
||||||
sudo: false
|
sudo: false
|
||||||
go:
|
go:
|
||||||
|
- 1.7.x # go testing suite support, which we use, was introduced in go 1.7
|
||||||
- 1.8.x
|
- 1.8.x
|
||||||
- 1.9.x
|
- 1.9.x
|
||||||
- tip
|
- tip
|
||||||
|
2
vendor/github.com/ugorji/go/README.md
generated
vendored
2
vendor/github.com/ugorji/go/README.md
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
[![Build Status](https://travis-ci.org/ugorji/go.svg?branch=master)](https://travis-ci.org/ugorji/go)
|
[![Build Status](https://travis-ci.org/ugorji/go.svg?branch=master)](https://travis-ci.org/ugorji/go)
|
||||||
[![codecov](https://codecov.io/gh/ugorji/go/branch/master/graph/badge.svg)](https://codecov.io/gh/ugorji/go)
|
[![codecov](https://codecov.io/gh/ugorji/go/branch/master/graph/badge.svg)](https://codecov.io/gh/ugorji/go)
|
||||||
[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/ugorji/go/codec)
|
[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/ugorji/go/codec)
|
||||||
[![rcard](https://goreportcard.com/badge/github.com/ugorji/go/codec)](https://goreportcard.com/report/github.com/ugorji/go/codec)
|
[![rcard](https://goreportcard.com/badge/github.com/ugorji/go/codec?v=2)](https://goreportcard.com/report/github.com/ugorji/go/codec)
|
||||||
[![License](http://img.shields.io/badge/license-mit-blue.svg?style=flat-square)](https://raw.githubusercontent.com/ugorji/go/master/LICENSE)
|
[![License](http://img.shields.io/badge/license-mit-blue.svg?style=flat-square)](https://raw.githubusercontent.com/ugorji/go/master/LICENSE)
|
||||||
|
|
||||||
# go/codec
|
# go/codec
|
||||||
|
74
vendor/github.com/ugorji/go/codec/0doc.go
generated
vendored
74
vendor/github.com/ugorji/go/codec/0doc.go
generated
vendored
@ -1,9 +1,10 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
High Performance, Feature-Rich Idiomatic Go 1.4+ codec/encoding library for
|
Package codec provides a
|
||||||
binc, msgpack, cbor, json
|
High Performance, Feature-Rich Idiomatic Go 1.4+ codec/encoding library
|
||||||
|
for binc, msgpack, cbor, json.
|
||||||
|
|
||||||
Supported Serialization formats are:
|
Supported Serialization formats are:
|
||||||
|
|
||||||
@ -32,15 +33,14 @@ Rich Feature Set includes:
|
|||||||
|
|
||||||
- Simple but extremely powerful and feature-rich API
|
- Simple but extremely powerful and feature-rich API
|
||||||
- Support for go1.4 and above, while selectively using newer APIs for later releases
|
- Support for go1.4 and above, while selectively using newer APIs for later releases
|
||||||
- Good code coverage ( > 70% )
|
- Excellent code coverage ( > 90% )
|
||||||
- Very High Performance.
|
- Very High Performance.
|
||||||
Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X.
|
Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X.
|
||||||
- Careful selected use of 'unsafe' for targeted performance gains.
|
- Careful selected use of 'unsafe' for targeted performance gains.
|
||||||
100% mode exists where 'unsafe' is not used at all.
|
100% mode exists where 'unsafe' is not used at all.
|
||||||
- Lock-free (sans mutex) concurrency for scaling to 100's of cores
|
- Lock-free (sans mutex) concurrency for scaling to 100's of cores
|
||||||
- Multiple conversions:
|
- Coerce types where appropriate
|
||||||
Package coerces types where appropriate
|
e.g. decode an int in the stream into a float, decode numbers from formatted strings, etc
|
||||||
e.g. decode an int in the stream into a float, etc.
|
|
||||||
- Corner Cases:
|
- Corner Cases:
|
||||||
Overflows, nil maps/slices, nil values in streams are handled correctly
|
Overflows, nil maps/slices, nil values in streams are handled correctly
|
||||||
- Standard field renaming via tags
|
- Standard field renaming via tags
|
||||||
@ -49,10 +49,16 @@ Rich Feature Set includes:
|
|||||||
(struct, slice, map, primitives, pointers, interface{}, etc)
|
(struct, slice, map, primitives, pointers, interface{}, etc)
|
||||||
- Extensions to support efficient encoding/decoding of any named types
|
- Extensions to support efficient encoding/decoding of any named types
|
||||||
- Support encoding.(Binary|Text)(M|Unm)arshaler interfaces
|
- Support encoding.(Binary|Text)(M|Unm)arshaler interfaces
|
||||||
|
- Support IsZero() bool to determine if a value is a zero value.
|
||||||
|
Analogous to time.Time.IsZero() bool.
|
||||||
- Decoding without a schema (into a interface{}).
|
- Decoding without a schema (into a interface{}).
|
||||||
Includes Options to configure what specific map or slice type to use
|
Includes Options to configure what specific map or slice type to use
|
||||||
when decoding an encoded list or map into a nil interface{}
|
when decoding an encoded list or map into a nil interface{}
|
||||||
|
- Mapping a non-interface type to an interface, so we can decode appropriately
|
||||||
|
into any interface type with a correctly configured non-interface value.
|
||||||
- Encode a struct as an array, and decode struct from an array in the data stream
|
- Encode a struct as an array, and decode struct from an array in the data stream
|
||||||
|
- Option to encode struct keys as numbers (instead of strings)
|
||||||
|
(to support structured streams with fields encoded as numeric codes)
|
||||||
- Comprehensive support for anonymous fields
|
- Comprehensive support for anonymous fields
|
||||||
- Fast (no-reflection) encoding/decoding of common maps and slices
|
- Fast (no-reflection) encoding/decoding of common maps and slices
|
||||||
- Code-generation for faster performance.
|
- Code-generation for faster performance.
|
||||||
@ -109,7 +115,7 @@ This symmetry is important to reduce chances of issues happening because the
|
|||||||
encoding and decoding sides are out of sync e.g. decoded via very specific
|
encoding and decoding sides are out of sync e.g. decoded via very specific
|
||||||
encoding.TextUnmarshaler but encoded via kind-specific generalized mode.
|
encoding.TextUnmarshaler but encoded via kind-specific generalized mode.
|
||||||
|
|
||||||
Consequently, if a type only defines one-half of the symetry
|
Consequently, if a type only defines one-half of the symmetry
|
||||||
(e.g. it implements UnmarshalJSON() but not MarshalJSON() ),
|
(e.g. it implements UnmarshalJSON() but not MarshalJSON() ),
|
||||||
then that type doesn't satisfy the check and we will continue walking down the
|
then that type doesn't satisfy the check and we will continue walking down the
|
||||||
decision tree.
|
decision tree.
|
||||||
@ -201,6 +207,58 @@ Running Benchmarks
|
|||||||
|
|
||||||
Please see http://github.com/ugorji/go-codec-bench .
|
Please see http://github.com/ugorji/go-codec-bench .
|
||||||
|
|
||||||
|
Caveats
|
||||||
|
|
||||||
|
Struct fields matching the following are ignored during encoding and decoding
|
||||||
|
- struct tag value set to -
|
||||||
|
- func, complex numbers, unsafe pointers
|
||||||
|
- unexported and not embedded
|
||||||
|
- unexported and embedded and not struct kind
|
||||||
|
- unexported and embedded pointers (from go1.10)
|
||||||
|
|
||||||
|
Every other field in a struct will be encoded/decoded.
|
||||||
|
|
||||||
|
Embedded fields are encoded as if they exist in the top-level struct,
|
||||||
|
with some caveats. See Encode documentation.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
package codec
|
package codec
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// - In Go 1.10, when mid-stack inlining is enabled,
|
||||||
|
// we should use committed functions for writeXXX and readXXX calls.
|
||||||
|
// This involves uncommenting the methods for decReaderSwitch and encWriterSwitch
|
||||||
|
// and using those (decReaderSwitch and encWriterSwitch) in all handles
|
||||||
|
// instead of encWriter and decReader.
|
||||||
|
// The benefit is that, for the (En|De)coder over []byte, the encWriter/decReader
|
||||||
|
// will be inlined, giving a performance bump for that typical case.
|
||||||
|
// However, it will only be inlined if mid-stack inlining is enabled,
|
||||||
|
// as we call panic to raise errors, and panic currently prevents inlining.
|
||||||
|
//
|
||||||
|
// PUNTED:
|
||||||
|
// - To make Handle comparable, make extHandle in BasicHandle a non-embedded pointer,
|
||||||
|
// and use overlay methods on *BasicHandle to call through to extHandle after initializing
|
||||||
|
// the "xh *extHandle" to point to a real slice.
|
||||||
|
//
|
||||||
|
// BEFORE EACH RELEASE:
|
||||||
|
// - Look through and fix padding for each type, to eliminate false sharing
|
||||||
|
// - critical shared objects that are read many times
|
||||||
|
// TypeInfos
|
||||||
|
// - pooled objects:
|
||||||
|
// decNaked, decNakedContainers, codecFner, typeInfoLoadArray,
|
||||||
|
// - small objects allocated independently, that we read/use much across threads:
|
||||||
|
// codecFn, typeInfo
|
||||||
|
// - Objects allocated independently and used a lot
|
||||||
|
// Decoder, Encoder,
|
||||||
|
// xxxHandle, xxxEncDriver, xxxDecDriver (xxx = json, msgpack, cbor, binc, simple)
|
||||||
|
// - In all above, arrange values modified together to be close to each other.
|
||||||
|
//
|
||||||
|
// For all of these, either ensure that they occupy full cache lines,
|
||||||
|
// or ensure that the things just past the cache line boundary are hardly read/written
|
||||||
|
// e.g. JsonHandle.RawBytesExt - which is copied into json(En|De)cDriver at init
|
||||||
|
//
|
||||||
|
// Occupying full cache lines means they occupy 8*N words (where N is an integer).
|
||||||
|
// Check this out by running: ./run.sh -z
|
||||||
|
// - look at those tagged ****, meaning they are not occupying full cache lines
|
||||||
|
// - look at those tagged <<<<, meaning they are larger than 32 words (something to watch)
|
||||||
|
// - Run "golint -min_confidence 0.81"
|
||||||
|
29
vendor/github.com/ugorji/go/codec/README.md
generated
vendored
29
vendor/github.com/ugorji/go/codec/README.md
generated
vendored
@ -31,15 +31,14 @@ Rich Feature Set includes:
|
|||||||
|
|
||||||
- Simple but extremely powerful and feature-rich API
|
- Simple but extremely powerful and feature-rich API
|
||||||
- Support for go1.4 and above, while selectively using newer APIs for later releases
|
- Support for go1.4 and above, while selectively using newer APIs for later releases
|
||||||
- Good code coverage ( > 70% )
|
- Excellent code coverage ( > 90% )
|
||||||
- Very High Performance.
|
- Very High Performance.
|
||||||
Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X.
|
Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X.
|
||||||
- Careful selected use of 'unsafe' for targeted performance gains.
|
- Careful selected use of 'unsafe' for targeted performance gains.
|
||||||
100% mode exists where 'unsafe' is not used at all.
|
100% mode exists where 'unsafe' is not used at all.
|
||||||
- Lock-free (sans mutex) concurrency for scaling to 100's of cores
|
- Lock-free (sans mutex) concurrency for scaling to 100's of cores
|
||||||
- Multiple conversions:
|
- Coerce types where appropriate
|
||||||
Package coerces types where appropriate
|
e.g. decode an int in the stream into a float, decode numbers from formatted strings, etc
|
||||||
e.g. decode an int in the stream into a float, etc.
|
|
||||||
- Corner Cases:
|
- Corner Cases:
|
||||||
Overflows, nil maps/slices, nil values in streams are handled correctly
|
Overflows, nil maps/slices, nil values in streams are handled correctly
|
||||||
- Standard field renaming via tags
|
- Standard field renaming via tags
|
||||||
@ -48,10 +47,16 @@ Rich Feature Set includes:
|
|||||||
(struct, slice, map, primitives, pointers, interface{}, etc)
|
(struct, slice, map, primitives, pointers, interface{}, etc)
|
||||||
- Extensions to support efficient encoding/decoding of any named types
|
- Extensions to support efficient encoding/decoding of any named types
|
||||||
- Support encoding.(Binary|Text)(M|Unm)arshaler interfaces
|
- Support encoding.(Binary|Text)(M|Unm)arshaler interfaces
|
||||||
|
- Support IsZero() bool to determine if a value is a zero value.
|
||||||
|
Analogous to time.Time.IsZero() bool.
|
||||||
- Decoding without a schema (into a interface{}).
|
- Decoding without a schema (into a interface{}).
|
||||||
Includes Options to configure what specific map or slice type to use
|
Includes Options to configure what specific map or slice type to use
|
||||||
when decoding an encoded list or map into a nil interface{}
|
when decoding an encoded list or map into a nil interface{}
|
||||||
|
- Mapping a non-interface type to an interface, so we can decode appropriately
|
||||||
|
into any interface type with a correctly configured non-interface value.
|
||||||
- Encode a struct as an array, and decode struct from an array in the data stream
|
- Encode a struct as an array, and decode struct from an array in the data stream
|
||||||
|
- Option to encode struct keys as numbers (instead of strings)
|
||||||
|
(to support structured streams with fields encoded as numeric codes)
|
||||||
- Comprehensive support for anonymous fields
|
- Comprehensive support for anonymous fields
|
||||||
- Fast (no-reflection) encoding/decoding of common maps and slices
|
- Fast (no-reflection) encoding/decoding of common maps and slices
|
||||||
- Code-generation for faster performance.
|
- Code-generation for faster performance.
|
||||||
@ -107,7 +112,7 @@ This symmetry is important to reduce chances of issues happening because the
|
|||||||
encoding and decoding sides are out of sync e.g. decoded via very specific
|
encoding and decoding sides are out of sync e.g. decoded via very specific
|
||||||
encoding.TextUnmarshaler but encoded via kind-specific generalized mode.
|
encoding.TextUnmarshaler but encoded via kind-specific generalized mode.
|
||||||
|
|
||||||
Consequently, if a type only defines one-half of the symetry
|
Consequently, if a type only defines one-half of the symmetry
|
||||||
(e.g. it implements UnmarshalJSON() but not MarshalJSON() ),
|
(e.g. it implements UnmarshalJSON() but not MarshalJSON() ),
|
||||||
then that type doesn't satisfy the check and we will continue walking down the
|
then that type doesn't satisfy the check and we will continue walking down the
|
||||||
decision tree.
|
decision tree.
|
||||||
@ -185,3 +190,17 @@ You can run the tag 'safe' to run tests or build in safe mode. e.g.
|
|||||||
|
|
||||||
Please see http://github.com/ugorji/go-codec-bench .
|
Please see http://github.com/ugorji/go-codec-bench .
|
||||||
|
|
||||||
|
## Caveats
|
||||||
|
|
||||||
|
Struct fields matching the following are ignored during encoding and decoding
|
||||||
|
|
||||||
|
- struct tag value set to -
|
||||||
|
- func, complex numbers, unsafe pointers
|
||||||
|
- unexported and not embedded
|
||||||
|
- unexported and embedded and not struct kind
|
||||||
|
- unexported and embedded pointers (from go1.10)
|
||||||
|
|
||||||
|
Every other field in a struct will be encoded/decoded.
|
||||||
|
|
||||||
|
Embedded fields are encoded as if they exist in the top-level struct,
|
||||||
|
with some caveats. See Encode documentation.
|
||||||
|
330
vendor/github.com/ugorji/go/codec/binc.go
generated
vendored
330
vendor/github.com/ugorji/go/codec/binc.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
@ -57,38 +57,31 @@ const (
|
|||||||
|
|
||||||
type bincEncDriver struct {
|
type bincEncDriver struct {
|
||||||
e *Encoder
|
e *Encoder
|
||||||
|
h *BincHandle
|
||||||
w encWriter
|
w encWriter
|
||||||
m map[string]uint16 // symbols
|
m map[string]uint16 // symbols
|
||||||
b [scratchByteArrayLen]byte
|
b [16]byte // scratch, used for encoding numbers - bigendian style
|
||||||
s uint16 // symbols sequencer
|
s uint16 // symbols sequencer
|
||||||
|
// c containerState
|
||||||
|
encDriverTrackContainerWriter
|
||||||
|
noBuiltInTypes
|
||||||
// encNoSeparator
|
// encNoSeparator
|
||||||
encDriverNoopContainerWriter
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *bincEncDriver) IsBuiltinType(rt uintptr) bool {
|
|
||||||
return rt == timeTypId
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *bincEncDriver) EncodeBuiltin(rt uintptr, v interface{}) {
|
|
||||||
if rt == timeTypId {
|
|
||||||
var bs []byte
|
|
||||||
switch x := v.(type) {
|
|
||||||
case time.Time:
|
|
||||||
bs = encodeTime(x)
|
|
||||||
case *time.Time:
|
|
||||||
bs = encodeTime(*x)
|
|
||||||
default:
|
|
||||||
e.e.errorf("binc error encoding builtin: expect time.Time, received %T", v)
|
|
||||||
}
|
|
||||||
e.w.writen1(bincVdTimestamp<<4 | uint8(len(bs)))
|
|
||||||
e.w.writeb(bs)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *bincEncDriver) EncodeNil() {
|
func (e *bincEncDriver) EncodeNil() {
|
||||||
e.w.writen1(bincVdSpecial<<4 | bincSpNil)
|
e.w.writen1(bincVdSpecial<<4 | bincSpNil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *bincEncDriver) EncodeTime(t time.Time) {
|
||||||
|
if t.IsZero() {
|
||||||
|
e.EncodeNil()
|
||||||
|
} else {
|
||||||
|
bs := bincEncodeTime(t)
|
||||||
|
e.w.writen1(bincVdTimestamp<<4 | uint8(len(bs)))
|
||||||
|
e.w.writeb(bs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (e *bincEncDriver) EncodeBool(b bool) {
|
func (e *bincEncDriver) EncodeBool(b bool) {
|
||||||
if b {
|
if b {
|
||||||
e.w.writen1(bincVdSpecial<<4 | bincSpTrue)
|
e.w.writen1(bincVdSpecial<<4 | bincSpTrue)
|
||||||
@ -198,13 +191,19 @@ func (e *bincEncDriver) encodeExtPreamble(xtag byte, length int) {
|
|||||||
|
|
||||||
func (e *bincEncDriver) WriteArrayStart(length int) {
|
func (e *bincEncDriver) WriteArrayStart(length int) {
|
||||||
e.encLen(bincVdArray<<4, uint64(length))
|
e.encLen(bincVdArray<<4, uint64(length))
|
||||||
|
e.c = containerArrayStart
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *bincEncDriver) WriteMapStart(length int) {
|
func (e *bincEncDriver) WriteMapStart(length int) {
|
||||||
e.encLen(bincVdMap<<4, uint64(length))
|
e.encLen(bincVdMap<<4, uint64(length))
|
||||||
|
e.c = containerMapStart
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *bincEncDriver) EncodeString(c charEncoding, v string) {
|
func (e *bincEncDriver) EncodeString(c charEncoding, v string) {
|
||||||
|
if e.c == containerMapKey && c == cUTF8 && (e.h.AsSymbols == 0 || e.h.AsSymbols == 1) {
|
||||||
|
e.EncodeSymbol(v)
|
||||||
|
return
|
||||||
|
}
|
||||||
l := uint64(len(v))
|
l := uint64(len(v))
|
||||||
e.encBytesLen(c, l)
|
e.encBytesLen(c, l)
|
||||||
if l > 0 {
|
if l > 0 {
|
||||||
@ -214,7 +213,7 @@ func (e *bincEncDriver) EncodeString(c charEncoding, v string) {
|
|||||||
|
|
||||||
func (e *bincEncDriver) EncodeSymbol(v string) {
|
func (e *bincEncDriver) EncodeSymbol(v string) {
|
||||||
// if WriteSymbolsNoRefs {
|
// if WriteSymbolsNoRefs {
|
||||||
// e.encodeString(c_UTF8, v)
|
// e.encodeString(cUTF8, v)
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@ -224,10 +223,10 @@ func (e *bincEncDriver) EncodeSymbol(v string) {
|
|||||||
|
|
||||||
l := len(v)
|
l := len(v)
|
||||||
if l == 0 {
|
if l == 0 {
|
||||||
e.encBytesLen(c_UTF8, 0)
|
e.encBytesLen(cUTF8, 0)
|
||||||
return
|
return
|
||||||
} else if l == 1 {
|
} else if l == 1 {
|
||||||
e.encBytesLen(c_UTF8, 1)
|
e.encBytesLen(cUTF8, 1)
|
||||||
e.w.writen1(v[0])
|
e.w.writen1(v[0])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -277,6 +276,10 @@ func (e *bincEncDriver) EncodeSymbol(v string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *bincEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
|
func (e *bincEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
|
||||||
|
if v == nil {
|
||||||
|
e.EncodeNil()
|
||||||
|
return
|
||||||
|
}
|
||||||
l := uint64(len(v))
|
l := uint64(len(v))
|
||||||
e.encBytesLen(c, l)
|
e.encBytesLen(c, l)
|
||||||
if l > 0 {
|
if l > 0 {
|
||||||
@ -286,7 +289,7 @@ func (e *bincEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
|
|||||||
|
|
||||||
func (e *bincEncDriver) encBytesLen(c charEncoding, length uint64) {
|
func (e *bincEncDriver) encBytesLen(c charEncoding, length uint64) {
|
||||||
//TODO: support bincUnicodeOther (for now, just use string or bytearray)
|
//TODO: support bincUnicodeOther (for now, just use string or bytearray)
|
||||||
if c == c_RAW {
|
if c == cRAW {
|
||||||
e.encLen(bincVdByteArray<<4, length)
|
e.encLen(bincVdByteArray<<4, length)
|
||||||
} else {
|
} else {
|
||||||
e.encLen(bincVdString<<4, length)
|
e.encLen(bincVdString<<4, length)
|
||||||
@ -325,6 +328,9 @@ type bincDecSymbol struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type bincDecDriver struct {
|
type bincDecDriver struct {
|
||||||
|
decDriverNoopContainerReader
|
||||||
|
noBuiltInTypes
|
||||||
|
|
||||||
d *Decoder
|
d *Decoder
|
||||||
h *BincHandle
|
h *BincHandle
|
||||||
r decReader
|
r decReader
|
||||||
@ -333,14 +339,15 @@ type bincDecDriver struct {
|
|||||||
bd byte
|
bd byte
|
||||||
vd byte
|
vd byte
|
||||||
vs byte
|
vs byte
|
||||||
// noStreamingCodec
|
_ [3]byte // padding
|
||||||
// decNoSeparator
|
|
||||||
b [scratchByteArrayLen]byte
|
|
||||||
|
|
||||||
// linear searching on this slice is ok,
|
// linear searching on this slice is ok,
|
||||||
// because we typically expect < 32 symbols in each stream.
|
// because we typically expect < 32 symbols in each stream.
|
||||||
s []bincDecSymbol
|
s []bincDecSymbol
|
||||||
decDriverNoopContainerReader
|
|
||||||
|
// noStreamingCodec
|
||||||
|
// decNoSeparator
|
||||||
|
|
||||||
|
b [8 * 8]byte // scratch
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *bincDecDriver) readNextBd() {
|
func (d *bincDecDriver) readNextBd() {
|
||||||
@ -371,9 +378,10 @@ func (d *bincDecDriver) ContainerType() (vt valueType) {
|
|||||||
return valueTypeArray
|
return valueTypeArray
|
||||||
} else if d.vd == bincVdMap {
|
} else if d.vd == bincVdMap {
|
||||||
return valueTypeMap
|
return valueTypeMap
|
||||||
} else {
|
|
||||||
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
|
|
||||||
}
|
}
|
||||||
|
// else {
|
||||||
|
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
|
||||||
|
// }
|
||||||
return valueTypeUnset
|
return valueTypeUnset
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,27 +396,24 @@ func (d *bincDecDriver) TryDecodeAsNil() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *bincDecDriver) IsBuiltinType(rt uintptr) bool {
|
func (d *bincDecDriver) DecodeTime() (t time.Time) {
|
||||||
return rt == timeTypId
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *bincDecDriver) DecodeBuiltin(rt uintptr, v interface{}) {
|
|
||||||
if !d.bdRead {
|
if !d.bdRead {
|
||||||
d.readNextBd()
|
d.readNextBd()
|
||||||
}
|
}
|
||||||
if rt == timeTypId {
|
if d.bd == bincVdSpecial<<4|bincSpNil {
|
||||||
|
d.bdRead = false
|
||||||
|
return
|
||||||
|
}
|
||||||
if d.vd != bincVdTimestamp {
|
if d.vd != bincVdTimestamp {
|
||||||
d.d.errorf("Invalid d.vd. Expecting 0x%x. Received: 0x%x", bincVdTimestamp, d.vd)
|
d.d.errorf("Invalid d.vd. Expecting 0x%x. Received: 0x%x", bincVdTimestamp, d.vd)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tt, err := decodeTime(d.r.readx(int(d.vs)))
|
t, err := bincDecodeTime(d.r.readx(int(d.vs)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
var vt *time.Time = v.(*time.Time)
|
|
||||||
*vt = tt
|
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
}
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *bincDecDriver) decFloatPre(vs, defaultLen byte) {
|
func (d *bincDecDriver) decFloatPre(vs, defaultLen byte) {
|
||||||
@ -497,45 +502,33 @@ func (d *bincDecDriver) decCheckInteger() (ui uint64, neg bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
d.d.errorf("number can only be decoded from uint or int values. d.bd: 0x%x, d.vd: 0x%x", d.bd, d.vd)
|
d.d.errorf("integer can only be decoded from int/uint. d.bd: 0x%x, d.vd: 0x%x", d.bd, d.vd)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *bincDecDriver) DecodeInt(bitsize uint8) (i int64) {
|
func (d *bincDecDriver) DecodeInt64() (i int64) {
|
||||||
ui, neg := d.decCheckInteger()
|
ui, neg := d.decCheckInteger()
|
||||||
i, overflow := chkOvf.SignedInt(ui)
|
i = chkOvf.SignedIntV(ui)
|
||||||
if overflow {
|
|
||||||
d.d.errorf("simple: overflow converting %v to signed integer", ui)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if neg {
|
if neg {
|
||||||
i = -i
|
i = -i
|
||||||
}
|
}
|
||||||
if chkOvf.Int(i, bitsize) {
|
|
||||||
d.d.errorf("binc: overflow integer: %v for num bits: %v", i, bitsize)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *bincDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
|
func (d *bincDecDriver) DecodeUint64() (ui uint64) {
|
||||||
ui, neg := d.decCheckInteger()
|
ui, neg := d.decCheckInteger()
|
||||||
if neg {
|
if neg {
|
||||||
d.d.errorf("Assigning negative signed value to unsigned type")
|
d.d.errorf("Assigning negative signed value to unsigned type")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if chkOvf.Uint(ui, bitsize) {
|
|
||||||
d.d.errorf("binc: overflow integer: %v", ui)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *bincDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
|
func (d *bincDecDriver) DecodeFloat64() (f float64) {
|
||||||
if !d.bdRead {
|
if !d.bdRead {
|
||||||
d.readNextBd()
|
d.readNextBd()
|
||||||
}
|
}
|
||||||
@ -557,11 +550,7 @@ func (d *bincDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
|
|||||||
} else if vd == bincVdFloat {
|
} else if vd == bincVdFloat {
|
||||||
f = d.decFloat()
|
f = d.decFloat()
|
||||||
} else {
|
} else {
|
||||||
f = float64(d.DecodeInt(64))
|
f = float64(d.DecodeInt64())
|
||||||
}
|
|
||||||
if chkOverflow32 && chkOvf.Float32(f) {
|
|
||||||
d.d.errorf("binc: float32 overflow: %v", f)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
return
|
return
|
||||||
@ -633,7 +622,8 @@ func (d *bincDecDriver) decLenNumber() (v uint64) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool) (bs2 []byte, s string) {
|
func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool) (
|
||||||
|
bs2 []byte, s string) {
|
||||||
if !d.bdRead {
|
if !d.bdRead {
|
||||||
d.readNextBd()
|
d.readNextBd()
|
||||||
}
|
}
|
||||||
@ -641,7 +631,7 @@ func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool)
|
|||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var slen int = -1
|
var slen = -1
|
||||||
// var ok bool
|
// var ok bool
|
||||||
switch d.vd {
|
switch d.vd {
|
||||||
case bincVdString, bincVdByteArray:
|
case bincVdString, bincVdByteArray:
|
||||||
@ -743,6 +733,11 @@ func (d *bincDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
|
|||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
// check if an "array" of uint8's (see ContainerType for how to infer if an array)
|
||||||
|
if d.vd == bincVdArray {
|
||||||
|
bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
|
||||||
|
return
|
||||||
|
}
|
||||||
var clen int
|
var clen int
|
||||||
if d.vd == bincVdString || d.vd == bincVdByteArray {
|
if d.vd == bincVdString || d.vd == bincVdByteArray {
|
||||||
clen = d.decLen()
|
clen = d.decLen()
|
||||||
@ -863,8 +858,8 @@ func (d *bincDecDriver) DecodeNaked() {
|
|||||||
n.v = valueTypeBytes
|
n.v = valueTypeBytes
|
||||||
n.l = d.DecodeBytes(nil, false)
|
n.l = d.DecodeBytes(nil, false)
|
||||||
case bincVdTimestamp:
|
case bincVdTimestamp:
|
||||||
n.v = valueTypeTimestamp
|
n.v = valueTypeTime
|
||||||
tt, err := decodeTime(d.r.readx(int(d.vs)))
|
tt, err := bincDecodeTime(d.r.readx(int(d.vs)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -912,27 +907,50 @@ type BincHandle struct {
|
|||||||
BasicHandle
|
BasicHandle
|
||||||
binaryEncodingType
|
binaryEncodingType
|
||||||
noElemSeparators
|
noElemSeparators
|
||||||
|
|
||||||
|
// AsSymbols defines what should be encoded as symbols.
|
||||||
|
//
|
||||||
|
// Encoding as symbols can reduce the encoded size significantly.
|
||||||
|
//
|
||||||
|
// However, during decoding, each string to be encoded as a symbol must
|
||||||
|
// be checked to see if it has been seen before. Consequently, encoding time
|
||||||
|
// will increase if using symbols, because string comparisons has a clear cost.
|
||||||
|
//
|
||||||
|
// Values:
|
||||||
|
// - 0: default: library uses best judgement
|
||||||
|
// - 1: use symbols
|
||||||
|
// - 2: do not use symbols
|
||||||
|
AsSymbols uint8
|
||||||
|
|
||||||
|
// AsSymbols: may later on introduce more options ...
|
||||||
|
// - m: map keys
|
||||||
|
// - s: struct fields
|
||||||
|
// - n: none
|
||||||
|
// - a: all: same as m, s, ...
|
||||||
|
|
||||||
|
_ [1]uint64 // padding
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name returns the name of the handle: binc
|
||||||
|
func (h *BincHandle) Name() string { return "binc" }
|
||||||
|
|
||||||
|
// SetBytesExt sets an extension
|
||||||
func (h *BincHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
|
func (h *BincHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
|
||||||
return h.SetExt(rt, tag, &setExtWrapper{b: ext})
|
return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *BincHandle) newEncDriver(e *Encoder) encDriver {
|
func (h *BincHandle) newEncDriver(e *Encoder) encDriver {
|
||||||
return &bincEncDriver{e: e, w: e.w}
|
return &bincEncDriver{e: e, h: h, w: e.w}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *BincHandle) newDecDriver(d *Decoder) decDriver {
|
func (h *BincHandle) newDecDriver(d *Decoder) decDriver {
|
||||||
return &bincDecDriver{d: d, h: h, r: d.r, br: d.bytes}
|
return &bincDecDriver{d: d, h: h, r: d.r, br: d.bytes}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ *BincHandle) IsBuiltinType(rt uintptr) bool {
|
|
||||||
return rt == timeTypId
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *bincEncDriver) reset() {
|
func (e *bincEncDriver) reset() {
|
||||||
e.w = e.e.w
|
e.w = e.e.w
|
||||||
e.s = 0
|
e.s = 0
|
||||||
|
e.c = 0
|
||||||
e.m = nil
|
e.m = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -942,5 +960,165 @@ func (d *bincDecDriver) reset() {
|
|||||||
d.bd, d.bdRead, d.vd, d.vs = 0, false, 0, 0
|
d.bd, d.bdRead, d.vd, d.vs = 0, false, 0, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// var timeDigits = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
|
||||||
|
|
||||||
|
// EncodeTime encodes a time.Time as a []byte, including
|
||||||
|
// information on the instant in time and UTC offset.
|
||||||
|
//
|
||||||
|
// Format Description
|
||||||
|
//
|
||||||
|
// A timestamp is composed of 3 components:
|
||||||
|
//
|
||||||
|
// - secs: signed integer representing seconds since unix epoch
|
||||||
|
// - nsces: unsigned integer representing fractional seconds as a
|
||||||
|
// nanosecond offset within secs, in the range 0 <= nsecs < 1e9
|
||||||
|
// - tz: signed integer representing timezone offset in minutes east of UTC,
|
||||||
|
// and a dst (daylight savings time) flag
|
||||||
|
//
|
||||||
|
// When encoding a timestamp, the first byte is the descriptor, which
|
||||||
|
// defines which components are encoded and how many bytes are used to
|
||||||
|
// encode secs and nsecs components. *If secs/nsecs is 0 or tz is UTC, it
|
||||||
|
// is not encoded in the byte array explicitly*.
|
||||||
|
//
|
||||||
|
// Descriptor 8 bits are of the form `A B C DDD EE`:
|
||||||
|
// A: Is secs component encoded? 1 = true
|
||||||
|
// B: Is nsecs component encoded? 1 = true
|
||||||
|
// C: Is tz component encoded? 1 = true
|
||||||
|
// DDD: Number of extra bytes for secs (range 0-7).
|
||||||
|
// If A = 1, secs encoded in DDD+1 bytes.
|
||||||
|
// If A = 0, secs is not encoded, and is assumed to be 0.
|
||||||
|
// If A = 1, then we need at least 1 byte to encode secs.
|
||||||
|
// DDD says the number of extra bytes beyond that 1.
|
||||||
|
// E.g. if DDD=0, then secs is represented in 1 byte.
|
||||||
|
// if DDD=2, then secs is represented in 3 bytes.
|
||||||
|
// EE: Number of extra bytes for nsecs (range 0-3).
|
||||||
|
// If B = 1, nsecs encoded in EE+1 bytes (similar to secs/DDD above)
|
||||||
|
//
|
||||||
|
// Following the descriptor bytes, subsequent bytes are:
|
||||||
|
//
|
||||||
|
// secs component encoded in `DDD + 1` bytes (if A == 1)
|
||||||
|
// nsecs component encoded in `EE + 1` bytes (if B == 1)
|
||||||
|
// tz component encoded in 2 bytes (if C == 1)
|
||||||
|
//
|
||||||
|
// secs and nsecs components are integers encoded in a BigEndian
|
||||||
|
// 2-complement encoding format.
|
||||||
|
//
|
||||||
|
// tz component is encoded as 2 bytes (16 bits). Most significant bit 15 to
|
||||||
|
// Least significant bit 0 are described below:
|
||||||
|
//
|
||||||
|
// Timezone offset has a range of -12:00 to +14:00 (ie -720 to +840 minutes).
|
||||||
|
// Bit 15 = have\_dst: set to 1 if we set the dst flag.
|
||||||
|
// Bit 14 = dst\_on: set to 1 if dst is in effect at the time, or 0 if not.
|
||||||
|
// Bits 13..0 = timezone offset in minutes. It is a signed integer in Big Endian format.
|
||||||
|
//
|
||||||
|
func bincEncodeTime(t time.Time) []byte {
|
||||||
|
//t := rv.Interface().(time.Time)
|
||||||
|
tsecs, tnsecs := t.Unix(), t.Nanosecond()
|
||||||
|
var (
|
||||||
|
bd byte
|
||||||
|
btmp [8]byte
|
||||||
|
bs [16]byte
|
||||||
|
i int = 1
|
||||||
|
)
|
||||||
|
l := t.Location()
|
||||||
|
if l == time.UTC {
|
||||||
|
l = nil
|
||||||
|
}
|
||||||
|
if tsecs != 0 {
|
||||||
|
bd = bd | 0x80
|
||||||
|
bigen.PutUint64(btmp[:], uint64(tsecs))
|
||||||
|
f := pruneSignExt(btmp[:], tsecs >= 0)
|
||||||
|
bd = bd | (byte(7-f) << 2)
|
||||||
|
copy(bs[i:], btmp[f:])
|
||||||
|
i = i + (8 - f)
|
||||||
|
}
|
||||||
|
if tnsecs != 0 {
|
||||||
|
bd = bd | 0x40
|
||||||
|
bigen.PutUint32(btmp[:4], uint32(tnsecs))
|
||||||
|
f := pruneSignExt(btmp[:4], true)
|
||||||
|
bd = bd | byte(3-f)
|
||||||
|
copy(bs[i:], btmp[f:4])
|
||||||
|
i = i + (4 - f)
|
||||||
|
}
|
||||||
|
if l != nil {
|
||||||
|
bd = bd | 0x20
|
||||||
|
// Note that Go Libs do not give access to dst flag.
|
||||||
|
_, zoneOffset := t.Zone()
|
||||||
|
//zoneName, zoneOffset := t.Zone()
|
||||||
|
zoneOffset /= 60
|
||||||
|
z := uint16(zoneOffset)
|
||||||
|
bigen.PutUint16(btmp[:2], z)
|
||||||
|
// clear dst flags
|
||||||
|
bs[i] = btmp[0] & 0x3f
|
||||||
|
bs[i+1] = btmp[1]
|
||||||
|
i = i + 2
|
||||||
|
}
|
||||||
|
bs[0] = bd
|
||||||
|
return bs[0:i]
|
||||||
|
}
|
||||||
|
|
||||||
|
// bincDecodeTime decodes a []byte into a time.Time.
|
||||||
|
func bincDecodeTime(bs []byte) (tt time.Time, err error) {
|
||||||
|
bd := bs[0]
|
||||||
|
var (
|
||||||
|
tsec int64
|
||||||
|
tnsec uint32
|
||||||
|
tz uint16
|
||||||
|
i byte = 1
|
||||||
|
i2 byte
|
||||||
|
n byte
|
||||||
|
)
|
||||||
|
if bd&(1<<7) != 0 {
|
||||||
|
var btmp [8]byte
|
||||||
|
n = ((bd >> 2) & 0x7) + 1
|
||||||
|
i2 = i + n
|
||||||
|
copy(btmp[8-n:], bs[i:i2])
|
||||||
|
//if first bit of bs[i] is set, then fill btmp[0..8-n] with 0xff (ie sign extend it)
|
||||||
|
if bs[i]&(1<<7) != 0 {
|
||||||
|
copy(btmp[0:8-n], bsAll0xff)
|
||||||
|
//for j,k := byte(0), 8-n; j < k; j++ { btmp[j] = 0xff }
|
||||||
|
}
|
||||||
|
i = i2
|
||||||
|
tsec = int64(bigen.Uint64(btmp[:]))
|
||||||
|
}
|
||||||
|
if bd&(1<<6) != 0 {
|
||||||
|
var btmp [4]byte
|
||||||
|
n = (bd & 0x3) + 1
|
||||||
|
i2 = i + n
|
||||||
|
copy(btmp[4-n:], bs[i:i2])
|
||||||
|
i = i2
|
||||||
|
tnsec = bigen.Uint32(btmp[:])
|
||||||
|
}
|
||||||
|
if bd&(1<<5) == 0 {
|
||||||
|
tt = time.Unix(tsec, int64(tnsec)).UTC()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// In stdlib time.Parse, when a date is parsed without a zone name, it uses "" as zone name.
|
||||||
|
// However, we need name here, so it can be shown when time is printed.
|
||||||
|
// Zone name is in form: UTC-08:00.
|
||||||
|
// Note that Go Libs do not give access to dst flag, so we ignore dst bits
|
||||||
|
|
||||||
|
i2 = i + 2
|
||||||
|
tz = bigen.Uint16(bs[i:i2])
|
||||||
|
// i = i2
|
||||||
|
// sign extend sign bit into top 2 MSB (which were dst bits):
|
||||||
|
if tz&(1<<13) == 0 { // positive
|
||||||
|
tz = tz & 0x3fff //clear 2 MSBs: dst bits
|
||||||
|
} else { // negative
|
||||||
|
tz = tz | 0xc000 //set 2 MSBs: dst bits
|
||||||
|
}
|
||||||
|
tzint := int16(tz)
|
||||||
|
if tzint == 0 {
|
||||||
|
tt = time.Unix(tsec, int64(tnsec)).UTC()
|
||||||
|
} else {
|
||||||
|
// For Go Time, do not use a descriptive timezone.
|
||||||
|
// It's unnecessary, and makes it harder to do a reflect.DeepEqual.
|
||||||
|
// The Offset already tells what the offset should be, if not on UTC and unknown zone name.
|
||||||
|
// var zoneName = timeLocUTCName(tzint)
|
||||||
|
tt = time.Unix(tsec, int64(tnsec)).In(time.FixedZone("", int(tzint)*60))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var _ decDriver = (*bincDecDriver)(nil)
|
var _ decDriver = (*bincDecDriver)(nil)
|
||||||
var _ encDriver = (*bincEncDriver)(nil)
|
var _ encDriver = (*bincEncDriver)(nil)
|
||||||
|
186
vendor/github.com/ugorji/go/codec/cbor.go
generated
vendored
186
vendor/github.com/ugorji/go/codec/cbor.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
@ -6,6 +6,7 @@ package codec
|
|||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -38,6 +39,8 @@ const (
|
|||||||
cborBdBreak = 0xff
|
cborBdBreak = 0xff
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// These define some in-stream descriptors for
|
||||||
|
// manual encoding e.g. when doing explicit indefinite-length
|
||||||
const (
|
const (
|
||||||
CborStreamBytes byte = 0x5f
|
CborStreamBytes byte = 0x5f
|
||||||
CborStreamString = 0x7f
|
CborStreamString = 0x7f
|
||||||
@ -67,6 +70,7 @@ type cborEncDriver struct {
|
|||||||
w encWriter
|
w encWriter
|
||||||
h *CborHandle
|
h *CborHandle
|
||||||
x [8]byte
|
x [8]byte
|
||||||
|
_ [3]uint64 // padding
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *cborEncDriver) EncodeNil() {
|
func (e *cborEncDriver) EncodeNil() {
|
||||||
@ -124,6 +128,24 @@ func (e *cborEncDriver) encLen(bd byte, length int) {
|
|||||||
e.encUint(uint64(length), bd)
|
e.encUint(uint64(length), bd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *cborEncDriver) EncodeTime(t time.Time) {
|
||||||
|
if t.IsZero() {
|
||||||
|
e.EncodeNil()
|
||||||
|
} else if e.h.TimeRFC3339 {
|
||||||
|
e.encUint(0, cborBaseTag)
|
||||||
|
e.EncodeString(cUTF8, t.Format(time.RFC3339Nano))
|
||||||
|
} else {
|
||||||
|
e.encUint(1, cborBaseTag)
|
||||||
|
t = t.UTC().Round(time.Microsecond)
|
||||||
|
sec, nsec := t.Unix(), uint64(t.Nanosecond())
|
||||||
|
if nsec == 0 {
|
||||||
|
e.EncodeInt(sec)
|
||||||
|
} else {
|
||||||
|
e.EncodeFloat64(float64(sec) + float64(nsec)/1e9)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (e *cborEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Encoder) {
|
func (e *cborEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Encoder) {
|
||||||
e.encUint(uint64(xtag), cborBaseTag)
|
e.encUint(uint64(xtag), cborBaseTag)
|
||||||
if v := ext.ConvertExt(rv); v == nil {
|
if v := ext.ConvertExt(rv); v == nil {
|
||||||
@ -172,16 +194,14 @@ func (e *cborEncDriver) WriteArrayEnd() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *cborEncDriver) EncodeSymbol(v string) {
|
|
||||||
e.encStringBytesS(cborBaseString, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *cborEncDriver) EncodeString(c charEncoding, v string) {
|
func (e *cborEncDriver) EncodeString(c charEncoding, v string) {
|
||||||
e.encStringBytesS(cborBaseString, v)
|
e.encStringBytesS(cborBaseString, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *cborEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
|
func (e *cborEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
|
||||||
if c == c_RAW {
|
if v == nil {
|
||||||
|
e.EncodeNil()
|
||||||
|
} else if c == cRAW {
|
||||||
e.encStringBytesS(cborBaseBytes, stringView(v))
|
e.encStringBytesS(cborBaseBytes, stringView(v))
|
||||||
} else {
|
} else {
|
||||||
e.encStringBytesS(cborBaseString, stringView(v))
|
e.encStringBytesS(cborBaseString, stringView(v))
|
||||||
@ -226,13 +246,14 @@ type cborDecDriver struct {
|
|||||||
d *Decoder
|
d *Decoder
|
||||||
h *CborHandle
|
h *CborHandle
|
||||||
r decReader
|
r decReader
|
||||||
b [scratchByteArrayLen]byte
|
// b [scratchByteArrayLen]byte
|
||||||
br bool // bytes reader
|
br bool // bytes reader
|
||||||
bdRead bool
|
bdRead bool
|
||||||
bd byte
|
bd byte
|
||||||
noBuiltInTypes
|
noBuiltInTypes
|
||||||
// decNoSeparator
|
// decNoSeparator
|
||||||
decDriverNoopContainerReader
|
decDriverNoopContainerReader
|
||||||
|
_ [3]uint64 // padding
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *cborDecDriver) readNextBd() {
|
func (d *cborDecDriver) readNextBd() {
|
||||||
@ -261,9 +282,10 @@ func (d *cborDecDriver) ContainerType() (vt valueType) {
|
|||||||
return valueTypeArray
|
return valueTypeArray
|
||||||
} else if d.bd == cborBdIndefiniteMap || (d.bd >= cborBaseMap && d.bd < cborBaseTag) {
|
} else if d.bd == cborBdIndefiniteMap || (d.bd >= cborBaseMap && d.bd < cborBaseTag) {
|
||||||
return valueTypeMap
|
return valueTypeMap
|
||||||
} else {
|
|
||||||
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
|
|
||||||
}
|
}
|
||||||
|
// else {
|
||||||
|
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
|
||||||
|
// }
|
||||||
return valueTypeUnset
|
return valueTypeUnset
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,46 +348,30 @@ func (d *cborDecDriver) decCheckInteger() (neg bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *cborDecDriver) DecodeInt(bitsize uint8) (i int64) {
|
func (d *cborDecDriver) DecodeInt64() (i int64) {
|
||||||
neg := d.decCheckInteger()
|
neg := d.decCheckInteger()
|
||||||
ui := d.decUint()
|
ui := d.decUint()
|
||||||
// check if this number can be converted to an int without overflow
|
// check if this number can be converted to an int without overflow
|
||||||
var overflow bool
|
|
||||||
if neg {
|
if neg {
|
||||||
if i, overflow = chkOvf.SignedInt(ui + 1); overflow {
|
i = -(chkOvf.SignedIntV(ui + 1))
|
||||||
d.d.errorf("cbor: overflow converting %v to signed integer", ui+1)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
i = -i
|
|
||||||
} else {
|
} else {
|
||||||
if i, overflow = chkOvf.SignedInt(ui); overflow {
|
i = chkOvf.SignedIntV(ui)
|
||||||
d.d.errorf("cbor: overflow converting %v to signed integer", ui)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if chkOvf.Int(i, bitsize) {
|
|
||||||
d.d.errorf("cbor: overflow integer: %v", i)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *cborDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
|
func (d *cborDecDriver) DecodeUint64() (ui uint64) {
|
||||||
if d.decCheckInteger() {
|
if d.decCheckInteger() {
|
||||||
d.d.errorf("Assigning negative signed value to unsigned type")
|
d.d.errorf("Assigning negative signed value to unsigned type")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ui = d.decUint()
|
ui = d.decUint()
|
||||||
if chkOvf.Uint(ui, bitsize) {
|
|
||||||
d.d.errorf("cbor: overflow integer: %v", ui)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *cborDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
|
func (d *cborDecDriver) DecodeFloat64() (f float64) {
|
||||||
if !d.bdRead {
|
if !d.bdRead {
|
||||||
d.readNextBd()
|
d.readNextBd()
|
||||||
}
|
}
|
||||||
@ -376,15 +382,11 @@ func (d *cborDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
|
|||||||
} else if bd == cborBdFloat64 {
|
} else if bd == cborBdFloat64 {
|
||||||
f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
|
f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
|
||||||
} else if bd >= cborBaseUint && bd < cborBaseBytes {
|
} else if bd >= cborBaseUint && bd < cborBaseBytes {
|
||||||
f = float64(d.DecodeInt(64))
|
f = float64(d.DecodeInt64())
|
||||||
} else {
|
} else {
|
||||||
d.d.errorf("Float only valid from float16/32/64: Invalid descriptor: %v", bd)
|
d.d.errorf("Float only valid from float16/32/64: Invalid descriptor: %v", bd)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if chkOverflow32 && chkOvf.Float32(f) {
|
|
||||||
d.d.errorf("cbor: float32 overflow: %v", f)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -438,7 +440,8 @@ func (d *cborDecDriver) decAppendIndefiniteBytes(bs []byte) []byte {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
if major := d.bd >> 5; major != cborMajorBytes && major != cborMajorText {
|
if major := d.bd >> 5; major != cborMajorBytes && major != cborMajorText {
|
||||||
d.d.errorf("cbor: expect bytes or string major type in indefinite string/bytes; got: %v, byte: %v", major, d.bd)
|
d.d.errorf("expect bytes/string major type in indefinite string/bytes;"+
|
||||||
|
" got: %v, byte: %v", major, d.bd)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
n := d.decLen()
|
n := d.decLen()
|
||||||
@ -470,28 +473,82 @@ func (d *cborDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
|
|||||||
if d.bd == cborBdIndefiniteBytes || d.bd == cborBdIndefiniteString {
|
if d.bd == cborBdIndefiniteBytes || d.bd == cborBdIndefiniteString {
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
if bs == nil {
|
if bs == nil {
|
||||||
|
if zerocopy {
|
||||||
|
return d.decAppendIndefiniteBytes(d.d.b[:0])
|
||||||
|
}
|
||||||
return d.decAppendIndefiniteBytes(zeroByteSlice)
|
return d.decAppendIndefiniteBytes(zeroByteSlice)
|
||||||
}
|
}
|
||||||
return d.decAppendIndefiniteBytes(bs[:0])
|
return d.decAppendIndefiniteBytes(bs[:0])
|
||||||
}
|
}
|
||||||
|
// check if an "array" of uint8's (see ContainerType for how to infer if an array)
|
||||||
|
if d.bd == cborBdIndefiniteArray || (d.bd >= cborBaseArray && d.bd < cborBaseMap) {
|
||||||
|
bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
|
||||||
|
return
|
||||||
|
}
|
||||||
clen := d.decLen()
|
clen := d.decLen()
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
if zerocopy {
|
if zerocopy {
|
||||||
if d.br {
|
if d.br {
|
||||||
return d.r.readx(clen)
|
return d.r.readx(clen)
|
||||||
} else if len(bs) == 0 {
|
} else if len(bs) == 0 {
|
||||||
bs = d.b[:]
|
bs = d.d.b[:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return decByteSlice(d.r, clen, d.d.h.MaxInitLen, bs)
|
return decByteSlice(d.r, clen, d.h.MaxInitLen, bs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *cborDecDriver) DecodeString() (s string) {
|
func (d *cborDecDriver) DecodeString() (s string) {
|
||||||
return string(d.DecodeBytes(d.b[:], true))
|
return string(d.DecodeBytes(d.d.b[:], true))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *cborDecDriver) DecodeStringAsBytes() (s []byte) {
|
func (d *cborDecDriver) DecodeStringAsBytes() (s []byte) {
|
||||||
return d.DecodeBytes(d.b[:], true)
|
return d.DecodeBytes(d.d.b[:], true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *cborDecDriver) DecodeTime() (t time.Time) {
|
||||||
|
if !d.bdRead {
|
||||||
|
d.readNextBd()
|
||||||
|
}
|
||||||
|
if d.bd == cborBdNil || d.bd == cborBdUndefined {
|
||||||
|
d.bdRead = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
xtag := d.decUint()
|
||||||
|
d.bdRead = false
|
||||||
|
return d.decodeTime(xtag)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *cborDecDriver) decodeTime(xtag uint64) (t time.Time) {
|
||||||
|
if !d.bdRead {
|
||||||
|
d.readNextBd()
|
||||||
|
}
|
||||||
|
switch xtag {
|
||||||
|
case 0:
|
||||||
|
var err error
|
||||||
|
if t, err = time.Parse(time.RFC3339, stringView(d.DecodeStringAsBytes())); err != nil {
|
||||||
|
d.d.errorv(err)
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
// decode an int64 or a float, and infer time.Time from there.
|
||||||
|
// for floats, round to microseconds, as that is what is guaranteed to fit well.
|
||||||
|
switch {
|
||||||
|
case d.bd == cborBdFloat16, d.bd == cborBdFloat32:
|
||||||
|
f1, f2 := math.Modf(d.DecodeFloat64())
|
||||||
|
t = time.Unix(int64(f1), int64(f2*1e9))
|
||||||
|
case d.bd == cborBdFloat64:
|
||||||
|
f1, f2 := math.Modf(d.DecodeFloat64())
|
||||||
|
t = time.Unix(int64(f1), int64(f2*1e9))
|
||||||
|
case d.bd >= cborBaseUint && d.bd < cborBaseNegInt,
|
||||||
|
d.bd >= cborBaseNegInt && d.bd < cborBaseBytes:
|
||||||
|
t = time.Unix(d.DecodeInt64(), 0)
|
||||||
|
default:
|
||||||
|
d.d.errorf("time.Time can only be decoded from a number (or RFC3339 string)")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
d.d.errorf("invalid tag for time.Time - expecting 0 or 1, got 0x%x", xtag)
|
||||||
|
}
|
||||||
|
t = t.UTC().Round(time.Microsecond)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *cborDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
|
func (d *cborDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
|
||||||
@ -534,12 +591,9 @@ func (d *cborDecDriver) DecodeNaked() {
|
|||||||
case cborBdTrue:
|
case cborBdTrue:
|
||||||
n.v = valueTypeBool
|
n.v = valueTypeBool
|
||||||
n.b = true
|
n.b = true
|
||||||
case cborBdFloat16, cborBdFloat32:
|
case cborBdFloat16, cborBdFloat32, cborBdFloat64:
|
||||||
n.v = valueTypeFloat
|
n.v = valueTypeFloat
|
||||||
n.f = d.DecodeFloat(true)
|
n.f = d.DecodeFloat64()
|
||||||
case cborBdFloat64:
|
|
||||||
n.v = valueTypeFloat
|
|
||||||
n.f = d.DecodeFloat(false)
|
|
||||||
case cborBdIndefiniteBytes:
|
case cborBdIndefiniteBytes:
|
||||||
n.v = valueTypeBytes
|
n.v = valueTypeBytes
|
||||||
n.l = d.DecodeBytes(nil, false)
|
n.l = d.DecodeBytes(nil, false)
|
||||||
@ -557,14 +611,14 @@ func (d *cborDecDriver) DecodeNaked() {
|
|||||||
case d.bd >= cborBaseUint && d.bd < cborBaseNegInt:
|
case d.bd >= cborBaseUint && d.bd < cborBaseNegInt:
|
||||||
if d.h.SignedInteger {
|
if d.h.SignedInteger {
|
||||||
n.v = valueTypeInt
|
n.v = valueTypeInt
|
||||||
n.i = d.DecodeInt(64)
|
n.i = d.DecodeInt64()
|
||||||
} else {
|
} else {
|
||||||
n.v = valueTypeUint
|
n.v = valueTypeUint
|
||||||
n.u = d.DecodeUint(64)
|
n.u = d.DecodeUint64()
|
||||||
}
|
}
|
||||||
case d.bd >= cborBaseNegInt && d.bd < cborBaseBytes:
|
case d.bd >= cborBaseNegInt && d.bd < cborBaseBytes:
|
||||||
n.v = valueTypeInt
|
n.v = valueTypeInt
|
||||||
n.i = d.DecodeInt(64)
|
n.i = d.DecodeInt64()
|
||||||
case d.bd >= cborBaseBytes && d.bd < cborBaseString:
|
case d.bd >= cborBaseBytes && d.bd < cborBaseString:
|
||||||
n.v = valueTypeBytes
|
n.v = valueTypeBytes
|
||||||
n.l = d.DecodeBytes(nil, false)
|
n.l = d.DecodeBytes(nil, false)
|
||||||
@ -581,6 +635,11 @@ func (d *cborDecDriver) DecodeNaked() {
|
|||||||
n.v = valueTypeExt
|
n.v = valueTypeExt
|
||||||
n.u = d.decUint()
|
n.u = d.decUint()
|
||||||
n.l = nil
|
n.l = nil
|
||||||
|
if n.u == 0 || n.u == 1 {
|
||||||
|
d.bdRead = false
|
||||||
|
n.v = valueTypeTime
|
||||||
|
n.t = d.decodeTime(n.u)
|
||||||
|
}
|
||||||
// d.bdRead = false
|
// d.bdRead = false
|
||||||
// d.d.decode(&re.Value) // handled by decode itself.
|
// d.d.decode(&re.Value) // handled by decode itself.
|
||||||
// decodeFurther = true
|
// decodeFurther = true
|
||||||
@ -611,23 +670,8 @@ func (d *cborDecDriver) DecodeNaked() {
|
|||||||
//
|
//
|
||||||
// None of the optional extensions (with tags) defined in the spec are supported out-of-the-box.
|
// None of the optional extensions (with tags) defined in the spec are supported out-of-the-box.
|
||||||
// Users can implement them as needed (using SetExt), including spec-documented ones:
|
// Users can implement them as needed (using SetExt), including spec-documented ones:
|
||||||
// - timestamp, BigNum, BigFloat, Decimals, Encoded Text (e.g. URL, regexp, base64, MIME Message), etc.
|
// - timestamp, BigNum, BigFloat, Decimals,
|
||||||
//
|
// - Encoded Text (e.g. URL, regexp, base64, MIME Message), etc.
|
||||||
// To encode with indefinite lengths (streaming), users will use
|
|
||||||
// (Must)Encode methods of *Encoder, along with writing CborStreamXXX constants.
|
|
||||||
//
|
|
||||||
// For example, to encode "one-byte" as an indefinite length string:
|
|
||||||
// var buf bytes.Buffer
|
|
||||||
// e := NewEncoder(&buf, new(CborHandle))
|
|
||||||
// buf.WriteByte(CborStreamString)
|
|
||||||
// e.MustEncode("one-")
|
|
||||||
// e.MustEncode("byte")
|
|
||||||
// buf.WriteByte(CborStreamBreak)
|
|
||||||
// encodedBytes := buf.Bytes()
|
|
||||||
// var vv interface{}
|
|
||||||
// NewDecoderBytes(buf.Bytes(), new(CborHandle)).MustDecode(&vv)
|
|
||||||
// // Now, vv contains the same string "one-byte"
|
|
||||||
//
|
|
||||||
type CborHandle struct {
|
type CborHandle struct {
|
||||||
binaryEncodingType
|
binaryEncodingType
|
||||||
noElemSeparators
|
noElemSeparators
|
||||||
@ -635,10 +679,20 @@ type CborHandle struct {
|
|||||||
|
|
||||||
// IndefiniteLength=true, means that we encode using indefinitelength
|
// IndefiniteLength=true, means that we encode using indefinitelength
|
||||||
IndefiniteLength bool
|
IndefiniteLength bool
|
||||||
|
|
||||||
|
// TimeRFC3339 says to encode time.Time using RFC3339 format.
|
||||||
|
// If unset, we encode time.Time using seconds past epoch.
|
||||||
|
TimeRFC3339 bool
|
||||||
|
|
||||||
|
_ [1]uint64 // padding
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name returns the name of the handle: cbor
|
||||||
|
func (h *CborHandle) Name() string { return "cbor" }
|
||||||
|
|
||||||
|
// SetInterfaceExt sets an extension
|
||||||
func (h *CborHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
|
func (h *CborHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
|
||||||
return h.SetExt(rt, tag, &setExtWrapper{i: ext})
|
return h.SetExt(rt, tag, &extWrapper{bytesExtFailer{}, ext})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *CborHandle) newEncDriver(e *Encoder) encDriver {
|
func (h *CborHandle) newEncDriver(e *Encoder) encDriver {
|
||||||
|
2
vendor/github.com/ugorji/go/codec/cbor_test.go
generated
vendored
2
vendor/github.com/ugorji/go/codec/cbor_test.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
|
653
vendor/github.com/ugorji/go/codec/codec_test.go
generated
vendored
653
vendor/github.com/ugorji/go/codec/codec_test.go
generated
vendored
@ -1,28 +1,14 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
|
|
||||||
// Test works by using a slice of interfaces.
|
|
||||||
// It can test for encoding/decoding into/from a nil interface{}
|
|
||||||
// or passing the object to encode/decode into.
|
|
||||||
//
|
|
||||||
// There are basically 2 main tests here.
|
|
||||||
// First test internally encodes and decodes things and verifies that
|
|
||||||
// the artifact was as expected.
|
|
||||||
// Second test will use python msgpack to create a bunch of golden files,
|
|
||||||
// read those files, and compare them to what it should be. It then
|
|
||||||
// writes those files back out and compares the byte streams.
|
|
||||||
//
|
|
||||||
// Taken together, the tests are pretty extensive.
|
|
||||||
//
|
|
||||||
// The following manual tests must be done:
|
|
||||||
// - TestCodecUnderlyingType
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
@ -49,10 +35,34 @@ func init() {
|
|||||||
// )
|
// )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type testCustomStringT string
|
||||||
|
|
||||||
// make this a mapbyslice
|
// make this a mapbyslice
|
||||||
type testMbsT []interface{}
|
type testMbsT []interface{}
|
||||||
|
|
||||||
func (_ testMbsT) MapBySlice() {}
|
func (testMbsT) MapBySlice() {}
|
||||||
|
|
||||||
|
type testMbsCustStrT []testCustomStringT
|
||||||
|
|
||||||
|
func (testMbsCustStrT) MapBySlice() {}
|
||||||
|
|
||||||
|
type testIntfMapI interface {
|
||||||
|
GetIntfMapV() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type testIntfMapT1 struct {
|
||||||
|
IntfMapV string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *testIntfMapT1) GetIntfMapV() string { return x.IntfMapV }
|
||||||
|
|
||||||
|
type testIntfMapT2 struct {
|
||||||
|
IntfMapV string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x testIntfMapT2) GetIntfMapV() string { return x.IntfMapV }
|
||||||
|
|
||||||
|
// ----
|
||||||
|
|
||||||
type testVerifyFlag uint8
|
type testVerifyFlag uint8
|
||||||
|
|
||||||
@ -102,6 +112,9 @@ var (
|
|||||||
testRpcInt = new(TestRpcInt)
|
testRpcInt = new(TestRpcInt)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var wrapInt64Typ = reflect.TypeOf(wrapInt64(0))
|
||||||
|
var wrapBytesTyp = reflect.TypeOf(wrapBytes(nil))
|
||||||
|
|
||||||
func testByteBuf(in []byte) *bytes.Buffer {
|
func testByteBuf(in []byte) *bytes.Buffer {
|
||||||
return bytes.NewBuffer(in)
|
return bytes.NewBuffer(in)
|
||||||
}
|
}
|
||||||
@ -179,23 +192,27 @@ type TestRawValue struct {
|
|||||||
I int
|
I int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
|
||||||
type testUnixNanoTimeExt struct {
|
type testUnixNanoTimeExt struct {
|
||||||
// keep timestamp here, so that do not incur interface-conversion costs
|
// keep timestamp here, so that do not incur interface-conversion costs
|
||||||
ts int64
|
// ts int64
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (x *testUnixNanoTimeExt) WriteExt(interface{}) []byte { panic("unsupported") }
|
func (x *testUnixNanoTimeExt) WriteExt(v interface{}) []byte {
|
||||||
// func (x *testUnixNanoTimeExt) ReadExt(interface{}, []byte) { panic("unsupported") }
|
v2 := v.(*time.Time)
|
||||||
|
bs := make([]byte, 8)
|
||||||
|
bigen.PutUint64(bs, uint64(v2.UnixNano()))
|
||||||
|
return bs
|
||||||
|
}
|
||||||
|
func (x *testUnixNanoTimeExt) ReadExt(v interface{}, bs []byte) {
|
||||||
|
v2 := v.(*time.Time)
|
||||||
|
ui := bigen.Uint64(bs)
|
||||||
|
*v2 = time.Unix(0, int64(ui)).UTC()
|
||||||
|
}
|
||||||
func (x *testUnixNanoTimeExt) ConvertExt(v interface{}) interface{} {
|
func (x *testUnixNanoTimeExt) ConvertExt(v interface{}) interface{} {
|
||||||
switch v2 := v.(type) {
|
v2 := v.(*time.Time) // structs are encoded by passing the ptr
|
||||||
case time.Time:
|
return v2.UTC().UnixNano()
|
||||||
x.ts = v2.UTC().UnixNano()
|
|
||||||
case *time.Time:
|
|
||||||
x.ts = v2.UTC().UnixNano()
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("unsupported format for time conversion: expecting time.Time; got %T", v))
|
|
||||||
}
|
|
||||||
return &x.ts
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *testUnixNanoTimeExt) UpdateExt(dest interface{}, v interface{}) {
|
func (x *testUnixNanoTimeExt) UpdateExt(dest interface{}, v interface{}) {
|
||||||
@ -203,12 +220,8 @@ func (x *testUnixNanoTimeExt) UpdateExt(dest interface{}, v interface{}) {
|
|||||||
switch v2 := v.(type) {
|
switch v2 := v.(type) {
|
||||||
case int64:
|
case int64:
|
||||||
*tt = time.Unix(0, v2).UTC()
|
*tt = time.Unix(0, v2).UTC()
|
||||||
case *int64:
|
|
||||||
*tt = time.Unix(0, *v2).UTC()
|
|
||||||
case uint64:
|
case uint64:
|
||||||
*tt = time.Unix(0, int64(v2)).UTC()
|
*tt = time.Unix(0, int64(v2)).UTC()
|
||||||
case *uint64:
|
|
||||||
*tt = time.Unix(0, int64(*v2)).UTC()
|
|
||||||
//case float64:
|
//case float64:
|
||||||
//case string:
|
//case string:
|
||||||
default:
|
default:
|
||||||
@ -216,6 +229,91 @@ func (x *testUnixNanoTimeExt) UpdateExt(dest interface{}, v interface{}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
|
||||||
|
type wrapInt64Ext int64
|
||||||
|
|
||||||
|
func (x *wrapInt64Ext) WriteExt(v interface{}) []byte {
|
||||||
|
v2 := uint64(int64(v.(wrapInt64)))
|
||||||
|
bs := make([]byte, 8)
|
||||||
|
bigen.PutUint64(bs, v2)
|
||||||
|
return bs
|
||||||
|
}
|
||||||
|
func (x *wrapInt64Ext) ReadExt(v interface{}, bs []byte) {
|
||||||
|
v2 := v.(*wrapInt64)
|
||||||
|
ui := bigen.Uint64(bs)
|
||||||
|
*v2 = wrapInt64(int64(ui))
|
||||||
|
}
|
||||||
|
func (x *wrapInt64Ext) ConvertExt(v interface{}) interface{} {
|
||||||
|
return int64(v.(wrapInt64))
|
||||||
|
}
|
||||||
|
func (x *wrapInt64Ext) UpdateExt(dest interface{}, v interface{}) {
|
||||||
|
v2 := dest.(*wrapInt64)
|
||||||
|
*v2 = wrapInt64(v.(int64))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
|
||||||
|
type wrapBytesExt struct{}
|
||||||
|
|
||||||
|
func (x *wrapBytesExt) WriteExt(v interface{}) []byte {
|
||||||
|
return ([]byte)(v.(wrapBytes))
|
||||||
|
}
|
||||||
|
func (x *wrapBytesExt) ReadExt(v interface{}, bs []byte) {
|
||||||
|
v2 := v.(*wrapBytes)
|
||||||
|
*v2 = wrapBytes(bs)
|
||||||
|
}
|
||||||
|
func (x *wrapBytesExt) ConvertExt(v interface{}) interface{} {
|
||||||
|
return ([]byte)(v.(wrapBytes))
|
||||||
|
}
|
||||||
|
func (x *wrapBytesExt) UpdateExt(dest interface{}, v interface{}) {
|
||||||
|
v2 := dest.(*wrapBytes)
|
||||||
|
// some formats (e.g. json) cannot nakedly determine []byte from string, so expect both
|
||||||
|
switch v3 := v.(type) {
|
||||||
|
case []byte:
|
||||||
|
*v2 = wrapBytes(v3)
|
||||||
|
case string:
|
||||||
|
*v2 = wrapBytes([]byte(v3))
|
||||||
|
default:
|
||||||
|
panic("UpdateExt for wrapBytesExt expects string or []byte")
|
||||||
|
}
|
||||||
|
// *v2 = wrapBytes(v.([]byte))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
|
||||||
|
// timeExt is an extension handler for time.Time, that uses binc model for encoding/decoding time.
|
||||||
|
// we used binc model, as that is the only custom time representation that we designed ourselves.
|
||||||
|
type timeExt struct{}
|
||||||
|
|
||||||
|
func (x timeExt) WriteExt(v interface{}) (bs []byte) {
|
||||||
|
switch v2 := v.(type) {
|
||||||
|
case time.Time:
|
||||||
|
bs = bincEncodeTime(v2)
|
||||||
|
case *time.Time:
|
||||||
|
bs = bincEncodeTime(*v2)
|
||||||
|
default:
|
||||||
|
panic(fmt.Errorf("unsupported format for time conversion: expecting time.Time; got %T", v2))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (x timeExt) ReadExt(v interface{}, bs []byte) {
|
||||||
|
tt, err := bincDecodeTime(bs)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
*(v.(*time.Time)) = tt
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x timeExt) ConvertExt(v interface{}) interface{} {
|
||||||
|
return x.WriteExt(v)
|
||||||
|
}
|
||||||
|
func (x timeExt) UpdateExt(v interface{}, src interface{}) {
|
||||||
|
x.ReadExt(v, src.([]byte))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
|
||||||
func testCodecEncode(ts interface{}, bsIn []byte,
|
func testCodecEncode(ts interface{}, bsIn []byte,
|
||||||
fn func([]byte) *bytes.Buffer, h Handle) (bs []byte, err error) {
|
fn func([]byte) *bytes.Buffer, h Handle) (bs []byte, err error) {
|
||||||
return sTestCodecEncode(ts, bsIn, fn, h, h.getBasicHandle())
|
return sTestCodecEncode(ts, bsIn, fn, h, h.getBasicHandle())
|
||||||
@ -258,8 +356,8 @@ func testInit() {
|
|||||||
// pre-fill them first
|
// pre-fill them first
|
||||||
bh.EncodeOptions = testEncodeOptions
|
bh.EncodeOptions = testEncodeOptions
|
||||||
bh.DecodeOptions = testDecodeOptions
|
bh.DecodeOptions = testDecodeOptions
|
||||||
// bh.InterfaceReset = true // TODO: remove
|
// bh.InterfaceReset = true
|
||||||
// bh.PreferArrayOverSlice = true // TODO: remove
|
// bh.PreferArrayOverSlice = true
|
||||||
// modify from flag'ish things
|
// modify from flag'ish things
|
||||||
bh.InternString = testInternStr
|
bh.InternString = testInternStr
|
||||||
bh.Canonical = testCanonical
|
bh.Canonical = testCanonical
|
||||||
@ -270,31 +368,59 @@ func testInit() {
|
|||||||
|
|
||||||
testMsgpackH.RawToString = true
|
testMsgpackH.RawToString = true
|
||||||
|
|
||||||
// testMsgpackH.AddExt(byteSliceTyp, 0, testMsgpackH.BinaryEncodeExt, testMsgpackH.BinaryDecodeExt)
|
var tTimeExt timeExt
|
||||||
// testMsgpackH.AddExt(timeTyp, 1, testMsgpackH.TimeEncodeExt, testMsgpackH.TimeDecodeExt)
|
var tBytesExt wrapBytesExt
|
||||||
|
var tI64Ext wrapInt64Ext
|
||||||
|
|
||||||
// add extensions for msgpack, simple for time.Time, so we can encode/decode same way.
|
// create legacy functions suitable for deprecated AddExt functionality,
|
||||||
// use different flavors of XXXExt calls, including deprecated ones.
|
// and use on some places for testSimpleH e.g. for time.Time and wrapInt64
|
||||||
// NOTE:
|
|
||||||
// DO NOT set extensions for JsonH, so we can test json(M|Unm)arshal support.
|
|
||||||
var (
|
var (
|
||||||
timeExtEncFn = func(rv reflect.Value) (bs []byte, err error) {
|
myExtEncFn = func(x BytesExt, rv reflect.Value) (bs []byte, err error) {
|
||||||
defer panicToErr(&err)
|
defer panicToErr(errstrDecoratorDef{}, &err)
|
||||||
bs = timeExt{}.WriteExt(rv.Interface())
|
bs = x.WriteExt(rv.Interface())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
timeExtDecFn = func(rv reflect.Value, bs []byte) (err error) {
|
myExtDecFn = func(x BytesExt, rv reflect.Value, bs []byte) (err error) {
|
||||||
defer panicToErr(&err)
|
defer panicToErr(errstrDecoratorDef{}, &err)
|
||||||
timeExt{}.ReadExt(rv.Interface(), bs)
|
x.ReadExt(rv.Interface(), bs)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
timeExtEncFn = func(rv reflect.Value) (bs []byte, err error) { return myExtEncFn(tTimeExt, rv) }
|
||||||
|
timeExtDecFn = func(rv reflect.Value, bs []byte) (err error) { return myExtDecFn(tTimeExt, rv, bs) }
|
||||||
|
wrapInt64ExtEncFn = func(rv reflect.Value) (bs []byte, err error) { return myExtEncFn(&tI64Ext, rv) }
|
||||||
|
wrapInt64ExtDecFn = func(rv reflect.Value, bs []byte) (err error) { return myExtDecFn(&tI64Ext, rv, bs) }
|
||||||
)
|
)
|
||||||
testSimpleH.AddExt(timeTyp, 1, timeExtEncFn, timeExtDecFn)
|
|
||||||
|
chkErr := func(err error) {
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// time.Time is a native type, so extensions will have no effect.
|
||||||
|
// However, we add these here to ensure nothing happens.
|
||||||
|
chkErr(testSimpleH.AddExt(timeTyp, 1, timeExtEncFn, timeExtDecFn))
|
||||||
// testBincH.SetBytesExt(timeTyp, 1, timeExt{}) // time is builtin for binc
|
// testBincH.SetBytesExt(timeTyp, 1, timeExt{}) // time is builtin for binc
|
||||||
testMsgpackH.SetBytesExt(timeTyp, 1, timeExt{})
|
chkErr(testMsgpackH.SetBytesExt(timeTyp, 1, timeExt{}))
|
||||||
testCborH.SetInterfaceExt(timeTyp, 1, &testUnixNanoTimeExt{})
|
chkErr(testCborH.SetInterfaceExt(timeTyp, 1, &testUnixNanoTimeExt{}))
|
||||||
// testJsonH.SetInterfaceExt(timeTyp, 1, &testUnixNanoTimeExt{})
|
// testJsonH.SetInterfaceExt(timeTyp, 1, &testUnixNanoTimeExt{})
|
||||||
|
|
||||||
|
// Now, add extensions for the type wrapInt64 and wrapBytes,
|
||||||
|
// so we can execute the Encode/Decode Ext paths.
|
||||||
|
|
||||||
|
chkErr(testSimpleH.SetBytesExt(wrapBytesTyp, 32, &tBytesExt))
|
||||||
|
chkErr(testMsgpackH.SetBytesExt(wrapBytesTyp, 32, &tBytesExt))
|
||||||
|
chkErr(testBincH.SetBytesExt(wrapBytesTyp, 32, &tBytesExt))
|
||||||
|
chkErr(testJsonH.SetInterfaceExt(wrapBytesTyp, 32, &tBytesExt))
|
||||||
|
chkErr(testCborH.SetInterfaceExt(wrapBytesTyp, 32, &tBytesExt))
|
||||||
|
|
||||||
|
chkErr(testSimpleH.AddExt(wrapInt64Typ, 16, wrapInt64ExtEncFn, wrapInt64ExtDecFn))
|
||||||
|
// chkErr(testSimpleH.SetBytesExt(wrapInt64Typ, 16, &tI64Ext))
|
||||||
|
chkErr(testMsgpackH.SetBytesExt(wrapInt64Typ, 16, &tI64Ext))
|
||||||
|
chkErr(testBincH.SetBytesExt(wrapInt64Typ, 16, &tI64Ext))
|
||||||
|
chkErr(testJsonH.SetInterfaceExt(wrapInt64Typ, 16, &tI64Ext))
|
||||||
|
chkErr(testCborH.SetInterfaceExt(wrapInt64Typ, 16, &tI64Ext))
|
||||||
|
|
||||||
// primitives MUST be an even number, so it can be used as a mapBySlice also.
|
// primitives MUST be an even number, so it can be used as a mapBySlice also.
|
||||||
primitives := []interface{}{
|
primitives := []interface{}{
|
||||||
int8(-8),
|
int8(-8),
|
||||||
@ -427,6 +553,8 @@ func testTableVerify(f testVerifyFlag, h Handle) (av []interface{}) {
|
|||||||
av[i] = testVerifyVal(v, f, h)
|
av[i] = testVerifyVal(v, f, h)
|
||||||
case map[interface{}]interface{}:
|
case map[interface{}]interface{}:
|
||||||
av[i] = testVerifyVal(v, f, h)
|
av[i] = testVerifyVal(v, f, h)
|
||||||
|
case time.Time:
|
||||||
|
av[i] = testVerifyVal(v, f, h)
|
||||||
default:
|
default:
|
||||||
av[i] = v
|
av[i] = v
|
||||||
}
|
}
|
||||||
@ -455,6 +583,7 @@ func testVerifyVal(v interface{}, f testVerifyFlag, h Handle) (v2 interface{}) {
|
|||||||
// - all positive integers are unsigned 64-bit ints
|
// - all positive integers are unsigned 64-bit ints
|
||||||
// - all floats are float64
|
// - all floats are float64
|
||||||
_, isMsgp := h.(*MsgpackHandle)
|
_, isMsgp := h.(*MsgpackHandle)
|
||||||
|
_, isCbor := h.(*CborHandle)
|
||||||
switch iv := v.(type) {
|
switch iv := v.(type) {
|
||||||
case int8:
|
case int8:
|
||||||
v2 = testVerifyValInt(int64(iv), isMsgp)
|
v2 = testVerifyValInt(int64(iv), isMsgp)
|
||||||
@ -545,6 +674,11 @@ func testVerifyVal(v interface{}, f testVerifyFlag, h Handle) (v2 interface{}) {
|
|||||||
} else {
|
} else {
|
||||||
v2 = int64(iv2)
|
v2 = int64(iv2)
|
||||||
}
|
}
|
||||||
|
case isMsgp:
|
||||||
|
v2 = iv.UTC()
|
||||||
|
case isCbor:
|
||||||
|
// fmt.Printf("%%%% cbor verifier\n")
|
||||||
|
v2 = iv.UTC().Round(time.Microsecond)
|
||||||
default:
|
default:
|
||||||
v2 = v
|
v2 = v
|
||||||
}
|
}
|
||||||
@ -584,6 +718,17 @@ func testDeepEqualErr(v1, v2 interface{}, t *testing.T, name string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testReadWriteCloser(c io.ReadWriteCloser) io.ReadWriteCloser {
|
||||||
|
if testRpcBufsize <= 0 && rand.Int63()%2 == 0 {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return struct {
|
||||||
|
io.Closer
|
||||||
|
*bufio.Reader
|
||||||
|
*bufio.Writer
|
||||||
|
}{c, bufio.NewReaderSize(c, testRpcBufsize), bufio.NewWriterSize(c, testRpcBufsize)}
|
||||||
|
}
|
||||||
|
|
||||||
// doTestCodecTableOne allows us test for different variations based on arguments passed.
|
// doTestCodecTableOne allows us test for different variations based on arguments passed.
|
||||||
func doTestCodecTableOne(t *testing.T, testNil bool, h Handle,
|
func doTestCodecTableOne(t *testing.T, testNil bool, h Handle,
|
||||||
vs []interface{}, vsVerify []interface{}) {
|
vs []interface{}, vsVerify []interface{}) {
|
||||||
@ -623,7 +768,7 @@ func doTestCodecTableOne(t *testing.T, testNil bool, h Handle,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logT(t, " v1 returned: %T, %#v", v1, v1)
|
logT(t, " v1 returned: %T, %v %#v", v1, v1, v1)
|
||||||
// if v1 != nil {
|
// if v1 != nil {
|
||||||
// logT(t, " v1 returned: %T, %#v", v1, v1)
|
// logT(t, " v1 returned: %T, %#v", v1, v1)
|
||||||
// //we always indirect, because ptr to typed value may be passed (if not testNil)
|
// //we always indirect, because ptr to typed value may be passed (if not testNil)
|
||||||
@ -644,8 +789,8 @@ func doTestCodecTableOne(t *testing.T, testNil bool, h Handle,
|
|||||||
// logT(t, "-------- Before and After marshal do not match: Error: %v"+
|
// logT(t, "-------- Before and After marshal do not match: Error: %v"+
|
||||||
// " ====> GOLDEN: (%T) %#v, DECODED: (%T) %#v\n", err, v0check, v0check, v1, v1)
|
// " ====> GOLDEN: (%T) %#v, DECODED: (%T) %#v\n", err, v0check, v0check, v1, v1)
|
||||||
logT(t, "-------- FAIL: Before and After marshal do not match: Error: %v", err)
|
logT(t, "-------- FAIL: Before and After marshal do not match: Error: %v", err)
|
||||||
logT(t, " ....... GOLDEN: (%T) %#v", v0check, v0check)
|
logT(t, " ....... GOLDEN: (%T) %v %#v", v0check, v0check, v0check)
|
||||||
logT(t, " ....... DECODED: (%T) %#v", v1, v1)
|
logT(t, " ....... DECODED: (%T) %v %#v", v1, v1, v1)
|
||||||
failT(t)
|
failT(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -713,7 +858,7 @@ func testCodecMiscOne(t *testing.T, h Handle) {
|
|||||||
// logT(t, "------- Expecting error because we cannot unmarshal to int32 nil ptr")
|
// logT(t, "------- Expecting error because we cannot unmarshal to int32 nil ptr")
|
||||||
// failT(t)
|
// failT(t)
|
||||||
// }
|
// }
|
||||||
var i2 int32 = 0
|
var i2 int32
|
||||||
testUnmarshalErr(&i2, b, h, t, "int32-ptr")
|
testUnmarshalErr(&i2, b, h, t, "int32-ptr")
|
||||||
if i2 != int32(32) {
|
if i2 != int32(32) {
|
||||||
logT(t, "------- didn't unmarshal to 32: Received: %d", i2)
|
logT(t, "------- didn't unmarshal to 32: Received: %d", i2)
|
||||||
@ -814,6 +959,19 @@ func testCodecMiscOne(t *testing.T, h Handle) {
|
|||||||
var ya = ystruct{}
|
var ya = ystruct{}
|
||||||
testUnmarshalErr(&ya, []byte{0x91, 0x90}, h, t, "ya")
|
testUnmarshalErr(&ya, []byte{0x91, 0x90}, h, t, "ya")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tt1, tt2 time.Time
|
||||||
|
tt2 = time.Now()
|
||||||
|
bs = testMarshalErr(tt1, h, t, "zero-time-enc")
|
||||||
|
testUnmarshalErr(&tt2, bs, h, t, "zero-time-dec")
|
||||||
|
testDeepEqualErr(tt1, tt2, t, "zero-time-eq")
|
||||||
|
|
||||||
|
// test encoding a slice of byte (but not []byte) and decoding into a []byte
|
||||||
|
var sw = []wrapUint8{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'}
|
||||||
|
var bw []byte // ("ABCDEFGHIJ")
|
||||||
|
bs = testMarshalErr(sw, h, t, "wrap-bytes-enc")
|
||||||
|
testUnmarshalErr(&bw, bs, h, t, "wrap-bytes-dec")
|
||||||
|
testDeepEqualErr(bw, []byte("ABCDEFGHIJ"), t, "wrap-bytes-eq")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCodecEmbeddedPointer(t *testing.T, h Handle) {
|
func testCodecEmbeddedPointer(t *testing.T, h Handle) {
|
||||||
@ -1001,7 +1159,7 @@ func testCodecRpcOne(t *testing.T, rr Rpc, h Handle, doRequest bool, exitSleepMs
|
|||||||
// opts.MapType = mapStrIntfTyp
|
// opts.MapType = mapStrIntfTyp
|
||||||
// opts.RawToString = false
|
// opts.RawToString = false
|
||||||
serverExitChan := make(chan bool, 1)
|
serverExitChan := make(chan bool, 1)
|
||||||
var serverExitFlag uint64 = 0
|
var serverExitFlag uint64
|
||||||
serverFn := func() {
|
serverFn := func() {
|
||||||
for {
|
for {
|
||||||
conn1, err1 := ln.Accept()
|
conn1, err1 := ln.Accept()
|
||||||
@ -1015,7 +1173,7 @@ func testCodecRpcOne(t *testing.T, rr Rpc, h Handle, doRequest bool, exitSleepMs
|
|||||||
return // exit serverFn goroutine
|
return // exit serverFn goroutine
|
||||||
}
|
}
|
||||||
if err1 == nil {
|
if err1 == nil {
|
||||||
var sc rpc.ServerCodec = rr.ServerCodec(conn1, h)
|
sc := rr.ServerCodec(testReadWriteCloser(conn1), h)
|
||||||
srv.ServeCodec(sc)
|
srv.ServeCodec(sc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1066,7 +1224,7 @@ func testCodecRpcOne(t *testing.T, rr Rpc, h Handle, doRequest bool, exitSleepMs
|
|||||||
}
|
}
|
||||||
if doRequest {
|
if doRequest {
|
||||||
bs := connFn()
|
bs := connFn()
|
||||||
cc := rr.ClientCodec(bs, h)
|
cc := rr.ClientCodec(testReadWriteCloser(bs), h)
|
||||||
clientFn(cc)
|
clientFn(cc)
|
||||||
}
|
}
|
||||||
if exitSleepMs != 0 {
|
if exitSleepMs != 0 {
|
||||||
@ -1476,7 +1634,7 @@ func doTestMsgpackRpcSpecGoClientToPythonSvc(t *testing.T) {
|
|||||||
bs, err2 = net.Dial("tcp", ":"+openPort)
|
bs, err2 = net.Dial("tcp", ":"+openPort)
|
||||||
}
|
}
|
||||||
checkErrT(t, err2)
|
checkErrT(t, err2)
|
||||||
cc := MsgpackSpecRpc.ClientCodec(bs, testMsgpackH)
|
cc := MsgpackSpecRpc.ClientCodec(testReadWriteCloser(bs), testMsgpackH)
|
||||||
cl := rpc.NewClientWithCodec(cc)
|
cl := rpc.NewClientWithCodec(cc)
|
||||||
defer cl.Close()
|
defer cl.Close()
|
||||||
var rstr string
|
var rstr string
|
||||||
@ -1520,39 +1678,75 @@ func doTestSwallowAndZero(t *testing.T, h Handle) {
|
|||||||
logT(t, "swallow didn't consume all encoded bytes: %v out of %v", d1.r.numread(), len(b1))
|
logT(t, "swallow didn't consume all encoded bytes: %v out of %v", d1.r.numread(), len(b1))
|
||||||
failT(t)
|
failT(t)
|
||||||
}
|
}
|
||||||
d1.setZero(v1)
|
setZero(v1)
|
||||||
testDeepEqualErr(v1, &TestStrucFlex{}, t, "filled-and-zeroed")
|
testDeepEqualErr(v1, &TestStrucFlex{}, t, "filled-and-zeroed")
|
||||||
}
|
}
|
||||||
|
|
||||||
func doTestRawExt(t *testing.T, h Handle) {
|
func doTestRawExt(t *testing.T, h Handle) {
|
||||||
testOnce.Do(testInitAll)
|
testOnce.Do(testInitAll)
|
||||||
// return // TODO: need to fix this ...
|
|
||||||
var b []byte
|
var b []byte
|
||||||
var v interface{}
|
var v RawExt // interface{}
|
||||||
_, isJson := h.(*JsonHandle)
|
_, isJson := h.(*JsonHandle)
|
||||||
_, isCbor := h.(*CborHandle)
|
_, isCbor := h.(*CborHandle)
|
||||||
isValuer := isJson || isCbor
|
bh := h.getBasicHandle()
|
||||||
_ = isValuer
|
// isValuer := isJson || isCbor
|
||||||
|
// _ = isValuer
|
||||||
for _, r := range []RawExt{
|
for _, r := range []RawExt{
|
||||||
{Tag: 99, Value: "9999", Data: []byte("9999")},
|
{Tag: 99, Value: "9999", Data: []byte("9999")},
|
||||||
} {
|
} {
|
||||||
e := NewEncoderBytes(&b, h)
|
e := NewEncoderBytes(&b, h)
|
||||||
e.MustEncode(&r)
|
e.MustEncode(&r)
|
||||||
|
// fmt.Printf(">>>> rawext: isnil? %v, %d - %v\n", b == nil, len(b), b)
|
||||||
d := NewDecoderBytes(b, h)
|
d := NewDecoderBytes(b, h)
|
||||||
d.MustDecode(&v)
|
d.MustDecode(&v)
|
||||||
switch h.(type) {
|
var r2 = r
|
||||||
case *JsonHandle:
|
switch {
|
||||||
testDeepEqualErr(r.Value, v, t, "rawext-json")
|
case isJson:
|
||||||
default:
|
r2.Tag = 0
|
||||||
r2 := r
|
|
||||||
if isValuer {
|
|
||||||
r2.Data = nil
|
r2.Data = nil
|
||||||
} else {
|
case isCbor:
|
||||||
|
r2.Data = nil
|
||||||
|
default:
|
||||||
r2.Value = nil
|
r2.Value = nil
|
||||||
}
|
}
|
||||||
testDeepEqualErr(v, r2, t, "rawext-default")
|
testDeepEqualErr(v, r2, t, "rawext-default")
|
||||||
|
// switch h.(type) {
|
||||||
|
// case *JsonHandle:
|
||||||
|
// testDeepEqualErr(r.Value, v, t, "rawext-json")
|
||||||
|
// default:
|
||||||
|
// var r2 = r
|
||||||
|
// if isValuer {
|
||||||
|
// r2.Data = nil
|
||||||
|
// } else {
|
||||||
|
// r2.Value = nil
|
||||||
|
// }
|
||||||
|
// testDeepEqualErr(v, r2, t, "rawext-default")
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add testing for Raw also
|
||||||
|
if b != nil {
|
||||||
|
b = b[:0]
|
||||||
}
|
}
|
||||||
|
oldRawMode := bh.Raw
|
||||||
|
defer func() { bh.Raw = oldRawMode }()
|
||||||
|
bh.Raw = true
|
||||||
|
|
||||||
|
var v2 Raw
|
||||||
|
for _, s := range []string{
|
||||||
|
"goodbye",
|
||||||
|
"hello",
|
||||||
|
} {
|
||||||
|
e := NewEncoderBytes(&b, h)
|
||||||
|
e.MustEncode(&s)
|
||||||
|
// fmt.Printf(">>>> rawext: isnil? %v, %d - %v\n", b == nil, len(b), b)
|
||||||
|
var r Raw = make([]byte, len(b))
|
||||||
|
copy(r, b)
|
||||||
|
d := NewDecoderBytes(b, h)
|
||||||
|
d.MustDecode(&v2)
|
||||||
|
testDeepEqualErr(v2, r, t, "raw-default")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// func doTestTimeExt(t *testing.T, h Handle) {
|
// func doTestTimeExt(t *testing.T, h Handle) {
|
||||||
@ -1589,6 +1783,7 @@ func doTestMapStructKey(t *testing.T, h Handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func doTestDecodeNilMapValue(t *testing.T, handle Handle) {
|
func doTestDecodeNilMapValue(t *testing.T, handle Handle) {
|
||||||
|
testOnce.Do(testInitAll)
|
||||||
type Struct struct {
|
type Struct struct {
|
||||||
Field map[uint16]map[uint32]struct{}
|
Field map[uint16]map[uint32]struct{}
|
||||||
}
|
}
|
||||||
@ -1631,6 +1826,7 @@ func doTestDecodeNilMapValue(t *testing.T, handle Handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func doTestEmbeddedFieldPrecedence(t *testing.T, h Handle) {
|
func doTestEmbeddedFieldPrecedence(t *testing.T, h Handle) {
|
||||||
|
testOnce.Do(testInitAll)
|
||||||
type Embedded struct {
|
type Embedded struct {
|
||||||
Field byte
|
Field byte
|
||||||
}
|
}
|
||||||
@ -1672,6 +1868,7 @@ func doTestEmbeddedFieldPrecedence(t *testing.T, h Handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func doTestLargeContainerLen(t *testing.T, h Handle) {
|
func doTestLargeContainerLen(t *testing.T, h Handle) {
|
||||||
|
testOnce.Do(testInitAll)
|
||||||
m := make(map[int][]struct{})
|
m := make(map[int][]struct{})
|
||||||
for i := range []int{
|
for i := range []int{
|
||||||
0, 1,
|
0, 1,
|
||||||
@ -1691,8 +1888,6 @@ func doTestLargeContainerLen(t *testing.T, h Handle) {
|
|||||||
testUnmarshalErr(m2, bs, h, t, "-")
|
testUnmarshalErr(m2, bs, h, t, "-")
|
||||||
testDeepEqualErr(m, m2, t, "-")
|
testDeepEqualErr(m, m2, t, "-")
|
||||||
|
|
||||||
// TODO: skip rest if 32-bit
|
|
||||||
|
|
||||||
// do same tests for large strings (encoded as symbols or not)
|
// do same tests for large strings (encoded as symbols or not)
|
||||||
// skip if 32-bit or not using unsafe mode
|
// skip if 32-bit or not using unsafe mode
|
||||||
if safeMode || (32<<(^uint(0)>>63)) < 64 {
|
if safeMode || (32<<(^uint(0)>>63)) < 64 {
|
||||||
@ -1704,10 +1899,11 @@ func doTestLargeContainerLen(t *testing.T, h Handle) {
|
|||||||
// to do this, we create a simple one-field struct,
|
// to do this, we create a simple one-field struct,
|
||||||
// use use flags to switch from symbols to non-symbols
|
// use use flags to switch from symbols to non-symbols
|
||||||
|
|
||||||
bh := h.getBasicHandle()
|
hbinc, okbinc := h.(*BincHandle)
|
||||||
oldAsSymbols := bh.AsSymbols
|
if okbinc {
|
||||||
defer func() { bh.AsSymbols = oldAsSymbols }()
|
oldAsSymbols := hbinc.AsSymbols
|
||||||
|
defer func() { hbinc.AsSymbols = oldAsSymbols }()
|
||||||
|
}
|
||||||
var out []byte = make([]byte, 0, math.MaxUint16*3/2)
|
var out []byte = make([]byte, 0, math.MaxUint16*3/2)
|
||||||
var in []byte = make([]byte, math.MaxUint16*3/2)
|
var in []byte = make([]byte, math.MaxUint16*3/2)
|
||||||
for i := range in {
|
for i := range in {
|
||||||
@ -1728,7 +1924,9 @@ func doTestLargeContainerLen(t *testing.T, h Handle) {
|
|||||||
// fmt.Printf("testcontainerlen: large string: i: %v, |%s|\n", i, s1)
|
// fmt.Printf("testcontainerlen: large string: i: %v, |%s|\n", i, s1)
|
||||||
m1[s1] = true
|
m1[s1] = true
|
||||||
|
|
||||||
bh.AsSymbols = AsSymbolNone
|
if okbinc {
|
||||||
|
hbinc.AsSymbols = 2
|
||||||
|
}
|
||||||
out = out[:0]
|
out = out[:0]
|
||||||
e.ResetBytes(&out)
|
e.ResetBytes(&out)
|
||||||
e.MustEncode(m1)
|
e.MustEncode(m1)
|
||||||
@ -1737,8 +1935,9 @@ func doTestLargeContainerLen(t *testing.T, h Handle) {
|
|||||||
testUnmarshalErr(m2, out, h, t, "no-symbols")
|
testUnmarshalErr(m2, out, h, t, "no-symbols")
|
||||||
testDeepEqualErr(m1, m2, t, "no-symbols")
|
testDeepEqualErr(m1, m2, t, "no-symbols")
|
||||||
|
|
||||||
|
if okbinc {
|
||||||
// now, do as symbols
|
// now, do as symbols
|
||||||
bh.AsSymbols = AsSymbolAll
|
hbinc.AsSymbols = 1
|
||||||
out = out[:0]
|
out = out[:0]
|
||||||
e.ResetBytes(&out)
|
e.ResetBytes(&out)
|
||||||
e.MustEncode(m1)
|
e.MustEncode(m1)
|
||||||
@ -1747,6 +1946,7 @@ func doTestLargeContainerLen(t *testing.T, h Handle) {
|
|||||||
testUnmarshalErr(m2, out, h, t, "symbols")
|
testUnmarshalErr(m2, out, h, t, "symbols")
|
||||||
testDeepEqualErr(m1, m2, t, "symbols")
|
testDeepEqualErr(m1, m2, t, "symbols")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1813,7 +2013,9 @@ func testRandomFillRV(v reflect.Value) {
|
|||||||
case reflect.Float32, reflect.Float64:
|
case reflect.Float32, reflect.Float64:
|
||||||
v.SetFloat(float64(fneg()) * float64(rand.Float32()))
|
v.SetFloat(float64(fneg()) * float64(rand.Float32()))
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
v.SetString(strings.Repeat(strconv.FormatInt(rand.Int63n(99), 10), rand.Intn(8)))
|
// ensure this string can test the extent of json string decoding
|
||||||
|
v.SetString(strings.Repeat(strconv.FormatInt(rand.Int63n(99), 10), rand.Intn(8)) +
|
||||||
|
"- ABC \x41=\x42 \u2318 - \r \b \f - \u2028 and \u2029 .")
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("testRandomFillRV: unsupported type: %v", v.Kind()))
|
panic(fmt.Errorf("testRandomFillRV: unsupported type: %v", v.Kind()))
|
||||||
}
|
}
|
||||||
@ -1838,6 +2040,7 @@ func testMammoth(t *testing.T, name string, h Handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testTime(t *testing.T, name string, h Handle) {
|
func testTime(t *testing.T, name string, h Handle) {
|
||||||
|
testOnce.Do(testInitAll)
|
||||||
// test time which uses the time.go implementation (ie Binc)
|
// test time which uses the time.go implementation (ie Binc)
|
||||||
var tt, tt2 time.Time
|
var tt, tt2 time.Time
|
||||||
// time in 1990
|
// time in 1990
|
||||||
@ -1854,6 +2057,7 @@ func testTime(t *testing.T, name string, h Handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testUintToInt(t *testing.T, name string, h Handle) {
|
func testUintToInt(t *testing.T, name string, h Handle) {
|
||||||
|
testOnce.Do(testInitAll)
|
||||||
var golden = [...]int64{
|
var golden = [...]int64{
|
||||||
0, 1, 22, 333, 4444, 55555, 666666,
|
0, 1, 22, 333, 4444, 55555, 666666,
|
||||||
// msgpack ones
|
// msgpack ones
|
||||||
@ -1895,9 +2099,197 @@ func testUintToInt(t *testing.T, name string, h Handle) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func doTestDifferentMapOrSliceType(t *testing.T, name string, h Handle) {
|
||||||
|
testOnce.Do(testInitAll)
|
||||||
|
|
||||||
|
// - maptype, slicetype: diff from map[string]intf, map[intf]intf or []intf, etc
|
||||||
|
// include map[interface{}]string where some keys are []byte.
|
||||||
|
// To test, take a sequence of []byte and string, and decode into []string and []interface.
|
||||||
|
// Also, decode into map[string]string, map[string]interface{}, map[interface{}]string
|
||||||
|
|
||||||
|
bh := h.getBasicHandle()
|
||||||
|
oldM, oldS := bh.MapType, bh.SliceType
|
||||||
|
defer func() { bh.MapType, bh.SliceType = oldM, oldS }()
|
||||||
|
|
||||||
|
var b []byte
|
||||||
|
|
||||||
|
var vi = []interface{}{
|
||||||
|
"hello 1",
|
||||||
|
[]byte("hello 2"),
|
||||||
|
"hello 3",
|
||||||
|
[]byte("hello 4"),
|
||||||
|
"hello 5",
|
||||||
|
}
|
||||||
|
var vs []string
|
||||||
|
var v2i, v2s testMbsT
|
||||||
|
var v2ss testMbsCustStrT
|
||||||
|
// encode it as a map or as a slice
|
||||||
|
for i, v := range vi {
|
||||||
|
vv, ok := v.(string)
|
||||||
|
if !ok {
|
||||||
|
vv = string(v.([]byte))
|
||||||
|
}
|
||||||
|
vs = append(vs, vv)
|
||||||
|
v2i = append(v2i, v, strconv.FormatInt(int64(i+1), 10))
|
||||||
|
v2s = append(v2s, vv, strconv.FormatInt(int64(i+1), 10))
|
||||||
|
v2ss = append(v2ss, testCustomStringT(vv), testCustomStringT(strconv.FormatInt(int64(i+1), 10)))
|
||||||
|
}
|
||||||
|
|
||||||
|
var v2d interface{}
|
||||||
|
|
||||||
|
// encode vs as a list, and decode into a list and compare
|
||||||
|
var goldSliceS = []string{"hello 1", "hello 2", "hello 3", "hello 4", "hello 5"}
|
||||||
|
var goldSliceI = []interface{}{"hello 1", "hello 2", "hello 3", "hello 4", "hello 5"}
|
||||||
|
var goldSlice = []interface{}{goldSliceS, goldSliceI}
|
||||||
|
for j, g := range goldSlice {
|
||||||
|
bh.SliceType = reflect.TypeOf(g)
|
||||||
|
name := fmt.Sprintf("slice-%s-%v", name, j+1)
|
||||||
|
b = testMarshalErr(vs, h, t, name)
|
||||||
|
v2d = nil
|
||||||
|
// v2d = reflect.New(bh.SliceType).Elem().Interface()
|
||||||
|
testUnmarshalErr(&v2d, b, h, t, name)
|
||||||
|
testDeepEqualErr(v2d, goldSlice[j], t, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// to ensure that we do not use fast-path for map[intf]string, use a custom string type (for goldMapIS).
|
||||||
|
// this will allow us to test out the path that sees a []byte where a map has an interface{} type,
|
||||||
|
// and convert it to a string for the decoded map key.
|
||||||
|
|
||||||
|
// encode v2i as a map, and decode into a map and compare
|
||||||
|
var goldMapSS = map[string]string{"hello 1": "1", "hello 2": "2", "hello 3": "3", "hello 4": "4", "hello 5": "5"}
|
||||||
|
var goldMapSI = map[string]interface{}{"hello 1": "1", "hello 2": "2", "hello 3": "3", "hello 4": "4", "hello 5": "5"}
|
||||||
|
var goldMapIS = map[interface{}]testCustomStringT{"hello 1": "1", "hello 2": "2", "hello 3": "3", "hello 4": "4", "hello 5": "5"}
|
||||||
|
var goldMap = []interface{}{goldMapSS, goldMapSI, goldMapIS}
|
||||||
|
for j, g := range goldMap {
|
||||||
|
bh.MapType = reflect.TypeOf(g)
|
||||||
|
name := fmt.Sprintf("map-%s-%v", name, j+1)
|
||||||
|
// for formats that clearly differentiate binary from string, use v2i
|
||||||
|
// else use the v2s (with all strings, no []byte)
|
||||||
|
v2d = nil
|
||||||
|
// v2d = reflect.New(bh.MapType).Elem().Interface()
|
||||||
|
switch h.(type) {
|
||||||
|
case *MsgpackHandle, *BincHandle, *CborHandle:
|
||||||
|
b = testMarshalErr(v2i, h, t, name)
|
||||||
|
testUnmarshalErr(&v2d, b, h, t, name)
|
||||||
|
testDeepEqualErr(v2d, goldMap[j], t, name)
|
||||||
|
default:
|
||||||
|
b = testMarshalErr(v2s, h, t, name)
|
||||||
|
testUnmarshalErr(&v2d, b, h, t, name)
|
||||||
|
testDeepEqualErr(v2d, goldMap[j], t, name)
|
||||||
|
b = testMarshalErr(v2ss, h, t, name)
|
||||||
|
v2d = nil
|
||||||
|
testUnmarshalErr(&v2d, b, h, t, name)
|
||||||
|
testDeepEqualErr(v2d, goldMap[j], t, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func doTestScalars(t *testing.T, name string, h Handle) {
|
||||||
|
testOnce.Do(testInitAll)
|
||||||
|
|
||||||
|
// for each scalar:
|
||||||
|
// - encode its ptr
|
||||||
|
// - encode it (non-ptr)
|
||||||
|
// - check that bytes are same
|
||||||
|
// - make a copy (using reflect)
|
||||||
|
// - check that same
|
||||||
|
// - set zero on it
|
||||||
|
// - check that its equal to 0 value
|
||||||
|
// - decode into new
|
||||||
|
// - compare to original
|
||||||
|
|
||||||
|
bh := h.getBasicHandle()
|
||||||
|
if !bh.Canonical {
|
||||||
|
bh.Canonical = true
|
||||||
|
defer func() { bh.Canonical = false }()
|
||||||
|
}
|
||||||
|
|
||||||
|
vi := []interface{}{
|
||||||
|
int(0),
|
||||||
|
int8(0),
|
||||||
|
int16(0),
|
||||||
|
int32(0),
|
||||||
|
int64(0),
|
||||||
|
uint(0),
|
||||||
|
uint8(0),
|
||||||
|
uint16(0),
|
||||||
|
uint32(0),
|
||||||
|
uint64(0),
|
||||||
|
uintptr(0),
|
||||||
|
float32(0),
|
||||||
|
float64(0),
|
||||||
|
bool(false),
|
||||||
|
string(""),
|
||||||
|
[]byte(nil),
|
||||||
|
}
|
||||||
|
for _, v := range fastpathAV {
|
||||||
|
vi = append(vi, reflect.Zero(v.rt).Interface())
|
||||||
|
}
|
||||||
|
for _, v := range vi {
|
||||||
|
rv := reflect.New(reflect.TypeOf(v)).Elem()
|
||||||
|
testRandomFillRV(rv)
|
||||||
|
v = rv.Interface()
|
||||||
|
|
||||||
|
rv2 := reflect.New(rv.Type())
|
||||||
|
rv2.Elem().Set(rv)
|
||||||
|
vp := rv2.Interface()
|
||||||
|
|
||||||
|
var tname string
|
||||||
|
switch rv.Kind() {
|
||||||
|
case reflect.Map:
|
||||||
|
tname = "map[" + rv.Type().Key().Name() + "]" + rv.Type().Elem().Name()
|
||||||
|
case reflect.Slice:
|
||||||
|
tname = "[]" + rv.Type().Elem().Name()
|
||||||
|
default:
|
||||||
|
tname = rv.Type().Name()
|
||||||
|
}
|
||||||
|
|
||||||
|
var b, b1, b2 []byte
|
||||||
|
b1 = testMarshalErr(v, h, t, tname+"-enc")
|
||||||
|
// store b1 into b, as b1 slice is reused for next marshal
|
||||||
|
b = make([]byte, len(b1))
|
||||||
|
copy(b, b1)
|
||||||
|
b2 = testMarshalErr(vp, h, t, tname+"-enc-ptr")
|
||||||
|
testDeepEqualErr(b1, b2, t, tname+"-enc-eq")
|
||||||
|
setZero(vp)
|
||||||
|
testDeepEqualErr(rv2.Elem().Interface(), reflect.Zero(rv.Type()).Interface(), t, tname+"-enc-eq-zero-ref")
|
||||||
|
|
||||||
|
vp = rv2.Interface()
|
||||||
|
testUnmarshalErr(vp, b, h, t, tname+"-dec")
|
||||||
|
testDeepEqualErr(rv2.Elem().Interface(), v, t, tname+"-dec-eq")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func doTestIntfMapping(t *testing.T, name string, h Handle) {
|
||||||
|
testOnce.Do(testInitAll)
|
||||||
|
rti := reflect.TypeOf((*testIntfMapI)(nil)).Elem()
|
||||||
|
defer func() { h.getBasicHandle().Intf2Impl(rti, nil) }()
|
||||||
|
|
||||||
|
type T9 struct {
|
||||||
|
I testIntfMapI
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, v := range []testIntfMapI{
|
||||||
|
// Use a valid string to test some extents of json string decoding
|
||||||
|
&testIntfMapT1{"ABC \x41=\x42 \u2318 - \r \b \f - \u2028 and \u2029 ."},
|
||||||
|
testIntfMapT2{"DEF"},
|
||||||
|
} {
|
||||||
|
if err := h.getBasicHandle().Intf2Impl(rti, reflect.TypeOf(v)); err != nil {
|
||||||
|
failT(t, "Error mapping %v to %T", rti, v)
|
||||||
|
}
|
||||||
|
var v1, v2 T9
|
||||||
|
v1 = T9{v}
|
||||||
|
b := testMarshalErr(v1, h, t, name+"-enc-"+strconv.Itoa(i))
|
||||||
|
testUnmarshalErr(&v2, b, h, t, name+"-dec-"+strconv.Itoa(i))
|
||||||
|
testDeepEqualErr(v1, v2, t, name+"-dec-eq-"+strconv.Itoa(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------
|
// -----------------
|
||||||
|
|
||||||
func TestJsonDecodeNonStringScalarInStringContext(t *testing.T) {
|
func TestJsonDecodeNonStringScalarInStringContext(t *testing.T) {
|
||||||
|
testOnce.Do(testInitAll)
|
||||||
var b = `{"s.true": "true", "b.true": true, "s.false": "false", "b.false": false, "s.10": "10", "i.10": 10, "i.-10": -10}`
|
var b = `{"s.true": "true", "b.true": true, "s.false": "false", "b.false": false, "s.10": "10", "i.10": 10, "i.-10": -10}`
|
||||||
var golden = map[string]string{"s.true": "true", "b.true": "true", "s.false": "false", "b.false": "false", "s.10": "10", "i.10": "10", "i.-10": "-10"}
|
var golden = map[string]string{"s.true": "true", "b.true": "true", "s.false": "false", "b.false": "false", "s.10": "10", "i.10": "10", "i.-10": "-10"}
|
||||||
|
|
||||||
@ -1913,6 +2305,7 @@ func TestJsonDecodeNonStringScalarInStringContext(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestJsonEncodeIndent(t *testing.T) {
|
func TestJsonEncodeIndent(t *testing.T) {
|
||||||
|
testOnce.Do(testInitAll)
|
||||||
v := TestSimplish{
|
v := TestSimplish{
|
||||||
Ii: -794,
|
Ii: -794,
|
||||||
Ss: `A Man is
|
Ss: `A Man is
|
||||||
@ -2026,6 +2419,7 @@ after the new line
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBufioDecReader(t *testing.T) {
|
func TestBufioDecReader(t *testing.T) {
|
||||||
|
testOnce.Do(testInitAll)
|
||||||
// try to read 85 bytes in chunks of 7 at a time.
|
// try to read 85 bytes in chunks of 7 at a time.
|
||||||
var s = strings.Repeat("01234'56789 ", 5)
|
var s = strings.Repeat("01234'56789 ", 5)
|
||||||
// fmt.Printf("s: %s\n", s)
|
// fmt.Printf("s: %s\n", s)
|
||||||
@ -2092,6 +2486,7 @@ func TestBufioDecReader(t *testing.T) {
|
|||||||
// -----------
|
// -----------
|
||||||
|
|
||||||
func TestJsonLargeInteger(t *testing.T) {
|
func TestJsonLargeInteger(t *testing.T) {
|
||||||
|
testOnce.Do(testInitAll)
|
||||||
for _, i := range []uint8{'L', 'A', 0} {
|
for _, i := range []uint8{'L', 'A', 0} {
|
||||||
for _, j := range []interface{}{
|
for _, j := range []interface{}{
|
||||||
int64(1 << 60),
|
int64(1 << 60),
|
||||||
@ -2109,6 +2504,7 @@ func TestJsonLargeInteger(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestJsonInvalidUnicode(t *testing.T) {
|
func TestJsonInvalidUnicode(t *testing.T) {
|
||||||
|
testOnce.Do(testInitAll)
|
||||||
var m = map[string]string{
|
var m = map[string]string{
|
||||||
`"\udc49\u0430abc"`: "\uFFFDabc",
|
`"\udc49\u0430abc"`: "\uFFFDabc",
|
||||||
`"\udc49\u0430"`: "\uFFFD",
|
`"\udc49\u0430"`: "\uFFFD",
|
||||||
@ -2431,6 +2827,11 @@ func TestCborMammothMapsAndSlices(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMsgpackMammothMapsAndSlices(t *testing.T) {
|
func TestMsgpackMammothMapsAndSlices(t *testing.T) {
|
||||||
|
old1, old2 := testMsgpackH.RawToString, testMsgpackH.WriteExt
|
||||||
|
defer func() { testMsgpackH.RawToString, testMsgpackH.WriteExt = old1, old2 }()
|
||||||
|
testMsgpackH.RawToString = true
|
||||||
|
testMsgpackH.WriteExt = true
|
||||||
|
|
||||||
doTestMammothMapsAndSlices(t, testMsgpackH)
|
doTestMammothMapsAndSlices(t, testMsgpackH)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2482,41 +2883,85 @@ func TestSimpleUintToInt(t *testing.T) {
|
|||||||
testUintToInt(t, "simple", testSimpleH)
|
testUintToInt(t, "simple", testSimpleH)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestJsonDifferentMapOrSliceType(t *testing.T) {
|
||||||
|
doTestDifferentMapOrSliceType(t, "json", testJsonH)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCborDifferentMapOrSliceType(t *testing.T) {
|
||||||
|
doTestDifferentMapOrSliceType(t, "cbor", testCborH)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMsgpackDifferentMapOrSliceType(t *testing.T) {
|
||||||
|
doTestDifferentMapOrSliceType(t, "msgpack", testMsgpackH)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBincDifferentMapOrSliceType(t *testing.T) {
|
||||||
|
doTestDifferentMapOrSliceType(t, "binc", testBincH)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSimpleDifferentMapOrSliceType(t *testing.T) {
|
||||||
|
doTestDifferentMapOrSliceType(t, "simple", testSimpleH)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJsonScalars(t *testing.T) {
|
||||||
|
doTestScalars(t, "json", testJsonH)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCborScalars(t *testing.T) {
|
||||||
|
doTestScalars(t, "cbor", testCborH)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMsgpackScalars(t *testing.T) {
|
||||||
|
doTestScalars(t, "msgpack", testMsgpackH)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBincScalars(t *testing.T) {
|
||||||
|
doTestScalars(t, "binc", testBincH)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSimpleScalars(t *testing.T) {
|
||||||
|
doTestScalars(t, "simple", testSimpleH)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJsonIntfMapping(t *testing.T) {
|
||||||
|
doTestIntfMapping(t, "json", testJsonH)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCborIntfMapping(t *testing.T) {
|
||||||
|
doTestIntfMapping(t, "cbor", testCborH)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMsgpackIntfMapping(t *testing.T) {
|
||||||
|
doTestIntfMapping(t, "msgpack", testMsgpackH)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBincIntfMapping(t *testing.T) {
|
||||||
|
doTestIntfMapping(t, "binc", testBincH)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSimpleIntfMapping(t *testing.T) {
|
||||||
|
doTestIntfMapping(t, "simple", testSimpleH)
|
||||||
|
}
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
//
|
//
|
||||||
// Add Tests for:
|
// Add Tests for:
|
||||||
// - struct tags:
|
// - struct tags: on anonymous fields, _struct (all fields), etc
|
||||||
// on anonymous fields, _struct (all fields), etc
|
// - chan to encode and decode (with support for codecgen also)
|
||||||
// - codecgen of struct containing channels.
|
|
||||||
// - (encode extensions: ext, raw ext, etc)
|
|
||||||
// - extension that isn't builtin e.g. type uint64Ext uint64.
|
|
||||||
// it encodes as a uint64.
|
|
||||||
//
|
//
|
||||||
// Add negative tests for failure conditions:
|
// Add negative tests for failure conditions:
|
||||||
// - bad input with large array length prefix
|
// - bad input with large array length prefix
|
||||||
//
|
//
|
||||||
// msgpack
|
// decode.go (standalone)
|
||||||
// - support time as built-in extension:
|
|
||||||
// see https://github.com/msgpack/msgpack/blob/master/spec.md#timestamp-extension-type
|
|
||||||
//
|
|
||||||
// decode.go
|
|
||||||
// - UnreadByte: only 2 states (z.ls = 2 and z.ls = 1) (0 --> 2 --> 1)
|
// - UnreadByte: only 2 states (z.ls = 2 and z.ls = 1) (0 --> 2 --> 1)
|
||||||
// - track
|
// - track: z.trb: track, stop track, check
|
||||||
// z.trb: track, stop track, check
|
// - PreferArrayOverSlice???
|
||||||
// - maptype, slicetype: diff from map[string]intf, map[intf]intf or []intf,
|
// - InterfaceReset
|
||||||
// - PreferArrayOverSlice??? (standalone test)
|
|
||||||
// - InterfaceReset (standalone test)
|
|
||||||
// - (chan byte) to decode []byte (with mapbyslice track)
|
// - (chan byte) to decode []byte (with mapbyslice track)
|
||||||
// - decode slice of len 6, 16 into slice of (len 4, cap 8) and (len ) with maxinitlen=6, 8, 16
|
// - decode slice of len 6, 16 into slice of (len 4, cap 8) and (len ) with maxinitlen=6, 8, 16
|
||||||
// - ktypeisintf
|
// - DeleteOnNilMapValue
|
||||||
// - DeleteOnNilMapValue (standalone test)
|
|
||||||
// - decnaked: n.l == nil
|
// - decnaked: n.l == nil
|
||||||
// - setZero: all types: *bool, *intXXX, *uintXXX, *floatXXX, *Raw, *[]byte, etc (not just struct)
|
|
||||||
// - codec.Selfer implementation
|
|
||||||
// Ensure it is called when (en|de)coding interface{} or reflect.Value (2 different codepaths).
|
|
||||||
// - ensureDecodeable (try to decode into a non-decodeable thing e.g. a nil interface{},
|
// - ensureDecodeable (try to decode into a non-decodeable thing e.g. a nil interface{},
|
||||||
//
|
//
|
||||||
// encode.go
|
// encode.go (standalone)
|
||||||
// - mapbyslice (for non-fastpath things)
|
|
||||||
// - nil and 0-len slices and maps for non-fastpath things
|
// - nil and 0-len slices and maps for non-fastpath things
|
||||||
// - pointers to scalars at top-level e.g. v := uint(7), encode(&v)
|
|
||||||
|
51
vendor/github.com/ugorji/go/codec/codecgen/gen.go
generated
vendored
51
vendor/github.com/ugorji/go/codec/codecgen/gen.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// codecgen generates codec.Selfer implementations for a set of types.
|
// codecgen generates codec.Selfer implementations for a set of types.
|
||||||
@ -29,6 +29,8 @@ const genCodecPkg = "codec1978" // keep this in sync with codec.genCodecPkg
|
|||||||
|
|
||||||
const genFrunMainTmpl = `//+build ignore
|
const genFrunMainTmpl = `//+build ignore
|
||||||
|
|
||||||
|
// Code generated - temporary main package for codecgen - DO NOT EDIT.
|
||||||
|
|
||||||
package main
|
package main
|
||||||
{{ if .Types }}import "{{ .ImportPath }}"{{ end }}
|
{{ if .Types }}import "{{ .ImportPath }}"{{ end }}
|
||||||
func main() {
|
func main() {
|
||||||
@ -38,6 +40,9 @@ func main() {
|
|||||||
|
|
||||||
// const genFrunPkgTmpl = `//+build codecgen
|
// const genFrunPkgTmpl = `//+build codecgen
|
||||||
const genFrunPkgTmpl = `
|
const genFrunPkgTmpl = `
|
||||||
|
|
||||||
|
// Code generated - temporary package for codecgen - DO NOT EDIT.
|
||||||
|
|
||||||
package {{ $.PackageName }}
|
package {{ $.PackageName }}
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -50,20 +55,33 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func CodecGenTempWrite{{ .RandString }}() {
|
func CodecGenTempWrite{{ .RandString }}() {
|
||||||
|
os.Remove("{{ .OutFile }}")
|
||||||
fout, err := os.Create("{{ .OutFile }}")
|
fout, err := os.Create("{{ .OutFile }}")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
defer fout.Close()
|
defer fout.Close()
|
||||||
var out bytes.Buffer
|
|
||||||
|
|
||||||
var typs []reflect.Type
|
var typs []reflect.Type
|
||||||
|
var typ reflect.Type
|
||||||
|
var numfields int
|
||||||
{{ range $index, $element := .Types }}
|
{{ range $index, $element := .Types }}
|
||||||
var t{{ $index }} {{ . }}
|
var t{{ $index }} {{ . }}
|
||||||
typs = append(typs, reflect.TypeOf(t{{ $index }}))
|
typ = reflect.TypeOf(t{{ $index }})
|
||||||
|
typs = append(typs, typ)
|
||||||
|
if typ.Kind() == reflect.Struct { numfields += typ.NumField() } else { numfields += 1 }
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ if not .CodecPkgFiles }}{{ .CodecPkgName }}.{{ end }}Gen(&out, "{{ .BuildTag }}", "{{ .PackageName }}", "{{ .RandString }}", {{ .NoExtensions }}, {{ if not .CodecPkgFiles }}{{ .CodecPkgName }}.{{ end }}NewTypeInfos(strings.Split("{{ .StructTags }}", ",")), typs...)
|
|
||||||
|
// println("initializing {{ .OutFile }}, buf size: {{ .AllFilesSize }}*16",
|
||||||
|
// {{ .AllFilesSize }}*16, "num fields: ", numfields)
|
||||||
|
var out = bytes.NewBuffer(make([]byte, 0, numfields*1024)) // {{ .AllFilesSize }}*16
|
||||||
|
{{ if not .CodecPkgFiles }}{{ .CodecPkgName }}.{{ end }}Gen(out,
|
||||||
|
"{{ .BuildTag }}", "{{ .PackageName }}", "{{ .RandString }}", {{ .NoExtensions }},
|
||||||
|
{{ if not .CodecPkgFiles }}{{ .CodecPkgName }}.{{ end }}NewTypeInfos(strings.Split("{{ .StructTags }}", ",")),
|
||||||
|
typs...)
|
||||||
|
|
||||||
bout, err := format.Source(out.Bytes())
|
bout, err := format.Source(out.Bytes())
|
||||||
|
// println("... lengths: before formatting: ", len(out.Bytes()), ", after formatting", len(bout))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fout.Write(out.Bytes())
|
fout.Write(out.Bytes())
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -98,8 +116,7 @@ func Generate(outfile, buildTag, codecPkgPath string,
|
|||||||
}
|
}
|
||||||
if uid < 0 {
|
if uid < 0 {
|
||||||
uid = -uid
|
uid = -uid
|
||||||
}
|
} else if uid == 0 {
|
||||||
if uid == 0 {
|
|
||||||
rr := rand.New(rand.NewSource(time.Now().UnixNano()))
|
rr := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
uid = 101 + rr.Int63n(9777)
|
uid = 101 + rr.Int63n(9777)
|
||||||
}
|
}
|
||||||
@ -124,6 +141,7 @@ func Generate(outfile, buildTag, codecPkgPath string,
|
|||||||
BuildTag string
|
BuildTag string
|
||||||
StructTags string
|
StructTags string
|
||||||
Types []string
|
Types []string
|
||||||
|
AllFilesSize int64
|
||||||
CodecPkgFiles bool
|
CodecPkgFiles bool
|
||||||
NoExtensions bool
|
NoExtensions bool
|
||||||
}
|
}
|
||||||
@ -145,11 +163,17 @@ func Generate(outfile, buildTag, codecPkgPath string,
|
|||||||
tv.ImportPath = stripVendor(tv.ImportPath)
|
tv.ImportPath = stripVendor(tv.ImportPath)
|
||||||
}
|
}
|
||||||
astfiles := make([]*ast.File, len(infiles))
|
astfiles := make([]*ast.File, len(infiles))
|
||||||
|
var fi os.FileInfo
|
||||||
for i, infile := range infiles {
|
for i, infile := range infiles {
|
||||||
if filepath.Dir(infile) != lastdir {
|
if filepath.Dir(infile) != lastdir {
|
||||||
err = errors.New("in files must all be in same directory as outfile")
|
err = errors.New("in files must all be in same directory as outfile")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if fi, err = os.Stat(infile); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tv.AllFilesSize += fi.Size()
|
||||||
|
|
||||||
fset := token.NewFileSet()
|
fset := token.NewFileSet()
|
||||||
astfiles[i], err = parser.ParseFile(fset, infile, nil, 0)
|
astfiles[i], err = parser.ParseFile(fset, infile, nil, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -211,6 +235,10 @@ func Generate(outfile, buildTag, codecPkgPath string,
|
|||||||
// chan: ChanType
|
// chan: ChanType
|
||||||
// do not generate:
|
// do not generate:
|
||||||
// FuncType, InterfaceType, StarExpr (ptr), etc
|
// FuncType, InterfaceType, StarExpr (ptr), etc
|
||||||
|
//
|
||||||
|
// We generate for all these types (not just structs), because they may be a field
|
||||||
|
// in another struct which doesn't have codecgen run on it, and it will be nice
|
||||||
|
// to take advantage of the fact that the type is a Selfer.
|
||||||
switch td.Type.(type) {
|
switch td.Type.(type) {
|
||||||
case *ast.StructType, *ast.Ident, *ast.MapType, *ast.ArrayType, *ast.ChanType:
|
case *ast.StructType, *ast.Ident, *ast.MapType, *ast.ArrayType, *ast.ChanType:
|
||||||
// only add to tv.Types iff
|
// only add to tv.Types iff
|
||||||
@ -286,6 +314,7 @@ func gen1(frunName, tmplStr string, tv interface{}) (frun *os.File, err error) {
|
|||||||
}
|
}
|
||||||
bw := bufio.NewWriter(frun)
|
bw := bufio.NewWriter(frun)
|
||||||
if err = t.Execute(bw, tv); err != nil {
|
if err = t.Execute(bw, tv); err != nil {
|
||||||
|
bw.Flush()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = bw.Flush(); err != nil {
|
if err = bw.Flush(); err != nil {
|
||||||
@ -317,14 +346,14 @@ func main() {
|
|||||||
rt := flag.String("rt", "", "tags for go run")
|
rt := flag.String("rt", "", "tags for go run")
|
||||||
st := flag.String("st", "codec,json", "struct tag keys to introspect")
|
st := flag.String("st", "codec,json", "struct tag keys to introspect")
|
||||||
x := flag.Bool("x", false, "keep temp file")
|
x := flag.Bool("x", false, "keep temp file")
|
||||||
_ = flag.Bool("u", false, "*IGNORED - kept for backwards compatibility*: Allow unsafe use")
|
_ = flag.Bool("u", false, "Allow unsafe use. ***IGNORED*** - kept for backwards compatibility: ")
|
||||||
d := flag.Int64("d", 0, "random identifier for use in generated code")
|
d := flag.Int64("d", 0, "random identifier for use in generated code")
|
||||||
nx := flag.Bool("nx", false, "no extensions")
|
nx := flag.Bool("nx", false, "do not support extensions - support of extensions may cause extra allocation")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
if err := Generate(*o, *t, *c, *d, *rt, *st,
|
err := Generate(*o, *t, *c, *d, *rt, *st,
|
||||||
regexp.MustCompile(*r), regexp.MustCompile(*nr), !*x, *nx,
|
regexp.MustCompile(*r), regexp.MustCompile(*nr), !*x, *nx, flag.Args()...)
|
||||||
flag.Args()...); err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "codecgen error: %v\n", err)
|
fmt.Fprintf(os.Stderr, "codecgen error: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
886
vendor/github.com/ugorji/go/codec/decode.go
generated
vendored
886
vendor/github.com/ugorji/go/codec/decode.go
generated
vendored
File diff suppressed because it is too large
Load Diff
733
vendor/github.com/ugorji/go/codec/encode.go
generated
vendored
733
vendor/github.com/ugorji/go/codec/encode.go
generated
vendored
File diff suppressed because it is too large
Load Diff
16279
vendor/github.com/ugorji/go/codec/fast-path.generated.go
generated
vendored
16279
vendor/github.com/ugorji/go/codec/fast-path.generated.go
generated
vendored
File diff suppressed because it is too large
Load Diff
278
vendor/github.com/ugorji/go/codec/fast-path.go.tmpl
generated
vendored
278
vendor/github.com/ugorji/go/codec/fast-path.go.tmpl
generated
vendored
@ -3,10 +3,7 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// ************************************************************
|
// Code generated from fast-path.go.tmpl - DO NOT EDIT.
|
||||||
// DO NOT EDIT.
|
|
||||||
// THIS FILE IS AUTO-GENERATED from fast-path.go.tmpl
|
|
||||||
// ************************************************************
|
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
|
|
||||||
@ -80,26 +77,19 @@ var fastpathAV fastpathA
|
|||||||
|
|
||||||
// due to possible initialization loop error, make fastpath in an init()
|
// due to possible initialization loop error, make fastpath in an init()
|
||||||
func init() {
|
func init() {
|
||||||
if useLookupRecognizedTypes && recognizedRtidsLoaded {
|
|
||||||
panic("recognizedRtidsLoaded = true - cannot happen")
|
|
||||||
}
|
|
||||||
i := 0
|
i := 0
|
||||||
fn := func(v interface{},
|
fn := func(v interface{},
|
||||||
fe func(*Encoder, *codecFnInfo, reflect.Value),
|
fe func(*Encoder, *codecFnInfo, reflect.Value),
|
||||||
fd func(*Decoder, *codecFnInfo, reflect.Value)) (f fastpathE) {
|
fd func(*Decoder, *codecFnInfo, reflect.Value)) (f fastpathE) {
|
||||||
xrt := reflect.TypeOf(v)
|
xrt := reflect.TypeOf(v)
|
||||||
xptr := rt2id(xrt)
|
xptr := rt2id(xrt)
|
||||||
if useLookupRecognizedTypes {
|
|
||||||
recognizedRtids = append(recognizedRtids, xptr)
|
|
||||||
recognizedRtidPtrs = append(recognizedRtidPtrs, rt2id(reflect.PtrTo(xrt)))
|
|
||||||
}
|
|
||||||
fastpathAV[i] = fastpathE{xptr, xrt, fe, fd}
|
fastpathAV[i] = fastpathE{xptr, xrt, fe, fd}
|
||||||
i++
|
i++
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
{{/* do not register []uint8 in fast-path */}}
|
||||||
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
|
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
|
||||||
fn([]{{ .Elem }}(nil), (*Encoder).{{ .MethodNamePfx "fastpathEnc" false }}R, (*Decoder).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}}
|
fn([]{{ .Elem }}(nil), (*Encoder).{{ .MethodNamePfx "fastpathEnc" false }}R, (*Decoder).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}}{{end}}
|
||||||
|
|
||||||
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
|
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
|
||||||
fn(map[{{ .MapKey }}]{{ .Elem }}(nil), (*Encoder).{{ .MethodNamePfx "fastpathEnc" false }}R, (*Decoder).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}}
|
fn(map[{{ .MapKey }}]{{ .Elem }}(nil), (*Encoder).{{ .MethodNamePfx "fastpathEnc" false }}R, (*Decoder).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}}
|
||||||
@ -112,22 +102,37 @@ func init() {
|
|||||||
// -- -- fast path type switch
|
// -- -- fast path type switch
|
||||||
func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool {
|
func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool {
|
||||||
switch v := iv.(type) {
|
switch v := iv.(type) {
|
||||||
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
|
|
||||||
case []{{ .Elem }}:{{else}}
|
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
|
||||||
case map[{{ .MapKey }}]{{ .Elem }}:{{end}}
|
case []{{ .Elem }}:
|
||||||
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e){{if not .MapKey }}
|
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
|
||||||
case *[]{{ .Elem }}:{{else}}
|
case *[]{{ .Elem }}:
|
||||||
case *map[{{ .MapKey }}]{{ .Elem }}:{{end}}
|
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e){{/*
|
||||||
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
|
*/}}{{end}}{{end}}{{end}}{{end}}
|
||||||
{{end}}{{end}}
|
|
||||||
|
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
|
||||||
|
case map[{{ .MapKey }}]{{ .Elem }}:
|
||||||
|
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
|
||||||
|
case *map[{{ .MapKey }}]{{ .Elem }}:
|
||||||
|
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e){{/*
|
||||||
|
*/}}{{end}}{{end}}{{end}}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
_ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release)
|
_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
{{/* **** removing this block, as they are never called directly ****
|
{{/*
|
||||||
|
**** removing this block, as they are never called directly ****
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**** removing this block, as they are never called directly ****
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool {
|
func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool {
|
||||||
switch v := iv.(type) {
|
switch v := iv.(type) {
|
||||||
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
|
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
|
||||||
@ -137,7 +142,7 @@ func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool {
|
|||||||
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
|
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
|
||||||
{{end}}{{end}}{{end}}
|
{{end}}{{end}}{{end}}
|
||||||
default:
|
default:
|
||||||
_ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release)
|
_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -152,16 +157,23 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool {
|
|||||||
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
|
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
|
||||||
{{end}}{{end}}{{end}}
|
{{end}}{{end}}{{end}}
|
||||||
default:
|
default:
|
||||||
_ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release)
|
_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**** removing this block, as they are never called directly ****
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**** removing this block, as they are never called directly ****
|
||||||
*/}}
|
*/}}
|
||||||
|
|
||||||
// -- -- fast path functions
|
// -- -- fast path functions
|
||||||
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
|
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
|
||||||
|
|
||||||
func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) {
|
func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) {
|
||||||
if f.ti.mbs {
|
if f.ti.mbs {
|
||||||
fastpathTV.{{ .MethodNamePfx "EncAsMap" false }}V(rv2i(rv).([]{{ .Elem }}), e)
|
fastpathTV.{{ .MethodNamePfx "EncAsMap" false }}V(rv2i(rv).([]{{ .Elem }}), e)
|
||||||
@ -173,13 +185,22 @@ func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v []{{ .Elem }}, e *Encoder
|
|||||||
if v == nil { e.e.EncodeNil(); return }
|
if v == nil { e.e.EncodeNil(); return }
|
||||||
ee, esep := e.e, e.hh.hasElemSeparators()
|
ee, esep := e.e, e.hh.hasElemSeparators()
|
||||||
ee.WriteArrayStart(len(v))
|
ee.WriteArrayStart(len(v))
|
||||||
|
if esep {
|
||||||
|
for _, v2 := range v {
|
||||||
|
ee.WriteArrayElem()
|
||||||
|
{{ encmd .Elem "v2"}}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, v2 := range v {
|
||||||
|
{{ encmd .Elem "v2"}}
|
||||||
|
}
|
||||||
|
} {{/*
|
||||||
for _, v2 := range v {
|
for _, v2 := range v {
|
||||||
if esep { ee.WriteArrayElem() }
|
if esep { ee.WriteArrayElem() }
|
||||||
{{ encmd .Elem "v2"}}
|
{{ encmd .Elem "v2"}}
|
||||||
}
|
} */}}
|
||||||
ee.WriteArrayEnd()
|
ee.WriteArrayEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, e *Encoder) {
|
func (_ fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, e *Encoder) {
|
||||||
ee, esep := e.e, e.hh.hasElemSeparators()
|
ee, esep := e.e, e.hh.hasElemSeparators()
|
||||||
if len(v)%2 == 1 {
|
if len(v)%2 == 1 {
|
||||||
@ -187,6 +208,20 @@ func (_ fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, e *En
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
ee.WriteMapStart(len(v) / 2)
|
ee.WriteMapStart(len(v) / 2)
|
||||||
|
if esep {
|
||||||
|
for j, v2 := range v {
|
||||||
|
if j%2 == 0 {
|
||||||
|
ee.WriteMapElemKey()
|
||||||
|
} else {
|
||||||
|
ee.WriteMapElemValue()
|
||||||
|
}
|
||||||
|
{{ encmd .Elem "v2"}}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, v2 := range v {
|
||||||
|
{{ encmd .Elem "v2"}}
|
||||||
|
}
|
||||||
|
} {{/*
|
||||||
for j, v2 := range v {
|
for j, v2 := range v {
|
||||||
if esep {
|
if esep {
|
||||||
if j%2 == 0 {
|
if j%2 == 0 {
|
||||||
@ -196,14 +231,12 @@ func (_ fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, e *En
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{ encmd .Elem "v2"}}
|
{{ encmd .Elem "v2"}}
|
||||||
}
|
} */}}
|
||||||
ee.WriteMapEnd()
|
ee.WriteMapEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
{{end}}{{end}}{{end}}
|
{{end}}{{end}}{{end}}
|
||||||
|
|
||||||
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
|
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
|
||||||
|
|
||||||
func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) {
|
func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) {
|
||||||
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), e)
|
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), e)
|
||||||
}
|
}
|
||||||
@ -211,8 +244,7 @@ func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v map[{{ .MapKey }}]{{ .Ele
|
|||||||
if v == nil { e.e.EncodeNil(); return }
|
if v == nil { e.e.EncodeNil(); return }
|
||||||
ee, esep := e.e, e.hh.hasElemSeparators()
|
ee, esep := e.e, e.hh.hasElemSeparators()
|
||||||
ee.WriteMapStart(len(v))
|
ee.WriteMapStart(len(v))
|
||||||
{{if eq .MapKey "string"}}asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
|
if e.h.Canonical {
|
||||||
{{end}}if e.h.Canonical {
|
|
||||||
{{if eq .MapKey "interface{}"}}{{/* out of band
|
{{if eq .MapKey "interface{}"}}{{/* out of band
|
||||||
*/}}var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
|
*/}}var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
|
||||||
e2 := NewEncoderBytes(&mksv, e.hh)
|
e2 := NewEncoderBytes(&mksv, e.hh)
|
||||||
@ -228,76 +260,126 @@ func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v map[{{ .MapKey }}]{{ .Ele
|
|||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
sort.Sort(bytesISlice(v2))
|
sort.Sort(bytesISlice(v2))
|
||||||
|
if esep {
|
||||||
|
for j := range v2 {
|
||||||
|
ee.WriteMapElemKey()
|
||||||
|
e.asis(v2[j].v)
|
||||||
|
ee.WriteMapElemValue()
|
||||||
|
e.encode(v[v2[j].i])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for j := range v2 {
|
||||||
|
e.asis(v2[j].v)
|
||||||
|
e.encode(v[v2[j].i])
|
||||||
|
}
|
||||||
|
} {{/*
|
||||||
for j := range v2 {
|
for j := range v2 {
|
||||||
if esep { ee.WriteMapElemKey() }
|
if esep { ee.WriteMapElemKey() }
|
||||||
e.asis(v2[j].v)
|
e.asis(v2[j].v)
|
||||||
if esep { ee.WriteMapElemValue() }
|
if esep { ee.WriteMapElemValue() }
|
||||||
e.encode(v[v2[j].i])
|
e.encode(v[v2[j].i])
|
||||||
} {{else}}{{ $x := sorttype .MapKey true}}v2 := make([]{{ $x }}, len(v))
|
} */}} {{else}}{{ $x := sorttype .MapKey true}}v2 := make([]{{ $x }}, len(v))
|
||||||
var i int
|
var i int
|
||||||
for k, _ := range v {
|
for k, _ := range v {
|
||||||
v2[i] = {{ $x }}(k)
|
v2[i] = {{ $x }}(k)
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
sort.Sort({{ sorttype .MapKey false}}(v2))
|
sort.Sort({{ sorttype .MapKey false}}(v2))
|
||||||
|
if esep {
|
||||||
|
for _, k2 := range v2 {
|
||||||
|
ee.WriteMapElemKey()
|
||||||
|
{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
|
||||||
|
ee.WriteMapElemValue()
|
||||||
|
{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, k2 := range v2 {
|
||||||
|
{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
|
||||||
|
{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
|
||||||
|
}
|
||||||
|
} {{/*
|
||||||
for _, k2 := range v2 {
|
for _, k2 := range v2 {
|
||||||
if esep { ee.WriteMapElemKey() }
|
if esep { ee.WriteMapElemKey() }
|
||||||
{{if eq .MapKey "string"}}if asSymbols {
|
{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
|
||||||
ee.EncodeSymbol(k2)
|
|
||||||
} else {
|
|
||||||
ee.EncodeString(c_UTF8, k2)
|
|
||||||
}{{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
|
|
||||||
if esep { ee.WriteMapElemValue() }
|
if esep { ee.WriteMapElemValue() }
|
||||||
{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
|
{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
|
||||||
} {{end}}
|
} */}} {{end}}
|
||||||
} else {
|
} else {
|
||||||
|
if esep {
|
||||||
for k2, v2 := range v {
|
for k2, v2 := range v {
|
||||||
if esep { ee.WriteMapElemKey() }
|
ee.WriteMapElemKey()
|
||||||
{{if eq .MapKey "string"}}if asSymbols {
|
{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ encmd .MapKey "k2"}}{{end}}
|
||||||
ee.EncodeSymbol(k2)
|
ee.WriteMapElemValue()
|
||||||
} else {
|
|
||||||
ee.EncodeString(c_UTF8, k2)
|
|
||||||
}{{else}}{{ encmd .MapKey "k2"}}{{end}}
|
|
||||||
if esep { ee.WriteMapElemValue() }
|
|
||||||
{{ encmd .Elem "v2"}}
|
{{ encmd .Elem "v2"}}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for k2, v2 := range v {
|
||||||
|
{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ encmd .MapKey "k2"}}{{end}}
|
||||||
|
{{ encmd .Elem "v2"}}
|
||||||
|
}
|
||||||
|
} {{/*
|
||||||
|
for k2, v2 := range v {
|
||||||
|
if esep { ee.WriteMapElemKey() }
|
||||||
|
{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ encmd .MapKey "k2"}}{{end}}
|
||||||
|
if esep { ee.WriteMapElemValue() }
|
||||||
|
{{ encmd .Elem "v2"}}
|
||||||
|
} */}}
|
||||||
}
|
}
|
||||||
ee.WriteMapEnd()
|
ee.WriteMapEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
{{end}}{{end}}{{end}}
|
{{end}}{{end}}{{end}}
|
||||||
|
|
||||||
// -- decode
|
// -- decode
|
||||||
|
|
||||||
// -- -- fast path type switch
|
// -- -- fast path type switch
|
||||||
func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool {
|
func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool {
|
||||||
|
var changed bool
|
||||||
switch v := iv.(type) {
|
switch v := iv.(type) {
|
||||||
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
|
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
|
||||||
case []{{ .Elem }}:{{else}}
|
case []{{ .Elem }}:
|
||||||
case map[{{ .MapKey }}]{{ .Elem }}:{{end}}
|
var v2 []{{ .Elem }}
|
||||||
fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, false, d){{if not .MapKey }}
|
v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, false, d)
|
||||||
case *[]{{ .Elem }}: {{else}}
|
if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
|
||||||
case *map[{{ .MapKey }}]{{ .Elem }}: {{end}}
|
copy(v, v2)
|
||||||
if v2, changed2 := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*v, true, d); changed2 {
|
|
||||||
*v = v2
|
|
||||||
}
|
}
|
||||||
{{end}}{{end}}
|
case *[]{{ .Elem }}:
|
||||||
|
var v2 []{{ .Elem }}
|
||||||
|
v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*v, true, d)
|
||||||
|
if changed {
|
||||||
|
*v = v2
|
||||||
|
}{{/*
|
||||||
|
*/}}{{end}}{{end}}{{end}}{{end}}
|
||||||
|
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}{{/*
|
||||||
|
// maps only change if nil, and in that case, there's no point copying
|
||||||
|
*/}}
|
||||||
|
case map[{{ .MapKey }}]{{ .Elem }}:
|
||||||
|
fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, false, d)
|
||||||
|
case *map[{{ .MapKey }}]{{ .Elem }}:
|
||||||
|
var v2 map[{{ .MapKey }}]{{ .Elem }}
|
||||||
|
v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*v, true, d)
|
||||||
|
if changed {
|
||||||
|
*v = v2
|
||||||
|
}{{/*
|
||||||
|
*/}}{{end}}{{end}}{{end}}
|
||||||
default:
|
default:
|
||||||
_ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release)
|
_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func fastpathDecodeSetZeroTypeSwitch(iv interface{}, d *Decoder) bool {
|
func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool {
|
||||||
switch v := iv.(type) {
|
switch v := iv.(type) {
|
||||||
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
|
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
|
||||||
case *[]{{ .Elem }}: {{else}}
|
case *[]{{ .Elem }}:
|
||||||
case *map[{{ .MapKey }}]{{ .Elem }}: {{end}}
|
*v = nil {{/*
|
||||||
*v = nil
|
*/}}{{end}}{{end}}{{end}}
|
||||||
{{end}}{{end}}
|
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
|
||||||
|
case *map[{{ .MapKey }}]{{ .Elem }}:
|
||||||
|
*v = nil {{/*
|
||||||
|
*/}}{{end}}{{end}}{{end}}
|
||||||
default:
|
default:
|
||||||
_ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release)
|
_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -313,36 +395,34 @@ Slices can change if they
|
|||||||
*/}}
|
*/}}
|
||||||
func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) {
|
||||||
if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
|
if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
|
||||||
var vp = rv2i(rv).(*[]{{ .Elem }})
|
vp := rv2i(rv).(*[]{{ .Elem }})
|
||||||
if v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, !array, d); changed {
|
v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, !array, d)
|
||||||
*vp = v
|
if changed { *vp = v }
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
fastpathTV.{{ .MethodNamePfx "Dec" false }}V(rv2i(rv).([]{{ .Elem }}), !array, d)
|
v := rv2i(rv).([]{{ .Elem }})
|
||||||
|
v2, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, !array, d)
|
||||||
|
if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
|
||||||
|
copy(v, v2)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *[]{{ .Elem }}, d *Decoder) {
|
func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *[]{{ .Elem }}, d *Decoder) {
|
||||||
if v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d); changed {
|
v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d)
|
||||||
*vp = v
|
if changed { *vp = v }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, canChange bool, d *Decoder) (_ []{{ .Elem }}, changed bool) {
|
func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, canChange bool, d *Decoder) (_ []{{ .Elem }}, changed bool) {
|
||||||
dd := d.d
|
dd := d.d{{/*
|
||||||
{{/* // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() */}}
|
// if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil()
|
||||||
|
*/}}
|
||||||
slh, containerLenS := d.decSliceHelperStart()
|
slh, containerLenS := d.decSliceHelperStart()
|
||||||
if containerLenS == 0 {
|
if containerLenS == 0 {
|
||||||
if canChange {
|
if canChange {
|
||||||
if v == nil {
|
if v == nil { v = []{{ .Elem }}{} } else if len(v) != 0 { v = v[:0] }
|
||||||
v = []{{ .Elem }}{}
|
|
||||||
} else if len(v) != 0 {
|
|
||||||
v = v[:0]
|
|
||||||
}
|
|
||||||
changed = true
|
changed = true
|
||||||
}
|
}
|
||||||
slh.End()
|
slh.End()
|
||||||
return v, changed
|
return v, changed
|
||||||
}
|
}
|
||||||
|
|
||||||
hasLen := containerLenS > 0
|
hasLen := containerLenS > 0
|
||||||
var xlen int
|
var xlen int
|
||||||
if hasLen && canChange {
|
if hasLen && canChange {
|
||||||
@ -361,7 +441,7 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, canChange
|
|||||||
}
|
}
|
||||||
j := 0
|
j := 0
|
||||||
for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
|
for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
|
||||||
if j == 0 && len(v) == 0 {
|
if j == 0 && len(v) == 0 && canChange {
|
||||||
if hasLen {
|
if hasLen {
|
||||||
xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
|
xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
|
||||||
} else {
|
} else {
|
||||||
@ -384,6 +464,8 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, canChange
|
|||||||
slh.ElemContainerState(j)
|
slh.ElemContainerState(j)
|
||||||
if decodeIntoBlank {
|
if decodeIntoBlank {
|
||||||
d.swallow()
|
d.swallow()
|
||||||
|
} else if dd.TryDecodeAsNil() {
|
||||||
|
v[j] = {{ zerocmd .Elem }}
|
||||||
} else {
|
} else {
|
||||||
{{ if eq .Elem "interface{}" }}d.decode(&v[j]){{ else }}v[j] = {{ decmd .Elem }}{{ end }}
|
{{ if eq .Elem "interface{}" }}d.decode(&v[j]){{ else }}v[j] = {{ decmd .Elem }}{{ end }}
|
||||||
}
|
}
|
||||||
@ -400,10 +482,8 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, canChange
|
|||||||
slh.End()
|
slh.End()
|
||||||
return v, changed
|
return v, changed
|
||||||
}
|
}
|
||||||
|
|
||||||
{{end}}{{end}}{{end}}
|
{{end}}{{end}}{{end}}
|
||||||
|
|
||||||
|
|
||||||
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
|
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
|
||||||
{{/*
|
{{/*
|
||||||
Maps can change if they are
|
Maps can change if they are
|
||||||
@ -413,22 +493,21 @@ Maps can change if they are
|
|||||||
func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) {
|
||||||
if rv.Kind() == reflect.Ptr {
|
if rv.Kind() == reflect.Ptr {
|
||||||
vp := rv2i(rv).(*map[{{ .MapKey }}]{{ .Elem }})
|
vp := rv2i(rv).(*map[{{ .MapKey }}]{{ .Elem }})
|
||||||
if v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d); changed {
|
v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d);
|
||||||
*vp = v
|
if changed { *vp = v }
|
||||||
}
|
} else {
|
||||||
return
|
|
||||||
}
|
|
||||||
fastpathTV.{{ .MethodNamePfx "Dec" false }}V(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), false, d)
|
fastpathTV.{{ .MethodNamePfx "Dec" false }}V(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), false, d)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *map[{{ .MapKey }}]{{ .Elem }}, d *Decoder) {
|
func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *map[{{ .MapKey }}]{{ .Elem }}, d *Decoder) {
|
||||||
if v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d); changed {
|
v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d)
|
||||||
*vp = v
|
if changed { *vp = v }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, canChange bool,
|
func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, canChange bool,
|
||||||
d *Decoder) (_ map[{{ .MapKey }}]{{ .Elem }}, changed bool) {
|
d *Decoder) (_ map[{{ .MapKey }}]{{ .Elem }}, changed bool) {
|
||||||
dd, esep := d.d, d.hh.hasElemSeparators()
|
dd, esep := d.d, d.hh.hasElemSeparators(){{/*
|
||||||
{{/* // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() */}}
|
// if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil()
|
||||||
|
*/}}
|
||||||
containerLen := dd.ReadMapStart()
|
containerLen := dd.ReadMapStart()
|
||||||
if canChange && v == nil {
|
if canChange && v == nil {
|
||||||
xlen := decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }})
|
xlen := decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }})
|
||||||
@ -439,8 +518,8 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Ele
|
|||||||
dd.ReadMapEnd()
|
dd.ReadMapEnd()
|
||||||
return v, changed
|
return v, changed
|
||||||
}
|
}
|
||||||
{{ if eq .Elem "interface{}" }}mapGet := !d.h.MapValueReset && !d.h.InterfaceReset{{end}}
|
{{ if eq .Elem "interface{}" }}mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
|
||||||
var mk {{ .MapKey }}
|
{{end}}var mk {{ .MapKey }}
|
||||||
var mv {{ .Elem }}
|
var mv {{ .Elem }}
|
||||||
hasLen := containerLen > 0
|
hasLen := containerLen > 0
|
||||||
for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
|
for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
|
||||||
@ -452,17 +531,14 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Ele
|
|||||||
}{{ else }}mk = {{ decmd .MapKey }}{{ end }}
|
}{{ else }}mk = {{ decmd .MapKey }}{{ end }}
|
||||||
if esep { dd.ReadMapElemValue() }
|
if esep { dd.ReadMapElemValue() }
|
||||||
if dd.TryDecodeAsNil() {
|
if dd.TryDecodeAsNil() {
|
||||||
if d.h.DeleteOnNilMapValue { delete(v, mk) } else { v[mk] = {{ zerocmd .Elem }} }
|
if v == nil {} else if d.h.DeleteOnNilMapValue { delete(v, mk) } else { v[mk] = {{ zerocmd .Elem }} }
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
{{ if eq .Elem "interface{}" }}if mapGet { mv = v[mk] } else { mv = nil }
|
{{ if eq .Elem "interface{}" }}if mapGet { mv = v[mk] } else { mv = nil }
|
||||||
d.decode(&mv){{ else }}mv = {{ decmd .Elem }}{{ end }}
|
d.decode(&mv){{ else }}mv = {{ decmd .Elem }}{{ end }}
|
||||||
if v != nil {
|
if v != nil { v[mk] = mv }
|
||||||
v[mk] = mv
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
dd.ReadMapEnd()
|
dd.ReadMapEnd()
|
||||||
return v, changed
|
return v, changed
|
||||||
}
|
}
|
||||||
|
|
||||||
{{end}}{{end}}{{end}}
|
{{end}}{{end}}{{end}}
|
||||||
|
11
vendor/github.com/ugorji/go/codec/fast-path.not.go
generated
vendored
11
vendor/github.com/ugorji/go/codec/fast-path.not.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// +build notfastpath
|
// +build notfastpath
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
@ -18,7 +21,7 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { return f
|
|||||||
func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { return false }
|
func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { return false }
|
||||||
func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool { return false }
|
func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool { return false }
|
||||||
func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { return false }
|
func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { return false }
|
||||||
func fastpathDecodeSetZeroTypeSwitch(iv interface{}, d *Decoder) bool { return false }
|
func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool { return false }
|
||||||
|
|
||||||
type fastpathT struct{}
|
type fastpathT struct{}
|
||||||
type fastpathE struct {
|
type fastpathE struct {
|
||||||
@ -31,6 +34,12 @@ type fastpathA [0]fastpathE
|
|||||||
|
|
||||||
func (x fastpathA) index(rtid uintptr) int { return -1 }
|
func (x fastpathA) index(rtid uintptr) int { return -1 }
|
||||||
|
|
||||||
|
func (_ fastpathT) DecSliceUint8V(v []uint8, canChange bool, d *Decoder) (_ []uint8, changed bool) {
|
||||||
|
fn := d.cfer().get(uint8SliceTyp, true, true)
|
||||||
|
d.kSlice(&fn.i, reflect.ValueOf(&v).Elem())
|
||||||
|
return v, true
|
||||||
|
}
|
||||||
|
|
||||||
var fastpathAV fastpathA
|
var fastpathAV fastpathA
|
||||||
var fastpathTV fastpathT
|
var fastpathTV fastpathT
|
||||||
|
|
||||||
|
2
vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl
generated
vendored
2
vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl
generated
vendored
@ -43,7 +43,7 @@ if {{var "l"}} == 0 {
|
|||||||
{{var "c"}} = true
|
{{var "c"}} = true
|
||||||
}{{end}}
|
}{{end}}
|
||||||
{{var "h"}}.ElemContainerState({{var "j"}})
|
{{var "h"}}.ElemContainerState({{var "j"}})
|
||||||
// {{var "dn"}} = r.TryDecodeAsNil()
|
{{/* {{var "dn"}} = r.TryDecodeAsNil() */}}
|
||||||
{{if isChan}}{{ $x := printf "%[1]vv%[2]v" .TempVar .Rand }}var {{var $x}} {{ .Typ }}
|
{{if isChan}}{{ $x := printf "%[1]vv%[2]v" .TempVar .Rand }}var {{var $x}} {{ .Typ }}
|
||||||
{{ decLineVar $x }}
|
{{ decLineVar $x }}
|
||||||
{{var "v"}} <- {{ $x }}
|
{{var "v"}} <- {{ $x }}
|
||||||
|
182
vendor/github.com/ugorji/go/codec/gen-helper.generated.go
generated
vendored
182
vendor/github.com/ugorji/go/codec/gen-helper.generated.go
generated
vendored
@ -3,10 +3,7 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// ************************************************************
|
// Code generated from gen-helper.go.tmpl - DO NOT EDIT.
|
||||||
// DO NOT EDIT.
|
|
||||||
// THIS FILE IS AUTO-GENERATED from gen-helper.go.tmpl
|
|
||||||
// ************************************************************
|
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
|
|
||||||
@ -31,25 +28,73 @@ const GenVersion = 8
|
|||||||
// GenHelperEncoder is exported so that it can be used externally by codecgen.
|
// GenHelperEncoder is exported so that it can be used externally by codecgen.
|
||||||
//
|
//
|
||||||
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
|
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
|
||||||
func GenHelperEncoder(e *Encoder) (genHelperEncoder, encDriver) {
|
func GenHelperEncoder(e *Encoder) (ge genHelperEncoder, ee genHelperEncDriver) {
|
||||||
return genHelperEncoder{e: e}, e.e
|
ge = genHelperEncoder{e: e}
|
||||||
|
ee = genHelperEncDriver{encDriver: e.e}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenHelperDecoder is exported so that it can be used externally by codecgen.
|
// GenHelperDecoder is exported so that it can be used externally by codecgen.
|
||||||
//
|
//
|
||||||
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
|
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
|
||||||
func GenHelperDecoder(d *Decoder) (genHelperDecoder, decDriver) {
|
func GenHelperDecoder(d *Decoder) (gd genHelperDecoder, dd genHelperDecDriver) {
|
||||||
return genHelperDecoder{d: d}, d.d
|
gd = genHelperDecoder{d: d}
|
||||||
|
dd = genHelperDecDriver{decDriver: d.d}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type genHelperEncDriver struct {
|
||||||
|
encDriver
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x genHelperEncDriver) EncodeBuiltin(rt uintptr, v interface{}) {}
|
||||||
|
func (x genHelperEncDriver) EncStructFieldKey(keyType valueType, s string) {
|
||||||
|
encStructFieldKey(x.encDriver, keyType, s)
|
||||||
|
}
|
||||||
|
func (x genHelperEncDriver) EncodeSymbol(s string) {
|
||||||
|
x.encDriver.EncodeString(cUTF8, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
type genHelperDecDriver struct {
|
||||||
|
decDriver
|
||||||
|
C checkOverflow
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x genHelperDecDriver) DecodeBuiltin(rt uintptr, v interface{}) {}
|
||||||
|
func (x genHelperDecDriver) DecStructFieldKey(keyType valueType, buf *[decScratchByteArrayLen]byte) []byte {
|
||||||
|
return decStructFieldKey(x.decDriver, keyType, buf)
|
||||||
|
}
|
||||||
|
func (x genHelperDecDriver) DecodeInt(bitsize uint8) (i int64) {
|
||||||
|
return x.C.IntV(x.decDriver.DecodeInt64(), bitsize)
|
||||||
|
}
|
||||||
|
func (x genHelperDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
|
||||||
|
return x.C.UintV(x.decDriver.DecodeUint64(), bitsize)
|
||||||
|
}
|
||||||
|
func (x genHelperDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
|
||||||
|
f = x.DecodeFloat64()
|
||||||
|
if chkOverflow32 && chkOvf.Float32(f) {
|
||||||
|
panicv.errorf("float32 overflow: %v", f)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (x genHelperDecDriver) DecodeFloat32As64() (f float64) {
|
||||||
|
f = x.DecodeFloat64()
|
||||||
|
if chkOvf.Float32(f) {
|
||||||
|
panicv.errorf("float32 overflow: %v", f)
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
type genHelperEncoder struct {
|
type genHelperEncoder struct {
|
||||||
|
M must
|
||||||
e *Encoder
|
e *Encoder
|
||||||
F fastpathT
|
F fastpathT
|
||||||
}
|
}
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
type genHelperDecoder struct {
|
type genHelperDecoder struct {
|
||||||
|
C checkOverflow
|
||||||
d *Decoder
|
d *Decoder
|
||||||
F fastpathT
|
F fastpathT
|
||||||
}
|
}
|
||||||
@ -61,7 +106,12 @@ func (f genHelperEncoder) EncBasicHandle() *BasicHandle {
|
|||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperEncoder) EncBinary() bool {
|
func (f genHelperEncoder) EncBinary() bool {
|
||||||
return f.e.cf.be // f.e.hh.isBinaryEncoding()
|
return f.e.be // f.e.hh.isBinaryEncoding()
|
||||||
|
}
|
||||||
|
|
||||||
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
func (f genHelperEncoder) IsJSONHandle() bool {
|
||||||
|
return f.e.js
|
||||||
}
|
}
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
@ -74,52 +124,65 @@ func (f genHelperEncoder) EncFallback(iv interface{}) {
|
|||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) {
|
func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) {
|
||||||
bs, fnerr := iv.MarshalText()
|
bs, fnerr := iv.MarshalText()
|
||||||
f.e.marshal(bs, fnerr, false, c_UTF8)
|
f.e.marshal(bs, fnerr, false, cUTF8)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) {
|
func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) {
|
||||||
bs, fnerr := iv.MarshalJSON()
|
bs, fnerr := iv.MarshalJSON()
|
||||||
f.e.marshal(bs, fnerr, true, c_UTF8)
|
f.e.marshal(bs, fnerr, true, cUTF8)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) {
|
func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) {
|
||||||
bs, fnerr := iv.MarshalBinary()
|
bs, fnerr := iv.MarshalBinary()
|
||||||
f.e.marshal(bs, fnerr, false, c_RAW)
|
f.e.marshal(bs, fnerr, false, cRAW)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperEncoder) EncRaw(iv Raw) {
|
func (f genHelperEncoder) EncRaw(iv Raw) { f.e.rawBytes(iv) }
|
||||||
f.e.rawBytes(iv)
|
|
||||||
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
//
|
||||||
|
// Deprecated: builtin no longer supported - so we make this method a no-op,
|
||||||
|
// but leave in-place so that old generated files continue to work without regeneration.
|
||||||
|
func (f genHelperEncoder) TimeRtidIfBinc() (v uintptr) { return }
|
||||||
|
|
||||||
|
// func (f genHelperEncoder) TimeRtidIfBinc() uintptr {
|
||||||
|
// if _, ok := f.e.hh.(*BincHandle); ok {
|
||||||
|
// return timeTypId
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
func (f genHelperEncoder) I2Rtid(v interface{}) uintptr {
|
||||||
|
return i2rtid(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperEncoder) TimeRtidIfBinc() uintptr {
|
func (f genHelperEncoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
|
||||||
if _, ok := f.e.hh.(*BincHandle); ok {
|
return f.e.h.getExt(rtid)
|
||||||
return timeTypId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperEncoder) IsJSONHandle() bool {
|
func (f genHelperEncoder) EncExtension(v interface{}, xfFn *extTypeTagFn) {
|
||||||
return f.e.cf.js
|
f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
//
|
||||||
|
// Deprecated: No longer used,
|
||||||
|
// but leave in-place so that old generated files continue to work without regeneration.
|
||||||
func (f genHelperEncoder) HasExtensions() bool {
|
func (f genHelperEncoder) HasExtensions() bool {
|
||||||
return len(f.e.h.extHandle) != 0
|
return len(f.e.h.extHandle) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
//
|
||||||
|
// Deprecated: No longer used,
|
||||||
|
// but leave in-place so that old generated files continue to work without regeneration.
|
||||||
func (f genHelperEncoder) EncExt(v interface{}) (r bool) {
|
func (f genHelperEncoder) EncExt(v interface{}) (r bool) {
|
||||||
rt := reflect.TypeOf(v)
|
if xfFn := f.e.h.getExt(i2rtid(v)); xfFn != nil {
|
||||||
if rt.Kind() == reflect.Ptr {
|
|
||||||
rt = rt.Elem()
|
|
||||||
}
|
|
||||||
rtid := rt2id(rt)
|
|
||||||
if xfFn := f.e.h.getExt(rtid); xfFn != nil {
|
|
||||||
f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
|
f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -139,15 +202,18 @@ func (f genHelperDecoder) DecBinary() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperDecoder) DecSwallow() {
|
func (f genHelperDecoder) DecSwallow() { f.d.swallow() }
|
||||||
f.d.swallow()
|
|
||||||
}
|
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperDecoder) DecScratchBuffer() []byte {
|
func (f genHelperDecoder) DecScratchBuffer() []byte {
|
||||||
return f.d.b[:]
|
return f.d.b[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
func (f genHelperDecoder) DecScratchArrayBuffer() *[decScratchByteArrayLen]byte {
|
||||||
|
return &f.d.b
|
||||||
|
}
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
|
func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
|
||||||
// println(">>>>>>>>> DecFallback")
|
// println(">>>>>>>>> DecFallback")
|
||||||
@ -155,7 +221,7 @@ func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
|
|||||||
if chkPtr {
|
if chkPtr {
|
||||||
rv = f.d.ensureDecodeable(rv)
|
rv = f.d.ensureDecodeable(rv)
|
||||||
}
|
}
|
||||||
f.d.decodeValue(rv, nil, false, false)
|
f.d.decodeValue(rv, nil, false)
|
||||||
// f.d.decodeValueFallback(rv)
|
// f.d.decodeValueFallback(rv)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,17 +267,21 @@ func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperDecoder) DecRaw() []byte {
|
func (f genHelperDecoder) DecRaw() []byte { return f.d.rawBytes() }
|
||||||
return f.d.rawBytes()
|
|
||||||
}
|
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperDecoder) TimeRtidIfBinc() uintptr {
|
//
|
||||||
if _, ok := f.d.hh.(*BincHandle); ok {
|
// Deprecated: builtin no longer supported - so we make this method a no-op,
|
||||||
return timeTypId
|
// but leave in-place so that old generated files continue to work without regeneration.
|
||||||
}
|
func (f genHelperDecoder) TimeRtidIfBinc() (v uintptr) { return }
|
||||||
return 0
|
|
||||||
}
|
// func (f genHelperDecoder) TimeRtidIfBinc() uintptr {
|
||||||
|
// // Note: builtin is no longer supported - so make this a no-op
|
||||||
|
// if _, ok := f.d.hh.(*BincHandle); ok {
|
||||||
|
// return timeTypId
|
||||||
|
// }
|
||||||
|
// return 0
|
||||||
|
// }
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperDecoder) IsJSONHandle() bool {
|
func (f genHelperDecoder) IsJSONHandle() bool {
|
||||||
@ -219,15 +289,34 @@ func (f genHelperDecoder) IsJSONHandle() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
func (f genHelperDecoder) I2Rtid(v interface{}) uintptr {
|
||||||
|
return i2rtid(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
func (f genHelperDecoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
|
||||||
|
return f.d.h.getExt(rtid)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
func (f genHelperDecoder) DecExtension(v interface{}, xfFn *extTypeTagFn) {
|
||||||
|
f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
//
|
||||||
|
// Deprecated: No longer used,
|
||||||
|
// but leave in-place so that old generated files continue to work without regeneration.
|
||||||
func (f genHelperDecoder) HasExtensions() bool {
|
func (f genHelperDecoder) HasExtensions() bool {
|
||||||
return len(f.d.h.extHandle) != 0
|
return len(f.d.h.extHandle) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
//
|
||||||
|
// Deprecated: No longer used,
|
||||||
|
// but leave in-place so that old generated files continue to work without regeneration.
|
||||||
func (f genHelperDecoder) DecExt(v interface{}) (r bool) {
|
func (f genHelperDecoder) DecExt(v interface{}) (r bool) {
|
||||||
rt := reflect.TypeOf(v).Elem()
|
if xfFn := f.d.h.getExt(i2rtid(v)); xfFn != nil {
|
||||||
rtid := rt2id(rt)
|
|
||||||
if xfFn := f.d.h.getExt(rtid); xfFn != nil {
|
|
||||||
f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
|
f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -240,6 +329,7 @@ func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperDecoder) StringView(v []byte) string {
|
//
|
||||||
return stringView(v)
|
// Deprecated: no longer used,
|
||||||
}
|
// but leave in-place so that old generated files continue to work without regeneration.
|
||||||
|
func (f genHelperDecoder) StringView(v []byte) string { return stringView(v) }
|
||||||
|
176
vendor/github.com/ugorji/go/codec/gen-helper.go.tmpl
generated
vendored
176
vendor/github.com/ugorji/go/codec/gen-helper.go.tmpl
generated
vendored
@ -3,10 +3,7 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// ************************************************************
|
// Code generated from gen-helper.go.tmpl - DO NOT EDIT.
|
||||||
// DO NOT EDIT.
|
|
||||||
// THIS FILE IS AUTO-GENERATED from gen-helper.go.tmpl
|
|
||||||
// ************************************************************
|
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
|
|
||||||
@ -31,25 +28,73 @@ const GenVersion = {{ .Version }}
|
|||||||
// GenHelperEncoder is exported so that it can be used externally by codecgen.
|
// GenHelperEncoder is exported so that it can be used externally by codecgen.
|
||||||
//
|
//
|
||||||
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
|
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
|
||||||
func GenHelperEncoder(e *Encoder) (genHelperEncoder, encDriver) {
|
func GenHelperEncoder(e *Encoder) (ge genHelperEncoder, ee genHelperEncDriver) {
|
||||||
return genHelperEncoder{e:e}, e.e
|
ge = genHelperEncoder{e: e}
|
||||||
|
ee = genHelperEncDriver{encDriver: e.e}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenHelperDecoder is exported so that it can be used externally by codecgen.
|
// GenHelperDecoder is exported so that it can be used externally by codecgen.
|
||||||
//
|
//
|
||||||
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
|
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
|
||||||
func GenHelperDecoder(d *Decoder) (genHelperDecoder, decDriver) {
|
func GenHelperDecoder(d *Decoder) (gd genHelperDecoder, dd genHelperDecDriver) {
|
||||||
return genHelperDecoder{d:d}, d.d
|
gd = genHelperDecoder{d: d}
|
||||||
|
dd = genHelperDecDriver{decDriver: d.d}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type genHelperEncDriver struct {
|
||||||
|
encDriver
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x genHelperEncDriver) EncodeBuiltin(rt uintptr, v interface{}) {}
|
||||||
|
func (x genHelperEncDriver) EncStructFieldKey(keyType valueType, s string) {
|
||||||
|
encStructFieldKey(x.encDriver, keyType, s)
|
||||||
|
}
|
||||||
|
func (x genHelperEncDriver) EncodeSymbol(s string) {
|
||||||
|
x.encDriver.EncodeString(cUTF8, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
type genHelperDecDriver struct {
|
||||||
|
decDriver
|
||||||
|
C checkOverflow
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x genHelperDecDriver) DecodeBuiltin(rt uintptr, v interface{}) {}
|
||||||
|
func (x genHelperDecDriver) DecStructFieldKey(keyType valueType, buf *[decScratchByteArrayLen]byte) []byte {
|
||||||
|
return decStructFieldKey(x.decDriver, keyType, buf)
|
||||||
|
}
|
||||||
|
func (x genHelperDecDriver) DecodeInt(bitsize uint8) (i int64) {
|
||||||
|
return x.C.IntV(x.decDriver.DecodeInt64(), bitsize)
|
||||||
|
}
|
||||||
|
func (x genHelperDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
|
||||||
|
return x.C.UintV(x.decDriver.DecodeUint64(), bitsize)
|
||||||
|
}
|
||||||
|
func (x genHelperDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
|
||||||
|
f = x.DecodeFloat64()
|
||||||
|
if chkOverflow32 && chkOvf.Float32(f) {
|
||||||
|
panicv.errorf("float32 overflow: %v", f)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (x genHelperDecDriver) DecodeFloat32As64() (f float64) {
|
||||||
|
f = x.DecodeFloat64()
|
||||||
|
if chkOvf.Float32(f) {
|
||||||
|
panicv.errorf("float32 overflow: %v", f)
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
type genHelperEncoder struct {
|
type genHelperEncoder struct {
|
||||||
|
M must
|
||||||
e *Encoder
|
e *Encoder
|
||||||
F fastpathT
|
F fastpathT
|
||||||
}
|
}
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
type genHelperDecoder struct {
|
type genHelperDecoder struct {
|
||||||
|
C checkOverflow
|
||||||
d *Decoder
|
d *Decoder
|
||||||
F fastpathT
|
F fastpathT
|
||||||
}
|
}
|
||||||
@ -58,10 +103,13 @@ type genHelperDecoder struct {
|
|||||||
func (f genHelperEncoder) EncBasicHandle() *BasicHandle {
|
func (f genHelperEncoder) EncBasicHandle() *BasicHandle {
|
||||||
return f.e.h
|
return f.e.h
|
||||||
}
|
}
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperEncoder) EncBinary() bool {
|
func (f genHelperEncoder) EncBinary() bool {
|
||||||
return f.e.cf.be // f.e.hh.isBinaryEncoding()
|
return f.e.be // f.e.hh.isBinaryEncoding()
|
||||||
|
}
|
||||||
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
func (f genHelperEncoder) IsJSONHandle() bool {
|
||||||
|
return f.e.js
|
||||||
}
|
}
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperEncoder) EncFallback(iv interface{}) {
|
func (f genHelperEncoder) EncFallback(iv interface{}) {
|
||||||
@ -72,45 +120,56 @@ func (f genHelperEncoder) EncFallback(iv interface{}) {
|
|||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) {
|
func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) {
|
||||||
bs, fnerr := iv.MarshalText()
|
bs, fnerr := iv.MarshalText()
|
||||||
f.e.marshal(bs, fnerr, false, c_UTF8)
|
f.e.marshal(bs, fnerr, false, cUTF8)
|
||||||
}
|
}
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) {
|
func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) {
|
||||||
bs, fnerr := iv.MarshalJSON()
|
bs, fnerr := iv.MarshalJSON()
|
||||||
f.e.marshal(bs, fnerr, true, c_UTF8)
|
f.e.marshal(bs, fnerr, true, cUTF8)
|
||||||
}
|
}
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) {
|
func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) {
|
||||||
bs, fnerr := iv.MarshalBinary()
|
bs, fnerr := iv.MarshalBinary()
|
||||||
f.e.marshal(bs, fnerr, false, c_RAW)
|
f.e.marshal(bs, fnerr, false, cRAW)
|
||||||
}
|
}
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperEncoder) EncRaw(iv Raw) {
|
func (f genHelperEncoder) EncRaw(iv Raw) { f.e.rawBytes(iv) }
|
||||||
f.e.rawBytes(iv)
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
//
|
||||||
|
// Deprecated: builtin no longer supported - so we make this method a no-op,
|
||||||
|
// but leave in-place so that old generated files continue to work without regeneration.
|
||||||
|
func (f genHelperEncoder) TimeRtidIfBinc() (v uintptr) { return }
|
||||||
|
// func (f genHelperEncoder) TimeRtidIfBinc() uintptr {
|
||||||
|
// if _, ok := f.e.hh.(*BincHandle); ok {
|
||||||
|
// return timeTypId
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
func (f genHelperEncoder) I2Rtid(v interface{}) uintptr {
|
||||||
|
return i2rtid(v)
|
||||||
}
|
}
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperEncoder) TimeRtidIfBinc() uintptr {
|
func (f genHelperEncoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
|
||||||
if _, ok := f.e.hh.(*BincHandle); ok {
|
return f.e.h.getExt(rtid)
|
||||||
return timeTypId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperEncoder) IsJSONHandle() bool {
|
func (f genHelperEncoder) EncExtension(v interface{}, xfFn *extTypeTagFn) {
|
||||||
return f.e.cf.js
|
f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
|
||||||
}
|
}
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
//
|
||||||
|
// Deprecated: No longer used,
|
||||||
|
// but leave in-place so that old generated files continue to work without regeneration.
|
||||||
func (f genHelperEncoder) HasExtensions() bool {
|
func (f genHelperEncoder) HasExtensions() bool {
|
||||||
return len(f.e.h.extHandle) != 0
|
return len(f.e.h.extHandle) != 0
|
||||||
}
|
}
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
//
|
||||||
|
// Deprecated: No longer used,
|
||||||
|
// but leave in-place so that old generated files continue to work without regeneration.
|
||||||
func (f genHelperEncoder) EncExt(v interface{}) (r bool) {
|
func (f genHelperEncoder) EncExt(v interface{}) (r bool) {
|
||||||
rt := reflect.TypeOf(v)
|
if xfFn := f.e.h.getExt(i2rtid(v)); xfFn != nil {
|
||||||
if rt.Kind() == reflect.Ptr {
|
|
||||||
rt = rt.Elem()
|
|
||||||
}
|
|
||||||
rtid := rt2id(rt)
|
|
||||||
if xfFn := f.e.h.getExt(rtid); xfFn != nil {
|
|
||||||
f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
|
f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -128,21 +187,23 @@ func (f genHelperDecoder) DecBinary() bool {
|
|||||||
return f.d.be // f.d.hh.isBinaryEncoding()
|
return f.d.be // f.d.hh.isBinaryEncoding()
|
||||||
}
|
}
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperDecoder) DecSwallow() {
|
func (f genHelperDecoder) DecSwallow() { f.d.swallow() }
|
||||||
f.d.swallow()
|
|
||||||
}
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperDecoder) DecScratchBuffer() []byte {
|
func (f genHelperDecoder) DecScratchBuffer() []byte {
|
||||||
return f.d.b[:]
|
return f.d.b[:]
|
||||||
}
|
}
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
func (f genHelperDecoder) DecScratchArrayBuffer() *[decScratchByteArrayLen]byte {
|
||||||
|
return &f.d.b
|
||||||
|
}
|
||||||
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
|
func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
|
||||||
// println(">>>>>>>>> DecFallback")
|
// println(">>>>>>>>> DecFallback")
|
||||||
rv := reflect.ValueOf(iv)
|
rv := reflect.ValueOf(iv)
|
||||||
if chkPtr {
|
if chkPtr {
|
||||||
rv = f.d.ensureDecodeable(rv)
|
rv = f.d.ensureDecodeable(rv)
|
||||||
}
|
}
|
||||||
f.d.decodeValue(rv, nil, false, false)
|
f.d.decodeValue(rv, nil, false)
|
||||||
// f.d.decodeValueFallback(rv)
|
// f.d.decodeValueFallback(rv)
|
||||||
}
|
}
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
@ -181,29 +242,49 @@ func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperDecoder) DecRaw() []byte {
|
func (f genHelperDecoder) DecRaw() []byte { return f.d.rawBytes() }
|
||||||
return f.d.rawBytes()
|
|
||||||
}
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperDecoder) TimeRtidIfBinc() uintptr {
|
//
|
||||||
if _, ok := f.d.hh.(*BincHandle); ok {
|
// Deprecated: builtin no longer supported - so we make this method a no-op,
|
||||||
return timeTypId
|
// but leave in-place so that old generated files continue to work without regeneration.
|
||||||
}
|
func (f genHelperDecoder) TimeRtidIfBinc() (v uintptr) { return }
|
||||||
return 0
|
// func (f genHelperDecoder) TimeRtidIfBinc() uintptr {
|
||||||
}
|
// // Note: builtin is no longer supported - so make this a no-op
|
||||||
|
// if _, ok := f.d.hh.(*BincHandle); ok {
|
||||||
|
// return timeTypId
|
||||||
|
// }
|
||||||
|
// return 0
|
||||||
|
// }
|
||||||
|
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperDecoder) IsJSONHandle() bool {
|
func (f genHelperDecoder) IsJSONHandle() bool {
|
||||||
return f.d.js
|
return f.d.js
|
||||||
}
|
}
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
func (f genHelperDecoder) I2Rtid(v interface{}) uintptr {
|
||||||
|
return i2rtid(v)
|
||||||
|
}
|
||||||
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
func (f genHelperDecoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
|
||||||
|
return f.d.h.getExt(rtid)
|
||||||
|
}
|
||||||
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
func (f genHelperDecoder) DecExtension(v interface{}, xfFn *extTypeTagFn) {
|
||||||
|
f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
|
||||||
|
}
|
||||||
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
//
|
||||||
|
// Deprecated: No longer used,
|
||||||
|
// but leave in-place so that old generated files continue to work without regeneration.
|
||||||
func (f genHelperDecoder) HasExtensions() bool {
|
func (f genHelperDecoder) HasExtensions() bool {
|
||||||
return len(f.d.h.extHandle) != 0
|
return len(f.d.h.extHandle) != 0
|
||||||
}
|
}
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
|
//
|
||||||
|
// Deprecated: No longer used,
|
||||||
|
// but leave in-place so that old generated files continue to work without regeneration.
|
||||||
func (f genHelperDecoder) DecExt(v interface{}) (r bool) {
|
func (f genHelperDecoder) DecExt(v interface{}) (r bool) {
|
||||||
rt := reflect.TypeOf(v).Elem()
|
if xfFn := f.d.h.getExt(i2rtid(v)); xfFn != nil {
|
||||||
rtid := rt2id(rt)
|
|
||||||
if xfFn := f.d.h.getExt(rtid); xfFn != nil {
|
|
||||||
f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
|
f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -214,7 +295,8 @@ func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int) {
|
|||||||
return decInferLen(clen, maxlen, unit)
|
return decInferLen(clen, maxlen, unit)
|
||||||
}
|
}
|
||||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||||
func (f genHelperDecoder) StringView(v []byte) string {
|
//
|
||||||
return stringView(v)
|
// Deprecated: no longer used,
|
||||||
}
|
// but leave in-place so that old generated files continue to work without regeneration.
|
||||||
|
func (f genHelperDecoder) StringView(v []byte) string { return stringView(v) }
|
||||||
|
|
||||||
|
5
vendor/github.com/ugorji/go/codec/gen.generated.go
generated
vendored
5
vendor/github.com/ugorji/go/codec/gen.generated.go
generated
vendored
@ -1,3 +1,5 @@
|
|||||||
|
// +build codecgen.exec
|
||||||
|
|
||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
@ -96,7 +98,7 @@ if {{var "l"}} == 0 {
|
|||||||
{{var "c"}} = true
|
{{var "c"}} = true
|
||||||
}{{end}}
|
}{{end}}
|
||||||
{{var "h"}}.ElemContainerState({{var "j"}})
|
{{var "h"}}.ElemContainerState({{var "j"}})
|
||||||
// {{var "dn"}} = r.TryDecodeAsNil()
|
{{/* {{var "dn"}} = r.TryDecodeAsNil() */}}
|
||||||
{{if isChan}}{{ $x := printf "%[1]vv%[2]v" .TempVar .Rand }}var {{var $x}} {{ .Typ }}
|
{{if isChan}}{{ $x := printf "%[1]vv%[2]v" .TempVar .Rand }}var {{var $x}} {{ .Typ }}
|
||||||
{{ decLineVar $x }}
|
{{ decLineVar $x }}
|
||||||
{{var "v"}} <- {{ $x }}
|
{{var "v"}} <- {{ $x }}
|
||||||
@ -129,4 +131,3 @@ if {{var "l"}} == 0 {
|
|||||||
}{{end}}
|
}{{end}}
|
||||||
|
|
||||||
`
|
`
|
||||||
|
|
||||||
|
899
vendor/github.com/ugorji/go/codec/gen.go
generated
vendored
899
vendor/github.com/ugorji/go/codec/gen.go
generated
vendored
File diff suppressed because it is too large
Load Diff
2
vendor/github.com/ugorji/go/codec/goversion_arrayof_gte_go15.go
generated
vendored
2
vendor/github.com/ugorji/go/codec/goversion_arrayof_gte_go15.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// +build go1.5
|
// +build go1.5
|
||||||
|
2
vendor/github.com/ugorji/go/codec/goversion_arrayof_lt_go15.go
generated
vendored
2
vendor/github.com/ugorji/go/codec/goversion_arrayof_lt_go15.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// +build !go1.5
|
// +build !go1.5
|
||||||
|
2
vendor/github.com/ugorji/go/codec/goversion_makemap_gte_go19.go
generated
vendored
2
vendor/github.com/ugorji/go/codec/goversion_makemap_gte_go19.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// +build go1.9
|
// +build go1.9
|
||||||
|
2
vendor/github.com/ugorji/go/codec/goversion_makemap_lt_go19.go
generated
vendored
2
vendor/github.com/ugorji/go/codec/goversion_makemap_lt_go19.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// +build !go1.9
|
// +build !go1.9
|
||||||
|
8
vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_gte_go110.go
generated
vendored
Normal file
8
vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_gte_go110.go
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build go1.10
|
||||||
|
|
||||||
|
package codec
|
||||||
|
|
||||||
|
const allowSetUnexportedEmbeddedPtr = false
|
8
vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_lt_go110.go
generated
vendored
Normal file
8
vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_lt_go110.go
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !go1.10
|
||||||
|
|
||||||
|
package codec
|
||||||
|
|
||||||
|
const allowSetUnexportedEmbeddedPtr = true
|
2
vendor/github.com/ugorji/go/codec/goversion_unsupported_lt_go14.go
generated
vendored
2
vendor/github.com/ugorji/go/codec/goversion_unsupported_lt_go14.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// +build !go1.4
|
// +build !go1.4
|
||||||
|
2
vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go15.go
generated
vendored
2
vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go15.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// +build go1.5,!go1.6
|
// +build go1.5,!go1.6
|
||||||
|
2
vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go16.go
generated
vendored
2
vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go16.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// +build go1.6,!go1.7
|
// +build go1.6,!go1.7
|
||||||
|
2
vendor/github.com/ugorji/go/codec/goversion_vendor_gte_go17.go
generated
vendored
2
vendor/github.com/ugorji/go/codec/goversion_vendor_gte_go17.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// +build go1.7
|
// +build go1.7
|
||||||
|
2
vendor/github.com/ugorji/go/codec/goversion_vendor_lt_go15.go
generated
vendored
2
vendor/github.com/ugorji/go/codec/goversion_vendor_lt_go15.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// +build !go1.5
|
// +build !go1.5
|
||||||
|
1496
vendor/github.com/ugorji/go/codec/helper.go
generated
vendored
1496
vendor/github.com/ugorji/go/codec/helper.go
generated
vendored
File diff suppressed because it is too large
Load Diff
74
vendor/github.com/ugorji/go/codec/helper_internal.go
generated
vendored
74
vendor/github.com/ugorji/go/codec/helper_internal.go
generated
vendored
@ -6,73 +6,6 @@ package codec
|
|||||||
// All non-std package dependencies live in this file,
|
// All non-std package dependencies live in this file,
|
||||||
// so porting to different environment is easy (just update functions).
|
// so porting to different environment is easy (just update functions).
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
func panicValToErr(panicVal interface{}, err *error) {
|
|
||||||
if panicVal == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// case nil
|
|
||||||
switch xerr := panicVal.(type) {
|
|
||||||
case error:
|
|
||||||
*err = xerr
|
|
||||||
case string:
|
|
||||||
*err = errors.New(xerr)
|
|
||||||
default:
|
|
||||||
*err = fmt.Errorf("%v", panicVal)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func hIsEmptyValue(v reflect.Value, deref, checkStruct bool) bool {
|
|
||||||
switch v.Kind() {
|
|
||||||
case reflect.Invalid:
|
|
||||||
return true
|
|
||||||
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
|
|
||||||
return v.Len() == 0
|
|
||||||
case reflect.Bool:
|
|
||||||
return !v.Bool()
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
return v.Int() == 0
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
||||||
return v.Uint() == 0
|
|
||||||
case reflect.Float32, reflect.Float64:
|
|
||||||
return v.Float() == 0
|
|
||||||
case reflect.Interface, reflect.Ptr:
|
|
||||||
if deref {
|
|
||||||
if v.IsNil() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return hIsEmptyValue(v.Elem(), deref, checkStruct)
|
|
||||||
} else {
|
|
||||||
return v.IsNil()
|
|
||||||
}
|
|
||||||
case reflect.Struct:
|
|
||||||
if !checkStruct {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// return true if all fields are empty. else return false.
|
|
||||||
// we cannot use equality check, because some fields may be maps/slices/etc
|
|
||||||
// and consequently the structs are not comparable.
|
|
||||||
// return v.Interface() == reflect.Zero(v.Type()).Interface()
|
|
||||||
for i, n := 0, v.NumField(); i < n; i++ {
|
|
||||||
if !hIsEmptyValue(v.Field(i), deref, checkStruct) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func isEmptyValue(v reflect.Value, deref, checkStruct bool) bool {
|
|
||||||
return hIsEmptyValue(v, deref, checkStruct)
|
|
||||||
}
|
|
||||||
|
|
||||||
func pruneSignExt(v []byte, pos bool) (n int) {
|
func pruneSignExt(v []byte, pos bool) (n int) {
|
||||||
if len(v) < 2 {
|
if len(v) < 2 {
|
||||||
} else if pos && v[0] == 0 {
|
} else if pos && v[0] == 0 {
|
||||||
@ -97,7 +30,8 @@ func halfFloatToFloatBits(yy uint16) (d uint32) {
|
|||||||
if e == 0 {
|
if e == 0 {
|
||||||
if m == 0 { // plu or minus 0
|
if m == 0 { // plu or minus 0
|
||||||
return s << 31
|
return s << 31
|
||||||
} else { // Denormalized number -- renormalize it
|
}
|
||||||
|
// Denormalized number -- renormalize it
|
||||||
for (m & 0x00000400) == 0 {
|
for (m & 0x00000400) == 0 {
|
||||||
m <<= 1
|
m <<= 1
|
||||||
e -= 1
|
e -= 1
|
||||||
@ -105,13 +39,11 @@ func halfFloatToFloatBits(yy uint16) (d uint32) {
|
|||||||
e += 1
|
e += 1
|
||||||
const zz uint32 = 0x0400
|
const zz uint32 = 0x0400
|
||||||
m &= ^zz
|
m &= ^zz
|
||||||
}
|
|
||||||
} else if e == 31 {
|
} else if e == 31 {
|
||||||
if m == 0 { // Inf
|
if m == 0 { // Inf
|
||||||
return (s << 31) | 0x7f800000
|
return (s << 31) | 0x7f800000
|
||||||
} else { // NaN
|
|
||||||
return (s << 31) | 0x7f800000 | (m << 13)
|
|
||||||
}
|
}
|
||||||
|
return (s << 31) | 0x7f800000 | (m << 13) // NaN
|
||||||
}
|
}
|
||||||
e = e + (127 - 15)
|
e = e + (127 - 15)
|
||||||
m = m << 13
|
m = m << 13
|
||||||
|
132
vendor/github.com/ugorji/go/codec/helper_not_unsafe.go
generated
vendored
132
vendor/github.com/ugorji/go/codec/helper_not_unsafe.go
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
// +build !go1.7 safe appengine
|
// +build !go1.7 safe appengine
|
||||||
|
|
||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
@ -8,6 +8,7 @@ package codec
|
|||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const safeMode = true
|
const safeMode = true
|
||||||
@ -34,29 +35,10 @@ func bytesView(v string) []byte {
|
|||||||
|
|
||||||
func definitelyNil(v interface{}) bool {
|
func definitelyNil(v interface{}) bool {
|
||||||
// this is a best-effort option.
|
// this is a best-effort option.
|
||||||
// We just return false, so we don't unneessarily incur the cost of reflection this early.
|
// We just return false, so we don't unnecessarily incur the cost of reflection this early.
|
||||||
return false
|
return false
|
||||||
// rv := reflect.ValueOf(v)
|
|
||||||
// switch rv.Kind() {
|
|
||||||
// case reflect.Invalid:
|
|
||||||
// return true
|
|
||||||
// case reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Slice, reflect.Map, reflect.Func:
|
|
||||||
// return rv.IsNil()
|
|
||||||
// default:
|
|
||||||
// return false
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// // keepAlive4BytesView maintains a reference to the input parameter for bytesView.
|
|
||||||
// //
|
|
||||||
// // Usage: call this at point where done with the bytes view.
|
|
||||||
// func keepAlive4BytesView(v string) {}
|
|
||||||
|
|
||||||
// // keepAlive4BytesView maintains a reference to the input parameter for stringView.
|
|
||||||
// //
|
|
||||||
// // Usage: call this at point where done with the string view.
|
|
||||||
// func keepAlive4StringView(v []byte) {}
|
|
||||||
|
|
||||||
func rv2i(rv reflect.Value) interface{} {
|
func rv2i(rv reflect.Value) interface{} {
|
||||||
return rv.Interface()
|
return rv.Interface()
|
||||||
}
|
}
|
||||||
@ -69,28 +51,62 @@ func rv2rtid(rv reflect.Value) uintptr {
|
|||||||
return reflect.ValueOf(rv.Type()).Pointer()
|
return reflect.ValueOf(rv.Type()).Pointer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func i2rtid(i interface{}) uintptr {
|
||||||
|
return reflect.ValueOf(reflect.TypeOf(i)).Pointer()
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------
|
||||||
|
|
||||||
|
func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Invalid:
|
||||||
|
return true
|
||||||
|
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
|
||||||
|
return v.Len() == 0
|
||||||
|
case reflect.Bool:
|
||||||
|
return !v.Bool()
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return v.Int() == 0
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
return v.Uint() == 0
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return v.Float() == 0
|
||||||
|
case reflect.Interface, reflect.Ptr:
|
||||||
|
if deref {
|
||||||
|
if v.IsNil() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
|
||||||
|
}
|
||||||
|
return v.IsNil()
|
||||||
|
case reflect.Struct:
|
||||||
|
return isEmptyStruct(v, tinfos, deref, checkStruct)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------------
|
// --------------------------
|
||||||
// type ptrToRvMap struct{}
|
// type ptrToRvMap struct{}
|
||||||
|
|
||||||
// func (_ *ptrToRvMap) init() {}
|
// func (*ptrToRvMap) init() {}
|
||||||
// func (_ *ptrToRvMap) get(i interface{}) reflect.Value {
|
// func (*ptrToRvMap) get(i interface{}) reflect.Value {
|
||||||
// return reflect.ValueOf(i).Elem()
|
// return reflect.ValueOf(i).Elem()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// --------------------------
|
// --------------------------
|
||||||
type atomicTypeInfoSlice struct {
|
type atomicTypeInfoSlice struct { // expected to be 2 words
|
||||||
v atomic.Value
|
v atomic.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *atomicTypeInfoSlice) load() *[]rtid2ti {
|
func (x *atomicTypeInfoSlice) load() []rtid2ti {
|
||||||
i := x.v.Load()
|
i := x.v.Load()
|
||||||
if i == nil {
|
if i == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return i.(*[]rtid2ti)
|
return i.([]rtid2ti)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *atomicTypeInfoSlice) store(p *[]rtid2ti) {
|
func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
|
||||||
x.v.Store(p)
|
x.v.Store(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,56 +123,64 @@ func (d *Decoder) kBool(f *codecFnInfo, rv reflect.Value) {
|
|||||||
rv.SetBool(d.d.DecodeBool())
|
rv.SetBool(d.d.DecodeBool())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Decoder) kTime(f *codecFnInfo, rv reflect.Value) {
|
||||||
|
rv.Set(reflect.ValueOf(d.d.DecodeTime()))
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
|
||||||
rv.SetFloat(d.d.DecodeFloat(true))
|
fv := d.d.DecodeFloat64()
|
||||||
|
if chkOvf.Float32(fv) {
|
||||||
|
d.errorf("float32 overflow: %v", fv)
|
||||||
|
}
|
||||||
|
rv.SetFloat(fv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
|
||||||
rv.SetFloat(d.d.DecodeFloat(false))
|
rv.SetFloat(d.d.DecodeFloat64())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) {
|
||||||
rv.SetInt(d.d.DecodeInt(intBitsize))
|
rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) {
|
||||||
rv.SetInt(d.d.DecodeInt(8))
|
rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 8))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) {
|
||||||
rv.SetInt(d.d.DecodeInt(16))
|
rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 16))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) {
|
||||||
rv.SetInt(d.d.DecodeInt(32))
|
rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 32))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) {
|
||||||
rv.SetInt(d.d.DecodeInt(64))
|
rv.SetInt(d.d.DecodeInt64())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) {
|
||||||
rv.SetUint(d.d.DecodeUint(uintBitsize))
|
rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
|
||||||
rv.SetUint(d.d.DecodeUint(uintBitsize))
|
rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) {
|
||||||
rv.SetUint(d.d.DecodeUint(8))
|
rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 8))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) {
|
||||||
rv.SetUint(d.d.DecodeUint(16))
|
rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 16))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) {
|
||||||
rv.SetUint(d.d.DecodeUint(32))
|
rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 32))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) {
|
||||||
rv.SetUint(d.d.DecodeUint(64))
|
rv.SetUint(d.d.DecodeUint64())
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------
|
// ----------------
|
||||||
@ -165,8 +189,12 @@ func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) {
|
|||||||
e.e.EncodeBool(rv.Bool())
|
e.e.EncodeBool(rv.Bool())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
|
||||||
|
e.e.EncodeTime(rv2i(rv).(time.Time))
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
|
func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
|
||||||
e.e.EncodeString(c_UTF8, rv.String())
|
e.e.EncodeString(cUTF8, rv.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
|
func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
|
||||||
@ -220,3 +248,25 @@ func (e *Encoder) kUint64(f *codecFnInfo, rv reflect.Value) {
|
|||||||
func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
|
func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
|
||||||
e.e.EncodeUint(rv.Uint())
|
e.e.EncodeUint(rv.Uint())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// // keepAlive4BytesView maintains a reference to the input parameter for bytesView.
|
||||||
|
// //
|
||||||
|
// // Usage: call this at point where done with the bytes view.
|
||||||
|
// func keepAlive4BytesView(v string) {}
|
||||||
|
|
||||||
|
// // keepAlive4BytesView maintains a reference to the input parameter for stringView.
|
||||||
|
// //
|
||||||
|
// // Usage: call this at point where done with the string view.
|
||||||
|
// func keepAlive4StringView(v []byte) {}
|
||||||
|
|
||||||
|
// func definitelyNil(v interface{}) bool {
|
||||||
|
// rv := reflect.ValueOf(v)
|
||||||
|
// switch rv.Kind() {
|
||||||
|
// case reflect.Invalid:
|
||||||
|
// return true
|
||||||
|
// case reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Slice, reflect.Map, reflect.Func:
|
||||||
|
// return rv.IsNil()
|
||||||
|
// default:
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
244
vendor/github.com/ugorji/go/codec/helper_unsafe.go
generated
vendored
244
vendor/github.com/ugorji/go/codec/helper_unsafe.go
generated
vendored
@ -2,7 +2,7 @@
|
|||||||
// +build !appengine
|
// +build !appengine
|
||||||
// +build go1.7
|
// +build go1.7
|
||||||
|
|
||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
@ -10,6 +10,7 @@ package codec
|
|||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -22,12 +23,12 @@ const safeMode = false
|
|||||||
const unsafeFlagIndir = 1 << 7 // keep in sync with GO_ROOT/src/reflect/value.go
|
const unsafeFlagIndir = 1 << 7 // keep in sync with GO_ROOT/src/reflect/value.go
|
||||||
|
|
||||||
type unsafeString struct {
|
type unsafeString struct {
|
||||||
Data uintptr
|
Data unsafe.Pointer
|
||||||
Len int
|
Len int
|
||||||
}
|
}
|
||||||
|
|
||||||
type unsafeSlice struct {
|
type unsafeSlice struct {
|
||||||
Data uintptr
|
Data unsafe.Pointer
|
||||||
Len int
|
Len int
|
||||||
Cap int
|
Cap int
|
||||||
}
|
}
|
||||||
@ -47,20 +48,16 @@ func stringView(v []byte) string {
|
|||||||
if len(v) == 0 {
|
if len(v) == 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
bx := (*unsafeSlice)(unsafe.Pointer(&v))
|
bx := (*unsafeSlice)(unsafe.Pointer(&v))
|
||||||
sx := unsafeString{bx.Data, bx.Len}
|
return *(*string)(unsafe.Pointer(&unsafeString{bx.Data, bx.Len}))
|
||||||
return *(*string)(unsafe.Pointer(&sx))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func bytesView(v string) []byte {
|
func bytesView(v string) []byte {
|
||||||
if len(v) == 0 {
|
if len(v) == 0 {
|
||||||
return zeroByteSlice
|
return zeroByteSlice
|
||||||
}
|
}
|
||||||
|
|
||||||
sx := (*unsafeString)(unsafe.Pointer(&v))
|
sx := (*unsafeString)(unsafe.Pointer(&v))
|
||||||
bx := unsafeSlice{sx.Data, sx.Len, sx.Len}
|
return *(*[]byte)(unsafe.Pointer(&unsafeSlice{sx.Data, sx.Len, sx.Len}))
|
||||||
return *(*[]byte)(unsafe.Pointer(&bx))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func definitelyNil(v interface{}) bool {
|
func definitelyNil(v interface{}) bool {
|
||||||
@ -68,41 +65,32 @@ func definitelyNil(v interface{}) bool {
|
|||||||
// For true references (map, ptr, func, chan), you can just look
|
// For true references (map, ptr, func, chan), you can just look
|
||||||
// at the word of the interface. However, for slices, you have to dereference
|
// at the word of the interface. However, for slices, you have to dereference
|
||||||
// the word, and get a pointer to the 3-word interface value.
|
// the word, and get a pointer to the 3-word interface value.
|
||||||
|
//
|
||||||
|
// However, the following are cheap calls
|
||||||
|
// - TypeOf(interface): cheap 2-line call.
|
||||||
|
// - ValueOf(interface{}): expensive
|
||||||
|
// - type.Kind: cheap call through an interface
|
||||||
|
// - Value.Type(): cheap call
|
||||||
|
// except it's a method value (e.g. r.Read, which implies that it is a Func)
|
||||||
|
|
||||||
// var ui *unsafeIntf = (*unsafeIntf)(unsafe.Pointer(&v))
|
|
||||||
// var word unsafe.Pointer = ui.word
|
|
||||||
// // fmt.Printf(">>>> definitely nil: isnil: %v, TYPE: \t%T, word: %v, *word: %v, type: %v, nil: %v\n", v == nil, v, word, *((*unsafe.Pointer)(word)), ui.typ, nil)
|
|
||||||
// return word == nil // || *((*unsafe.Pointer)(word)) == nil
|
|
||||||
return ((*unsafeIntf)(unsafe.Pointer(&v))).word == nil
|
return ((*unsafeIntf)(unsafe.Pointer(&v))).word == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// func keepAlive4BytesView(v string) {
|
|
||||||
// runtime.KeepAlive(v)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func keepAlive4StringView(v []byte) {
|
|
||||||
// runtime.KeepAlive(v)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// TODO: consider a more generally-known optimization for reflect.Value ==> Interface
|
|
||||||
//
|
|
||||||
// Currently, we use this fragile method that taps into implememtation details from
|
|
||||||
// the source go stdlib reflect/value.go,
|
|
||||||
// and trims the implementation.
|
|
||||||
func rv2i(rv reflect.Value) interface{} {
|
func rv2i(rv reflect.Value) interface{} {
|
||||||
|
// TODO: consider a more generally-known optimization for reflect.Value ==> Interface
|
||||||
|
//
|
||||||
|
// Currently, we use this fragile method that taps into implememtation details from
|
||||||
|
// the source go stdlib reflect/value.go, and trims the implementation.
|
||||||
|
|
||||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
// true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
|
// true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
|
||||||
var ptr unsafe.Pointer
|
var ptr unsafe.Pointer
|
||||||
// kk := reflect.Kind(urv.flag & (1<<5 - 1))
|
|
||||||
// if (kk == reflect.Map || kk == reflect.Ptr || kk == reflect.Chan || kk == reflect.Func) && urv.flag&unsafeFlagIndir != 0 {
|
|
||||||
if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
|
if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
|
||||||
ptr = *(*unsafe.Pointer)(urv.ptr)
|
ptr = *(*unsafe.Pointer)(urv.ptr)
|
||||||
} else {
|
} else {
|
||||||
ptr = urv.ptr
|
ptr = urv.ptr
|
||||||
}
|
}
|
||||||
return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
|
return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
|
||||||
// return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
|
|
||||||
// return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func rt2id(rt reflect.Type) uintptr {
|
func rt2id(rt reflect.Type) uintptr {
|
||||||
@ -113,32 +101,104 @@ func rv2rtid(rv reflect.Value) uintptr {
|
|||||||
return uintptr((*unsafeReflectValue)(unsafe.Pointer(&rv)).typ)
|
return uintptr((*unsafeReflectValue)(unsafe.Pointer(&rv)).typ)
|
||||||
}
|
}
|
||||||
|
|
||||||
// func rv0t(rt reflect.Type) reflect.Value {
|
func i2rtid(i interface{}) uintptr {
|
||||||
// ut := (*unsafeIntf)(unsafe.Pointer(&rt))
|
return uintptr(((*unsafeIntf)(unsafe.Pointer(&i))).typ)
|
||||||
// // we need to determine whether ifaceIndir, and then whether to just pass 0 as the ptr
|
}
|
||||||
// uv := unsafeReflectValue{ut.word, &zeroRTv, flag(rt.Kind())}
|
|
||||||
// return *(*reflect.Value)(unsafe.Pointer(&uv})
|
|
||||||
// }
|
|
||||||
|
|
||||||
// --------------------------
|
// --------------------------
|
||||||
type atomicTypeInfoSlice struct {
|
|
||||||
v unsafe.Pointer
|
func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
|
||||||
|
urv := (*unsafeReflectValue)(unsafe.Pointer(&v))
|
||||||
|
if urv.flag == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Invalid:
|
||||||
|
return true
|
||||||
|
case reflect.String:
|
||||||
|
return (*unsafeString)(urv.ptr).Len == 0
|
||||||
|
case reflect.Slice:
|
||||||
|
return (*unsafeSlice)(urv.ptr).Len == 0
|
||||||
|
case reflect.Bool:
|
||||||
|
return !*(*bool)(urv.ptr)
|
||||||
|
case reflect.Int:
|
||||||
|
return *(*int)(urv.ptr) == 0
|
||||||
|
case reflect.Int8:
|
||||||
|
return *(*int8)(urv.ptr) == 0
|
||||||
|
case reflect.Int16:
|
||||||
|
return *(*int16)(urv.ptr) == 0
|
||||||
|
case reflect.Int32:
|
||||||
|
return *(*int32)(urv.ptr) == 0
|
||||||
|
case reflect.Int64:
|
||||||
|
return *(*int64)(urv.ptr) == 0
|
||||||
|
case reflect.Uint:
|
||||||
|
return *(*uint)(urv.ptr) == 0
|
||||||
|
case reflect.Uint8:
|
||||||
|
return *(*uint8)(urv.ptr) == 0
|
||||||
|
case reflect.Uint16:
|
||||||
|
return *(*uint16)(urv.ptr) == 0
|
||||||
|
case reflect.Uint32:
|
||||||
|
return *(*uint32)(urv.ptr) == 0
|
||||||
|
case reflect.Uint64:
|
||||||
|
return *(*uint64)(urv.ptr) == 0
|
||||||
|
case reflect.Uintptr:
|
||||||
|
return *(*uintptr)(urv.ptr) == 0
|
||||||
|
case reflect.Float32:
|
||||||
|
return *(*float32)(urv.ptr) == 0
|
||||||
|
case reflect.Float64:
|
||||||
|
return *(*float64)(urv.ptr) == 0
|
||||||
|
case reflect.Interface:
|
||||||
|
isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
|
||||||
|
if deref {
|
||||||
|
if isnil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
|
||||||
|
}
|
||||||
|
return isnil
|
||||||
|
case reflect.Ptr:
|
||||||
|
isnil := urv.ptr == nil
|
||||||
|
if deref {
|
||||||
|
if isnil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
|
||||||
|
}
|
||||||
|
return isnil
|
||||||
|
case reflect.Struct:
|
||||||
|
return isEmptyStruct(v, tinfos, deref, checkStruct)
|
||||||
|
case reflect.Map, reflect.Array, reflect.Chan:
|
||||||
|
return v.Len() == 0
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *atomicTypeInfoSlice) load() *[]rtid2ti {
|
// --------------------------
|
||||||
return (*[]rtid2ti)(atomic.LoadPointer(&x.v))
|
|
||||||
|
type atomicTypeInfoSlice struct { // expected to be 2 words
|
||||||
|
v unsafe.Pointer // data array - Pointer (not uintptr) to maintain GC reference
|
||||||
|
l int64 // length of the data array
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *atomicTypeInfoSlice) store(p *[]rtid2ti) {
|
func (x *atomicTypeInfoSlice) load() []rtid2ti {
|
||||||
atomic.StorePointer(&x.v, unsafe.Pointer(p))
|
l := int(atomic.LoadInt64(&x.l))
|
||||||
|
if l == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return *(*[]rtid2ti)(unsafe.Pointer(&unsafeSlice{Data: atomic.LoadPointer(&x.v), Len: l, Cap: l}))
|
||||||
|
// return (*[]rtid2ti)(atomic.LoadPointer(&x.v))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
|
||||||
|
s := (*unsafeSlice)(unsafe.Pointer(&p))
|
||||||
|
atomic.StorePointer(&x.v, s.Data)
|
||||||
|
atomic.StoreInt64(&x.l, int64(s.Len))
|
||||||
|
// atomic.StorePointer(&x.v, unsafe.Pointer(p))
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------
|
// --------------------------
|
||||||
func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
|
||||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
// if urv.flag&unsafeFlagIndir != 0 {
|
|
||||||
// urv.ptr = *(*unsafe.Pointer)(urv.ptr)
|
|
||||||
// }
|
|
||||||
*(*[]byte)(urv.ptr) = d.rawBytes()
|
*(*[]byte)(urv.ptr) = d.rawBytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,69 +212,78 @@ func (d *Decoder) kBool(f *codecFnInfo, rv reflect.Value) {
|
|||||||
*(*bool)(urv.ptr) = d.d.DecodeBool()
|
*(*bool)(urv.ptr) = d.d.DecodeBool()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kTime(f *codecFnInfo, rv reflect.Value) {
|
||||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
*(*float32)(urv.ptr) = float32(d.d.DecodeFloat(true))
|
*(*time.Time)(urv.ptr) = d.d.DecodeTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
|
||||||
|
fv := d.d.DecodeFloat64()
|
||||||
|
if chkOvf.Float32(fv) {
|
||||||
|
d.errorf("float32 overflow: %v", fv)
|
||||||
|
}
|
||||||
|
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
|
*(*float32)(urv.ptr) = float32(fv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
|
||||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
*(*float64)(urv.ptr) = d.d.DecodeFloat(false)
|
*(*float64)(urv.ptr) = d.d.DecodeFloat64()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) {
|
||||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
*(*int)(urv.ptr) = int(d.d.DecodeInt(intBitsize))
|
*(*int)(urv.ptr) = int(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) {
|
||||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
*(*int8)(urv.ptr) = int8(d.d.DecodeInt(8))
|
*(*int8)(urv.ptr) = int8(chkOvf.IntV(d.d.DecodeInt64(), 8))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) {
|
||||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
*(*int16)(urv.ptr) = int16(d.d.DecodeInt(16))
|
*(*int16)(urv.ptr) = int16(chkOvf.IntV(d.d.DecodeInt64(), 16))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) {
|
||||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
*(*int32)(urv.ptr) = int32(d.d.DecodeInt(32))
|
*(*int32)(urv.ptr) = int32(chkOvf.IntV(d.d.DecodeInt64(), 32))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) {
|
||||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
*(*int64)(urv.ptr) = d.d.DecodeInt(64)
|
*(*int64)(urv.ptr) = d.d.DecodeInt64()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) {
|
||||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
*(*uint)(urv.ptr) = uint(d.d.DecodeUint(uintBitsize))
|
*(*uint)(urv.ptr) = uint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
|
||||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
*(*uintptr)(urv.ptr) = uintptr(d.d.DecodeUint(uintBitsize))
|
*(*uintptr)(urv.ptr) = uintptr(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) {
|
||||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
*(*uint8)(urv.ptr) = uint8(d.d.DecodeUint(8))
|
*(*uint8)(urv.ptr) = uint8(chkOvf.UintV(d.d.DecodeUint64(), 8))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) {
|
||||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
*(*uint16)(urv.ptr) = uint16(d.d.DecodeUint(16))
|
*(*uint16)(urv.ptr) = uint16(chkOvf.UintV(d.d.DecodeUint64(), 16))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) {
|
||||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
*(*uint32)(urv.ptr) = uint32(d.d.DecodeUint(32))
|
*(*uint32)(urv.ptr) = uint32(chkOvf.UintV(d.d.DecodeUint64(), 32))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) {
|
func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) {
|
||||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
*(*uint64)(urv.ptr) = d.d.DecodeUint(64)
|
*(*uint64)(urv.ptr) = d.d.DecodeUint64()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------
|
// ------------
|
||||||
@ -224,9 +293,14 @@ func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) {
|
|||||||
e.e.EncodeBool(*(*bool)(v.ptr))
|
e.e.EncodeBool(*(*bool)(v.ptr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
|
||||||
|
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
|
e.e.EncodeTime(*(*time.Time)(v.ptr))
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
|
func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
|
||||||
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
e.e.EncodeString(c_UTF8, *(*string)(v.ptr))
|
e.e.EncodeString(cUTF8, *(*string)(v.ptr))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
|
func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
|
||||||
@ -296,6 +370,56 @@ func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
|
|||||||
|
|
||||||
// ------------
|
// ------------
|
||||||
|
|
||||||
|
// func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
|
||||||
|
// urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
|
// // if urv.flag&unsafeFlagIndir != 0 {
|
||||||
|
// // urv.ptr = *(*unsafe.Pointer)(urv.ptr)
|
||||||
|
// // }
|
||||||
|
// *(*[]byte)(urv.ptr) = d.rawBytes()
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func rv0t(rt reflect.Type) reflect.Value {
|
||||||
|
// ut := (*unsafeIntf)(unsafe.Pointer(&rt))
|
||||||
|
// // we need to determine whether ifaceIndir, and then whether to just pass 0 as the ptr
|
||||||
|
// uv := unsafeReflectValue{ut.word, &zeroRTv, flag(rt.Kind())}
|
||||||
|
// return *(*reflect.Value)(unsafe.Pointer(&uv})
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func rv2i(rv reflect.Value) interface{} {
|
||||||
|
// urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||||
|
// // true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
|
||||||
|
// var ptr unsafe.Pointer
|
||||||
|
// // kk := reflect.Kind(urv.flag & (1<<5 - 1))
|
||||||
|
// // if (kk == reflect.Map || kk == reflect.Ptr || kk == reflect.Chan || kk == reflect.Func) && urv.flag&unsafeFlagIndir != 0 {
|
||||||
|
// if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
|
||||||
|
// ptr = *(*unsafe.Pointer)(urv.ptr)
|
||||||
|
// } else {
|
||||||
|
// ptr = urv.ptr
|
||||||
|
// }
|
||||||
|
// return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
|
||||||
|
// // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
|
||||||
|
// // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func definitelyNil(v interface{}) bool {
|
||||||
|
// var ui *unsafeIntf = (*unsafeIntf)(unsafe.Pointer(&v))
|
||||||
|
// if ui.word == nil {
|
||||||
|
// return true
|
||||||
|
// }
|
||||||
|
// var tk = reflect.TypeOf(v).Kind()
|
||||||
|
// return (tk == reflect.Interface || tk == reflect.Slice) && *(*unsafe.Pointer)(ui.word) == nil
|
||||||
|
// fmt.Printf(">>>> definitely nil: isnil: %v, TYPE: \t%T, word: %v, *word: %v, type: %v, nil: %v\n",
|
||||||
|
// v == nil, v, word, *((*unsafe.Pointer)(word)), ui.typ, nil)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func keepAlive4BytesView(v string) {
|
||||||
|
// runtime.KeepAlive(v)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func keepAlive4StringView(v []byte) {
|
||||||
|
// runtime.KeepAlive(v)
|
||||||
|
// }
|
||||||
|
|
||||||
// func rt2id(rt reflect.Type) uintptr {
|
// func rt2id(rt reflect.Type) uintptr {
|
||||||
// return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
|
// return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
|
||||||
// // var i interface{} = rt
|
// // var i interface{} = rt
|
||||||
|
889
vendor/github.com/ugorji/go/codec/json.go
generated
vendored
889
vendor/github.com/ugorji/go/codec/json.go
generated
vendored
File diff suppressed because it is too large
Load Diff
88
vendor/github.com/ugorji/go/codec/mammoth-test.go.tmpl
generated
vendored
88
vendor/github.com/ugorji/go/codec/mammoth-test.go.tmpl
generated
vendored
@ -1,15 +1,13 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// ************************************************************
|
// Code generated from mammoth-test.go.tmpl - DO NOT EDIT.
|
||||||
// DO NOT EDIT.
|
|
||||||
// THIS FILE IS AUTO-GENERATED from mammoth-test.go.tmpl
|
|
||||||
// ************************************************************
|
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
|
|
||||||
import "testing"
|
import "testing"
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
// TestMammoth has all the different paths optimized in fast-path
|
// TestMammoth has all the different paths optimized in fast-path
|
||||||
// It has all the primitives, slices and maps.
|
// It has all the primitives, slices and maps.
|
||||||
@ -38,36 +36,78 @@ type TestMammoth struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{{range .Values }}{{if not .Primitive }}{{if not .MapKey }}{{/*
|
{{range .Values }}{{if not .Primitive }}{{if not .MapKey }}{{/*
|
||||||
*/}} type {{ .MethodNamePfx "type" false }} []{{ .Elem }}
|
*/}} type {{ .MethodNamePfx "typMbs" false }} []{{ .Elem }}
|
||||||
func (_ {{ .MethodNamePfx "type" false }}) MapBySlice() { }
|
func (_ {{ .MethodNamePfx "typMbs" false }}) MapBySlice() { }
|
||||||
|
{{end}}{{end}}{{end}}
|
||||||
|
|
||||||
|
{{range .Values }}{{if not .Primitive }}{{if .MapKey }}{{/*
|
||||||
|
*/}} type {{ .MethodNamePfx "typMap" false }} map[{{ .MapKey }}]{{ .Elem }}
|
||||||
{{end}}{{end}}{{end}}
|
{{end}}{{end}}{{end}}
|
||||||
|
|
||||||
func doTestMammothSlices(t *testing.T, h Handle) {
|
func doTestMammothSlices(t *testing.T, h Handle) {
|
||||||
{{range $i, $e := .Values }}{{if not .Primitive }}{{if not .MapKey }}{{/*
|
{{range $i, $e := .Values }}{{if not .Primitive }}{{if not .MapKey }}{{/*
|
||||||
*/}}
|
*/}}
|
||||||
for _, v := range [][]{{ .Elem }}{ nil, []{{ .Elem }}{}, []{{ .Elem }}{ {{ nonzerocmd .Elem }}, {{ nonzerocmd .Elem }} } } {
|
var v{{$i}}va [8]{{ .Elem }}
|
||||||
|
for _, v := range [][]{{ .Elem }}{ nil, {}, { {{ nonzerocmd .Elem }}, {{ zerocmd .Elem }}, {{ zerocmd .Elem }}, {{ nonzerocmd .Elem }} } } { {{/*
|
||||||
// fmt.Printf(">>>> running mammoth slice v{{$i}}: %v\n", v)
|
// fmt.Printf(">>>> running mammoth slice v{{$i}}: %v\n", v)
|
||||||
var v{{$i}}v1, v{{$i}}v2, v{{$i}}v3, v{{$i}}v4 []{{ .Elem }}
|
// - encode value to some []byte
|
||||||
|
// - decode into a length-wise-equal []byte
|
||||||
|
// - check if equal to initial slice
|
||||||
|
// - encode ptr to the value
|
||||||
|
// - check if encode bytes are same
|
||||||
|
// - decode into ptrs to: nil, then 1-elem slice, equal-length, then large len slice
|
||||||
|
// - decode into non-addressable slice of equal length, then larger len
|
||||||
|
// - for each decode, compare elem-by-elem to the original slice
|
||||||
|
// -
|
||||||
|
// - rinse and repeat for a MapBySlice version
|
||||||
|
// -
|
||||||
|
*/}}
|
||||||
|
var v{{$i}}v1, v{{$i}}v2 []{{ .Elem }}
|
||||||
v{{$i}}v1 = v
|
v{{$i}}v1 = v
|
||||||
bs{{$i}} := testMarshalErr(v{{$i}}v1, h, t, "enc-slice-v{{$i}}")
|
bs{{$i}} := testMarshalErr(v{{$i}}v1, h, t, "enc-slice-v{{$i}}")
|
||||||
if v != nil { v{{$i}}v2 = make([]{{ .Elem }}, len(v)) }
|
if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make([]{{ .Elem }}, len(v)) }
|
||||||
testUnmarshalErr(v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}")
|
testUnmarshalErr(v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}")
|
||||||
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}")
|
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}")
|
||||||
|
if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make([]{{ .Elem }}, len(v)) }
|
||||||
|
testUnmarshalErr(reflect.ValueOf(v{{$i}}v2), bs{{$i}}, h, t, "dec-slice-v{{$i}}-noaddr") // non-addressable value
|
||||||
|
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-noaddr")
|
||||||
|
// ...
|
||||||
bs{{$i}} = testMarshalErr(&v{{$i}}v1, h, t, "enc-slice-v{{$i}}-p")
|
bs{{$i}} = testMarshalErr(&v{{$i}}v1, h, t, "enc-slice-v{{$i}}-p")
|
||||||
v{{$i}}v2 = nil
|
v{{$i}}v2 = nil
|
||||||
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p")
|
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p")
|
||||||
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p")
|
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p")
|
||||||
|
v{{$i}}va = [8]{{ .Elem }}{} // clear the array
|
||||||
|
v{{$i}}v2 = v{{$i}}va[:1:1]
|
||||||
|
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-1")
|
||||||
|
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p-1")
|
||||||
|
v{{$i}}va = [8]{{ .Elem }}{} // clear the array
|
||||||
|
v{{$i}}v2 = v{{$i}}va[:len(v{{$i}}v1):len(v{{$i}}v1)]
|
||||||
|
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-len")
|
||||||
|
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p-len")
|
||||||
|
v{{$i}}va = [8]{{ .Elem }}{} // clear the array
|
||||||
|
v{{$i}}v2 = v{{$i}}va[:]
|
||||||
|
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-cap")
|
||||||
|
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p-cap")
|
||||||
|
if len(v{{$i}}v1) > 1 {
|
||||||
|
v{{$i}}va = [8]{{ .Elem }}{} // clear the array
|
||||||
|
testUnmarshalErr((&v{{$i}}va)[:len(v{{$i}}v1)], bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-len-noaddr")
|
||||||
|
testDeepEqualErr(v{{$i}}v1, v{{$i}}va[:len(v{{$i}}v1)], t, "equal-slice-v{{$i}}-p-len-noaddr")
|
||||||
|
v{{$i}}va = [8]{{ .Elem }}{} // clear the array
|
||||||
|
testUnmarshalErr((&v{{$i}}va)[:], bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-cap-noaddr")
|
||||||
|
testDeepEqualErr(v{{$i}}v1, v{{$i}}va[:len(v{{$i}}v1)], t, "equal-slice-v{{$i}}-p-cap-noaddr")
|
||||||
|
}
|
||||||
// ...
|
// ...
|
||||||
|
var v{{$i}}v3, v{{$i}}v4 {{ .MethodNamePfx "typMbs" false }}
|
||||||
v{{$i}}v2 = nil
|
v{{$i}}v2 = nil
|
||||||
if v != nil { v{{$i}}v2 = make([]{{ .Elem }}, len(v)) }
|
if v != nil { v{{$i}}v2 = make([]{{ .Elem }}, len(v)) }
|
||||||
v{{$i}}v3 = {{ .MethodNamePfx "type" false }}(v{{$i}}v1)
|
v{{$i}}v3 = {{ .MethodNamePfx "typMbs" false }}(v{{$i}}v1)
|
||||||
|
v{{$i}}v4 = {{ .MethodNamePfx "typMbs" false }}(v{{$i}}v2)
|
||||||
bs{{$i}} = testMarshalErr(v{{$i}}v3, h, t, "enc-slice-v{{$i}}-custom")
|
bs{{$i}} = testMarshalErr(v{{$i}}v3, h, t, "enc-slice-v{{$i}}-custom")
|
||||||
v{{$i}}v4 = {{ .MethodNamePfx "type" false }}(v{{$i}}v2)
|
|
||||||
testUnmarshalErr(v{{$i}}v4, bs{{$i}}, h, t, "dec-slice-v{{$i}}-custom")
|
testUnmarshalErr(v{{$i}}v4, bs{{$i}}, h, t, "dec-slice-v{{$i}}-custom")
|
||||||
testDeepEqualErr(v{{$i}}v3, v{{$i}}v4, t, "equal-slice-v{{$i}}-custom")
|
testDeepEqualErr(v{{$i}}v3, v{{$i}}v4, t, "equal-slice-v{{$i}}-custom")
|
||||||
v{{$i}}v2 = nil
|
|
||||||
bs{{$i}} = testMarshalErr(&v{{$i}}v3, h, t, "enc-slice-v{{$i}}-custom-p")
|
bs{{$i}} = testMarshalErr(&v{{$i}}v3, h, t, "enc-slice-v{{$i}}-custom-p")
|
||||||
v{{$i}}v4 = {{ .MethodNamePfx "type" false }}(v{{$i}}v2)
|
v{{$i}}v2 = nil
|
||||||
|
v{{$i}}v4 = {{ .MethodNamePfx "typMbs" false }}(v{{$i}}v2)
|
||||||
testUnmarshalErr(&v{{$i}}v4, bs{{$i}}, h, t, "dec-slice-v{{$i}}-custom-p")
|
testUnmarshalErr(&v{{$i}}v4, bs{{$i}}, h, t, "dec-slice-v{{$i}}-custom-p")
|
||||||
testDeepEqualErr(v{{$i}}v3, v{{$i}}v4, t, "equal-slice-v{{$i}}-custom-p")
|
testDeepEqualErr(v{{$i}}v3, v{{$i}}v4, t, "equal-slice-v{{$i}}-custom-p")
|
||||||
}
|
}
|
||||||
@ -77,18 +117,32 @@ func doTestMammothSlices(t *testing.T, h Handle) {
|
|||||||
func doTestMammothMaps(t *testing.T, h Handle) {
|
func doTestMammothMaps(t *testing.T, h Handle) {
|
||||||
{{range $i, $e := .Values }}{{if not .Primitive }}{{if .MapKey }}{{/*
|
{{range $i, $e := .Values }}{{if not .Primitive }}{{if .MapKey }}{{/*
|
||||||
*/}}
|
*/}}
|
||||||
for _, v := range []map[{{ .MapKey }}]{{ .Elem }}{ nil, map[{{ .MapKey }}]{{ .Elem }}{}, map[{{ .MapKey }}]{{ .Elem }}{ {{ nonzerocmd .MapKey }}:{{ nonzerocmd .Elem }} } } {
|
for _, v := range []map[{{ .MapKey }}]{{ .Elem }}{ nil, {}, { {{ nonzerocmd .MapKey }}:{{ zerocmd .Elem }} {{if ne "bool" .MapKey}}, {{ nonzerocmd .MapKey }}:{{ nonzerocmd .Elem }} {{end}} } } {
|
||||||
// fmt.Printf(">>>> running mammoth map v{{$i}}: %v\n", v)
|
// fmt.Printf(">>>> running mammoth map v{{$i}}: %v\n", v)
|
||||||
var v{{$i}}v1, v{{$i}}v2 map[{{ .MapKey }}]{{ .Elem }}
|
var v{{$i}}v1, v{{$i}}v2 map[{{ .MapKey }}]{{ .Elem }}
|
||||||
v{{$i}}v1 = v
|
v{{$i}}v1 = v
|
||||||
bs{{$i}} := testMarshalErr(v{{$i}}v1, h, t, "enc-map-v{{$i}}")
|
bs{{$i}} := testMarshalErr(v{{$i}}v1, h, t, "enc-map-v{{$i}}")
|
||||||
if v != nil { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) }
|
if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
|
||||||
testUnmarshalErr(v{{$i}}v2, bs{{$i}}, h, t, "dec-map-v{{$i}}")
|
testUnmarshalErr(v{{$i}}v2, bs{{$i}}, h, t, "dec-map-v{{$i}}")
|
||||||
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}")
|
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}")
|
||||||
|
if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
|
||||||
|
testUnmarshalErr(reflect.ValueOf(v{{$i}}v2), bs{{$i}}, h, t, "dec-map-v{{$i}}-noaddr") // decode into non-addressable map value
|
||||||
|
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}-noaddr")
|
||||||
|
if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
|
||||||
|
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-map-v{{$i}}-p-len")
|
||||||
|
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}-p-len")
|
||||||
bs{{$i}} = testMarshalErr(&v{{$i}}v1, h, t, "enc-map-v{{$i}}-p")
|
bs{{$i}} = testMarshalErr(&v{{$i}}v1, h, t, "enc-map-v{{$i}}-p")
|
||||||
v{{$i}}v2 = nil
|
v{{$i}}v2 = nil
|
||||||
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-map-v{{$i}}-p")
|
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-map-v{{$i}}-p-nil")
|
||||||
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}-p")
|
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}-p-nil")
|
||||||
|
// ...
|
||||||
|
if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
|
||||||
|
var v{{$i}}v3, v{{$i}}v4 {{ .MethodNamePfx "typMap" false }}
|
||||||
|
v{{$i}}v3 = {{ .MethodNamePfx "typMap" false }}(v{{$i}}v1)
|
||||||
|
v{{$i}}v4 = {{ .MethodNamePfx "typMap" false }}(v{{$i}}v2)
|
||||||
|
bs{{$i}} = testMarshalErr(v{{$i}}v3, h, t, "enc-map-v{{$i}}-custom")
|
||||||
|
testUnmarshalErr(v{{$i}}v4, bs{{$i}}, h, t, "dec-map-v{{$i}}-p-len")
|
||||||
|
testDeepEqualErr(v{{$i}}v3, v{{$i}}v4, t, "equal-map-v{{$i}}-p-len")
|
||||||
}
|
}
|
||||||
{{end}}{{end}}{{end}}
|
{{end}}{{end}}{{end}}
|
||||||
|
|
||||||
|
5
vendor/github.com/ugorji/go/codec/mammoth2-test.go.tmpl
generated
vendored
5
vendor/github.com/ugorji/go/codec/mammoth2-test.go.tmpl
generated
vendored
@ -3,10 +3,7 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// ************************************************************
|
// Code generated from mammoth2-test.go.tmpl - DO NOT EDIT.
|
||||||
// DO NOT EDIT.
|
|
||||||
// THIS FILE IS AUTO-GENERATED from mammoth2-test.go.tmpl
|
|
||||||
// ************************************************************
|
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
|
|
||||||
|
23089
vendor/github.com/ugorji/go/codec/mammoth2_codecgen_generated_test.go
generated
vendored
23089
vendor/github.com/ugorji/go/codec/mammoth2_codecgen_generated_test.go
generated
vendored
File diff suppressed because it is too large
Load Diff
7
vendor/github.com/ugorji/go/codec/mammoth2_generated_test.go
generated
vendored
7
vendor/github.com/ugorji/go/codec/mammoth2_generated_test.go
generated
vendored
@ -3,10 +3,7 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// ************************************************************
|
// Code generated from mammoth2-test.go.tmpl - DO NOT EDIT.
|
||||||
// DO NOT EDIT.
|
|
||||||
// THIS FILE IS AUTO-GENERATED from mammoth2-test.go.tmpl
|
|
||||||
// ************************************************************
|
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
|
|
||||||
@ -74,6 +71,8 @@ type TestMammoth2 struct {
|
|||||||
FptrSliceFloat64 *[]float64
|
FptrSliceFloat64 *[]float64
|
||||||
FSliceUint []uint
|
FSliceUint []uint
|
||||||
FptrSliceUint *[]uint
|
FptrSliceUint *[]uint
|
||||||
|
FSliceUint8 []uint8
|
||||||
|
FptrSliceUint8 *[]uint8
|
||||||
FSliceUint16 []uint16
|
FSliceUint16 []uint16
|
||||||
FptrSliceUint16 *[]uint16
|
FptrSliceUint16 *[]uint16
|
||||||
FSliceUint32 []uint32
|
FSliceUint32 []uint32
|
||||||
|
12046
vendor/github.com/ugorji/go/codec/mammoth_generated_test.go
generated
vendored
12046
vendor/github.com/ugorji/go/codec/mammoth_generated_test.go
generated
vendored
File diff suppressed because it is too large
Load Diff
235
vendor/github.com/ugorji/go/codec/msgpack.go
generated
vendored
235
vendor/github.com/ugorji/go/codec/msgpack.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -15,8 +15,8 @@ For compatibility with behaviour of msgpack-c reference implementation:
|
|||||||
- Go intX (<0)
|
- Go intX (<0)
|
||||||
IS ENCODED AS
|
IS ENCODED AS
|
||||||
msgpack -ve fixnum, signed
|
msgpack -ve fixnum, signed
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -25,6 +25,7 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"net/rpc"
|
"net/rpc"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -78,6 +79,9 @@ const (
|
|||||||
mpNegFixNumMax = 0xff
|
mpNegFixNumMax = 0xff
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var mpTimeExtTag int8 = -1
|
||||||
|
var mpTimeExtTagU = uint8(mpTimeExtTag)
|
||||||
|
|
||||||
// MsgpackSpecRpcMultiArgs is a special type which signifies to the MsgpackSpecRpcCodec
|
// MsgpackSpecRpcMultiArgs is a special type which signifies to the MsgpackSpecRpcCodec
|
||||||
// that the backend RPC service takes multiple arguments, which have been arranged
|
// that the backend RPC service takes multiple arguments, which have been arranged
|
||||||
// in sequence in the slice.
|
// in sequence in the slice.
|
||||||
@ -94,10 +98,18 @@ type msgpackContainerType struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
msgpackContainerStr = msgpackContainerType{32, mpFixStrMin, mpStr8, mpStr16, mpStr32, true, true, false}
|
msgpackContainerStr = msgpackContainerType{
|
||||||
msgpackContainerBin = msgpackContainerType{0, 0, mpBin8, mpBin16, mpBin32, false, true, true}
|
32, mpFixStrMin, mpStr8, mpStr16, mpStr32, true, true, false,
|
||||||
msgpackContainerList = msgpackContainerType{16, mpFixArrayMin, 0, mpArray16, mpArray32, true, false, false}
|
}
|
||||||
msgpackContainerMap = msgpackContainerType{16, mpFixMapMin, 0, mpMap16, mpMap32, true, false, false}
|
msgpackContainerBin = msgpackContainerType{
|
||||||
|
0, 0, mpBin8, mpBin16, mpBin32, false, true, true,
|
||||||
|
}
|
||||||
|
msgpackContainerList = msgpackContainerType{
|
||||||
|
16, mpFixArrayMin, 0, mpArray16, mpArray32, true, false, false,
|
||||||
|
}
|
||||||
|
msgpackContainerMap = msgpackContainerType{
|
||||||
|
16, mpFixMapMin, 0, mpMap16, mpMap32, true, false, false,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
//---------------------------------------------
|
//---------------------------------------------
|
||||||
@ -110,6 +122,7 @@ type msgpackEncDriver struct {
|
|||||||
w encWriter
|
w encWriter
|
||||||
h *MsgpackHandle
|
h *MsgpackHandle
|
||||||
x [8]byte
|
x [8]byte
|
||||||
|
_ [3]uint64 // padding
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *msgpackEncDriver) EncodeNil() {
|
func (e *msgpackEncDriver) EncodeNil() {
|
||||||
@ -190,6 +203,39 @@ func (e *msgpackEncDriver) EncodeFloat64(f float64) {
|
|||||||
bigenHelper{e.x[:8], e.w}.writeUint64(math.Float64bits(f))
|
bigenHelper{e.x[:8], e.w}.writeUint64(math.Float64bits(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *msgpackEncDriver) EncodeTime(t time.Time) {
|
||||||
|
if t.IsZero() {
|
||||||
|
e.EncodeNil()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t = t.UTC()
|
||||||
|
sec, nsec := t.Unix(), uint64(t.Nanosecond())
|
||||||
|
var data64 uint64
|
||||||
|
var l = 4
|
||||||
|
if sec >= 0 && sec>>34 == 0 {
|
||||||
|
data64 = (nsec << 34) | uint64(sec)
|
||||||
|
if data64&0xffffffff00000000 != 0 {
|
||||||
|
l = 8
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
l = 12
|
||||||
|
}
|
||||||
|
if e.h.WriteExt {
|
||||||
|
e.encodeExtPreamble(mpTimeExtTagU, l)
|
||||||
|
} else {
|
||||||
|
e.writeContainerLen(msgpackContainerStr, l)
|
||||||
|
}
|
||||||
|
switch l {
|
||||||
|
case 4:
|
||||||
|
bigenHelper{e.x[:4], e.w}.writeUint32(uint32(data64))
|
||||||
|
case 8:
|
||||||
|
bigenHelper{e.x[:8], e.w}.writeUint64(data64)
|
||||||
|
case 12:
|
||||||
|
bigenHelper{e.x[:4], e.w}.writeUint32(uint32(nsec))
|
||||||
|
bigenHelper{e.x[:8], e.w}.writeUint64(uint64(sec))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (e *msgpackEncDriver) EncodeExt(v interface{}, xtag uint64, ext Ext, _ *Encoder) {
|
func (e *msgpackEncDriver) EncodeExt(v interface{}, xtag uint64, ext Ext, _ *Encoder) {
|
||||||
bs := ext.WriteExt(v)
|
bs := ext.WriteExt(v)
|
||||||
if bs == nil {
|
if bs == nil {
|
||||||
@ -200,7 +246,7 @@ func (e *msgpackEncDriver) EncodeExt(v interface{}, xtag uint64, ext Ext, _ *Enc
|
|||||||
e.encodeExtPreamble(uint8(xtag), len(bs))
|
e.encodeExtPreamble(uint8(xtag), len(bs))
|
||||||
e.w.writeb(bs)
|
e.w.writeb(bs)
|
||||||
} else {
|
} else {
|
||||||
e.EncodeStringBytes(c_RAW, bs)
|
e.EncodeStringBytes(cRAW, bs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,7 +290,7 @@ func (e *msgpackEncDriver) WriteMapStart(length int) {
|
|||||||
|
|
||||||
func (e *msgpackEncDriver) EncodeString(c charEncoding, s string) {
|
func (e *msgpackEncDriver) EncodeString(c charEncoding, s string) {
|
||||||
slen := len(s)
|
slen := len(s)
|
||||||
if c == c_RAW && e.h.WriteExt {
|
if c == cRAW && e.h.WriteExt {
|
||||||
e.writeContainerLen(msgpackContainerBin, slen)
|
e.writeContainerLen(msgpackContainerBin, slen)
|
||||||
} else {
|
} else {
|
||||||
e.writeContainerLen(msgpackContainerStr, slen)
|
e.writeContainerLen(msgpackContainerStr, slen)
|
||||||
@ -254,13 +300,13 @@ func (e *msgpackEncDriver) EncodeString(c charEncoding, s string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *msgpackEncDriver) EncodeSymbol(v string) {
|
|
||||||
e.EncodeString(c_UTF8, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *msgpackEncDriver) EncodeStringBytes(c charEncoding, bs []byte) {
|
func (e *msgpackEncDriver) EncodeStringBytes(c charEncoding, bs []byte) {
|
||||||
|
if bs == nil {
|
||||||
|
e.EncodeNil()
|
||||||
|
return
|
||||||
|
}
|
||||||
slen := len(bs)
|
slen := len(bs)
|
||||||
if c == c_RAW && e.h.WriteExt {
|
if c == cRAW && e.h.WriteExt {
|
||||||
e.writeContainerLen(msgpackContainerBin, slen)
|
e.writeContainerLen(msgpackContainerBin, slen)
|
||||||
} else {
|
} else {
|
||||||
e.writeContainerLen(msgpackContainerStr, slen)
|
e.writeContainerLen(msgpackContainerStr, slen)
|
||||||
@ -290,7 +336,7 @@ type msgpackDecDriver struct {
|
|||||||
d *Decoder
|
d *Decoder
|
||||||
r decReader // *Decoder decReader decReaderT
|
r decReader // *Decoder decReader decReaderT
|
||||||
h *MsgpackHandle
|
h *MsgpackHandle
|
||||||
b [scratchByteArrayLen]byte
|
// b [scratchByteArrayLen]byte
|
||||||
bd byte
|
bd byte
|
||||||
bdRead bool
|
bdRead bool
|
||||||
br bool // bytes reader
|
br bool // bytes reader
|
||||||
@ -298,6 +344,7 @@ type msgpackDecDriver struct {
|
|||||||
// noStreamingCodec
|
// noStreamingCodec
|
||||||
// decNoSeparator
|
// decNoSeparator
|
||||||
decDriverNoopContainerReader
|
decDriverNoopContainerReader
|
||||||
|
_ [3]uint64 // padding
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: This returns either a primitive (int, bool, etc) for non-containers,
|
// Note: This returns either a primitive (int, bool, etc) for non-containers,
|
||||||
@ -388,7 +435,12 @@ func (d *msgpackDecDriver) DecodeNaked() {
|
|||||||
n.v = valueTypeExt
|
n.v = valueTypeExt
|
||||||
clen := d.readExtLen()
|
clen := d.readExtLen()
|
||||||
n.u = uint64(d.r.readn1())
|
n.u = uint64(d.r.readn1())
|
||||||
|
if n.u == uint64(mpTimeExtTagU) {
|
||||||
|
n.v = valueTypeTime
|
||||||
|
n.t = d.decodeTime(clen)
|
||||||
|
} else {
|
||||||
n.l = d.r.readx(clen)
|
n.l = d.r.readx(clen)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
d.d.errorf("Nil-Deciphered DecodeValue: %s: hex: %x, dec: %d", msgBadDesc, bd, bd)
|
d.d.errorf("Nil-Deciphered DecodeValue: %s: hex: %x, dec: %d", msgBadDesc, bd, bd)
|
||||||
}
|
}
|
||||||
@ -404,7 +456,7 @@ func (d *msgpackDecDriver) DecodeNaked() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// int can be decoded from msgpack type: intXXX or uintXXX
|
// int can be decoded from msgpack type: intXXX or uintXXX
|
||||||
func (d *msgpackDecDriver) DecodeInt(bitsize uint8) (i int64) {
|
func (d *msgpackDecDriver) DecodeInt64() (i int64) {
|
||||||
if !d.bdRead {
|
if !d.bdRead {
|
||||||
d.readNextBd()
|
d.readNextBd()
|
||||||
}
|
}
|
||||||
@ -436,19 +488,12 @@ func (d *msgpackDecDriver) DecodeInt(bitsize uint8) (i int64) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check overflow (logic adapted from std pkg reflect/value.go OverflowUint()
|
|
||||||
if bitsize > 0 {
|
|
||||||
if trunc := (i << (64 - bitsize)) >> (64 - bitsize); i != trunc {
|
|
||||||
d.d.errorf("Overflow int value: %v", i)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// uint can be decoded from msgpack type: intXXX or uintXXX
|
// uint can be decoded from msgpack type: intXXX or uintXXX
|
||||||
func (d *msgpackDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
|
func (d *msgpackDecDriver) DecodeUint64() (ui uint64) {
|
||||||
if !d.bdRead {
|
if !d.bdRead {
|
||||||
d.readNextBd()
|
d.readNextBd()
|
||||||
}
|
}
|
||||||
@ -501,19 +546,12 @@ func (d *msgpackDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check overflow (logic adapted from std pkg reflect/value.go OverflowUint()
|
|
||||||
if bitsize > 0 {
|
|
||||||
if trunc := (ui << (64 - bitsize)) >> (64 - bitsize); ui != trunc {
|
|
||||||
d.d.errorf("Overflow uint value: %v", ui)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// float can either be decoded from msgpack type: float, double or intX
|
// float can either be decoded from msgpack type: float, double or intX
|
||||||
func (d *msgpackDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
|
func (d *msgpackDecDriver) DecodeFloat64() (f float64) {
|
||||||
if !d.bdRead {
|
if !d.bdRead {
|
||||||
d.readNextBd()
|
d.readNextBd()
|
||||||
}
|
}
|
||||||
@ -522,11 +560,7 @@ func (d *msgpackDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
|
|||||||
} else if d.bd == mpDouble {
|
} else if d.bd == mpDouble {
|
||||||
f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
|
f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
|
||||||
} else {
|
} else {
|
||||||
f = float64(d.DecodeInt(0))
|
f = float64(d.DecodeInt64())
|
||||||
}
|
|
||||||
if chkOverflow32 && chkOvf.Float32(f) {
|
|
||||||
d.d.errorf("msgpack: float32 overflow: %v", f)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
return
|
return
|
||||||
@ -554,13 +588,15 @@ func (d *msgpackDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte)
|
|||||||
d.readNextBd()
|
d.readNextBd()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if an "array" of uint8's (see ContainerType for how to infer if an array)
|
||||||
|
bd := d.bd
|
||||||
// DecodeBytes could be from: bin str fixstr fixarray array ...
|
// DecodeBytes could be from: bin str fixstr fixarray array ...
|
||||||
var clen int
|
var clen int
|
||||||
vt := d.ContainerType()
|
vt := d.ContainerType()
|
||||||
switch vt {
|
switch vt {
|
||||||
case valueTypeBytes:
|
case valueTypeBytes:
|
||||||
// valueTypeBytes may be a mpBin or an mpStr container
|
// valueTypeBytes may be a mpBin or an mpStr container
|
||||||
if bd := d.bd; bd == mpBin8 || bd == mpBin16 || bd == mpBin32 {
|
if bd == mpBin8 || bd == mpBin16 || bd == mpBin32 {
|
||||||
clen = d.readContainerLen(msgpackContainerBin)
|
clen = d.readContainerLen(msgpackContainerBin)
|
||||||
} else {
|
} else {
|
||||||
clen = d.readContainerLen(msgpackContainerStr)
|
clen = d.readContainerLen(msgpackContainerStr)
|
||||||
@ -568,28 +604,17 @@ func (d *msgpackDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte)
|
|||||||
case valueTypeString:
|
case valueTypeString:
|
||||||
clen = d.readContainerLen(msgpackContainerStr)
|
clen = d.readContainerLen(msgpackContainerStr)
|
||||||
case valueTypeArray:
|
case valueTypeArray:
|
||||||
clen = d.readContainerLen(msgpackContainerList)
|
if zerocopy && len(bs) == 0 {
|
||||||
// ensure everything after is one byte each
|
bs = d.d.b[:]
|
||||||
for i := 0; i < clen; i++ {
|
}
|
||||||
d.readNextBd()
|
bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
|
||||||
if d.bd == mpNil {
|
|
||||||
bs = append(bs, 0)
|
|
||||||
} else if d.bd == mpUint8 {
|
|
||||||
bs = append(bs, d.r.readn1())
|
|
||||||
} else {
|
|
||||||
d.d.errorf("cannot read non-byte into a byte array")
|
|
||||||
return
|
return
|
||||||
}
|
|
||||||
}
|
|
||||||
d.bdRead = false
|
|
||||||
return bs
|
|
||||||
default:
|
default:
|
||||||
d.d.errorf("invalid container type: expecting bin|str|array")
|
d.d.errorf("invalid container type: expecting bin|str|array, got: 0x%x", uint8(vt))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// these are (bin|str)(8|16|32)
|
// these are (bin|str)(8|16|32)
|
||||||
// println("DecodeBytes: clen: ", clen)
|
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
// bytes may be nil, so handle it. if nil, clen=-1.
|
// bytes may be nil, so handle it. if nil, clen=-1.
|
||||||
if clen < 0 {
|
if clen < 0 {
|
||||||
@ -599,18 +624,18 @@ func (d *msgpackDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte)
|
|||||||
if d.br {
|
if d.br {
|
||||||
return d.r.readx(clen)
|
return d.r.readx(clen)
|
||||||
} else if len(bs) == 0 {
|
} else if len(bs) == 0 {
|
||||||
bs = d.b[:]
|
bs = d.d.b[:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return decByteSlice(d.r, clen, d.d.h.MaxInitLen, bs)
|
return decByteSlice(d.r, clen, d.h.MaxInitLen, bs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *msgpackDecDriver) DecodeString() (s string) {
|
func (d *msgpackDecDriver) DecodeString() (s string) {
|
||||||
return string(d.DecodeBytes(d.b[:], true))
|
return string(d.DecodeBytes(d.d.b[:], true))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *msgpackDecDriver) DecodeStringAsBytes() (s []byte) {
|
func (d *msgpackDecDriver) DecodeStringAsBytes() (s []byte) {
|
||||||
return d.DecodeBytes(d.b[:], true)
|
return d.DecodeBytes(d.d.b[:], true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *msgpackDecDriver) readNextBd() {
|
func (d *msgpackDecDriver) readNextBd() {
|
||||||
@ -643,9 +668,10 @@ func (d *msgpackDecDriver) ContainerType() (vt valueType) {
|
|||||||
return valueTypeArray
|
return valueTypeArray
|
||||||
} else if bd == mpMap16 || bd == mpMap32 || (bd >= mpFixMapMin && bd <= mpFixMapMax) {
|
} else if bd == mpMap16 || bd == mpMap32 || (bd >= mpFixMapMin && bd <= mpFixMapMax) {
|
||||||
return valueTypeMap
|
return valueTypeMap
|
||||||
} else {
|
|
||||||
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
|
|
||||||
}
|
}
|
||||||
|
// else {
|
||||||
|
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
|
||||||
|
// }
|
||||||
return valueTypeUnset
|
return valueTypeUnset
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,7 +681,7 @@ func (d *msgpackDecDriver) TryDecodeAsNil() (v bool) {
|
|||||||
}
|
}
|
||||||
if d.bd == mpNil {
|
if d.bd == mpNil {
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
v = true
|
return true
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -721,6 +747,57 @@ func (d *msgpackDecDriver) readExtLen() (clen int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *msgpackDecDriver) DecodeTime() (t time.Time) {
|
||||||
|
// decode time from string bytes or ext
|
||||||
|
if !d.bdRead {
|
||||||
|
d.readNextBd()
|
||||||
|
}
|
||||||
|
if d.bd == mpNil {
|
||||||
|
d.bdRead = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var clen int
|
||||||
|
switch d.ContainerType() {
|
||||||
|
case valueTypeBytes, valueTypeString:
|
||||||
|
clen = d.readContainerLen(msgpackContainerStr)
|
||||||
|
default:
|
||||||
|
// expect to see mpFixExt4,-1 OR mpFixExt8,-1 OR mpExt8,12,-1
|
||||||
|
d.bdRead = false
|
||||||
|
b2 := d.r.readn1()
|
||||||
|
if d.bd == mpFixExt4 && b2 == mpTimeExtTagU {
|
||||||
|
clen = 4
|
||||||
|
} else if d.bd == mpFixExt8 && b2 == mpTimeExtTagU {
|
||||||
|
clen = 8
|
||||||
|
} else if d.bd == mpExt8 && b2 == 12 && d.r.readn1() == mpTimeExtTagU {
|
||||||
|
clen = 12
|
||||||
|
} else {
|
||||||
|
d.d.errorf("invalid bytes for decoding time as extension: got 0x%x, 0x%x", d.bd, b2)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return d.decodeTime(clen)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *msgpackDecDriver) decodeTime(clen int) (t time.Time) {
|
||||||
|
// bs = d.r.readx(clen)
|
||||||
|
d.bdRead = false
|
||||||
|
switch clen {
|
||||||
|
case 4:
|
||||||
|
t = time.Unix(int64(bigen.Uint32(d.r.readx(4))), 0).UTC()
|
||||||
|
case 8:
|
||||||
|
tv := bigen.Uint64(d.r.readx(8))
|
||||||
|
t = time.Unix(int64(tv&0x00000003ffffffff), int64(tv>>34)).UTC()
|
||||||
|
case 12:
|
||||||
|
nsec := bigen.Uint32(d.r.readx(4))
|
||||||
|
sec := bigen.Uint64(d.r.readx(8))
|
||||||
|
t = time.Unix(int64(sec), int64(nsec)).UTC()
|
||||||
|
default:
|
||||||
|
d.d.errorf("invalid length of bytes for decoding time - expecting 4 or 8 or 12, got %d", clen)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (d *msgpackDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
|
func (d *msgpackDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
|
||||||
if xtag > 0xff {
|
if xtag > 0xff {
|
||||||
d.d.errorf("decodeExt: tag must be <= 0xff; got: %v", xtag)
|
d.d.errorf("decodeExt: tag must be <= 0xff; got: %v", xtag)
|
||||||
@ -784,12 +861,19 @@ type MsgpackHandle struct {
|
|||||||
// type is provided (e.g. decoding into a nil interface{}), you get back
|
// type is provided (e.g. decoding into a nil interface{}), you get back
|
||||||
// a []byte or string based on the setting of RawToString.
|
// a []byte or string based on the setting of RawToString.
|
||||||
WriteExt bool
|
WriteExt bool
|
||||||
|
|
||||||
binaryEncodingType
|
binaryEncodingType
|
||||||
noElemSeparators
|
noElemSeparators
|
||||||
|
|
||||||
|
_ [1]uint64 // padding
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name returns the name of the handle: msgpack
|
||||||
|
func (h *MsgpackHandle) Name() string { return "msgpack" }
|
||||||
|
|
||||||
|
// SetBytesExt sets an extension
|
||||||
func (h *MsgpackHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
|
func (h *MsgpackHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
|
||||||
return h.SetExt(rt, tag, &setExtWrapper{b: ext})
|
return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *MsgpackHandle) newEncDriver(e *Encoder) encDriver {
|
func (h *MsgpackHandle) newEncDriver(e *Encoder) encDriver {
|
||||||
@ -827,7 +911,7 @@ func (c *msgpackSpecRpcCodec) WriteRequest(r *rpc.Request, body interface{}) err
|
|||||||
bodyArr = []interface{}{body}
|
bodyArr = []interface{}{body}
|
||||||
}
|
}
|
||||||
r2 := []interface{}{0, uint32(r.Seq), r.ServiceMethod, bodyArr}
|
r2 := []interface{}{0, uint32(r.Seq), r.ServiceMethod, bodyArr}
|
||||||
return c.write(r2, nil, false, true)
|
return c.write(r2, nil, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *msgpackSpecRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error {
|
func (c *msgpackSpecRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error {
|
||||||
@ -839,7 +923,7 @@ func (c *msgpackSpecRpcCodec) WriteResponse(r *rpc.Response, body interface{}) e
|
|||||||
body = nil
|
body = nil
|
||||||
}
|
}
|
||||||
r2 := []interface{}{1, uint32(r.Seq), moe, body}
|
r2 := []interface{}{1, uint32(r.Seq), moe, body}
|
||||||
return c.write(r2, nil, false, true)
|
return c.write(r2, nil, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *msgpackSpecRpcCodec) ReadResponseHeader(r *rpc.Response) error {
|
func (c *msgpackSpecRpcCodec) ReadResponseHeader(r *rpc.Response) error {
|
||||||
@ -887,21 +971,19 @@ func (c *msgpackSpecRpcCodec) parseCustomHeader(expectTypeByte byte, msgid *uint
|
|||||||
var b = ba[0]
|
var b = ba[0]
|
||||||
if b != fia {
|
if b != fia {
|
||||||
err = fmt.Errorf("Unexpected value for array descriptor: Expecting %v. Received %v", fia, b)
|
err = fmt.Errorf("Unexpected value for array descriptor: Expecting %v. Received %v", fia, b)
|
||||||
return
|
} else {
|
||||||
}
|
err = c.read(&b)
|
||||||
|
if err == nil {
|
||||||
if err = c.read(&b); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if b != expectTypeByte {
|
if b != expectTypeByte {
|
||||||
err = fmt.Errorf("Unexpected byte descriptor in header. Expecting %v. Received %v", expectTypeByte, b)
|
err = fmt.Errorf("Unexpected byte descriptor. Expecting %v; Received %v",
|
||||||
return
|
expectTypeByte, b)
|
||||||
|
} else {
|
||||||
|
err = c.read(msgid)
|
||||||
|
if err == nil {
|
||||||
|
err = c.read(methodOrError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err = c.read(msgid); err != nil {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if err = c.read(methodOrError); err != nil {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -914,7 +996,8 @@ type msgpackSpecRpc struct{}
|
|||||||
|
|
||||||
// MsgpackSpecRpc implements Rpc using the communication protocol defined in
|
// MsgpackSpecRpc implements Rpc using the communication protocol defined in
|
||||||
// the msgpack spec at https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md .
|
// the msgpack spec at https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md .
|
||||||
// Its methods (ServerCodec and ClientCodec) return values that implement RpcCodecBuffered.
|
//
|
||||||
|
// See GoRpc documentation, for information on buffering for better performance.
|
||||||
var MsgpackSpecRpc msgpackSpecRpc
|
var MsgpackSpecRpc msgpackSpecRpc
|
||||||
|
|
||||||
func (x msgpackSpecRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {
|
func (x msgpackSpecRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {
|
||||||
|
17
vendor/github.com/ugorji/go/codec/noop.go
generated
vendored
17
vendor/github.com/ugorji/go/codec/noop.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// +build ignore
|
// +build ignore
|
||||||
@ -92,7 +92,8 @@ func (h *noopDrv) EncodeMapStart(length int) { h.start(false) }
|
|||||||
func (h *noopDrv) EncodeEnd() { h.end() }
|
func (h *noopDrv) EncodeEnd() { h.end() }
|
||||||
|
|
||||||
func (h *noopDrv) EncodeString(c charEncoding, v string) {}
|
func (h *noopDrv) EncodeString(c charEncoding, v string) {}
|
||||||
func (h *noopDrv) EncodeSymbol(v string) {}
|
|
||||||
|
// func (h *noopDrv) EncodeSymbol(v string) {}
|
||||||
func (h *noopDrv) EncodeStringBytes(c charEncoding, v []byte) {}
|
func (h *noopDrv) EncodeStringBytes(c charEncoding, v []byte) {}
|
||||||
|
|
||||||
func (h *noopDrv) EncodeExt(rv interface{}, xtag uint64, ext Ext, e *Encoder) {}
|
func (h *noopDrv) EncodeExt(rv interface{}, xtag uint64, ext Ext, e *Encoder) {}
|
||||||
@ -119,9 +120,12 @@ func (h *noopDrv) ReadArrayStart() int { h.start(false); return h.m(10) }
|
|||||||
|
|
||||||
func (h *noopDrv) ContainerType() (vt valueType) {
|
func (h *noopDrv) ContainerType() (vt valueType) {
|
||||||
// return h.m(2) == 0
|
// return h.m(2) == 0
|
||||||
// handle kStruct, which will bomb is it calls this and doesn't get back a map or array.
|
// handle kStruct, which will bomb is it calls this and
|
||||||
// consequently, if the return value is not map or array, reset it to one of them based on h.m(7) % 2
|
// doesn't get back a map or array.
|
||||||
// for kstruct: at least one out of every 2 times, return one of valueTypeMap or Array (else kstruct bombs)
|
// consequently, if the return value is not map or array,
|
||||||
|
// reset it to one of them based on h.m(7) % 2
|
||||||
|
// for kstruct: at least one out of every 2 times,
|
||||||
|
// return one of valueTypeMap or Array (else kstruct bombs)
|
||||||
// however, every 10th time it is called, we just return something else.
|
// however, every 10th time it is called, we just return something else.
|
||||||
var vals = [...]valueType{valueTypeArray, valueTypeMap}
|
var vals = [...]valueType{valueTypeArray, valueTypeMap}
|
||||||
// ------------ TAKE ------------
|
// ------------ TAKE ------------
|
||||||
@ -150,7 +154,8 @@ func (h *noopDrv) ContainerType() (vt valueType) {
|
|||||||
// }
|
// }
|
||||||
// return valueTypeUnset
|
// return valueTypeUnset
|
||||||
// TODO: may need to tweak this so it works.
|
// TODO: may need to tweak this so it works.
|
||||||
// if h.ct == valueTypeMap && vt == valueTypeArray || h.ct == valueTypeArray && vt == valueTypeMap {
|
// if h.ct == valueTypeMap && vt == valueTypeArray ||
|
||||||
|
// h.ct == valueTypeArray && vt == valueTypeMap {
|
||||||
// h.cb = !h.cb
|
// h.cb = !h.cb
|
||||||
// h.ct = vt
|
// h.ct = vt
|
||||||
// return h.cb
|
// return h.cb
|
||||||
|
2
vendor/github.com/ugorji/go/codec/py_test.go
generated
vendored
2
vendor/github.com/ugorji/go/codec/py_test.go
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
// +build x
|
// +build x
|
||||||
|
|
||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
|
168
vendor/github.com/ugorji/go/codec/rpc.go
generated
vendored
168
vendor/github.com/ugorji/go/codec/rpc.go
generated
vendored
@ -1,9 +1,10 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net/rpc"
|
"net/rpc"
|
||||||
@ -16,19 +17,14 @@ type Rpc interface {
|
|||||||
ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec
|
ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec
|
||||||
}
|
}
|
||||||
|
|
||||||
// // RpcCodecBuffered allows access to the underlying bufio.Reader/Writer
|
// RPCOptions holds options specific to rpc functionality
|
||||||
// // used by the rpc connection. It accommodates use-cases where the connection
|
type RPCOptions struct {
|
||||||
// // should be used by rpc and non-rpc functions, e.g. streaming a file after
|
// RPCNoBuffer configures whether we attempt to buffer reads and writes during RPC calls.
|
||||||
// // sending an rpc response.
|
//
|
||||||
// type RpcCodecBuffered interface {
|
// Set RPCNoBuffer=true to turn buffering off.
|
||||||
// BufferedReader() *bufio.Reader
|
// Buffering can still be done if buffered connections are passed in, or
|
||||||
// BufferedWriter() *bufio.Writer
|
// buffering is configured on the handle.
|
||||||
// }
|
RPCNoBuffer bool
|
||||||
|
|
||||||
// -------------------------------------
|
|
||||||
|
|
||||||
type rpcFlusher interface {
|
|
||||||
Flush() error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// rpcCodec defines the struct members and common methods.
|
// rpcCodec defines the struct members and common methods.
|
||||||
@ -36,7 +32,7 @@ type rpcCodec struct {
|
|||||||
c io.Closer
|
c io.Closer
|
||||||
r io.Reader
|
r io.Reader
|
||||||
w io.Writer
|
w io.Writer
|
||||||
f rpcFlusher
|
f ioFlusher
|
||||||
|
|
||||||
dec *Decoder
|
dec *Decoder
|
||||||
enc *Encoder
|
enc *Encoder
|
||||||
@ -47,6 +43,7 @@ type rpcCodec struct {
|
|||||||
|
|
||||||
cls bool
|
cls bool
|
||||||
clsmu sync.RWMutex
|
clsmu sync.RWMutex
|
||||||
|
clsErr error
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRPCCodec(conn io.ReadWriteCloser, h Handle) rpcCodec {
|
func newRPCCodec(conn io.ReadWriteCloser, h Handle) rpcCodec {
|
||||||
@ -59,7 +56,26 @@ func newRPCCodec2(r io.Reader, w io.Writer, c io.Closer, h Handle) rpcCodec {
|
|||||||
if jsonH, ok := h.(*JsonHandle); ok && !jsonH.TermWhitespace {
|
if jsonH, ok := h.(*JsonHandle); ok && !jsonH.TermWhitespace {
|
||||||
panic(errors.New("rpc requires a JsonHandle with TermWhitespace set to true"))
|
panic(errors.New("rpc requires a JsonHandle with TermWhitespace set to true"))
|
||||||
}
|
}
|
||||||
f, _ := w.(rpcFlusher)
|
// always ensure that we use a flusher, and always flush what was written to the connection.
|
||||||
|
// we lose nothing by using a buffered writer internally.
|
||||||
|
f, ok := w.(ioFlusher)
|
||||||
|
bh := h.getBasicHandle()
|
||||||
|
if !bh.RPCNoBuffer {
|
||||||
|
if bh.WriterBufferSize <= 0 {
|
||||||
|
if !ok {
|
||||||
|
bw := bufio.NewWriter(w)
|
||||||
|
f, w = bw, bw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if bh.ReaderBufferSize <= 0 {
|
||||||
|
if _, ok = w.(ioPeeker); !ok {
|
||||||
|
if _, ok = w.(ioBuffered); !ok {
|
||||||
|
br := bufio.NewReader(r)
|
||||||
|
r = br
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return rpcCodec{
|
return rpcCodec{
|
||||||
c: c,
|
c: c,
|
||||||
w: w,
|
w: w,
|
||||||
@ -71,66 +87,75 @@ func newRPCCodec2(r io.Reader, w io.Writer, c io.Closer, h Handle) rpcCodec {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (c *rpcCodec) BufferedReader() *bufio.Reader {
|
func (c *rpcCodec) write(obj1, obj2 interface{}, writeObj2 bool) (err error) {
|
||||||
// return c.br
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (c *rpcCodec) BufferedWriter() *bufio.Writer {
|
|
||||||
// return c.bw
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (c *rpcCodec) write(obj1, obj2 interface{}, writeObj2, doFlush bool) (err error) {
|
|
||||||
if c.isClosed() {
|
if c.isClosed() {
|
||||||
return io.EOF
|
return c.clsErr
|
||||||
}
|
|
||||||
if err = c.enc.Encode(obj1); err != nil {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
err = c.enc.Encode(obj1)
|
||||||
|
if err == nil {
|
||||||
if writeObj2 {
|
if writeObj2 {
|
||||||
if err = c.enc.Encode(obj2); err != nil {
|
err = c.enc.Encode(obj2)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
// if err == nil && c.f != nil {
|
||||||
|
// err = c.f.Flush()
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
if c.f != nil {
|
||||||
|
if err == nil {
|
||||||
|
err = c.f.Flush()
|
||||||
|
} else {
|
||||||
|
c.f.Flush()
|
||||||
}
|
}
|
||||||
if doFlush && c.f != nil {
|
|
||||||
return c.f.Flush()
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *rpcCodec) swallow(err *error) {
|
||||||
|
defer panicToErr(c.dec, err)
|
||||||
|
c.dec.swallow()
|
||||||
|
}
|
||||||
|
|
||||||
func (c *rpcCodec) read(obj interface{}) (err error) {
|
func (c *rpcCodec) read(obj interface{}) (err error) {
|
||||||
if c.isClosed() {
|
if c.isClosed() {
|
||||||
return io.EOF
|
return c.clsErr
|
||||||
}
|
}
|
||||||
//If nil is passed in, we should still attempt to read content to nowhere.
|
//If nil is passed in, we should read and discard
|
||||||
if obj == nil {
|
if obj == nil {
|
||||||
var obj2 interface{}
|
// var obj2 interface{}
|
||||||
return c.dec.Decode(&obj2)
|
// return c.dec.Decode(&obj2)
|
||||||
|
c.swallow(&err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
return c.dec.Decode(obj)
|
return c.dec.Decode(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *rpcCodec) isClosed() bool {
|
func (c *rpcCodec) isClosed() (b bool) {
|
||||||
if c.c == nil {
|
if c.c != nil {
|
||||||
return false
|
|
||||||
}
|
|
||||||
c.clsmu.RLock()
|
c.clsmu.RLock()
|
||||||
x := c.cls
|
b = c.cls
|
||||||
c.clsmu.RUnlock()
|
c.clsmu.RUnlock()
|
||||||
return x
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *rpcCodec) Close() error {
|
func (c *rpcCodec) Close() error {
|
||||||
if c.c == nil {
|
if c.c == nil || c.isClosed() {
|
||||||
return nil
|
return c.clsErr
|
||||||
}
|
|
||||||
if c.isClosed() {
|
|
||||||
return io.EOF
|
|
||||||
}
|
}
|
||||||
c.clsmu.Lock()
|
c.clsmu.Lock()
|
||||||
c.cls = true
|
c.cls = true
|
||||||
err := c.c.Close()
|
// var fErr error
|
||||||
|
// if c.f != nil {
|
||||||
|
// fErr = c.f.Flush()
|
||||||
|
// }
|
||||||
|
// _ = fErr
|
||||||
|
// c.clsErr = c.c.Close()
|
||||||
|
// if c.clsErr == nil && fErr != nil {
|
||||||
|
// c.clsErr = fErr
|
||||||
|
// }
|
||||||
|
c.clsErr = c.c.Close()
|
||||||
c.clsmu.Unlock()
|
c.clsmu.Unlock()
|
||||||
return err
|
return c.clsErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *rpcCodec) ReadResponseBody(body interface{}) error {
|
func (c *rpcCodec) ReadResponseBody(body interface{}) error {
|
||||||
@ -147,13 +172,13 @@ func (c *goRpcCodec) WriteRequest(r *rpc.Request, body interface{}) error {
|
|||||||
// Must protect for concurrent access as per API
|
// Must protect for concurrent access as per API
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
return c.write(r, body, true, true)
|
return c.write(r, body, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *goRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error {
|
func (c *goRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
return c.write(r, body, true, true)
|
return c.write(r, body, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *goRpcCodec) ReadResponseHeader(r *rpc.Response) error {
|
func (c *goRpcCodec) ReadResponseHeader(r *rpc.Response) error {
|
||||||
@ -175,7 +200,36 @@ func (c *goRpcCodec) ReadRequestBody(body interface{}) error {
|
|||||||
type goRpc struct{}
|
type goRpc struct{}
|
||||||
|
|
||||||
// GoRpc implements Rpc using the communication protocol defined in net/rpc package.
|
// GoRpc implements Rpc using the communication protocol defined in net/rpc package.
|
||||||
// Its methods (ServerCodec and ClientCodec) return values that implement RpcCodecBuffered.
|
//
|
||||||
|
// Note: network connection (from net.Dial, of type io.ReadWriteCloser) is not buffered.
|
||||||
|
//
|
||||||
|
// For performance, you should configure WriterBufferSize and ReaderBufferSize on the handle.
|
||||||
|
// This ensures we use an adequate buffer during reading and writing.
|
||||||
|
// If not configured, we will internally initialize and use a buffer during reads and writes.
|
||||||
|
// This can be turned off via the RPCNoBuffer option on the Handle.
|
||||||
|
// var handle codec.JsonHandle
|
||||||
|
// handle.RPCNoBuffer = true // turns off attempt by rpc module to initialize a buffer
|
||||||
|
//
|
||||||
|
// Example 1: one way of configuring buffering explicitly:
|
||||||
|
// var handle codec.JsonHandle // codec handle
|
||||||
|
// handle.ReaderBufferSize = 1024
|
||||||
|
// handle.WriterBufferSize = 1024
|
||||||
|
// var conn io.ReadWriteCloser // connection got from a socket
|
||||||
|
// var serverCodec = GoRpc.ServerCodec(conn, handle)
|
||||||
|
// var clientCodec = GoRpc.ClientCodec(conn, handle)
|
||||||
|
//
|
||||||
|
// Example 2: you can also explicitly create a buffered connection yourself,
|
||||||
|
// and not worry about configuring the buffer sizes in the Handle.
|
||||||
|
// var handle codec.Handle // codec handle
|
||||||
|
// var conn io.ReadWriteCloser // connection got from a socket
|
||||||
|
// var bufconn = struct { // bufconn here is a buffered io.ReadWriteCloser
|
||||||
|
// io.Closer
|
||||||
|
// *bufio.Reader
|
||||||
|
// *bufio.Writer
|
||||||
|
// }{conn, bufio.NewReader(conn), bufio.NewWriter(conn)}
|
||||||
|
// var serverCodec = GoRpc.ServerCodec(bufconn, handle)
|
||||||
|
// var clientCodec = GoRpc.ClientCodec(bufconn, handle)
|
||||||
|
//
|
||||||
var GoRpc goRpc
|
var GoRpc goRpc
|
||||||
|
|
||||||
func (x goRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {
|
func (x goRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {
|
||||||
@ -185,11 +239,3 @@ func (x goRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {
|
|||||||
func (x goRpc) ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec {
|
func (x goRpc) ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec {
|
||||||
return &goRpcCodec{newRPCCodec(conn, h)}
|
return &goRpcCodec{newRPCCodec(conn, h)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use this method to allow you create wrapped versions of the reader, writer if desired.
|
|
||||||
// For example, to create a buffered implementation.
|
|
||||||
func (x goRpc) Codec(r io.Reader, w io.Writer, c io.Closer, h Handle) *goRpcCodec {
|
|
||||||
return &goRpcCodec{newRPCCodec2(r, w, c, h)}
|
|
||||||
}
|
|
||||||
|
|
||||||
// var _ RpcCodecBuffered = (*rpcCodec)(nil) // ensure *rpcCodec implements RpcCodecBuffered
|
|
||||||
|
11
vendor/github.com/ugorji/go/codec/shared_test.go
generated
vendored
11
vendor/github.com/ugorji/go/codec/shared_test.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
@ -45,6 +45,8 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@ -110,6 +112,8 @@ var (
|
|||||||
testMaxInitLen int
|
testMaxInitLen int
|
||||||
|
|
||||||
testNumRepeatString int
|
testNumRepeatString int
|
||||||
|
|
||||||
|
testRpcBufsize int
|
||||||
)
|
)
|
||||||
|
|
||||||
// variables that are not flags, but which can configure the handles
|
// variables that are not flags, but which can configure the handles
|
||||||
@ -131,6 +135,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
log.SetOutput(ioutil.Discard) // don't allow things log to standard out/err
|
||||||
testHEDs = make([]testHED, 0, 32)
|
testHEDs = make([]testHED, 0, 32)
|
||||||
testHandles = append(testHandles,
|
testHandles = append(testHandles,
|
||||||
// testNoopH,
|
// testNoopH,
|
||||||
@ -143,7 +148,7 @@ func init() {
|
|||||||
func testInitFlags() {
|
func testInitFlags() {
|
||||||
// delete(testDecOpts.ExtFuncs, timeTyp)
|
// delete(testDecOpts.ExtFuncs, timeTyp)
|
||||||
flag.IntVar(&testDepth, "tsd", 0, "Test Struc Depth")
|
flag.IntVar(&testDepth, "tsd", 0, "Test Struc Depth")
|
||||||
flag.BoolVar(&testVerbose, "tv", false, "Test Verbose")
|
flag.BoolVar(&testVerbose, "tv", false, "Test Verbose (no longer used - here for compatibility)")
|
||||||
flag.BoolVar(&testInitDebug, "tg", false, "Test Init Debug")
|
flag.BoolVar(&testInitDebug, "tg", false, "Test Init Debug")
|
||||||
flag.IntVar(&testUseIoEncDec, "ti", -1, "Use IO Reader/Writer for Marshal/Unmarshal ie >= 0")
|
flag.IntVar(&testUseIoEncDec, "ti", -1, "Use IO Reader/Writer for Marshal/Unmarshal ie >= 0")
|
||||||
flag.BoolVar(&testUseIoWrapper, "tiw", false, "Wrap the IO Reader/Writer with a base pass-through reader/writer")
|
flag.BoolVar(&testUseIoWrapper, "tiw", false, "Wrap the IO Reader/Writer with a base pass-through reader/writer")
|
||||||
@ -272,7 +277,7 @@ func logT(x interface{}, format string, args ...interface{}) {
|
|||||||
t.Logf(format, args...)
|
t.Logf(format, args...)
|
||||||
} else if b, ok := x.(*testing.B); ok && b != nil {
|
} else if b, ok := x.(*testing.B); ok && b != nil {
|
||||||
b.Logf(format, args...)
|
b.Logf(format, args...)
|
||||||
} else if testVerbose {
|
} else { // if testing.Verbose() { // if testVerbose {
|
||||||
if len(format) == 0 || format[len(format)-1] != '\n' {
|
if len(format) == 0 || format[len(format)-1] != '\n' {
|
||||||
format = format + "\n"
|
format = format + "\n"
|
||||||
}
|
}
|
||||||
|
225
vendor/github.com/ugorji/go/codec/simple.go
generated
vendored
225
vendor/github.com/ugorji/go/codec/simple.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
@ -6,6 +6,7 @@ package codec
|
|||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -20,6 +21,8 @@ const (
|
|||||||
simpleVdPosInt = 8
|
simpleVdPosInt = 8
|
||||||
simpleVdNegInt = 12
|
simpleVdNegInt = 12
|
||||||
|
|
||||||
|
simpleVdTime = 24
|
||||||
|
|
||||||
// containers: each lasts for 4 (ie n, n+1, n+2, ... n+7)
|
// containers: each lasts for 4 (ie n, n+1, n+2, ... n+7)
|
||||||
simpleVdString = 216
|
simpleVdString = 216
|
||||||
simpleVdByteArray = 224
|
simpleVdByteArray = 224
|
||||||
@ -30,12 +33,15 @@ const (
|
|||||||
|
|
||||||
type simpleEncDriver struct {
|
type simpleEncDriver struct {
|
||||||
noBuiltInTypes
|
noBuiltInTypes
|
||||||
encDriverNoopContainerWriter
|
|
||||||
// encNoSeparator
|
// encNoSeparator
|
||||||
e *Encoder
|
e *Encoder
|
||||||
h *SimpleHandle
|
h *SimpleHandle
|
||||||
w encWriter
|
w encWriter
|
||||||
b [8]byte
|
b [8]byte
|
||||||
|
// c containerState
|
||||||
|
encDriverTrackContainerWriter
|
||||||
|
// encDriverNoopContainerWriter
|
||||||
|
_ [2]uint64 // padding
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *simpleEncDriver) EncodeNil() {
|
func (e *simpleEncDriver) EncodeNil() {
|
||||||
@ -43,6 +49,10 @@ func (e *simpleEncDriver) EncodeNil() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *simpleEncDriver) EncodeBool(b bool) {
|
func (e *simpleEncDriver) EncodeBool(b bool) {
|
||||||
|
if e.h.EncZeroValuesAsNil && e.c != containerMapKey && !b {
|
||||||
|
e.EncodeNil()
|
||||||
|
return
|
||||||
|
}
|
||||||
if b {
|
if b {
|
||||||
e.w.writen1(simpleVdTrue)
|
e.w.writen1(simpleVdTrue)
|
||||||
} else {
|
} else {
|
||||||
@ -51,11 +61,19 @@ func (e *simpleEncDriver) EncodeBool(b bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *simpleEncDriver) EncodeFloat32(f float32) {
|
func (e *simpleEncDriver) EncodeFloat32(f float32) {
|
||||||
|
if e.h.EncZeroValuesAsNil && e.c != containerMapKey && f == 0.0 {
|
||||||
|
e.EncodeNil()
|
||||||
|
return
|
||||||
|
}
|
||||||
e.w.writen1(simpleVdFloat32)
|
e.w.writen1(simpleVdFloat32)
|
||||||
bigenHelper{e.b[:4], e.w}.writeUint32(math.Float32bits(f))
|
bigenHelper{e.b[:4], e.w}.writeUint32(math.Float32bits(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *simpleEncDriver) EncodeFloat64(f float64) {
|
func (e *simpleEncDriver) EncodeFloat64(f float64) {
|
||||||
|
if e.h.EncZeroValuesAsNil && e.c != containerMapKey && f == 0.0 {
|
||||||
|
e.EncodeNil()
|
||||||
|
return
|
||||||
|
}
|
||||||
e.w.writen1(simpleVdFloat64)
|
e.w.writen1(simpleVdFloat64)
|
||||||
bigenHelper{e.b[:8], e.w}.writeUint64(math.Float64bits(f))
|
bigenHelper{e.b[:8], e.w}.writeUint64(math.Float64bits(f))
|
||||||
}
|
}
|
||||||
@ -73,6 +91,10 @@ func (e *simpleEncDriver) EncodeUint(v uint64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *simpleEncDriver) encUint(v uint64, bd uint8) {
|
func (e *simpleEncDriver) encUint(v uint64, bd uint8) {
|
||||||
|
if e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == 0 {
|
||||||
|
e.EncodeNil()
|
||||||
|
return
|
||||||
|
}
|
||||||
if v <= math.MaxUint8 {
|
if v <= math.MaxUint8 {
|
||||||
e.w.writen2(bd, uint8(v))
|
e.w.writen2(bd, uint8(v))
|
||||||
} else if v <= math.MaxUint16 {
|
} else if v <= math.MaxUint16 {
|
||||||
@ -126,27 +148,54 @@ func (e *simpleEncDriver) encodeExtPreamble(xtag byte, length int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *simpleEncDriver) WriteArrayStart(length int) {
|
func (e *simpleEncDriver) WriteArrayStart(length int) {
|
||||||
|
e.c = containerArrayStart
|
||||||
e.encLen(simpleVdArray, length)
|
e.encLen(simpleVdArray, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *simpleEncDriver) WriteMapStart(length int) {
|
func (e *simpleEncDriver) WriteMapStart(length int) {
|
||||||
|
e.c = containerMapStart
|
||||||
e.encLen(simpleVdMap, length)
|
e.encLen(simpleVdMap, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *simpleEncDriver) EncodeString(c charEncoding, v string) {
|
func (e *simpleEncDriver) EncodeString(c charEncoding, v string) {
|
||||||
|
if false && e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == "" {
|
||||||
|
e.EncodeNil()
|
||||||
|
return
|
||||||
|
}
|
||||||
e.encLen(simpleVdString, len(v))
|
e.encLen(simpleVdString, len(v))
|
||||||
e.w.writestr(v)
|
e.w.writestr(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *simpleEncDriver) EncodeSymbol(v string) {
|
// func (e *simpleEncDriver) EncodeSymbol(v string) {
|
||||||
e.EncodeString(c_UTF8, v)
|
// e.EncodeString(cUTF8, v)
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (e *simpleEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
|
func (e *simpleEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
|
||||||
|
// if e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == nil {
|
||||||
|
if v == nil {
|
||||||
|
e.EncodeNil()
|
||||||
|
return
|
||||||
|
}
|
||||||
e.encLen(simpleVdByteArray, len(v))
|
e.encLen(simpleVdByteArray, len(v))
|
||||||
e.w.writeb(v)
|
e.w.writeb(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *simpleEncDriver) EncodeTime(t time.Time) {
|
||||||
|
// if e.h.EncZeroValuesAsNil && e.c != containerMapKey && t.IsZero() {
|
||||||
|
if t.IsZero() {
|
||||||
|
e.EncodeNil()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
v, err := t.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
e.e.errorv(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// time.Time marshalbinary takes about 14 bytes.
|
||||||
|
e.w.writen2(simpleVdTime, uint8(len(v)))
|
||||||
|
e.w.writeb(v)
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
|
|
||||||
type simpleDecDriver struct {
|
type simpleDecDriver struct {
|
||||||
@ -155,11 +204,13 @@ type simpleDecDriver struct {
|
|||||||
r decReader
|
r decReader
|
||||||
bdRead bool
|
bdRead bool
|
||||||
bd byte
|
bd byte
|
||||||
br bool // bytes reader
|
br bool // a bytes reader?
|
||||||
b [scratchByteArrayLen]byte
|
c containerState
|
||||||
|
// b [scratchByteArrayLen]byte
|
||||||
noBuiltInTypes
|
noBuiltInTypes
|
||||||
// noStreamingCodec
|
// noStreamingCodec
|
||||||
decDriverNoopContainerReader
|
decDriverNoopContainerReader
|
||||||
|
_ [3]uint64 // padding
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *simpleDecDriver) readNextBd() {
|
func (d *simpleDecDriver) readNextBd() {
|
||||||
@ -178,23 +229,27 @@ func (d *simpleDecDriver) ContainerType() (vt valueType) {
|
|||||||
if !d.bdRead {
|
if !d.bdRead {
|
||||||
d.readNextBd()
|
d.readNextBd()
|
||||||
}
|
}
|
||||||
if d.bd == simpleVdNil {
|
switch d.bd {
|
||||||
|
case simpleVdNil:
|
||||||
return valueTypeNil
|
return valueTypeNil
|
||||||
} else if d.bd == simpleVdByteArray || d.bd == simpleVdByteArray+1 ||
|
case simpleVdByteArray, simpleVdByteArray + 1,
|
||||||
d.bd == simpleVdByteArray+2 || d.bd == simpleVdByteArray+3 || d.bd == simpleVdByteArray+4 {
|
simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
|
||||||
return valueTypeBytes
|
return valueTypeBytes
|
||||||
} else if d.bd == simpleVdString || d.bd == simpleVdString+1 ||
|
case simpleVdString, simpleVdString + 1,
|
||||||
d.bd == simpleVdString+2 || d.bd == simpleVdString+3 || d.bd == simpleVdString+4 {
|
simpleVdString + 2, simpleVdString + 3, simpleVdString + 4:
|
||||||
return valueTypeString
|
return valueTypeString
|
||||||
} else if d.bd == simpleVdArray || d.bd == simpleVdArray+1 ||
|
case simpleVdArray, simpleVdArray + 1,
|
||||||
d.bd == simpleVdArray+2 || d.bd == simpleVdArray+3 || d.bd == simpleVdArray+4 {
|
simpleVdArray + 2, simpleVdArray + 3, simpleVdArray + 4:
|
||||||
return valueTypeArray
|
return valueTypeArray
|
||||||
} else if d.bd == simpleVdMap || d.bd == simpleVdMap+1 ||
|
case simpleVdMap, simpleVdMap + 1,
|
||||||
d.bd == simpleVdMap+2 || d.bd == simpleVdMap+3 || d.bd == simpleVdMap+4 {
|
simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4:
|
||||||
return valueTypeMap
|
return valueTypeMap
|
||||||
} else {
|
// case simpleVdTime:
|
||||||
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
|
// return valueTypeTime
|
||||||
}
|
}
|
||||||
|
// else {
|
||||||
|
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
|
||||||
|
// }
|
||||||
return valueTypeUnset
|
return valueTypeUnset
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +290,7 @@ func (d *simpleDecDriver) decCheckInteger() (ui uint64, neg bool) {
|
|||||||
ui = uint64(bigen.Uint64(d.r.readx(8)))
|
ui = uint64(bigen.Uint64(d.r.readx(8)))
|
||||||
neg = true
|
neg = true
|
||||||
default:
|
default:
|
||||||
d.d.errorf("decIntAny: Integer only valid from pos/neg integer1..8. Invalid descriptor: %v", d.bd)
|
d.d.errorf("Integer only valid from pos/neg integer1..8. Invalid descriptor: %v", d.bd)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// don't do this check, because callers may only want the unsigned value.
|
// don't do this check, because callers may only want the unsigned value.
|
||||||
@ -246,39 +301,27 @@ func (d *simpleDecDriver) decCheckInteger() (ui uint64, neg bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *simpleDecDriver) DecodeInt(bitsize uint8) (i int64) {
|
func (d *simpleDecDriver) DecodeInt64() (i int64) {
|
||||||
ui, neg := d.decCheckInteger()
|
ui, neg := d.decCheckInteger()
|
||||||
i, overflow := chkOvf.SignedInt(ui)
|
i = chkOvf.SignedIntV(ui)
|
||||||
if overflow {
|
|
||||||
d.d.errorf("simple: overflow converting %v to signed integer", ui)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if neg {
|
if neg {
|
||||||
i = -i
|
i = -i
|
||||||
}
|
}
|
||||||
if chkOvf.Int(i, bitsize) {
|
|
||||||
d.d.errorf("simple: overflow integer: %v", i)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *simpleDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
|
func (d *simpleDecDriver) DecodeUint64() (ui uint64) {
|
||||||
ui, neg := d.decCheckInteger()
|
ui, neg := d.decCheckInteger()
|
||||||
if neg {
|
if neg {
|
||||||
d.d.errorf("Assigning negative signed value to unsigned type")
|
d.d.errorf("Assigning negative signed value to unsigned type")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if chkOvf.Uint(ui, bitsize) {
|
|
||||||
d.d.errorf("simple: overflow integer: %v", ui)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *simpleDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
|
func (d *simpleDecDriver) DecodeFloat64() (f float64) {
|
||||||
if !d.bdRead {
|
if !d.bdRead {
|
||||||
d.readNextBd()
|
d.readNextBd()
|
||||||
}
|
}
|
||||||
@ -288,16 +331,12 @@ func (d *simpleDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
|
|||||||
f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
|
f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
|
||||||
} else {
|
} else {
|
||||||
if d.bd >= simpleVdPosInt && d.bd <= simpleVdNegInt+3 {
|
if d.bd >= simpleVdPosInt && d.bd <= simpleVdNegInt+3 {
|
||||||
f = float64(d.DecodeInt(64))
|
f = float64(d.DecodeInt64())
|
||||||
} else {
|
} else {
|
||||||
d.d.errorf("Float only valid from float32/64: Invalid descriptor: %v", d.bd)
|
d.d.errorf("Float only valid from float32/64: Invalid descriptor: %v", d.bd)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if chkOverflow32 && chkOvf.Float32(f) {
|
|
||||||
d.d.errorf("msgpack: float32 overflow: %v", f)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -323,6 +362,7 @@ func (d *simpleDecDriver) ReadMapStart() (length int) {
|
|||||||
d.readNextBd()
|
d.readNextBd()
|
||||||
}
|
}
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
|
d.c = containerMapStart
|
||||||
return d.decLen()
|
return d.decLen()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,9 +371,30 @@ func (d *simpleDecDriver) ReadArrayStart() (length int) {
|
|||||||
d.readNextBd()
|
d.readNextBd()
|
||||||
}
|
}
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
|
d.c = containerArrayStart
|
||||||
return d.decLen()
|
return d.decLen()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *simpleDecDriver) ReadArrayElem() {
|
||||||
|
d.c = containerArrayElem
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *simpleDecDriver) ReadArrayEnd() {
|
||||||
|
d.c = containerArrayEnd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *simpleDecDriver) ReadMapElemKey() {
|
||||||
|
d.c = containerMapKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *simpleDecDriver) ReadMapElemValue() {
|
||||||
|
d.c = containerMapValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *simpleDecDriver) ReadMapEnd() {
|
||||||
|
d.c = containerMapEnd
|
||||||
|
}
|
||||||
|
|
||||||
func (d *simpleDecDriver) decLen() int {
|
func (d *simpleDecDriver) decLen() int {
|
||||||
switch d.bd % 8 {
|
switch d.bd % 8 {
|
||||||
case 0:
|
case 0:
|
||||||
@ -345,14 +406,14 @@ func (d *simpleDecDriver) decLen() int {
|
|||||||
case 3:
|
case 3:
|
||||||
ui := uint64(bigen.Uint32(d.r.readx(4)))
|
ui := uint64(bigen.Uint32(d.r.readx(4)))
|
||||||
if chkOvf.Uint(ui, intBitsize) {
|
if chkOvf.Uint(ui, intBitsize) {
|
||||||
d.d.errorf("simple: overflow integer: %v", ui)
|
d.d.errorf("overflow integer: %v", ui)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return int(ui)
|
return int(ui)
|
||||||
case 4:
|
case 4:
|
||||||
ui := bigen.Uint64(d.r.readx(8))
|
ui := bigen.Uint64(d.r.readx(8))
|
||||||
if chkOvf.Uint(ui, intBitsize) {
|
if chkOvf.Uint(ui, intBitsize) {
|
||||||
d.d.errorf("simple: overflow integer: %v", ui)
|
d.d.errorf("overflow integer: %v", ui)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return int(ui)
|
return int(ui)
|
||||||
@ -362,11 +423,11 @@ func (d *simpleDecDriver) decLen() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *simpleDecDriver) DecodeString() (s string) {
|
func (d *simpleDecDriver) DecodeString() (s string) {
|
||||||
return string(d.DecodeBytes(d.b[:], true))
|
return string(d.DecodeBytes(d.d.b[:], true))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *simpleDecDriver) DecodeStringAsBytes() (s []byte) {
|
func (d *simpleDecDriver) DecodeStringAsBytes() (s []byte) {
|
||||||
return d.DecodeBytes(d.b[:], true)
|
return d.DecodeBytes(d.d.b[:], true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *simpleDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
|
func (d *simpleDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
|
||||||
@ -377,18 +438,48 @@ func (d *simpleDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
|
|||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// check if an "array" of uint8's (see ContainerType for how to infer if an array)
|
||||||
|
if d.bd >= simpleVdArray && d.bd <= simpleVdMap+4 {
|
||||||
|
if len(bs) == 0 && zerocopy {
|
||||||
|
bs = d.d.b[:]
|
||||||
|
}
|
||||||
|
bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
clen := d.decLen()
|
clen := d.decLen()
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
if zerocopy {
|
if zerocopy {
|
||||||
if d.br {
|
if d.br {
|
||||||
return d.r.readx(clen)
|
return d.r.readx(clen)
|
||||||
} else if len(bs) == 0 {
|
} else if len(bs) == 0 {
|
||||||
bs = d.b[:]
|
bs = d.d.b[:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return decByteSlice(d.r, clen, d.d.h.MaxInitLen, bs)
|
return decByteSlice(d.r, clen, d.d.h.MaxInitLen, bs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *simpleDecDriver) DecodeTime() (t time.Time) {
|
||||||
|
if !d.bdRead {
|
||||||
|
d.readNextBd()
|
||||||
|
}
|
||||||
|
if d.bd == simpleVdNil {
|
||||||
|
d.bdRead = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if d.bd != simpleVdTime {
|
||||||
|
d.d.errorf("invalid descriptor for time.Time - expect 0x%x, received 0x%x", simpleVdTime, d.bd)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
d.bdRead = false
|
||||||
|
clen := int(d.r.readn1())
|
||||||
|
b := d.r.readx(clen)
|
||||||
|
if err := (&t).UnmarshalBinary(b); err != nil {
|
||||||
|
d.d.errorv(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (d *simpleDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
|
func (d *simpleDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
|
||||||
if xtag > 0xff {
|
if xtag > 0xff {
|
||||||
d.d.errorf("decodeExt: tag must be <= 0xff; got: %v", xtag)
|
d.d.errorf("decodeExt: tag must be <= 0xff; got: %v", xtag)
|
||||||
@ -419,10 +510,11 @@ func (d *simpleDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs [
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
xbs = d.r.readx(l)
|
xbs = d.r.readx(l)
|
||||||
case simpleVdByteArray, simpleVdByteArray + 1, simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
|
case simpleVdByteArray, simpleVdByteArray + 1,
|
||||||
|
simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
|
||||||
xbs = d.DecodeBytes(nil, true)
|
xbs = d.DecodeBytes(nil, true)
|
||||||
default:
|
default:
|
||||||
d.d.errorf("Invalid d.bd for extensions (Expecting extensions or byte array). Got: 0x%x", d.bd)
|
d.d.errorf("Invalid descriptor - expecting extensions/bytearray, got: 0x%x", d.bd)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
d.bdRead = false
|
d.bdRead = false
|
||||||
@ -449,24 +541,29 @@ func (d *simpleDecDriver) DecodeNaked() {
|
|||||||
case simpleVdPosInt, simpleVdPosInt + 1, simpleVdPosInt + 2, simpleVdPosInt + 3:
|
case simpleVdPosInt, simpleVdPosInt + 1, simpleVdPosInt + 2, simpleVdPosInt + 3:
|
||||||
if d.h.SignedInteger {
|
if d.h.SignedInteger {
|
||||||
n.v = valueTypeInt
|
n.v = valueTypeInt
|
||||||
n.i = d.DecodeInt(64)
|
n.i = d.DecodeInt64()
|
||||||
} else {
|
} else {
|
||||||
n.v = valueTypeUint
|
n.v = valueTypeUint
|
||||||
n.u = d.DecodeUint(64)
|
n.u = d.DecodeUint64()
|
||||||
}
|
}
|
||||||
case simpleVdNegInt, simpleVdNegInt + 1, simpleVdNegInt + 2, simpleVdNegInt + 3:
|
case simpleVdNegInt, simpleVdNegInt + 1, simpleVdNegInt + 2, simpleVdNegInt + 3:
|
||||||
n.v = valueTypeInt
|
n.v = valueTypeInt
|
||||||
n.i = d.DecodeInt(64)
|
n.i = d.DecodeInt64()
|
||||||
case simpleVdFloat32:
|
case simpleVdFloat32:
|
||||||
n.v = valueTypeFloat
|
n.v = valueTypeFloat
|
||||||
n.f = d.DecodeFloat(true)
|
n.f = d.DecodeFloat64()
|
||||||
case simpleVdFloat64:
|
case simpleVdFloat64:
|
||||||
n.v = valueTypeFloat
|
n.v = valueTypeFloat
|
||||||
n.f = d.DecodeFloat(false)
|
n.f = d.DecodeFloat64()
|
||||||
case simpleVdString, simpleVdString + 1, simpleVdString + 2, simpleVdString + 3, simpleVdString + 4:
|
case simpleVdTime:
|
||||||
|
n.v = valueTypeTime
|
||||||
|
n.t = d.DecodeTime()
|
||||||
|
case simpleVdString, simpleVdString + 1,
|
||||||
|
simpleVdString + 2, simpleVdString + 3, simpleVdString + 4:
|
||||||
n.v = valueTypeString
|
n.v = valueTypeString
|
||||||
n.s = d.DecodeString()
|
n.s = d.DecodeString()
|
||||||
case simpleVdByteArray, simpleVdByteArray + 1, simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
|
case simpleVdByteArray, simpleVdByteArray + 1,
|
||||||
|
simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
|
||||||
n.v = valueTypeBytes
|
n.v = valueTypeBytes
|
||||||
n.l = d.DecodeBytes(nil, false)
|
n.l = d.DecodeBytes(nil, false)
|
||||||
case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4:
|
case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4:
|
||||||
@ -474,7 +571,8 @@ func (d *simpleDecDriver) DecodeNaked() {
|
|||||||
l := d.decLen()
|
l := d.decLen()
|
||||||
n.u = uint64(d.r.readn1())
|
n.u = uint64(d.r.readn1())
|
||||||
n.l = d.r.readx(l)
|
n.l = d.r.readx(l)
|
||||||
case simpleVdArray, simpleVdArray + 1, simpleVdArray + 2, simpleVdArray + 3, simpleVdArray + 4:
|
case simpleVdArray, simpleVdArray + 1, simpleVdArray + 2,
|
||||||
|
simpleVdArray + 3, simpleVdArray + 4:
|
||||||
n.v = valueTypeArray
|
n.v = valueTypeArray
|
||||||
decodeFurther = true
|
decodeFurther = true
|
||||||
case simpleVdMap, simpleVdMap + 1, simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4:
|
case simpleVdMap, simpleVdMap + 1, simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4:
|
||||||
@ -500,7 +598,7 @@ func (d *simpleDecDriver) DecodeNaked() {
|
|||||||
// - Integers (intXXX, uintXXX) are encoded in 1, 2, 4 or 8 bytes (plus a descriptor byte).
|
// - Integers (intXXX, uintXXX) are encoded in 1, 2, 4 or 8 bytes (plus a descriptor byte).
|
||||||
// There are positive (uintXXX and intXXX >= 0) and negative (intXXX < 0) integers.
|
// There are positive (uintXXX and intXXX >= 0) and negative (intXXX < 0) integers.
|
||||||
// - Floats are encoded in 4 or 8 bytes (plus a descriptor byte)
|
// - Floats are encoded in 4 or 8 bytes (plus a descriptor byte)
|
||||||
// - Lenght of containers (strings, bytes, array, map, extensions)
|
// - Length of containers (strings, bytes, array, map, extensions)
|
||||||
// are encoded in 0, 1, 2, 4 or 8 bytes.
|
// are encoded in 0, 1, 2, 4 or 8 bytes.
|
||||||
// Zero-length containers have no length encoded.
|
// Zero-length containers have no length encoded.
|
||||||
// For others, the number of bytes is given by pow(2, bd%3)
|
// For others, the number of bytes is given by pow(2, bd%3)
|
||||||
@ -508,18 +606,29 @@ func (d *simpleDecDriver) DecodeNaked() {
|
|||||||
// - arrays are encoded as [bd] [length] [value]...
|
// - arrays are encoded as [bd] [length] [value]...
|
||||||
// - extensions are encoded as [bd] [length] [tag] [byte]...
|
// - extensions are encoded as [bd] [length] [tag] [byte]...
|
||||||
// - strings/bytearrays are encoded as [bd] [length] [byte]...
|
// - strings/bytearrays are encoded as [bd] [length] [byte]...
|
||||||
|
// - time.Time are encoded as [bd] [length] [byte]...
|
||||||
//
|
//
|
||||||
// The full spec will be published soon.
|
// The full spec will be published soon.
|
||||||
type SimpleHandle struct {
|
type SimpleHandle struct {
|
||||||
BasicHandle
|
BasicHandle
|
||||||
binaryEncodingType
|
binaryEncodingType
|
||||||
noElemSeparators
|
noElemSeparators
|
||||||
|
// EncZeroValuesAsNil says to encode zero values for numbers, bool, string, etc as nil
|
||||||
|
EncZeroValuesAsNil bool
|
||||||
|
|
||||||
|
_ [1]uint64 // padding
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name returns the name of the handle: simple
|
||||||
|
func (h *SimpleHandle) Name() string { return "simple" }
|
||||||
|
|
||||||
|
// SetBytesExt sets an extension
|
||||||
func (h *SimpleHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
|
func (h *SimpleHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
|
||||||
return h.SetExt(rt, tag, &setExtWrapper{b: ext})
|
return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *SimpleHandle) hasElemSeparators() bool { return true } // as it implements Write(Map|Array)XXX
|
||||||
|
|
||||||
func (h *SimpleHandle) newEncDriver(e *Encoder) encDriver {
|
func (h *SimpleHandle) newEncDriver(e *Encoder) encDriver {
|
||||||
return &simpleEncDriver{e: e, w: e.w, h: h}
|
return &simpleEncDriver{e: e, w: e.w, h: h}
|
||||||
}
|
}
|
||||||
@ -529,10 +638,12 @@ func (h *SimpleHandle) newDecDriver(d *Decoder) decDriver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *simpleEncDriver) reset() {
|
func (e *simpleEncDriver) reset() {
|
||||||
|
e.c = 0
|
||||||
e.w = e.e.w
|
e.w = e.e.w
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *simpleDecDriver) reset() {
|
func (d *simpleDecDriver) reset() {
|
||||||
|
d.c = 0
|
||||||
d.r, d.br = d.d.r, d.d.bytes
|
d.r, d.br = d.d.r, d.d.bytes
|
||||||
d.bd, d.bdRead = 0, false
|
d.bd, d.bdRead = 0, false
|
||||||
}
|
}
|
||||||
|
220
vendor/github.com/ugorji/go/codec/time.go
generated
vendored
220
vendor/github.com/ugorji/go/codec/time.go
generated
vendored
@ -1,220 +0,0 @@
|
|||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
|
||||||
|
|
||||||
package codec
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var timeDigits = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
|
|
||||||
|
|
||||||
type timeExt struct{}
|
|
||||||
|
|
||||||
func (x timeExt) WriteExt(v interface{}) (bs []byte) {
|
|
||||||
switch v2 := v.(type) {
|
|
||||||
case time.Time:
|
|
||||||
bs = encodeTime(v2)
|
|
||||||
case *time.Time:
|
|
||||||
bs = encodeTime(*v2)
|
|
||||||
default:
|
|
||||||
panic(fmt.Errorf("unsupported format for time conversion: expecting time.Time; got %T", v2))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
func (x timeExt) ReadExt(v interface{}, bs []byte) {
|
|
||||||
tt, err := decodeTime(bs)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
*(v.(*time.Time)) = tt
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x timeExt) ConvertExt(v interface{}) interface{} {
|
|
||||||
return x.WriteExt(v)
|
|
||||||
}
|
|
||||||
func (x timeExt) UpdateExt(v interface{}, src interface{}) {
|
|
||||||
x.ReadExt(v, src.([]byte))
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeTime encodes a time.Time as a []byte, including
|
|
||||||
// information on the instant in time and UTC offset.
|
|
||||||
//
|
|
||||||
// Format Description
|
|
||||||
//
|
|
||||||
// A timestamp is composed of 3 components:
|
|
||||||
//
|
|
||||||
// - secs: signed integer representing seconds since unix epoch
|
|
||||||
// - nsces: unsigned integer representing fractional seconds as a
|
|
||||||
// nanosecond offset within secs, in the range 0 <= nsecs < 1e9
|
|
||||||
// - tz: signed integer representing timezone offset in minutes east of UTC,
|
|
||||||
// and a dst (daylight savings time) flag
|
|
||||||
//
|
|
||||||
// When encoding a timestamp, the first byte is the descriptor, which
|
|
||||||
// defines which components are encoded and how many bytes are used to
|
|
||||||
// encode secs and nsecs components. *If secs/nsecs is 0 or tz is UTC, it
|
|
||||||
// is not encoded in the byte array explicitly*.
|
|
||||||
//
|
|
||||||
// Descriptor 8 bits are of the form `A B C DDD EE`:
|
|
||||||
// A: Is secs component encoded? 1 = true
|
|
||||||
// B: Is nsecs component encoded? 1 = true
|
|
||||||
// C: Is tz component encoded? 1 = true
|
|
||||||
// DDD: Number of extra bytes for secs (range 0-7).
|
|
||||||
// If A = 1, secs encoded in DDD+1 bytes.
|
|
||||||
// If A = 0, secs is not encoded, and is assumed to be 0.
|
|
||||||
// If A = 1, then we need at least 1 byte to encode secs.
|
|
||||||
// DDD says the number of extra bytes beyond that 1.
|
|
||||||
// E.g. if DDD=0, then secs is represented in 1 byte.
|
|
||||||
// if DDD=2, then secs is represented in 3 bytes.
|
|
||||||
// EE: Number of extra bytes for nsecs (range 0-3).
|
|
||||||
// If B = 1, nsecs encoded in EE+1 bytes (similar to secs/DDD above)
|
|
||||||
//
|
|
||||||
// Following the descriptor bytes, subsequent bytes are:
|
|
||||||
//
|
|
||||||
// secs component encoded in `DDD + 1` bytes (if A == 1)
|
|
||||||
// nsecs component encoded in `EE + 1` bytes (if B == 1)
|
|
||||||
// tz component encoded in 2 bytes (if C == 1)
|
|
||||||
//
|
|
||||||
// secs and nsecs components are integers encoded in a BigEndian
|
|
||||||
// 2-complement encoding format.
|
|
||||||
//
|
|
||||||
// tz component is encoded as 2 bytes (16 bits). Most significant bit 15 to
|
|
||||||
// Least significant bit 0 are described below:
|
|
||||||
//
|
|
||||||
// Timezone offset has a range of -12:00 to +14:00 (ie -720 to +840 minutes).
|
|
||||||
// Bit 15 = have\_dst: set to 1 if we set the dst flag.
|
|
||||||
// Bit 14 = dst\_on: set to 1 if dst is in effect at the time, or 0 if not.
|
|
||||||
// Bits 13..0 = timezone offset in minutes. It is a signed integer in Big Endian format.
|
|
||||||
//
|
|
||||||
func encodeTime(t time.Time) []byte {
|
|
||||||
//t := rv.Interface().(time.Time)
|
|
||||||
tsecs, tnsecs := t.Unix(), t.Nanosecond()
|
|
||||||
var (
|
|
||||||
bd byte
|
|
||||||
btmp [8]byte
|
|
||||||
bs [16]byte
|
|
||||||
i int = 1
|
|
||||||
)
|
|
||||||
l := t.Location()
|
|
||||||
if l == time.UTC {
|
|
||||||
l = nil
|
|
||||||
}
|
|
||||||
if tsecs != 0 {
|
|
||||||
bd = bd | 0x80
|
|
||||||
bigen.PutUint64(btmp[:], uint64(tsecs))
|
|
||||||
f := pruneSignExt(btmp[:], tsecs >= 0)
|
|
||||||
bd = bd | (byte(7-f) << 2)
|
|
||||||
copy(bs[i:], btmp[f:])
|
|
||||||
i = i + (8 - f)
|
|
||||||
}
|
|
||||||
if tnsecs != 0 {
|
|
||||||
bd = bd | 0x40
|
|
||||||
bigen.PutUint32(btmp[:4], uint32(tnsecs))
|
|
||||||
f := pruneSignExt(btmp[:4], true)
|
|
||||||
bd = bd | byte(3-f)
|
|
||||||
copy(bs[i:], btmp[f:4])
|
|
||||||
i = i + (4 - f)
|
|
||||||
}
|
|
||||||
if l != nil {
|
|
||||||
bd = bd | 0x20
|
|
||||||
// Note that Go Libs do not give access to dst flag.
|
|
||||||
_, zoneOffset := t.Zone()
|
|
||||||
//zoneName, zoneOffset := t.Zone()
|
|
||||||
zoneOffset /= 60
|
|
||||||
z := uint16(zoneOffset)
|
|
||||||
bigen.PutUint16(btmp[:2], z)
|
|
||||||
// clear dst flags
|
|
||||||
bs[i] = btmp[0] & 0x3f
|
|
||||||
bs[i+1] = btmp[1]
|
|
||||||
i = i + 2
|
|
||||||
}
|
|
||||||
bs[0] = bd
|
|
||||||
return bs[0:i]
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeTime decodes a []byte into a time.Time.
|
|
||||||
func decodeTime(bs []byte) (tt time.Time, err error) {
|
|
||||||
bd := bs[0]
|
|
||||||
var (
|
|
||||||
tsec int64
|
|
||||||
tnsec uint32
|
|
||||||
tz uint16
|
|
||||||
i byte = 1
|
|
||||||
i2 byte
|
|
||||||
n byte
|
|
||||||
)
|
|
||||||
if bd&(1<<7) != 0 {
|
|
||||||
var btmp [8]byte
|
|
||||||
n = ((bd >> 2) & 0x7) + 1
|
|
||||||
i2 = i + n
|
|
||||||
copy(btmp[8-n:], bs[i:i2])
|
|
||||||
//if first bit of bs[i] is set, then fill btmp[0..8-n] with 0xff (ie sign extend it)
|
|
||||||
if bs[i]&(1<<7) != 0 {
|
|
||||||
copy(btmp[0:8-n], bsAll0xff)
|
|
||||||
//for j,k := byte(0), 8-n; j < k; j++ { btmp[j] = 0xff }
|
|
||||||
}
|
|
||||||
i = i2
|
|
||||||
tsec = int64(bigen.Uint64(btmp[:]))
|
|
||||||
}
|
|
||||||
if bd&(1<<6) != 0 {
|
|
||||||
var btmp [4]byte
|
|
||||||
n = (bd & 0x3) + 1
|
|
||||||
i2 = i + n
|
|
||||||
copy(btmp[4-n:], bs[i:i2])
|
|
||||||
i = i2
|
|
||||||
tnsec = bigen.Uint32(btmp[:])
|
|
||||||
}
|
|
||||||
if bd&(1<<5) == 0 {
|
|
||||||
tt = time.Unix(tsec, int64(tnsec)).UTC()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// In stdlib time.Parse, when a date is parsed without a zone name, it uses "" as zone name.
|
|
||||||
// However, we need name here, so it can be shown when time is printed.
|
|
||||||
// Zone name is in form: UTC-08:00.
|
|
||||||
// Note that Go Libs do not give access to dst flag, so we ignore dst bits
|
|
||||||
|
|
||||||
i2 = i + 2
|
|
||||||
tz = bigen.Uint16(bs[i:i2])
|
|
||||||
i = i2
|
|
||||||
// sign extend sign bit into top 2 MSB (which were dst bits):
|
|
||||||
if tz&(1<<13) == 0 { // positive
|
|
||||||
tz = tz & 0x3fff //clear 2 MSBs: dst bits
|
|
||||||
} else { // negative
|
|
||||||
tz = tz | 0xc000 //set 2 MSBs: dst bits
|
|
||||||
//tzname[3] = '-' (TODO: verify. this works here)
|
|
||||||
}
|
|
||||||
tzint := int16(tz)
|
|
||||||
if tzint == 0 {
|
|
||||||
tt = time.Unix(tsec, int64(tnsec)).UTC()
|
|
||||||
} else {
|
|
||||||
// For Go Time, do not use a descriptive timezone.
|
|
||||||
// It's unnecessary, and makes it harder to do a reflect.DeepEqual.
|
|
||||||
// The Offset already tells what the offset should be, if not on UTC and unknown zone name.
|
|
||||||
// var zoneName = timeLocUTCName(tzint)
|
|
||||||
tt = time.Unix(tsec, int64(tnsec)).In(time.FixedZone("", int(tzint)*60))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// func timeLocUTCName(tzint int16) string {
|
|
||||||
// if tzint == 0 {
|
|
||||||
// return "UTC"
|
|
||||||
// }
|
|
||||||
// var tzname = []byte("UTC+00:00")
|
|
||||||
// //tzname := fmt.Sprintf("UTC%s%02d:%02d", tzsign, tz/60, tz%60) //perf issue using Sprintf. inline below.
|
|
||||||
// //tzhr, tzmin := tz/60, tz%60 //faster if u convert to int first
|
|
||||||
// var tzhr, tzmin int16
|
|
||||||
// if tzint < 0 {
|
|
||||||
// tzname[3] = '-' // (TODO: verify. this works here)
|
|
||||||
// tzhr, tzmin = -tzint/60, (-tzint)%60
|
|
||||||
// } else {
|
|
||||||
// tzhr, tzmin = tzint/60, tzint%60
|
|
||||||
// }
|
|
||||||
// tzname[4] = timeDigits[tzhr/10]
|
|
||||||
// tzname[5] = timeDigits[tzhr%10]
|
|
||||||
// tzname[7] = timeDigits[tzmin/10]
|
|
||||||
// tzname[8] = timeDigits[tzmin%10]
|
|
||||||
// return string(tzname)
|
|
||||||
// //return time.FixedZone(string(tzname), int(tzint)*60)
|
|
||||||
// }
|
|
125
vendor/github.com/ugorji/go/codec/values_flex_test.go
generated
vendored
125
vendor/github.com/ugorji/go/codec/values_flex_test.go
generated
vendored
@ -1,15 +1,83 @@
|
|||||||
/* // +build testing */
|
/* // +build testing */
|
||||||
|
|
||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
|
|
||||||
// This file contains values used by tests and benchmarks.
|
import "time"
|
||||||
|
|
||||||
|
// This file contains values used by tests alone.
|
||||||
|
// This is where we may try out different things,
|
||||||
|
// that other engines may not support or may barf upon
|
||||||
|
// e.g. custom extensions for wrapped types, maps with non-string keys, etc.
|
||||||
|
|
||||||
|
// Some unused types just stored here
|
||||||
|
type Bbool bool
|
||||||
|
type Sstring string
|
||||||
|
type Sstructsmall struct {
|
||||||
|
A int
|
||||||
|
}
|
||||||
|
|
||||||
|
type Sstructbig struct {
|
||||||
|
A int
|
||||||
|
B bool
|
||||||
|
c string
|
||||||
|
// Sval Sstruct
|
||||||
|
Ssmallptr *Sstructsmall
|
||||||
|
Ssmall *Sstructsmall
|
||||||
|
Sptr *Sstructbig
|
||||||
|
}
|
||||||
|
|
||||||
|
type SstructbigMapBySlice struct {
|
||||||
|
_struct struct{} `codec:",toarray"`
|
||||||
|
A int
|
||||||
|
B bool
|
||||||
|
c string
|
||||||
|
// Sval Sstruct
|
||||||
|
Ssmallptr *Sstructsmall
|
||||||
|
Ssmall *Sstructsmall
|
||||||
|
Sptr *Sstructbig
|
||||||
|
}
|
||||||
|
|
||||||
|
type Sinterface interface {
|
||||||
|
Noop()
|
||||||
|
}
|
||||||
|
|
||||||
|
// small struct for testing that codecgen works for unexported types
|
||||||
|
type tLowerFirstLetter struct {
|
||||||
|
I int
|
||||||
|
u uint64
|
||||||
|
S string
|
||||||
|
b []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some used types
|
||||||
|
type wrapInt64 int64
|
||||||
|
type wrapUint8 uint8
|
||||||
|
type wrapBytes []uint8
|
||||||
|
|
||||||
|
type AnonInTestStrucIntf struct {
|
||||||
|
Islice []interface{}
|
||||||
|
Ms map[string]interface{}
|
||||||
|
Nintf interface{} //don't set this, so we can test for nil
|
||||||
|
T time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
var testWRepeated512 wrapBytes
|
||||||
|
var testStrucTime = time.Date(2012, 2, 2, 2, 2, 2, 2000, time.UTC).UTC()
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
var testARepeated512 [512]byte
|
||||||
|
for i := range testARepeated512 {
|
||||||
|
testARepeated512[i] = 'A'
|
||||||
|
}
|
||||||
|
testWRepeated512 = wrapBytes(testARepeated512[:])
|
||||||
|
}
|
||||||
|
|
||||||
type TestStrucFlex struct {
|
type TestStrucFlex struct {
|
||||||
_struct struct{} `codec:",omitempty"` //set omitempty for every field
|
_struct struct{} `codec:",omitempty"` //set omitempty for every field
|
||||||
testStrucCommon
|
TestStrucCommon
|
||||||
|
|
||||||
Mis map[int]string
|
Mis map[int]string
|
||||||
Mbu64 map[bool]struct{}
|
Mbu64 map[bool]struct{}
|
||||||
@ -19,6 +87,20 @@ type TestStrucFlex struct {
|
|||||||
Mui2wss map[uint64]wrapStringSlice
|
Mui2wss map[uint64]wrapStringSlice
|
||||||
Msu2wss map[stringUint64T]wrapStringSlice
|
Msu2wss map[stringUint64T]wrapStringSlice
|
||||||
|
|
||||||
|
Ci64 wrapInt64
|
||||||
|
Swrapbytes []wrapBytes
|
||||||
|
Swrapuint8 []wrapUint8
|
||||||
|
|
||||||
|
ArrStrUi64T [4]stringUint64T
|
||||||
|
|
||||||
|
Ui64array [4]uint64
|
||||||
|
Ui64slicearray []*[4]uint64
|
||||||
|
|
||||||
|
// make this a ptr, so that it could be set or not.
|
||||||
|
// for comparison (e.g. with msgp), give it a struct tag (so it is not inlined),
|
||||||
|
// make this one omitempty (so it is excluded if nil).
|
||||||
|
*AnonInTestStrucIntf `json:",omitempty"`
|
||||||
|
|
||||||
//M map[interface{}]interface{} `json:"-",bson:"-"`
|
//M map[interface{}]interface{} `json:"-",bson:"-"`
|
||||||
Mtsptr map[string]*TestStrucFlex
|
Mtsptr map[string]*TestStrucFlex
|
||||||
Mts map[string]TestStrucFlex
|
Mts map[string]TestStrucFlex
|
||||||
@ -52,9 +134,42 @@ func newTestStrucFlex(depth, n int, bench, useInterface, useStringKeyOnly bool)
|
|||||||
22: "twenty two",
|
22: "twenty two",
|
||||||
-44: "minus forty four",
|
-44: "minus forty four",
|
||||||
},
|
},
|
||||||
Mbu64: map[bool]struct{}{false: struct{}{}, true: struct{}{}},
|
Mbu64: map[bool]struct{}{false: {}, true: {}},
|
||||||
|
|
||||||
|
Ci64: -22,
|
||||||
|
Swrapbytes: []wrapBytes{ // lengths of 1, 2, 4, 8, 16, 32, 64, 128, 256,
|
||||||
|
testWRepeated512[:1],
|
||||||
|
testWRepeated512[:2],
|
||||||
|
testWRepeated512[:4],
|
||||||
|
testWRepeated512[:8],
|
||||||
|
testWRepeated512[:16],
|
||||||
|
testWRepeated512[:32],
|
||||||
|
testWRepeated512[:64],
|
||||||
|
testWRepeated512[:128],
|
||||||
|
testWRepeated512[:256],
|
||||||
|
testWRepeated512[:512],
|
||||||
|
},
|
||||||
|
Swrapuint8: []wrapUint8{
|
||||||
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
|
||||||
|
},
|
||||||
|
Ui64array: [4]uint64{4, 16, 64, 256},
|
||||||
|
ArrStrUi64T: [4]stringUint64T{{"4", 4}, {"3", 3}, {"2", 2}, {"1", 1}},
|
||||||
}
|
}
|
||||||
populateTestStrucCommon(&ts.testStrucCommon, n, bench, useInterface, useStringKeyOnly)
|
|
||||||
|
ts.Ui64slicearray = []*[4]uint64{&ts.Ui64array, &ts.Ui64array}
|
||||||
|
|
||||||
|
if useInterface {
|
||||||
|
ts.AnonInTestStrucIntf = &AnonInTestStrucIntf{
|
||||||
|
Islice: []interface{}{strRpt(n, "true"), true, strRpt(n, "no"), false, uint64(288), float64(0.4)},
|
||||||
|
Ms: map[string]interface{}{
|
||||||
|
strRpt(n, "true"): strRpt(n, "true"),
|
||||||
|
strRpt(n, "int64(9)"): false,
|
||||||
|
},
|
||||||
|
T: testStrucTime,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
populateTestStrucCommon(&ts.TestStrucCommon, n, bench, useInterface, useStringKeyOnly)
|
||||||
if depth > 0 {
|
if depth > 0 {
|
||||||
depth--
|
depth--
|
||||||
if ts.Mtsptr == nil {
|
if ts.Mtsptr == nil {
|
||||||
|
172
vendor/github.com/ugorji/go/codec/values_test.go
generated
vendored
172
vendor/github.com/ugorji/go/codec/values_test.go
generated
vendored
@ -1,20 +1,31 @@
|
|||||||
/* // +build testing */
|
/* // +build testing */
|
||||||
|
|
||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
|
|
||||||
// This file contains values used by tests and benchmarks.
|
// This file contains values used by tests and benchmarks.
|
||||||
// JSON/BSON do not like maps with keys that are not strings,
|
// The benchmarks will test performance against other libraries
|
||||||
|
// (encoding/json, json-iterator, bson, gob, etc).
|
||||||
|
// Consequently, we only use values that will parse well in all engines,
|
||||||
|
// and only leverage features that work across multiple libraries for a truer comparison.
|
||||||
|
// For example,
|
||||||
|
// - JSON/BSON do not like maps with keys that are not strings,
|
||||||
// so we only use maps with string keys here.
|
// so we only use maps with string keys here.
|
||||||
|
// - _struct options are not honored by other libraries,
|
||||||
|
// so we don't use them in this file.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// func init() {
|
||||||
|
// rt := reflect.TypeOf((*TestStruc)(nil)).Elem()
|
||||||
|
// defTypeInfos.get(rt2id(rt), rt)
|
||||||
|
// }
|
||||||
|
|
||||||
type wrapSliceUint64 []uint64
|
type wrapSliceUint64 []uint64
|
||||||
type wrapSliceString []string
|
type wrapSliceString []string
|
||||||
type wrapUint64 uint64
|
type wrapUint64 uint64
|
||||||
@ -50,59 +61,36 @@ type AnonInTestStruc struct {
|
|||||||
AMSU16E map[string]uint16
|
AMSU16E map[string]uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
type AnonInTestStrucIntf struct {
|
// testSimpleFields is a sub-set of TestStrucCommon
|
||||||
Islice []interface{}
|
|
||||||
Ms map[string]interface{}
|
|
||||||
Nintf interface{} //don't set this, so we can test for nil
|
|
||||||
T time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
type testSimpleFields struct {
|
type testSimpleFields struct {
|
||||||
S string
|
S string
|
||||||
|
|
||||||
I64 int64
|
I64 int64
|
||||||
I32 int32
|
|
||||||
I16 int16
|
|
||||||
I8 int8
|
I8 int8
|
||||||
|
|
||||||
I64n int64
|
|
||||||
I32n int32
|
|
||||||
I16n int16
|
|
||||||
I8n int8
|
|
||||||
|
|
||||||
Ui64 uint64
|
Ui64 uint64
|
||||||
Ui32 uint32
|
|
||||||
Ui16 uint16
|
|
||||||
Ui8 uint8
|
Ui8 uint8
|
||||||
|
|
||||||
F64 float64
|
F64 float64
|
||||||
F32 float32
|
F32 float32
|
||||||
|
|
||||||
B bool
|
B bool
|
||||||
By uint8 // byte: msgp doesn't like byte
|
|
||||||
|
|
||||||
Sslice []string
|
Sslice []string
|
||||||
I64slice []int64
|
|
||||||
I16slice []int16
|
I16slice []int16
|
||||||
Ui64slice []uint64
|
Ui64slice []uint64
|
||||||
Ui8slice []uint8
|
Ui8slice []uint8
|
||||||
Bslice []bool
|
Bslice []bool
|
||||||
Byslice []byte
|
|
||||||
|
|
||||||
Iptrslice []*int64
|
Iptrslice []*int64
|
||||||
|
|
||||||
// TODO: test these separately, specifically for reflection and codecgen.
|
|
||||||
// Unfortunately, ffjson doesn't support these. Its compilation even fails.
|
|
||||||
|
|
||||||
Ui64array [4]uint64
|
|
||||||
Ui64slicearray []*[4]uint64
|
|
||||||
WrapSliceInt64 wrapSliceUint64
|
WrapSliceInt64 wrapSliceUint64
|
||||||
WrapSliceString wrapSliceString
|
WrapSliceString wrapSliceString
|
||||||
|
|
||||||
Msi64 map[string]int64
|
Msi64 map[string]int64
|
||||||
}
|
}
|
||||||
|
|
||||||
type testStrucCommon struct {
|
type TestStrucCommon struct {
|
||||||
S string
|
S string
|
||||||
|
|
||||||
I64 int64
|
I64 int64
|
||||||
@ -136,11 +124,6 @@ type testStrucCommon struct {
|
|||||||
|
|
||||||
Iptrslice []*int64
|
Iptrslice []*int64
|
||||||
|
|
||||||
// TODO: test these separately, specifically for reflection and codecgen.
|
|
||||||
// Unfortunately, ffjson doesn't support these. Its compilation even fails.
|
|
||||||
|
|
||||||
Ui64array [4]uint64
|
|
||||||
Ui64slicearray []*[4]uint64
|
|
||||||
WrapSliceInt64 wrapSliceUint64
|
WrapSliceInt64 wrapSliceUint64
|
||||||
WrapSliceString wrapSliceString
|
WrapSliceString wrapSliceString
|
||||||
|
|
||||||
@ -148,14 +131,14 @@ type testStrucCommon struct {
|
|||||||
|
|
||||||
Simplef testSimpleFields
|
Simplef testSimpleFields
|
||||||
|
|
||||||
|
SstrUi64T []stringUint64T
|
||||||
|
|
||||||
AnonInTestStruc
|
AnonInTestStruc
|
||||||
|
|
||||||
NotAnon AnonInTestStruc
|
NotAnon AnonInTestStruc
|
||||||
|
|
||||||
// make this a ptr, so that it could be set or not.
|
// R Raw // Testing Raw must be explicitly turned on, so use standalone test
|
||||||
// for comparison (e.g. with msgp), give it a struct tag (so it is not inlined),
|
// Rext RawExt // Testing RawExt is tricky, so use standalone test
|
||||||
// make this one omitempty (so it is excluded if nil).
|
|
||||||
*AnonInTestStrucIntf `codec:",omitempty"`
|
|
||||||
|
|
||||||
Nmap map[string]bool //don't set this, so we can test for nil
|
Nmap map[string]bool //don't set this, so we can test for nil
|
||||||
Nslice []byte //don't set this, so we can test for nil
|
Nslice []byte //don't set this, so we can test for nil
|
||||||
@ -163,9 +146,9 @@ type testStrucCommon struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type TestStruc struct {
|
type TestStruc struct {
|
||||||
_struct struct{} `codec:",omitempty"` //set omitempty for every field
|
// _struct struct{} `json:",omitempty"` //set omitempty for every field
|
||||||
|
|
||||||
testStrucCommon
|
TestStrucCommon
|
||||||
|
|
||||||
Mtsptr map[string]*TestStruc
|
Mtsptr map[string]*TestStruc
|
||||||
Mts map[string]TestStruc
|
Mts map[string]TestStruc
|
||||||
@ -173,52 +156,11 @@ type TestStruc struct {
|
|||||||
Nteststruc *TestStruc
|
Nteststruc *TestStruc
|
||||||
}
|
}
|
||||||
|
|
||||||
// small struct for testing that codecgen works for unexported types
|
func populateTestStrucCommon(ts *TestStrucCommon, n int, bench, useInterface, useStringKeyOnly bool) {
|
||||||
type tLowerFirstLetter struct {
|
|
||||||
I int
|
|
||||||
u uint64
|
|
||||||
S string
|
|
||||||
b []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some other types
|
|
||||||
|
|
||||||
type Sstring string
|
|
||||||
type Bbool bool
|
|
||||||
type Sstructsmall struct {
|
|
||||||
A int
|
|
||||||
}
|
|
||||||
|
|
||||||
type Sstructbig struct {
|
|
||||||
A int
|
|
||||||
B bool
|
|
||||||
c string
|
|
||||||
// Sval Sstruct
|
|
||||||
Ssmallptr *Sstructsmall
|
|
||||||
Ssmall *Sstructsmall
|
|
||||||
Sptr *Sstructbig
|
|
||||||
}
|
|
||||||
|
|
||||||
type SstructbigMapBySlice struct {
|
|
||||||
_struct struct{} `codec:",toarray"`
|
|
||||||
A int
|
|
||||||
B bool
|
|
||||||
c string
|
|
||||||
// Sval Sstruct
|
|
||||||
Ssmallptr *Sstructsmall
|
|
||||||
Ssmall *Sstructsmall
|
|
||||||
Sptr *Sstructbig
|
|
||||||
}
|
|
||||||
|
|
||||||
type Sinterface interface {
|
|
||||||
Noop()
|
|
||||||
}
|
|
||||||
|
|
||||||
var testStrucTime = time.Date(2012, 2, 2, 2, 2, 2, 2000, time.UTC).UTC()
|
|
||||||
|
|
||||||
func populateTestStrucCommon(ts *testStrucCommon, n int, bench, useInterface, useStringKeyOnly bool) {
|
|
||||||
var i64a, i64b, i64c, i64d int64 = 64, 6464, 646464, 64646464
|
var i64a, i64b, i64c, i64d int64 = 64, 6464, 646464, 64646464
|
||||||
|
|
||||||
|
// if bench, do not use uint64 values > math.MaxInt64, as bson, etc cannot decode them
|
||||||
|
|
||||||
var a = AnonInTestStruc{
|
var a = AnonInTestStruc{
|
||||||
// There's more leeway in altering this.
|
// There's more leeway in altering this.
|
||||||
AS: strRpt(n, "A-String"),
|
AS: strRpt(n, "A-String"),
|
||||||
@ -255,7 +197,6 @@ func populateTestStrucCommon(ts *testStrucCommon, n int, bench, useInterface, us
|
|||||||
math.MaxUint8, math.MaxUint8 + 4, math.MaxUint8 - 4,
|
math.MaxUint8, math.MaxUint8 + 4, math.MaxUint8 - 4,
|
||||||
math.MaxUint16, math.MaxUint16 + 4, math.MaxUint16 - 4,
|
math.MaxUint16, math.MaxUint16 + 4, math.MaxUint16 - 4,
|
||||||
math.MaxUint32, math.MaxUint32 + 4, math.MaxUint32 - 4,
|
math.MaxUint32, math.MaxUint32 + 4, math.MaxUint32 - 4,
|
||||||
math.MaxUint64, math.MaxUint64 - 4,
|
|
||||||
},
|
},
|
||||||
AMSU16: map[string]uint16{strRpt(n, "1"): 1, strRpt(n, "22"): 2, strRpt(n, "333"): 3, strRpt(n, "4444"): 4},
|
AMSU16: map[string]uint16{strRpt(n, "1"): 1, strRpt(n, "22"): 2, strRpt(n, "333"): 3, strRpt(n, "4444"): 4},
|
||||||
|
|
||||||
@ -300,7 +241,10 @@ func populateTestStrucCommon(ts *testStrucCommon, n int, bench, useInterface, us
|
|||||||
AMSU16E: map[string]uint16{},
|
AMSU16E: map[string]uint16{},
|
||||||
}
|
}
|
||||||
|
|
||||||
*ts = testStrucCommon{
|
if !bench {
|
||||||
|
a.AUi64slice = append(a.AUi64slice, math.MaxUint64, math.MaxUint64-4)
|
||||||
|
}
|
||||||
|
*ts = TestStrucCommon{
|
||||||
S: strRpt(n, `some really really cool names that are nigerian and american like "ugorji melody nwoke" - get it? `),
|
S: strRpt(n, `some really really cool names that are nigerian and american like "ugorji melody nwoke" - get it? `),
|
||||||
|
|
||||||
// set the numbers close to the limits
|
// set the numbers close to the limits
|
||||||
@ -338,11 +282,12 @@ func populateTestStrucCommon(ts *testStrucCommon, n int, bench, useInterface, us
|
|||||||
strRpt(n, "\"three\""): 3,
|
strRpt(n, "\"three\""): 3,
|
||||||
},
|
},
|
||||||
|
|
||||||
Ui64array: [4]uint64{4, 16, 64, 256},
|
|
||||||
|
|
||||||
WrapSliceInt64: []uint64{4, 16, 64, 256},
|
WrapSliceInt64: []uint64{4, 16, 64, 256},
|
||||||
WrapSliceString: []string{strRpt(n, "4"), strRpt(n, "16"), strRpt(n, "64"), strRpt(n, "256")},
|
WrapSliceString: []string{strRpt(n, "4"), strRpt(n, "16"), strRpt(n, "64"), strRpt(n, "256")},
|
||||||
|
|
||||||
|
// R: Raw([]byte("goodbye")),
|
||||||
|
// Rext: RawExt{ 120, []byte("hello"), }, // TODO: don't set this - it's hard to test
|
||||||
|
|
||||||
// DecodeNaked bombs here, because the stringUint64T is decoded as a map,
|
// DecodeNaked bombs here, because the stringUint64T is decoded as a map,
|
||||||
// and a map cannot be the key type of a map.
|
// and a map cannot be the key type of a map.
|
||||||
// Thus, don't initialize this here.
|
// Thus, don't initialize this here.
|
||||||
@ -352,37 +297,27 @@ func populateTestStrucCommon(ts *testStrucCommon, n int, bench, useInterface, us
|
|||||||
// },
|
// },
|
||||||
|
|
||||||
// make Simplef same as top-level
|
// make Simplef same as top-level
|
||||||
|
// TODO: should this have slightly different values???
|
||||||
Simplef: testSimpleFields{
|
Simplef: testSimpleFields{
|
||||||
S: strRpt(n, `some really really cool names that are nigerian and american like "ugorji melody nwoke" - get it? `),
|
S: strRpt(n, `some really really cool names that are nigerian and american like "ugorji melody nwoke" - get it? `),
|
||||||
|
|
||||||
// set the numbers close to the limits
|
// set the numbers close to the limits
|
||||||
I8: math.MaxInt8 * 2 / 3, // 8,
|
I8: math.MaxInt8 * 2 / 3, // 8,
|
||||||
I8n: math.MinInt8 * 2 / 3, // 8,
|
|
||||||
I16: math.MaxInt16 * 2 / 3, // 16,
|
|
||||||
I16n: math.MinInt16 * 2 / 3, // 16,
|
|
||||||
I32: math.MaxInt32 * 2 / 3, // 32,
|
|
||||||
I32n: math.MinInt32 * 2 / 3, // 32,
|
|
||||||
I64: math.MaxInt64 * 2 / 3, // 64,
|
I64: math.MaxInt64 * 2 / 3, // 64,
|
||||||
I64n: math.MinInt64 * 2 / 3, // 64,
|
|
||||||
|
|
||||||
Ui64: math.MaxUint64 * 2 / 3, // 64
|
Ui64: math.MaxUint64 * 2 / 3, // 64
|
||||||
Ui32: math.MaxUint32 * 2 / 3, // 32
|
|
||||||
Ui16: math.MaxUint16 * 2 / 3, // 16
|
|
||||||
Ui8: math.MaxUint8 * 2 / 3, // 8
|
Ui8: math.MaxUint8 * 2 / 3, // 8
|
||||||
|
|
||||||
F32: 3.402823e+38, // max representable float32 without losing precision
|
F32: 3.402823e+38, // max representable float32 without losing precision
|
||||||
F64: 3.40281991833838838338e+53,
|
F64: 3.40281991833838838338e+53,
|
||||||
|
|
||||||
B: true,
|
B: true,
|
||||||
By: 5,
|
|
||||||
|
|
||||||
Sslice: []string{strRpt(n, "one"), strRpt(n, "two"), strRpt(n, "three")},
|
Sslice: []string{strRpt(n, "one"), strRpt(n, "two"), strRpt(n, "three")},
|
||||||
I64slice: []int64{1111, 2222, 3333},
|
|
||||||
I16slice: []int16{44, 55, 66},
|
I16slice: []int16{44, 55, 66},
|
||||||
Ui64slice: []uint64{12121212, 34343434, 56565656},
|
Ui64slice: []uint64{12121212, 34343434, 56565656},
|
||||||
Ui8slice: []uint8{210, 211, 212},
|
Ui8slice: []uint8{210, 211, 212},
|
||||||
Bslice: []bool{true, false, true, false},
|
Bslice: []bool{true, false, true, false},
|
||||||
Byslice: []byte{13, 14, 15},
|
|
||||||
|
|
||||||
Msi64: map[string]int64{
|
Msi64: map[string]int64{
|
||||||
strRpt(n, "one"): 1,
|
strRpt(n, "one"): 1,
|
||||||
@ -390,27 +325,18 @@ func populateTestStrucCommon(ts *testStrucCommon, n int, bench, useInterface, us
|
|||||||
strRpt(n, "\"three\""): 3,
|
strRpt(n, "\"three\""): 3,
|
||||||
},
|
},
|
||||||
|
|
||||||
Ui64array: [4]uint64{4, 16, 64, 256},
|
|
||||||
|
|
||||||
WrapSliceInt64: []uint64{4, 16, 64, 256},
|
WrapSliceInt64: []uint64{4, 16, 64, 256},
|
||||||
WrapSliceString: []string{strRpt(n, "4"), strRpt(n, "16"), strRpt(n, "64"), strRpt(n, "256")},
|
WrapSliceString: []string{strRpt(n, "4"), strRpt(n, "16"), strRpt(n, "64"), strRpt(n, "256")},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
SstrUi64T: []stringUint64T{{"1", 1}, {"2", 2}, {"3", 3}, {"4", 4}},
|
||||||
AnonInTestStruc: a,
|
AnonInTestStruc: a,
|
||||||
NotAnon: a,
|
NotAnon: a,
|
||||||
}
|
}
|
||||||
|
|
||||||
ts.Ui64slicearray = []*[4]uint64{&ts.Ui64array, &ts.Ui64array}
|
if bench {
|
||||||
|
ts.Ui64 = math.MaxInt64 * 2 / 3
|
||||||
if useInterface {
|
ts.Simplef.Ui64 = ts.Ui64
|
||||||
ts.AnonInTestStrucIntf = &AnonInTestStrucIntf{
|
|
||||||
Islice: []interface{}{strRpt(n, "true"), true, strRpt(n, "no"), false, uint64(288), float64(0.4)},
|
|
||||||
Ms: map[string]interface{}{
|
|
||||||
strRpt(n, "true"): strRpt(n, "true"),
|
|
||||||
strRpt(n, "int64(9)"): false,
|
|
||||||
},
|
|
||||||
T: testStrucTime,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//For benchmarks, some things will not work.
|
//For benchmarks, some things will not work.
|
||||||
@ -431,7 +357,7 @@ func populateTestStrucCommon(ts *testStrucCommon, n int, bench, useInterface, us
|
|||||||
|
|
||||||
func newTestStruc(depth, n int, bench, useInterface, useStringKeyOnly bool) (ts *TestStruc) {
|
func newTestStruc(depth, n int, bench, useInterface, useStringKeyOnly bool) (ts *TestStruc) {
|
||||||
ts = &TestStruc{}
|
ts = &TestStruc{}
|
||||||
populateTestStrucCommon(&ts.testStrucCommon, n, bench, useInterface, useStringKeyOnly)
|
populateTestStrucCommon(&ts.TestStrucCommon, n, bench, useInterface, useStringKeyOnly)
|
||||||
if depth > 0 {
|
if depth > 0 {
|
||||||
depth--
|
depth--
|
||||||
if ts.Mtsptr == nil {
|
if ts.Mtsptr == nil {
|
||||||
@ -447,6 +373,28 @@ func newTestStruc(depth, n int, bench, useInterface, useStringKeyOnly bool) (ts
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var testStrRptMap = make(map[int]map[string]string)
|
||||||
|
|
||||||
func strRpt(n int, s string) string {
|
func strRpt(n int, s string) string {
|
||||||
|
if false {
|
||||||
|
// fmt.Printf(">>>> calling strings.Repeat on n: %d, key: %s\n", n, s)
|
||||||
return strings.Repeat(s, n)
|
return strings.Repeat(s, n)
|
||||||
|
}
|
||||||
|
m1, ok := testStrRptMap[n]
|
||||||
|
if !ok {
|
||||||
|
// fmt.Printf(">>>> making new map for n: %v\n", n)
|
||||||
|
m1 = make(map[string]string)
|
||||||
|
testStrRptMap[n] = m1
|
||||||
|
}
|
||||||
|
v1, ok := m1[s]
|
||||||
|
if !ok {
|
||||||
|
// fmt.Printf(">>>> creating new entry for key: %s\n", s)
|
||||||
|
v1 = strings.Repeat(s, n)
|
||||||
|
m1[s] = v1
|
||||||
|
}
|
||||||
|
return v1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func wstrRpt(n int, s string) wrapBytes {
|
||||||
|
// return wrapBytes(bytes.Repeat([]byte(s), n))
|
||||||
|
// }
|
||||||
|
123
vendor/github.com/ugorji/go/codec/x_bench_gen_test.go
generated
vendored
123
vendor/github.com/ugorji/go/codec/x_bench_gen_test.go
generated
vendored
@ -1,123 +0,0 @@
|
|||||||
// +build x
|
|
||||||
// +build generated
|
|
||||||
|
|
||||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
|
||||||
|
|
||||||
package codec
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/mailru/easyjson"
|
|
||||||
"github.com/pquerna/ffjson/ffjson"
|
|
||||||
"github.com/tinylib/msgp/msgp"
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
To update all these, use:
|
|
||||||
go get -u github.com/tinylib/msgp/msgp github.com/tinylib/msgp \
|
|
||||||
github.com/pquerna/ffjson/ffjson github.com/pquerna/ffjson \
|
|
||||||
github.com/mailru/easyjson/...
|
|
||||||
|
|
||||||
Known Issues with external libraries:
|
|
||||||
- msgp io.R/W support doesn't work. It throws error
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
testPreInitFns = append(testPreInitFns, benchXGenPreInit)
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchXGenPreInit() {
|
|
||||||
benchCheckers = append(benchCheckers,
|
|
||||||
benchChecker{"msgp", fnMsgpEncodeFn, fnMsgpDecodeFn},
|
|
||||||
benchChecker{"easyjson", fnEasyjsonEncodeFn, fnEasyjsonDecodeFn},
|
|
||||||
benchChecker{"ffjson", fnFfjsonEncodeFn, fnFfjsonDecodeFn},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func fnEasyjsonEncodeFn(ts interface{}, bsIn []byte) ([]byte, error) {
|
|
||||||
if _, ok := ts.(easyjson.Marshaler); !ok {
|
|
||||||
return nil, errors.New("easyjson: input is not a easyjson.Marshaler")
|
|
||||||
}
|
|
||||||
if testUseIoEncDec >= 0 {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
_, err := easyjson.MarshalToWriter(ts.(easyjson.Marshaler), buf)
|
|
||||||
return buf.Bytes(), err
|
|
||||||
}
|
|
||||||
return easyjson.Marshal(ts.(easyjson.Marshaler))
|
|
||||||
// return ts.(json.Marshaler).MarshalJSON()
|
|
||||||
}
|
|
||||||
|
|
||||||
func fnEasyjsonDecodeFn(buf []byte, ts interface{}) error {
|
|
||||||
if _, ok := ts.(easyjson.Unmarshaler); !ok {
|
|
||||||
return errors.New("easyjson: input is not a easyjson.Unmarshaler")
|
|
||||||
}
|
|
||||||
if testUseIoEncDec >= 0 {
|
|
||||||
return easyjson.UnmarshalFromReader(bytes.NewReader(buf), ts.(easyjson.Unmarshaler))
|
|
||||||
}
|
|
||||||
return easyjson.Unmarshal(buf, ts.(easyjson.Unmarshaler))
|
|
||||||
// return ts.(json.Unmarshaler).UnmarshalJSON(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
func fnFfjsonEncodeFn(ts interface{}, bsIn []byte) ([]byte, error) {
|
|
||||||
return ffjson.Marshal(ts)
|
|
||||||
// return ts.(json.Marshaler).MarshalJSON()
|
|
||||||
}
|
|
||||||
|
|
||||||
func fnFfjsonDecodeFn(buf []byte, ts interface{}) error {
|
|
||||||
return ffjson.Unmarshal(buf, ts)
|
|
||||||
// return ts.(json.Unmarshaler).UnmarshalJSON(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
func fnMsgpEncodeFn(ts interface{}, bsIn []byte) ([]byte, error) {
|
|
||||||
if _, ok := ts.(msgp.Encodable); !ok {
|
|
||||||
return nil, fmt.Errorf("msgp: input of type %T is not a msgp.Encodable", ts)
|
|
||||||
}
|
|
||||||
if testUseIoEncDec >= 0 {
|
|
||||||
buf := fnBenchmarkByteBuf(bsIn)
|
|
||||||
err := ts.(msgp.Encodable).EncodeMsg(msgp.NewWriter(buf))
|
|
||||||
return buf.Bytes(), err
|
|
||||||
}
|
|
||||||
return ts.(msgp.Marshaler).MarshalMsg(bsIn[:0]) // msgp appends to slice.
|
|
||||||
}
|
|
||||||
|
|
||||||
func fnMsgpDecodeFn(buf []byte, ts interface{}) (err error) {
|
|
||||||
if _, ok := ts.(msgp.Decodable); !ok {
|
|
||||||
return fmt.Errorf("msgp: input of type %T is not a msgp.Decodable", ts)
|
|
||||||
}
|
|
||||||
if testUseIoEncDec >= 0 {
|
|
||||||
err = ts.(msgp.Decodable).DecodeMsg(msgp.NewReader(bytes.NewReader(buf)))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_, err = ts.(msgp.Unmarshaler).UnmarshalMsg(buf)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func Benchmark__Msgp_______Encode(b *testing.B) {
|
|
||||||
fnBenchmarkEncode(b, "msgp", benchTs, fnMsgpEncodeFn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Benchmark__Msgp_______Decode(b *testing.B) {
|
|
||||||
fnBenchmarkDecode(b, "msgp", benchTs, fnMsgpEncodeFn, fnMsgpDecodeFn, fnBenchNewTs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Benchmark__Easyjson___Encode(b *testing.B) {
|
|
||||||
fnBenchmarkEncode(b, "easyjson", benchTs, fnEasyjsonEncodeFn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Benchmark__Easyjson___Decode(b *testing.B) {
|
|
||||||
fnBenchmarkDecode(b, "easyjson", benchTs, fnEasyjsonEncodeFn, fnEasyjsonDecodeFn, fnBenchNewTs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Benchmark__Ffjson_____Encode(b *testing.B) {
|
|
||||||
fnBenchmarkEncode(b, "ffjson", benchTs, fnFfjsonEncodeFn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Benchmark__Ffjson_____Decode(b *testing.B) {
|
|
||||||
fnBenchmarkDecode(b, "ffjson", benchTs, fnFfjsonEncodeFn, fnFfjsonDecodeFn, fnBenchNewTs)
|
|
||||||
}
|
|
130
vendor/github.com/ugorji/go/codec/xml.go
generated
vendored
130
vendor/github.com/ugorji/go/codec/xml.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// +build ignore
|
// +build ignore
|
||||||
|
|
||||||
package codec
|
package codec
|
||||||
@ -24,7 +27,6 @@ It is a replacement, based on the simplicity and performance of codec.
|
|||||||
Look at it like JAXB for Go.
|
Look at it like JAXB for Go.
|
||||||
|
|
||||||
Challenges:
|
Challenges:
|
||||||
|
|
||||||
- Need to output XML preamble, with all namespaces at the right location in the output.
|
- Need to output XML preamble, with all namespaces at the right location in the output.
|
||||||
- Each "end" block is dynamic, so we need to maintain a context-aware stack
|
- Each "end" block is dynamic, so we need to maintain a context-aware stack
|
||||||
- How to decide when to use an attribute VS an element
|
- How to decide when to use an attribute VS an element
|
||||||
@ -34,24 +36,26 @@ Challenges:
|
|||||||
|
|
||||||
Extend the struct tag. See representative example:
|
Extend the struct tag. See representative example:
|
||||||
type X struct {
|
type X struct {
|
||||||
ID uint8 codec:"xid|http://ugorji.net/x-namespace id,omitempty,toarray,attr,cdata"
|
ID uint8 `codec:"http://ugorji.net/x-namespace xid id,omitempty,toarray,attr,cdata"`
|
||||||
|
// format: [namespace-uri ][namespace-prefix ]local-name, ...
|
||||||
}
|
}
|
||||||
|
|
||||||
Based on this, we encode
|
Based on this, we encode
|
||||||
- fields as elements, BUT encode as attributes if struct tag contains ",attr".
|
- fields as elements, BUT
|
||||||
|
encode as attributes if struct tag contains ",attr" and is a scalar (bool, number or string)
|
||||||
- text as entity-escaped text, BUT encode as CDATA if struct tag contains ",cdata".
|
- text as entity-escaped text, BUT encode as CDATA if struct tag contains ",cdata".
|
||||||
|
|
||||||
In this mode, we only encode as attribute if ",attr" is found, and only encode as CDATA
|
|
||||||
if ",cdata" is found in the struct tag.
|
|
||||||
|
|
||||||
To handle namespaces:
|
To handle namespaces:
|
||||||
- XMLHandle is denoted as being namespace-aware.
|
- XMLHandle is denoted as being namespace-aware.
|
||||||
Consequently, we WILL use the ns:name pair to encode and decode if defined, else use the plain name.
|
Consequently, we WILL use the ns:name pair to encode and decode if defined, else use the plain name.
|
||||||
- *Encoder and *Decoder know whether the Handle "prefers" namespaces.
|
- *Encoder and *Decoder know whether the Handle "prefers" namespaces.
|
||||||
- add *Encoder.getEncName(*structFieldInfo).
|
- add *Encoder.getEncName(*structFieldInfo).
|
||||||
No one calls *structFieldInfo.indexForEncName directly anymore
|
No one calls *structFieldInfo.indexForEncName directly anymore
|
||||||
|
- OR better yet: indexForEncName is namespace-aware, and helper.go is all namespace-aware
|
||||||
|
indexForEncName takes a parameter of the form namespace:local-name OR local-name
|
||||||
- add *Decoder.getStructFieldInfo(encName string) // encName here is either like abc, or h1:nsabc
|
- add *Decoder.getStructFieldInfo(encName string) // encName here is either like abc, or h1:nsabc
|
||||||
No one accesses .encName anymore except in
|
by being a method on *Decoder, or maybe a method on the Handle itself.
|
||||||
|
No one accesses .encName anymore
|
||||||
- let encode.go and decode.go use these (for consistency)
|
- let encode.go and decode.go use these (for consistency)
|
||||||
- only problem exists for gen.go, where we create a big switch on encName.
|
- only problem exists for gen.go, where we create a big switch on encName.
|
||||||
Now, we also have to add a switch on strings.endsWith(kName, encNsName)
|
Now, we also have to add a switch on strings.endsWith(kName, encNsName)
|
||||||
@ -62,13 +66,14 @@ To handle namespaces:
|
|||||||
default {
|
default {
|
||||||
switch {
|
switch {
|
||||||
case !nsAware: panic(...)
|
case !nsAware: panic(...)
|
||||||
case strings.endsWith("nsabc"): x.abc()
|
case strings.endsWith(":abc"): x.abc()
|
||||||
|
case strings.endsWith(":def"): x.def()
|
||||||
default: panic(...)
|
default: panic(...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
The structure below accomodates this:
|
The structure below accommodates this:
|
||||||
|
|
||||||
type typeInfo struct {
|
type typeInfo struct {
|
||||||
sfi []*structFieldInfo // sorted by encName
|
sfi []*structFieldInfo // sorted by encName
|
||||||
@ -88,7 +93,10 @@ indexForEncName is now an internal helper function that takes a sorted array
|
|||||||
(one of ti.sfins or ti.sfi). It is only used by *Encoder.getStructFieldInfo(...)
|
(one of ti.sfins or ti.sfi). It is only used by *Encoder.getStructFieldInfo(...)
|
||||||
|
|
||||||
There will be a separate parser from the builder.
|
There will be a separate parser from the builder.
|
||||||
The parser will have a method: next() xmlToken method.
|
The parser will have a method: next() xmlToken method. It has lookahead support,
|
||||||
|
so you can pop multiple tokens, make a determination, and push them back in the order popped.
|
||||||
|
This will be needed to determine whether we are "nakedly" decoding a container or not.
|
||||||
|
The stack will be implemented using a slice and push/pop happens at the [0] element.
|
||||||
|
|
||||||
xmlToken has fields:
|
xmlToken has fields:
|
||||||
- type uint8: 0 | ElementStart | ElementEnd | AttrKey | AttrVal | Text
|
- type uint8: 0 | ElementStart | ElementEnd | AttrKey | AttrVal | Text
|
||||||
@ -132,7 +140,7 @@ At decode time, a structure containing the following is kept
|
|||||||
- all internal entities (<>&"' and others written in the document)
|
- all internal entities (<>&"' and others written in the document)
|
||||||
|
|
||||||
When decode starts, it parses XML namespace declarations and creates a map in the
|
When decode starts, it parses XML namespace declarations and creates a map in the
|
||||||
xmlDecDriver. While parsing, that map continously gets updated.
|
xmlDecDriver. While parsing, that map continuously gets updated.
|
||||||
The only problem happens when a namespace declaration happens on the node that it defines.
|
The only problem happens when a namespace declaration happens on the node that it defines.
|
||||||
e.g. <hn:name xmlns:hn="http://www.ugorji.net" >
|
e.g. <hn:name xmlns:hn="http://www.ugorji.net" >
|
||||||
To handle this, each Element must be fully parsed at a time,
|
To handle this, each Element must be fully parsed at a time,
|
||||||
@ -144,7 +152,7 @@ xmlns is a special attribute name.
|
|||||||
*We may decide later to allow user to use it e.g. you want to parse the xmlns mappings into a field.*
|
*We may decide later to allow user to use it e.g. you want to parse the xmlns mappings into a field.*
|
||||||
|
|
||||||
Number, bool, null, mapKey, etc can all be decoded from any xmlToken.
|
Number, bool, null, mapKey, etc can all be decoded from any xmlToken.
|
||||||
This accomodates map[int]string for example.
|
This accommodates map[int]string for example.
|
||||||
|
|
||||||
It should be possible to create a schema from the types,
|
It should be possible to create a schema from the types,
|
||||||
or vice versa (generate types from schema with appropriate tags).
|
or vice versa (generate types from schema with appropriate tags).
|
||||||
@ -178,8 +186,8 @@ An XML document is a name, a map of attributes and a list of children.
|
|||||||
Consequently, we cannot "DecodeNaked" into a map[string]interface{} (for example).
|
Consequently, we cannot "DecodeNaked" into a map[string]interface{} (for example).
|
||||||
We have to "DecodeNaked" into something that resembles XML data.
|
We have to "DecodeNaked" into something that resembles XML data.
|
||||||
|
|
||||||
To support DecodeNaked (decode into nil interface{}) we have to define some "supporting" types:
|
To support DecodeNaked (decode into nil interface{}), we have to define some "supporting" types:
|
||||||
type Name struct { // Prefered. Less allocations due to conversions.
|
type Name struct { // Preferred. Less allocations due to conversions.
|
||||||
Local string
|
Local string
|
||||||
Space string
|
Space string
|
||||||
}
|
}
|
||||||
@ -190,6 +198,8 @@ To support DecodeNaked (decode into nil interface{}) we have to define some "sup
|
|||||||
}
|
}
|
||||||
Only two "supporting" types are exposed for XML: Name and Element.
|
Only two "supporting" types are exposed for XML: Name and Element.
|
||||||
|
|
||||||
|
// ------------------
|
||||||
|
|
||||||
We considered 'type Name string' where Name is like "Space Local" (space-separated).
|
We considered 'type Name string' where Name is like "Space Local" (space-separated).
|
||||||
We decided against it, because each creation of a name would lead to
|
We decided against it, because each creation of a name would lead to
|
||||||
double allocation (first convert []byte to string, then concatenate them into a string).
|
double allocation (first convert []byte to string, then concatenate them into a string).
|
||||||
@ -215,16 +225,16 @@ intelligent accessor methods to extract information and for performance.
|
|||||||
}
|
}
|
||||||
func (x *Element) child(i) interface{} // returns string or *Element
|
func (x *Element) child(i) interface{} // returns string or *Element
|
||||||
|
|
||||||
Per XML spec and our default handling, white space is insignificant between elements,
|
// ------------------
|
||||||
specifically between parent-child or siblings. White space occuring alone between start
|
|
||||||
and end element IS significant. However, if xml:space='preserve', then we 'preserve'
|
Per XML spec and our default handling, white space is always treated as
|
||||||
all whitespace. This is more critical when doing a DecodeNaked, but MAY not be as critical
|
insignificant between elements, except in a text node. The xml:space='preserve'
|
||||||
when decoding into a typed value.
|
attribute is ignored.
|
||||||
|
|
||||||
**Note: there is no xml: namespace. The xml: attributes were defined before namespaces.**
|
**Note: there is no xml: namespace. The xml: attributes were defined before namespaces.**
|
||||||
**So treat them as just "directives" that should be interpreted to mean something**.
|
**So treat them as just "directives" that should be interpreted to mean something**.
|
||||||
|
|
||||||
On encoding, we don't add any prettifying markup (indenting, etc).
|
On encoding, we support indenting aka prettifying markup in the same way we support it for json.
|
||||||
|
|
||||||
A document or element can only be encoded/decoded from/to a struct. In this mode:
|
A document or element can only be encoded/decoded from/to a struct. In this mode:
|
||||||
- struct name maps to element name (or tag-info from _struct field)
|
- struct name maps to element name (or tag-info from _struct field)
|
||||||
@ -258,15 +268,14 @@ the struct tag signifying it should be attr, then all its fields are encoded as
|
|||||||
e.g.
|
e.g.
|
||||||
|
|
||||||
type X struct {
|
type X struct {
|
||||||
M map[string]int `codec:"m,attr"` // encode as attributes
|
M map[string]int `codec:"m,attr"` // encode keys as attributes named
|
||||||
}
|
}
|
||||||
|
|
||||||
Question:
|
Question:
|
||||||
- if encoding a map, what if map keys have spaces in them???
|
- if encoding a map, what if map keys have spaces in them???
|
||||||
Then they cannot be attributes or child elements. Error.
|
Then they cannot be attributes or child elements. Error.
|
||||||
|
|
||||||
Misc:
|
Options to consider adding later:
|
||||||
|
|
||||||
- For attribute values, normalize by trimming beginning and ending white space,
|
- For attribute values, normalize by trimming beginning and ending white space,
|
||||||
and converting every white space sequence to a single space.
|
and converting every white space sequence to a single space.
|
||||||
- ATTLIST restrictions are enforced.
|
- ATTLIST restrictions are enforced.
|
||||||
@ -284,6 +293,8 @@ Misc:
|
|||||||
CheckName bool
|
CheckName bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Misc:
|
||||||
|
|
||||||
ROADMAP (1 weeks):
|
ROADMAP (1 weeks):
|
||||||
- build encoder (1 day)
|
- build encoder (1 day)
|
||||||
- build decoder (based off xmlParser) (1 day)
|
- build decoder (based off xmlParser) (1 day)
|
||||||
@ -292,7 +303,78 @@ ROADMAP (1 weeks):
|
|||||||
- integrate and TEST (1 days)
|
- integrate and TEST (1 days)
|
||||||
- write article and post it (1 day)
|
- write article and post it (1 day)
|
||||||
|
|
||||||
|
// ---------- MORE NOTES FROM 2017-11-30 ------------
|
||||||
|
|
||||||
|
when parsing
|
||||||
|
- parse the attributes first
|
||||||
|
- then parse the nodes
|
||||||
|
|
||||||
|
basically:
|
||||||
|
- if encoding a field: we use the field name for the wrapper
|
||||||
|
- if encoding a non-field, then just use the element type name
|
||||||
|
|
||||||
|
map[string]string ==> <map><key>abc</key><value>val</value></map>... or
|
||||||
|
<map key="abc">val</map>... OR
|
||||||
|
<key1>val1</key1><key2>val2</key2>... <- PREFERED
|
||||||
|
[]string ==> <string>v1</string><string>v2</string>...
|
||||||
|
string v1 ==> <string>v1</string>
|
||||||
|
bool true ==> <bool>true</bool>
|
||||||
|
float 1.0 ==> <float>1.0</float>
|
||||||
|
...
|
||||||
|
|
||||||
|
F1 map[string]string ==> <F1><key>abc</key><value>val</value></F1>... OR
|
||||||
|
<F1 key="abc">val</F1>... OR
|
||||||
|
<F1><abc>val</abc>...</F1> <- PREFERED
|
||||||
|
F2 []string ==> <F2>v1</F2><F2>v2</F2>...
|
||||||
|
F3 bool ==> <F3>true</F3>
|
||||||
|
...
|
||||||
|
|
||||||
|
- a scalar is encoded as:
|
||||||
|
(value) of type T ==> <T><value/></T>
|
||||||
|
(value) of field F ==> <F><value/></F>
|
||||||
|
- A kv-pair is encoded as:
|
||||||
|
(key,value) ==> <map><key><value/></key></map> OR <map key="value">
|
||||||
|
(key,value) of field F ==> <F><key><value/></key></F> OR <F key="value">
|
||||||
|
- A map or struct is just a list of kv-pairs
|
||||||
|
- A list is encoded as sequences of same node e.g.
|
||||||
|
<F1 key1="value11">
|
||||||
|
<F1 key2="value12">
|
||||||
|
<F2>value21</F2>
|
||||||
|
<F2>value22</F2>
|
||||||
|
- we may have to singularize the field name, when entering into xml,
|
||||||
|
and pluralize them when encoding.
|
||||||
|
- bi-directional encode->decode->encode is not a MUST.
|
||||||
|
even encoding/xml cannot decode correctly what was encoded:
|
||||||
|
|
||||||
|
see https://play.golang.org/p/224V_nyhMS
|
||||||
|
func main() {
|
||||||
|
fmt.Println("Hello, playground")
|
||||||
|
v := []interface{}{"hello", 1, true, nil, time.Now()}
|
||||||
|
s, err := xml.Marshal(v)
|
||||||
|
fmt.Printf("err: %v, \ns: %s\n", err, s)
|
||||||
|
var v2 []interface{}
|
||||||
|
err = xml.Unmarshal(s, &v2)
|
||||||
|
fmt.Printf("err: %v, \nv2: %v\n", err, v2)
|
||||||
|
type T struct {
|
||||||
|
V []interface{}
|
||||||
|
}
|
||||||
|
v3 := T{V: v}
|
||||||
|
s, err = xml.Marshal(v3)
|
||||||
|
fmt.Printf("err: %v, \ns: %s\n", err, s)
|
||||||
|
var v4 T
|
||||||
|
err = xml.Unmarshal(s, &v4)
|
||||||
|
fmt.Printf("err: %v, \nv4: %v\n", err, v4)
|
||||||
|
}
|
||||||
|
Output:
|
||||||
|
err: <nil>,
|
||||||
|
s: <string>hello</string><int>1</int><bool>true</bool><Time>2009-11-10T23:00:00Z</Time>
|
||||||
|
err: <nil>,
|
||||||
|
v2: [<nil>]
|
||||||
|
err: <nil>,
|
||||||
|
s: <T><V>hello</V><V>1</V><V>true</V><V>2009-11-10T23:00:00Z</V></T>
|
||||||
|
err: <nil>,
|
||||||
|
v4: {[<nil> <nil> <nil> <nil>]}
|
||||||
|
-
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// ----------- PARSER -------------------
|
// ----------- PARSER -------------------
|
||||||
@ -419,7 +501,7 @@ func (h *XMLHandle) newDecDriver(d *Decoder) decDriver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *XMLHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
|
func (h *XMLHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
|
||||||
return h.SetExt(rt, tag, &setExtWrapper{i: ext})
|
return h.SetExt(rt, tag, &extWrapper{bytesExtFailer{}, ext})
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ decDriver = (*xmlDecDriver)(nil)
|
var _ decDriver = (*xmlDecDriver)(nil)
|
||||||
|
116
vendor/github.com/ugorji/go/codec/z_all_test.go
generated
vendored
116
vendor/github.com/ugorji/go/codec/z_all_test.go
generated
vendored
@ -1,3 +1,6 @@
|
|||||||
|
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||||
|
|
||||||
// +build alltests
|
// +build alltests
|
||||||
// +build go1.7
|
// +build go1.7
|
||||||
|
|
||||||
@ -41,11 +44,15 @@ func testGroupResetFlags() {
|
|||||||
testMaxInitLen = 0
|
testMaxInitLen = 0
|
||||||
testUseIoWrapper = false
|
testUseIoWrapper = false
|
||||||
testNumRepeatString = 8
|
testNumRepeatString = 8
|
||||||
|
testEncodeOptions.RecursiveEmptyCheck = false
|
||||||
|
testDecodeOptions.MapValueReset = false
|
||||||
|
testUseIoEncDec = -1
|
||||||
|
testDepth = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSuite(t *testing.T, f func(t *testing.T)) {
|
func testSuite(t *testing.T, f func(t *testing.T)) {
|
||||||
// find . -name "*_test.go" | xargs grep -e 'flag.' | cut -d '&' -f 2 | cut -d ',' -f 1 | grep -e '^test'
|
// find . -name "*_test.go" | xargs grep -e 'flag.' | cut -d '&' -f 2 | cut -d ',' -f 1 | grep -e '^test'
|
||||||
// Disregard the following: testVerbose, testInitDebug, testSkipIntf, testJsonIndent (Need a test for it)
|
// Disregard the following: testInitDebug, testSkipIntf, testJsonIndent (Need a test for it)
|
||||||
|
|
||||||
testReinit() // so flag.Parse() is called first, and never called again
|
testReinit() // so flag.Parse() is called first, and never called again
|
||||||
|
|
||||||
@ -65,20 +72,22 @@ func testSuite(t *testing.T, f func(t *testing.T)) {
|
|||||||
testCheckCircRef = true
|
testCheckCircRef = true
|
||||||
testUseReset = true
|
testUseReset = true
|
||||||
testDecodeOptions.MapValueReset = true
|
testDecodeOptions.MapValueReset = true
|
||||||
|
testEncodeOptions.RecursiveEmptyCheck = true
|
||||||
testReinit()
|
testReinit()
|
||||||
t.Run("optionsTrue", f)
|
t.Run("optionsTrue", f)
|
||||||
|
|
||||||
testEncodeOptions.AsSymbols = AsSymbolAll
|
testDepth = 6
|
||||||
|
testReinit()
|
||||||
|
t.Run("optionsTrue-deepstruct", f)
|
||||||
|
testDepth = 0
|
||||||
|
|
||||||
|
// testEncodeOptions.AsSymbols = AsSymbolAll
|
||||||
testUseIoWrapper = true
|
testUseIoWrapper = true
|
||||||
testReinit()
|
testReinit()
|
||||||
t.Run("optionsTrue-ioWrapper", f)
|
t.Run("optionsTrue-ioWrapper", f)
|
||||||
|
|
||||||
testUseIoEncDec = -1
|
testUseIoEncDec = -1
|
||||||
|
|
||||||
testDepth = 6
|
|
||||||
testReinit()
|
|
||||||
t.Run("optionsTrue-deepstruct", f)
|
|
||||||
|
|
||||||
// make buffer small enough so that we have to re-fill multiple times.
|
// make buffer small enough so that we have to re-fill multiple times.
|
||||||
testSkipRPCTests = true
|
testSkipRPCTests = true
|
||||||
testUseIoEncDec = 128
|
testUseIoEncDec = 128
|
||||||
@ -110,8 +119,7 @@ func testSuite(t *testing.T, f func(t *testing.T)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
z='codec_test.go'
|
find . -name "codec_test.go" | xargs grep -e '^func Test' | \
|
||||||
find . -name "$z" | xargs grep -e '^func Test' | \
|
|
||||||
cut -d '(' -f 1 | cut -d ' ' -f 2 | \
|
cut -d '(' -f 1 | cut -d ' ' -f 2 | \
|
||||||
while read f; do echo "t.Run(\"$f\", $f)"; done
|
while read f; do echo "t.Run(\"$f\", $f)"; done
|
||||||
*/
|
*/
|
||||||
@ -211,6 +219,21 @@ func testCodecGroup(t *testing.T) {
|
|||||||
t.Run("TestMsgpackUintToInt", TestMsgpackUintToInt)
|
t.Run("TestMsgpackUintToInt", TestMsgpackUintToInt)
|
||||||
t.Run("TestBincUintToInt", TestBincUintToInt)
|
t.Run("TestBincUintToInt", TestBincUintToInt)
|
||||||
t.Run("TestSimpleUintToInt", TestSimpleUintToInt)
|
t.Run("TestSimpleUintToInt", TestSimpleUintToInt)
|
||||||
|
t.Run("TestJsonDifferentMapOrSliceType", TestJsonDifferentMapOrSliceType)
|
||||||
|
t.Run("TestCborDifferentMapOrSliceType", TestCborDifferentMapOrSliceType)
|
||||||
|
t.Run("TestMsgpackDifferentMapOrSliceType", TestMsgpackDifferentMapOrSliceType)
|
||||||
|
t.Run("TestBincDifferentMapOrSliceType", TestBincDifferentMapOrSliceType)
|
||||||
|
t.Run("TestSimpleDifferentMapOrSliceType", TestSimpleDifferentMapOrSliceType)
|
||||||
|
t.Run("TestJsonScalars", TestJsonScalars)
|
||||||
|
t.Run("TestCborScalars", TestCborScalars)
|
||||||
|
t.Run("TestMsgpackScalars", TestMsgpackScalars)
|
||||||
|
t.Run("TestBincScalars", TestBincScalars)
|
||||||
|
t.Run("TestSimpleScalars", TestSimpleScalars)
|
||||||
|
t.Run("TestJsonIntfMapping", TestJsonIntfMapping)
|
||||||
|
t.Run("TestCborIntfMapping", TestCborIntfMapping)
|
||||||
|
t.Run("TestMsgpackIntfMapping", TestMsgpackIntfMapping)
|
||||||
|
t.Run("TestBincIntfMapping", TestBincIntfMapping)
|
||||||
|
t.Run("TestSimpleIntfMapping", TestSimpleIntfMapping)
|
||||||
|
|
||||||
t.Run("TestJsonInvalidUnicode", TestJsonInvalidUnicode)
|
t.Run("TestJsonInvalidUnicode", TestJsonInvalidUnicode)
|
||||||
t.Run("TestCborHalfFloat", TestCborHalfFloat)
|
t.Run("TestCborHalfFloat", TestCborHalfFloat)
|
||||||
@ -240,6 +263,9 @@ func testJsonGroup(t *testing.T) {
|
|||||||
t.Run("TestJsonInvalidUnicode", TestJsonInvalidUnicode)
|
t.Run("TestJsonInvalidUnicode", TestJsonInvalidUnicode)
|
||||||
t.Run("TestJsonTime", TestJsonTime)
|
t.Run("TestJsonTime", TestJsonTime)
|
||||||
t.Run("TestJsonUintToInt", TestJsonUintToInt)
|
t.Run("TestJsonUintToInt", TestJsonUintToInt)
|
||||||
|
t.Run("TestJsonDifferentMapOrSliceType", TestJsonDifferentMapOrSliceType)
|
||||||
|
t.Run("TestJsonScalars", TestJsonScalars)
|
||||||
|
t.Run("TestJsonIntfMapping", TestJsonIntfMapping)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testBincGroup(t *testing.T) {
|
func testBincGroup(t *testing.T) {
|
||||||
@ -261,6 +287,8 @@ func testBincGroup(t *testing.T) {
|
|||||||
t.Run("TestBincMammothMapsAndSlices", TestBincMammothMapsAndSlices)
|
t.Run("TestBincMammothMapsAndSlices", TestBincMammothMapsAndSlices)
|
||||||
t.Run("TestBincTime", TestBincTime)
|
t.Run("TestBincTime", TestBincTime)
|
||||||
t.Run("TestBincUintToInt", TestBincUintToInt)
|
t.Run("TestBincUintToInt", TestBincUintToInt)
|
||||||
|
t.Run("TestBincDifferentMapOrSliceType", TestBincDifferentMapOrSliceType)
|
||||||
|
t.Run("TestBincScalars", TestBincScalars)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCborGroup(t *testing.T) {
|
func testCborGroup(t *testing.T) {
|
||||||
@ -283,6 +311,8 @@ func testCborGroup(t *testing.T) {
|
|||||||
t.Run("TestCborMammothMapsAndSlices", TestCborMammothMapsAndSlices)
|
t.Run("TestCborMammothMapsAndSlices", TestCborMammothMapsAndSlices)
|
||||||
t.Run("TestCborTime", TestCborTime)
|
t.Run("TestCborTime", TestCborTime)
|
||||||
t.Run("TestCborUintToInt", TestCborUintToInt)
|
t.Run("TestCborUintToInt", TestCborUintToInt)
|
||||||
|
t.Run("TestCborDifferentMapOrSliceType", TestCborDifferentMapOrSliceType)
|
||||||
|
t.Run("TestCborScalars", TestCborScalars)
|
||||||
|
|
||||||
t.Run("TestCborHalfFloat", TestCborHalfFloat)
|
t.Run("TestCborHalfFloat", TestCborHalfFloat)
|
||||||
}
|
}
|
||||||
@ -305,6 +335,42 @@ func testMsgpackGroup(t *testing.T) {
|
|||||||
t.Run("TestMsgpackMammothMapsAndSlices", TestMsgpackMammothMapsAndSlices)
|
t.Run("TestMsgpackMammothMapsAndSlices", TestMsgpackMammothMapsAndSlices)
|
||||||
t.Run("TestMsgpackTime", TestMsgpackTime)
|
t.Run("TestMsgpackTime", TestMsgpackTime)
|
||||||
t.Run("TestMsgpackUintToInt", TestMsgpackUintToInt)
|
t.Run("TestMsgpackUintToInt", TestMsgpackUintToInt)
|
||||||
|
t.Run("TestMsgpackDifferentMapOrSliceType", TestMsgpackDifferentMapOrSliceType)
|
||||||
|
t.Run("TestMsgpackScalars", TestMsgpackScalars)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSimpleGroup(t *testing.T) {
|
||||||
|
t.Run("TestSimpleCodecsTable", TestSimpleCodecsTable)
|
||||||
|
t.Run("TestSimpleCodecsMisc", TestSimpleCodecsMisc)
|
||||||
|
t.Run("TestSimpleCodecsEmbeddedPointer", TestSimpleCodecsEmbeddedPointer)
|
||||||
|
t.Run("TestSimpleStdEncIntf", TestSimpleStdEncIntf)
|
||||||
|
t.Run("TestSimpleMammoth", TestSimpleMammoth)
|
||||||
|
t.Run("TestSimpleRaw", TestSimpleRaw)
|
||||||
|
t.Run("TestSimpleRpcGo", TestSimpleRpcGo)
|
||||||
|
t.Run("TestSimpleSwallowAndZero", TestSimpleSwallowAndZero)
|
||||||
|
t.Run("TestSimpleRawExt", TestSimpleRawExt)
|
||||||
|
t.Run("TestSimpleMapStructKey", TestSimpleMapStructKey)
|
||||||
|
t.Run("TestSimpleDecodeNilMapValue", TestSimpleDecodeNilMapValue)
|
||||||
|
t.Run("TestSimpleEmbeddedFieldPrecedence", TestSimpleEmbeddedFieldPrecedence)
|
||||||
|
t.Run("TestSimpleLargeContainerLen", TestSimpleLargeContainerLen)
|
||||||
|
t.Run("TestSimpleMammothMapsAndSlices", TestSimpleMammothMapsAndSlices)
|
||||||
|
t.Run("TestSimpleTime", TestSimpleTime)
|
||||||
|
t.Run("TestSimpleUintToInt", TestSimpleUintToInt)
|
||||||
|
t.Run("TestSimpleDifferentMapOrSliceType", TestSimpleDifferentMapOrSliceType)
|
||||||
|
t.Run("TestSimpleScalars", TestSimpleScalars)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSimpleMammothGroup(t *testing.T) {
|
||||||
|
t.Run("TestSimpleMammothMapsAndSlices", TestSimpleMammothMapsAndSlices)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testRpcGroup(t *testing.T) {
|
||||||
|
t.Run("TestBincRpcGo", TestBincRpcGo)
|
||||||
|
t.Run("TestSimpleRpcGo", TestSimpleRpcGo)
|
||||||
|
t.Run("TestMsgpackRpcGo", TestMsgpackRpcGo)
|
||||||
|
t.Run("TestCborRpcGo", TestCborRpcGo)
|
||||||
|
t.Run("TestJsonRpcGo", TestJsonRpcGo)
|
||||||
|
t.Run("TestMsgpackRpcSpec", TestMsgpackRpcSpec)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCodecSuite(t *testing.T) {
|
func TestCodecSuite(t *testing.T) {
|
||||||
@ -342,17 +408,23 @@ func TestCodecSuite(t *testing.T) {
|
|||||||
|
|
||||||
testCborH.IndefiniteLength = oldIndefLen
|
testCborH.IndefiniteLength = oldIndefLen
|
||||||
|
|
||||||
oldSymbols := testBincH.getBasicHandle().AsSymbols
|
oldTimeRFC3339 := testCborH.TimeRFC3339
|
||||||
|
testCborH.TimeRFC3339 = !testCborH.TimeRFC3339
|
||||||
|
testReinit()
|
||||||
|
t.Run("cbor-rfc3339", testCborGroup)
|
||||||
|
testCborH.TimeRFC3339 = oldTimeRFC3339
|
||||||
|
|
||||||
testBincH.getBasicHandle().AsSymbols = AsSymbolNone
|
oldSymbols := testBincH.AsSymbols
|
||||||
|
|
||||||
|
testBincH.AsSymbols = 2 // AsSymbolNone
|
||||||
testReinit()
|
testReinit()
|
||||||
t.Run("binc-no-symbols", testBincGroup)
|
t.Run("binc-no-symbols", testBincGroup)
|
||||||
|
|
||||||
testBincH.getBasicHandle().AsSymbols = AsSymbolAll
|
testBincH.AsSymbols = 1 // AsSymbolAll
|
||||||
testReinit()
|
testReinit()
|
||||||
t.Run("binc-all-symbols", testBincGroup)
|
t.Run("binc-all-symbols", testBincGroup)
|
||||||
|
|
||||||
testBincH.getBasicHandle().AsSymbols = oldSymbols
|
testBincH.AsSymbols = oldSymbols
|
||||||
|
|
||||||
oldWriteExt := testMsgpackH.WriteExt
|
oldWriteExt := testMsgpackH.WriteExt
|
||||||
oldNoFixedNum := testMsgpackH.NoFixedNum
|
oldNoFixedNum := testMsgpackH.NoFixedNum
|
||||||
@ -369,6 +441,26 @@ func TestCodecSuite(t *testing.T) {
|
|||||||
|
|
||||||
testMsgpackH.NoFixedNum = oldNoFixedNum
|
testMsgpackH.NoFixedNum = oldNoFixedNum
|
||||||
|
|
||||||
|
oldEncZeroValuesAsNil := testSimpleH.EncZeroValuesAsNil
|
||||||
|
testSimpleH.EncZeroValuesAsNil = !testSimpleH.EncZeroValuesAsNil
|
||||||
|
testUseMust = true
|
||||||
|
testReinit()
|
||||||
|
t.Run("simple-enczeroasnil", testSimpleMammothGroup) // testSimpleGroup
|
||||||
|
testSimpleH.EncZeroValuesAsNil = oldEncZeroValuesAsNil
|
||||||
|
|
||||||
|
oldRpcBufsize := testRpcBufsize
|
||||||
|
testRpcBufsize = 0
|
||||||
|
t.Run("rpc-buf-0", testRpcGroup)
|
||||||
|
testRpcBufsize = 0
|
||||||
|
t.Run("rpc-buf-00", testRpcGroup)
|
||||||
|
testRpcBufsize = 0
|
||||||
|
t.Run("rpc-buf-000", testRpcGroup)
|
||||||
|
testRpcBufsize = 16
|
||||||
|
t.Run("rpc-buf-16", testRpcGroup)
|
||||||
|
testRpcBufsize = 2048
|
||||||
|
t.Run("rpc-buf-2048", testRpcGroup)
|
||||||
|
testRpcBufsize = oldRpcBufsize
|
||||||
|
|
||||||
testGroupResetFlags()
|
testGroupResetFlags()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
49
vendor/github.com/ugorji/go/codec/z_all_x_bench_gen_test.go
generated
vendored
49
vendor/github.com/ugorji/go/codec/z_all_x_bench_gen_test.go
generated
vendored
@ -1,49 +0,0 @@
|
|||||||
// +build alltests
|
|
||||||
// +build x
|
|
||||||
// +build go1.7
|
|
||||||
// +build generated
|
|
||||||
|
|
||||||
package codec
|
|
||||||
|
|
||||||
// see notes in z_all_bench_test.go
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func benchmarkCodecXGenGroup(t *testing.B) {
|
|
||||||
logT(nil, "\n-------------------------------\n")
|
|
||||||
t.Run("Benchmark__Msgpack____Encode", Benchmark__Msgpack____Encode)
|
|
||||||
t.Run("Benchmark__Binc_______Encode", Benchmark__Binc_______Encode)
|
|
||||||
t.Run("Benchmark__Simple_____Encode", Benchmark__Simple_____Encode)
|
|
||||||
t.Run("Benchmark__Cbor_______Encode", Benchmark__Cbor_______Encode)
|
|
||||||
t.Run("Benchmark__Json_______Encode", Benchmark__Json_______Encode)
|
|
||||||
t.Run("Benchmark__Std_Json___Encode", Benchmark__Std_Json___Encode)
|
|
||||||
t.Run("Benchmark__Gob________Encode", Benchmark__Gob________Encode)
|
|
||||||
t.Run("Benchmark__JsonIter___Encode", Benchmark__JsonIter___Encode)
|
|
||||||
t.Run("Benchmark__Bson_______Encode", Benchmark__Bson_______Encode)
|
|
||||||
t.Run("Benchmark__VMsgpack___Encode", Benchmark__VMsgpack___Encode)
|
|
||||||
t.Run("Benchmark__Msgp_______Encode", Benchmark__Msgp_______Encode)
|
|
||||||
t.Run("Benchmark__Easyjson___Encode", Benchmark__Easyjson___Encode)
|
|
||||||
t.Run("Benchmark__Ffjson_____Encode", Benchmark__Ffjson_____Encode)
|
|
||||||
t.Run("Benchmark__Gcbor______Encode", Benchmark__Gcbor______Encode)
|
|
||||||
t.Run("Benchmark__Xdr________Encode", Benchmark__Xdr________Encode)
|
|
||||||
t.Run("Benchmark__Sereal_____Encode", Benchmark__Sereal_____Encode)
|
|
||||||
|
|
||||||
t.Run("Benchmark__Msgpack____Decode", Benchmark__Msgpack____Decode)
|
|
||||||
t.Run("Benchmark__Binc_______Decode", Benchmark__Binc_______Decode)
|
|
||||||
t.Run("Benchmark__Simple_____Decode", Benchmark__Simple_____Decode)
|
|
||||||
t.Run("Benchmark__Cbor_______Decode", Benchmark__Cbor_______Decode)
|
|
||||||
t.Run("Benchmark__Json_______Decode", Benchmark__Json_______Decode)
|
|
||||||
t.Run("Benchmark__Std_Json___Decode", Benchmark__Std_Json___Decode)
|
|
||||||
t.Run("Benchmark__Gob________Decode", Benchmark__Gob________Decode)
|
|
||||||
t.Run("Benchmark__JsonIter___Decode", Benchmark__JsonIter___Decode)
|
|
||||||
t.Run("Benchmark__Bson_______Decode", Benchmark__Bson_______Decode)
|
|
||||||
t.Run("Benchmark__VMsgpack___Decode", Benchmark__VMsgpack___Decode)
|
|
||||||
t.Run("Benchmark__Msgp_______Decode", Benchmark__Msgp_______Decode)
|
|
||||||
t.Run("Benchmark__Easyjson___Decode", Benchmark__Easyjson___Decode)
|
|
||||||
t.Run("Benchmark__Ffjson_____Decode", Benchmark__Ffjson_____Decode)
|
|
||||||
t.Run("Benchmark__Gcbor______Decode", Benchmark__Gcbor______Decode)
|
|
||||||
t.Run("Benchmark__Xdr________Decode", Benchmark__Xdr________Decode)
|
|
||||||
t.Run("Benchmark__Sereal_____Decode", Benchmark__Sereal_____Decode)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkCodecXGenSuite(t *testing.B) { benchmarkSuite(t, benchmarkCodecXGenGroup) }
|
|
2
vendor/golang.org/x/crypto/acme/acme_test.go
generated
vendored
2
vendor/golang.org/x/crypto/acme/acme_test.go
generated
vendored
@ -946,7 +946,7 @@ func TestNonce_add(t *testing.T) {
|
|||||||
c.addNonce(http.Header{"Replay-Nonce": {}})
|
c.addNonce(http.Header{"Replay-Nonce": {}})
|
||||||
c.addNonce(http.Header{"Replay-Nonce": {"nonce"}})
|
c.addNonce(http.Header{"Replay-Nonce": {"nonce"}})
|
||||||
|
|
||||||
nonces := map[string]struct{}{"nonce": struct{}{}}
|
nonces := map[string]struct{}{"nonce": {}}
|
||||||
if !reflect.DeepEqual(c.nonces, nonces) {
|
if !reflect.DeepEqual(c.nonces, nonces) {
|
||||||
t.Errorf("c.nonces = %q; want %q", c.nonces, nonces)
|
t.Errorf("c.nonces = %q; want %q", c.nonces, nonces)
|
||||||
}
|
}
|
||||||
|
308
vendor/golang.org/x/crypto/acme/autocert/autocert.go
generated
vendored
308
vendor/golang.org/x/crypto/acme/autocert/autocert.go
generated
vendored
@ -24,7 +24,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
mathrand "math/rand"
|
mathrand "math/rand"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -80,8 +82,9 @@ func defaultHostPolicy(context.Context, string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Manager is a stateful certificate manager built on top of acme.Client.
|
// Manager is a stateful certificate manager built on top of acme.Client.
|
||||||
// It obtains and refreshes certificates automatically,
|
// It obtains and refreshes certificates automatically using "tls-sni-01",
|
||||||
// as well as providing them to a TLS server via tls.Config.
|
// "tls-sni-02" and "http-01" challenge types, as well as providing them
|
||||||
|
// to a TLS server via tls.Config.
|
||||||
//
|
//
|
||||||
// You must specify a cache implementation, such as DirCache,
|
// You must specify a cache implementation, such as DirCache,
|
||||||
// to reuse obtained certificates across program restarts.
|
// to reuse obtained certificates across program restarts.
|
||||||
@ -150,15 +153,26 @@ type Manager struct {
|
|||||||
stateMu sync.Mutex
|
stateMu sync.Mutex
|
||||||
state map[string]*certState // keyed by domain name
|
state map[string]*certState // keyed by domain name
|
||||||
|
|
||||||
// tokenCert is keyed by token domain name, which matches server name
|
|
||||||
// of ClientHello. Keys always have ".acme.invalid" suffix.
|
|
||||||
tokenCertMu sync.RWMutex
|
|
||||||
tokenCert map[string]*tls.Certificate
|
|
||||||
|
|
||||||
// renewal tracks the set of domains currently running renewal timers.
|
// renewal tracks the set of domains currently running renewal timers.
|
||||||
// It is keyed by domain name.
|
// It is keyed by domain name.
|
||||||
renewalMu sync.Mutex
|
renewalMu sync.Mutex
|
||||||
renewal map[string]*domainRenewal
|
renewal map[string]*domainRenewal
|
||||||
|
|
||||||
|
// tokensMu guards the rest of the fields: tryHTTP01, certTokens and httpTokens.
|
||||||
|
tokensMu sync.RWMutex
|
||||||
|
// tryHTTP01 indicates whether the Manager should try "http-01" challenge type
|
||||||
|
// during the authorization flow.
|
||||||
|
tryHTTP01 bool
|
||||||
|
// httpTokens contains response body values for http-01 challenges
|
||||||
|
// and is keyed by the URL path at which a challenge response is expected
|
||||||
|
// to be provisioned.
|
||||||
|
// The entries are stored for the duration of the authorization flow.
|
||||||
|
httpTokens map[string][]byte
|
||||||
|
// certTokens contains temporary certificates for tls-sni challenges
|
||||||
|
// and is keyed by token domain name, which matches server name of ClientHello.
|
||||||
|
// Keys always have ".acme.invalid" suffix.
|
||||||
|
// The entries are stored for the duration of the authorization flow.
|
||||||
|
certTokens map[string]*tls.Certificate
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCertificate implements the tls.Config.GetCertificate hook.
|
// GetCertificate implements the tls.Config.GetCertificate hook.
|
||||||
@ -185,14 +199,16 @@ func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate,
|
|||||||
return nil, errors.New("acme/autocert: server name contains invalid character")
|
return nil, errors.New("acme/autocert: server name contains invalid character")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In the worst-case scenario, the timeout needs to account for caching, host policy,
|
||||||
|
// domain ownership verification and certificate issuance.
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// check whether this is a token cert requested for TLS-SNI challenge
|
// check whether this is a token cert requested for TLS-SNI challenge
|
||||||
if strings.HasSuffix(name, ".acme.invalid") {
|
if strings.HasSuffix(name, ".acme.invalid") {
|
||||||
m.tokenCertMu.RLock()
|
m.tokensMu.RLock()
|
||||||
defer m.tokenCertMu.RUnlock()
|
defer m.tokensMu.RUnlock()
|
||||||
if cert := m.tokenCert[name]; cert != nil {
|
if cert := m.certTokens[name]; cert != nil {
|
||||||
return cert, nil
|
return cert, nil
|
||||||
}
|
}
|
||||||
if cert, err := m.cacheGet(ctx, name); err == nil {
|
if cert, err := m.cacheGet(ctx, name); err == nil {
|
||||||
@ -224,6 +240,68 @@ func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate,
|
|||||||
return cert, nil
|
return cert, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HTTPHandler configures the Manager to provision ACME "http-01" challenge responses.
|
||||||
|
// It returns an http.Handler that responds to the challenges and must be
|
||||||
|
// running on port 80. If it receives a request that is not an ACME challenge,
|
||||||
|
// it delegates the request to the optional fallback handler.
|
||||||
|
//
|
||||||
|
// If fallback is nil, the returned handler redirects all GET and HEAD requests
|
||||||
|
// to the default TLS port 443 with 302 Found status code, preserving the original
|
||||||
|
// request path and query. It responds with 400 Bad Request to all other HTTP methods.
|
||||||
|
// The fallback is not protected by the optional HostPolicy.
|
||||||
|
//
|
||||||
|
// Because the fallback handler is run with unencrypted port 80 requests,
|
||||||
|
// the fallback should not serve TLS-only requests.
|
||||||
|
//
|
||||||
|
// If HTTPHandler is never called, the Manager will only use TLS SNI
|
||||||
|
// challenges for domain verification.
|
||||||
|
func (m *Manager) HTTPHandler(fallback http.Handler) http.Handler {
|
||||||
|
m.tokensMu.Lock()
|
||||||
|
defer m.tokensMu.Unlock()
|
||||||
|
m.tryHTTP01 = true
|
||||||
|
|
||||||
|
if fallback == nil {
|
||||||
|
fallback = http.HandlerFunc(handleHTTPRedirect)
|
||||||
|
}
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if !strings.HasPrefix(r.URL.Path, "/.well-known/acme-challenge/") {
|
||||||
|
fallback.ServeHTTP(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// A reasonable context timeout for cache and host policy only,
|
||||||
|
// because we don't wait for a new certificate issuance here.
|
||||||
|
ctx, cancel := context.WithTimeout(r.Context(), time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
if err := m.hostPolicy()(ctx, r.Host); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusForbidden)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data, err := m.httpToken(ctx, r.URL.Path)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Write(data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleHTTPRedirect(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != "GET" && r.Method != "HEAD" {
|
||||||
|
http.Error(w, "Use HTTPS", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
target := "https://" + stripPort(r.Host) + r.URL.RequestURI()
|
||||||
|
http.Redirect(w, r, target, http.StatusFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
func stripPort(hostport string) string {
|
||||||
|
host, _, err := net.SplitHostPort(hostport)
|
||||||
|
if err != nil {
|
||||||
|
return hostport
|
||||||
|
}
|
||||||
|
return net.JoinHostPort(host, "443")
|
||||||
|
}
|
||||||
|
|
||||||
// cert returns an existing certificate either from m.state or cache.
|
// cert returns an existing certificate either from m.state or cache.
|
||||||
// If a certificate is found in cache but not in m.state, the latter will be filled
|
// If a certificate is found in cache but not in m.state, the latter will be filled
|
||||||
// with the cached value.
|
// with the cached value.
|
||||||
@ -442,13 +520,14 @@ func (m *Manager) certState(domain string) (*certState, error) {
|
|||||||
// authorizedCert starts the domain ownership verification process and requests a new cert upon success.
|
// authorizedCert starts the domain ownership verification process and requests a new cert upon success.
|
||||||
// The key argument is the certificate private key.
|
// The key argument is the certificate private key.
|
||||||
func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, domain string) (der [][]byte, leaf *x509.Certificate, err error) {
|
func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, domain string) (der [][]byte, leaf *x509.Certificate, err error) {
|
||||||
if err := m.verify(ctx, domain); err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
client, err := m.acmeClient(ctx)
|
client, err := m.acmeClient(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := m.verify(ctx, client, domain); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
csr, err := certRequest(key, domain)
|
csr, err := certRequest(key, domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -464,98 +543,171 @@ func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, domain
|
|||||||
return der, leaf, nil
|
return der, leaf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify starts a new identifier (domain) authorization flow.
|
// verify runs the identifier (domain) authorization flow
|
||||||
// It prepares a challenge response and then blocks until the authorization
|
// using each applicable ACME challenge type.
|
||||||
// is marked as "completed" by the CA (either succeeded or failed).
|
func (m *Manager) verify(ctx context.Context, client *acme.Client, domain string) error {
|
||||||
//
|
// The list of challenge types we'll try to fulfill
|
||||||
// verify returns nil iff the verification was successful.
|
// in this specific order.
|
||||||
func (m *Manager) verify(ctx context.Context, domain string) error {
|
challengeTypes := []string{"tls-sni-02", "tls-sni-01"}
|
||||||
client, err := m.acmeClient(ctx)
|
m.tokensMu.RLock()
|
||||||
if err != nil {
|
if m.tryHTTP01 {
|
||||||
return err
|
challengeTypes = append(challengeTypes, "http-01")
|
||||||
}
|
}
|
||||||
|
m.tokensMu.RUnlock()
|
||||||
|
|
||||||
// start domain authorization and get the challenge
|
var nextTyp int // challengeType index of the next challenge type to try
|
||||||
|
for {
|
||||||
|
// Start domain authorization and get the challenge.
|
||||||
authz, err := client.Authorize(ctx, domain)
|
authz, err := client.Authorize(ctx, domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// maybe don't need to at all
|
// No point in accepting challenges if the authorization status
|
||||||
if authz.Status == acme.StatusValid {
|
// is in a final state.
|
||||||
return nil
|
switch authz.Status {
|
||||||
|
case acme.StatusValid:
|
||||||
|
return nil // already authorized
|
||||||
|
case acme.StatusInvalid:
|
||||||
|
return fmt.Errorf("acme/autocert: invalid authorization %q", authz.URI)
|
||||||
}
|
}
|
||||||
|
|
||||||
// pick a challenge: prefer tls-sni-02 over tls-sni-01
|
// Pick the next preferred challenge.
|
||||||
// TODO: consider authz.Combinations
|
|
||||||
var chal *acme.Challenge
|
var chal *acme.Challenge
|
||||||
for _, c := range authz.Challenges {
|
for chal == nil && nextTyp < len(challengeTypes) {
|
||||||
if c.Type == "tls-sni-02" {
|
chal = pickChallenge(challengeTypes[nextTyp], authz.Challenges)
|
||||||
chal = c
|
nextTyp++
|
||||||
break
|
|
||||||
}
|
|
||||||
if c.Type == "tls-sni-01" {
|
|
||||||
chal = c
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if chal == nil {
|
if chal == nil {
|
||||||
return errors.New("acme/autocert: no supported challenge type found")
|
return fmt.Errorf("acme/autocert: unable to authorize %q; tried %q", domain, challengeTypes)
|
||||||
}
|
|
||||||
|
|
||||||
// create a token cert for the challenge response
|
|
||||||
var (
|
|
||||||
cert tls.Certificate
|
|
||||||
name string
|
|
||||||
)
|
|
||||||
switch chal.Type {
|
|
||||||
case "tls-sni-01":
|
|
||||||
cert, name, err = client.TLSSNI01ChallengeCert(chal.Token)
|
|
||||||
case "tls-sni-02":
|
|
||||||
cert, name, err = client.TLSSNI02ChallengeCert(chal.Token)
|
|
||||||
default:
|
|
||||||
err = fmt.Errorf("acme/autocert: unknown challenge type %q", chal.Type)
|
|
||||||
}
|
}
|
||||||
|
cleanup, err := m.fulfill(ctx, client, chal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
continue
|
||||||
}
|
}
|
||||||
m.putTokenCert(ctx, name, &cert)
|
defer cleanup()
|
||||||
defer func() {
|
|
||||||
// verification has ended at this point
|
|
||||||
// don't need token cert anymore
|
|
||||||
go m.deleteTokenCert(name)
|
|
||||||
}()
|
|
||||||
|
|
||||||
// ready to fulfill the challenge
|
|
||||||
if _, err := client.Accept(ctx, chal); err != nil {
|
if _, err := client.Accept(ctx, chal); err != nil {
|
||||||
return err
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// A challenge is fulfilled and accepted: wait for the CA to validate.
|
||||||
|
if _, err := client.WaitAuthorization(ctx, authz.URI); err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// wait for the CA to validate
|
|
||||||
_, err = client.WaitAuthorization(ctx, authz.URI)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// putTokenCert stores the cert under the named key in both m.tokenCert map
|
// fulfill provisions a response to the challenge chal.
|
||||||
// and m.Cache.
|
// The cleanup is non-nil only if provisioning succeeded.
|
||||||
func (m *Manager) putTokenCert(ctx context.Context, name string, cert *tls.Certificate) {
|
func (m *Manager) fulfill(ctx context.Context, client *acme.Client, chal *acme.Challenge) (cleanup func(), err error) {
|
||||||
m.tokenCertMu.Lock()
|
switch chal.Type {
|
||||||
defer m.tokenCertMu.Unlock()
|
case "tls-sni-01":
|
||||||
if m.tokenCert == nil {
|
cert, name, err := client.TLSSNI01ChallengeCert(chal.Token)
|
||||||
m.tokenCert = make(map[string]*tls.Certificate)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
m.tokenCert[name] = cert
|
m.putCertToken(ctx, name, &cert)
|
||||||
|
return func() { go m.deleteCertToken(name) }, nil
|
||||||
|
case "tls-sni-02":
|
||||||
|
cert, name, err := client.TLSSNI02ChallengeCert(chal.Token)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
m.putCertToken(ctx, name, &cert)
|
||||||
|
return func() { go m.deleteCertToken(name) }, nil
|
||||||
|
case "http-01":
|
||||||
|
resp, err := client.HTTP01ChallengeResponse(chal.Token)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
p := client.HTTP01ChallengePath(chal.Token)
|
||||||
|
m.putHTTPToken(ctx, p, resp)
|
||||||
|
return func() { go m.deleteHTTPToken(p) }, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("acme/autocert: unknown challenge type %q", chal.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
func pickChallenge(typ string, chal []*acme.Challenge) *acme.Challenge {
|
||||||
|
for _, c := range chal {
|
||||||
|
if c.Type == typ {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// putCertToken stores the cert under the named key in both m.certTokens map
|
||||||
|
// and m.Cache.
|
||||||
|
func (m *Manager) putCertToken(ctx context.Context, name string, cert *tls.Certificate) {
|
||||||
|
m.tokensMu.Lock()
|
||||||
|
defer m.tokensMu.Unlock()
|
||||||
|
if m.certTokens == nil {
|
||||||
|
m.certTokens = make(map[string]*tls.Certificate)
|
||||||
|
}
|
||||||
|
m.certTokens[name] = cert
|
||||||
m.cachePut(ctx, name, cert)
|
m.cachePut(ctx, name, cert)
|
||||||
}
|
}
|
||||||
|
|
||||||
// deleteTokenCert removes the token certificate for the specified domain name
|
// deleteCertToken removes the token certificate for the specified domain name
|
||||||
// from both m.tokenCert map and m.Cache.
|
// from both m.certTokens map and m.Cache.
|
||||||
func (m *Manager) deleteTokenCert(name string) {
|
func (m *Manager) deleteCertToken(name string) {
|
||||||
m.tokenCertMu.Lock()
|
m.tokensMu.Lock()
|
||||||
defer m.tokenCertMu.Unlock()
|
defer m.tokensMu.Unlock()
|
||||||
delete(m.tokenCert, name)
|
delete(m.certTokens, name)
|
||||||
if m.Cache != nil {
|
if m.Cache != nil {
|
||||||
m.Cache.Delete(context.Background(), name)
|
m.Cache.Delete(context.Background(), name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// httpToken retrieves an existing http-01 token value from an in-memory map
|
||||||
|
// or the optional cache.
|
||||||
|
func (m *Manager) httpToken(ctx context.Context, tokenPath string) ([]byte, error) {
|
||||||
|
m.tokensMu.RLock()
|
||||||
|
defer m.tokensMu.RUnlock()
|
||||||
|
if v, ok := m.httpTokens[tokenPath]; ok {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
if m.Cache == nil {
|
||||||
|
return nil, fmt.Errorf("acme/autocert: no token at %q", tokenPath)
|
||||||
|
}
|
||||||
|
return m.Cache.Get(ctx, httpTokenCacheKey(tokenPath))
|
||||||
|
}
|
||||||
|
|
||||||
|
// putHTTPToken stores an http-01 token value using tokenPath as key
|
||||||
|
// in both in-memory map and the optional Cache.
|
||||||
|
//
|
||||||
|
// It ignores any error returned from Cache.Put.
|
||||||
|
func (m *Manager) putHTTPToken(ctx context.Context, tokenPath, val string) {
|
||||||
|
m.tokensMu.Lock()
|
||||||
|
defer m.tokensMu.Unlock()
|
||||||
|
if m.httpTokens == nil {
|
||||||
|
m.httpTokens = make(map[string][]byte)
|
||||||
|
}
|
||||||
|
b := []byte(val)
|
||||||
|
m.httpTokens[tokenPath] = b
|
||||||
|
if m.Cache != nil {
|
||||||
|
m.Cache.Put(ctx, httpTokenCacheKey(tokenPath), b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// deleteHTTPToken removes an http-01 token value from both in-memory map
|
||||||
|
// and the optional Cache, ignoring any error returned from the latter.
|
||||||
|
//
|
||||||
|
// If m.Cache is non-nil, it blocks until Cache.Delete returns without a timeout.
|
||||||
|
func (m *Manager) deleteHTTPToken(tokenPath string) {
|
||||||
|
m.tokensMu.Lock()
|
||||||
|
defer m.tokensMu.Unlock()
|
||||||
|
delete(m.httpTokens, tokenPath)
|
||||||
|
if m.Cache != nil {
|
||||||
|
m.Cache.Delete(context.Background(), httpTokenCacheKey(tokenPath))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// httpTokenCacheKey returns a key at which an http-01 token value may be stored
|
||||||
|
// in the Manager's optional Cache.
|
||||||
|
func httpTokenCacheKey(tokenPath string) string {
|
||||||
|
return "http-01-" + path.Base(tokenPath)
|
||||||
|
}
|
||||||
|
|
||||||
// renew starts a cert renewal timer loop, one per domain.
|
// renew starts a cert renewal timer loop, one per domain.
|
||||||
//
|
//
|
||||||
// The loop is scheduled in two cases:
|
// The loop is scheduled in two cases:
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user