添加vednor和验证码接口
This commit is contained in:
parent
2a1c947808
commit
48c5a9c552
@ -73,3 +73,10 @@ func GetMysqlConfig() *MysqlConfig{
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func GetLogConfig() *LogConfig {
|
||||||
|
if gConf.init{
|
||||||
|
return &gConf.Logs
|
||||||
|
}else{
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
@ -76,27 +76,9 @@ func Auth(c *gin.Context) {
|
|||||||
// @Success 200 {array} util.RespBase
|
// @Success 200 {array} util.RespBase
|
||||||
// @Router /accounts [get]
|
// @Router /accounts [get]
|
||||||
func SetUser(c *gin.Context){
|
func SetUser(c *gin.Context){
|
||||||
var req model.Users
|
|
||||||
var resp RespBase
|
|
||||||
resp.Msg = "操作失败"
|
|
||||||
resp.Status = 20
|
|
||||||
defer func() {
|
|
||||||
c.JSON(200,resp)
|
|
||||||
}()
|
|
||||||
e := c.BindJSON(&req)
|
|
||||||
if nil != e{
|
|
||||||
logs.Error(e.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
func DelUser(c *gin.Context){
|
func DelUser(c *gin.Context){
|
||||||
var resp RespBase
|
|
||||||
resp.Msg = "操作失败"
|
|
||||||
resp.Status = 20
|
|
||||||
defer func() {
|
|
||||||
c.JSON(200,resp)
|
|
||||||
}()
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,11 +100,11 @@ func GetUser(c *gin.Context) {
|
|||||||
if nil != e {
|
if nil != e {
|
||||||
logs.Error(e.Error())
|
logs.Error(e.Error())
|
||||||
}
|
}
|
||||||
delete(users,"socketToken")
|
delete(users,"socketToken" +
|
||||||
|
"")
|
||||||
resp.Status = 0
|
resp.Status = 0
|
||||||
resp.Msg = "操作成功"
|
resp.Msg = "操作成功"
|
||||||
resp.Data = users
|
resp.Data = users
|
||||||
|
|
||||||
}
|
}
|
||||||
// GetUsers godoc
|
// GetUsers godoc
|
||||||
// @Summary GetUsers
|
// @Summary GetUsers
|
||||||
@ -134,10 +116,6 @@ func GetUser(c *gin.Context) {
|
|||||||
// @Param displayname query string false "name search by q"
|
// @Param displayname query string false "name search by q"
|
||||||
// @Param department_id query string false "name search by q"
|
// @Param department_id query string false "name search by q"
|
||||||
// @Param permission_type query string false "name search by q"
|
// @Param permission_type query string false "name search by q"
|
||||||
// @Success 200 {array} util.RespBase
|
|
||||||
// @Failure 400 {object} util.RespBase
|
|
||||||
// @Failure 404 {object} util.RespBase
|
|
||||||
// @Failure 500 {object} util.RespBase
|
|
||||||
// @Router /api/users [get]
|
// @Router /api/users [get]
|
||||||
func GetUsers(c *gin.Context) {
|
func GetUsers(c *gin.Context) {
|
||||||
var statuscode int
|
var statuscode int
|
||||||
|
197
controller/mail/mail.go
Normal file
197
controller/mail/mail.go
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
package mail
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/smtp"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RespJson struct {
|
||||||
|
Msg string `json:"msg"`
|
||||||
|
Data interface{} `json:"data,omitempty"`
|
||||||
|
Affected int64 `json:"affected,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func PathExists(path string) (bool, error) {
|
||||||
|
_, err := os.Stat(path)
|
||||||
|
if err == nil {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
if os.IsExist(err) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetTemplateFile(template string) ([]byte, error) {
|
||||||
|
path := "G:\\GoPath\\Email\\" + template + ".tpl"
|
||||||
|
ok, err := PathExists(path)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("Count not Find File " + path)
|
||||||
|
}
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err.Error())
|
||||||
|
}
|
||||||
|
ret, err := ioutil.ReadAll(file)
|
||||||
|
file.Close()
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//静态文件存放地
|
||||||
|
const PATH_STATIC = "G://GoPath//Email//static//"
|
||||||
|
|
||||||
|
type ReqSendEmail struct {
|
||||||
|
From string `json:"from"`
|
||||||
|
To string `json:"to"`
|
||||||
|
Tittle string `json:"tittle"`
|
||||||
|
TempData interface{} `json:"temp_data"`
|
||||||
|
Template string `json:"template"`
|
||||||
|
Generate bool `json:"generate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendToMail(title, user, password, host, to, tplname string, content interface{}, mailtype string, ifgenerate bool) error {
|
||||||
|
var content_type string
|
||||||
|
var paseresult bytes.Buffer
|
||||||
|
writer := bufio.NewWriter(&paseresult)
|
||||||
|
hp := strings.Split(host, ":")
|
||||||
|
auth := smtp.PlainAuth("", user, password, hp[0])
|
||||||
|
|
||||||
|
if mailtype == "html" {
|
||||||
|
content_type = "Content-Type: text/" + mailtype + "; charset=UTF-8"
|
||||||
|
} else {
|
||||||
|
content_type = "Content-Type: text/plain" + "; charset=UTF-8"
|
||||||
|
}
|
||||||
|
//todo 获取模板文件内容
|
||||||
|
tpl, err := GetTemplateFile(tplname)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
//todo 渲染
|
||||||
|
tparse := template.New(tplname)
|
||||||
|
tparse, _ = tparse.Parse(string(tpl))
|
||||||
|
tparse.Execute(writer, content)
|
||||||
|
writer.Flush()
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := []byte("To: " + to + "\r\nFrom: " + user + "\r\nSubject: " + title + "\r\n" +
|
||||||
|
content_type + "\r\n\r\n" + paseresult.String() + "\r\n")
|
||||||
|
send_to := strings.Split(to, ";")
|
||||||
|
|
||||||
|
//todo 如果生成Html文件
|
||||||
|
if ifgenerate {
|
||||||
|
file, err := os.Create(PATH_STATIC + tplname + ".html")
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err.Error())
|
||||||
|
}
|
||||||
|
file.WriteString(paseresult.String())
|
||||||
|
file.Close()
|
||||||
|
}
|
||||||
|
//检测是否是邮件地址
|
||||||
|
for k, _ := range send_to {
|
||||||
|
match, _ := regexp.MatchString("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?", send_to[k])
|
||||||
|
if !match {
|
||||||
|
return errors.New("Format Error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = smtp.SendMail(host, auth, user, send_to, msg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
func OnSendEmailSendCloud(c *gin.Context){
|
||||||
|
var req ReqSendEmail
|
||||||
|
var resp mysqlcurd.RespJson
|
||||||
|
defer func() {
|
||||||
|
c.JSON(200, resp)
|
||||||
|
}()
|
||||||
|
|
||||||
|
e := c.Bind(&req)
|
||||||
|
if e!= nil{
|
||||||
|
log.Println(e.Error())
|
||||||
|
resp.Msg = "ParaErr"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sendcloud.UpdateApiInfo("a7458969_test_KIIqjl", "ovErXj6M8UJeiPJt")
|
||||||
|
var to = make([]map[string]string, 1)
|
||||||
|
to[0] = map[string]string{"to":"290198252@qq.com", "%url%": "http://www.baidu.com"}
|
||||||
|
var ok, err, result = sendcloud.SendTemplateMail("test_template_active", "290198252@sendcloud.org", "测试", "", "测试", to, nil)
|
||||||
|
if err != nil{
|
||||||
|
log.Print(err.Error())
|
||||||
|
resp.Msg = "Fail"
|
||||||
|
}
|
||||||
|
if !ok{
|
||||||
|
resp.Msg = "Fail"
|
||||||
|
}
|
||||||
|
resp.Msg = result
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
"tittle":"运维通知",
|
||||||
|
"from":"c7458969@163.com",
|
||||||
|
"to":"290198252@qq.com",
|
||||||
|
"template":"test",
|
||||||
|
"generate":true,
|
||||||
|
"temp_data":{
|
||||||
|
"content":"f发撒旦法时代阿达是否",
|
||||||
|
"title":"运维通知2",
|
||||||
|
"topimg":"http://img2.imgtn.bdimg.com/it/u=387283908,3372540416&fm=27&gp=0.jpg",
|
||||||
|
"button1text":"客服热线",
|
||||||
|
"button1url":"http://www.baidu.com",
|
||||||
|
"button2text":"查看详情",
|
||||||
|
"button2url":"http://www.baidu.com",
|
||||||
|
"logoimg":"http://news.tom.com/dimg/2016/1027/img-1479784632271.jpg"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
//from: 发送人邮箱
|
||||||
|
//to:接收邮件,可以是"290198252@qq.com;29019822@qq.com;2901982@qq.com" 邮箱之间用分号隔开
|
||||||
|
//template:模板名字
|
||||||
|
//content :网页模板的参数 key-value结构
|
||||||
|
//temp_data 模板内具体要替换的变量名字 Key-value结构
|
||||||
|
//generate 是否生成静态html
|
||||||
|
func OnSendEmail(c *gin.Context) {
|
||||||
|
var req ReqSendEmail
|
||||||
|
var resp RespJson
|
||||||
|
defer func() {
|
||||||
|
c.JSON(200, resp)
|
||||||
|
}()
|
||||||
|
|
||||||
|
e := c.Bind(&req)
|
||||||
|
if e != nil {
|
||||||
|
log.Println(e.Error())
|
||||||
|
resp.Msg = "ParaErr"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user := "c7458969@163.com"
|
||||||
|
password := "caiyu123"
|
||||||
|
host := "smtp.163.com:25"
|
||||||
|
//抄送给自己
|
||||||
|
//e = SendToMail(user,password,host,req.From,req.Template,req.Content,"html")
|
||||||
|
//发送
|
||||||
|
e = SendToMail(req.Tittle, user, password, host, req.To, req.Template, req.TempData, "html", req.Generate)
|
||||||
|
if nil != e {
|
||||||
|
log.Println(e.Error())
|
||||||
|
resp.Msg = "Error"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp.Msg = "OK"
|
||||||
|
}
|
39
controller/mail/upload.go
Normal file
39
controller/mail/upload.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package mail
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func OnUpload(c *gin.Context) {
|
||||||
|
file, header, err := c.Request.FormFile("upload")
|
||||||
|
filename := header.Filename
|
||||||
|
fmt.Println(header.Filename)
|
||||||
|
out, err := os.Create("G://GoPath//image//" + filename + ".png")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer out.Close()
|
||||||
|
_, err = io.Copy(out, file)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func OnDownLoad(c *gin.Context) {
|
||||||
|
file, header, err := c.Request.FormFile("upload")
|
||||||
|
filename := header.Filename
|
||||||
|
fmt.Println(header.Filename)
|
||||||
|
out, err := os.Create("G://GoPath//image//" + filename + ".png")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer out.Close()
|
||||||
|
_, err = io.Copy(out, file)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
2
db/db.go
2
db/db.go
@ -3,13 +3,13 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"document/logs"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
"user/logs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 数据容器抽象对象定义
|
// 数据容器抽象对象定义
|
||||||
|
@ -2,17 +2,15 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"user/config"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"log"
|
"user/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
var gDb Database
|
var gDb Database
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
mysqlconf := config.GetMysqlConfig()
|
mysqlconf := config.GetMysqlConfig()
|
||||||
log.Println(mysqlconf)
|
|
||||||
cnn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8",mysqlconf.UserName,mysqlconf.Password,
|
cnn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8",mysqlconf.UserName,mysqlconf.Password,
|
||||||
mysqlconf.Addr,mysqlconf.Db)
|
mysqlconf.Addr,mysqlconf.Db)
|
||||||
_db,err := sql.Open("mysql",cnn)
|
_db,err := sql.Open("mysql",cnn)
|
||||||
|
5
main.go
5
main.go
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/tommy351/gin-sessions"
|
||||||
"log"
|
"log"
|
||||||
"strconv"
|
"strconv"
|
||||||
"user/controller"
|
"user/controller"
|
||||||
@ -24,8 +25,12 @@ func main() {
|
|||||||
if nil != e{
|
if nil != e{
|
||||||
log.Println(e.Error())
|
log.Println(e.Error())
|
||||||
}
|
}
|
||||||
|
logs.Init(config.GetLogConfig().Dir,config.GetLogConfig().File,config.GetLogConfig().Level,config.GetLogConfig().SaveFile)
|
||||||
db.Init()
|
db.Init()
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
|
store := sessions.NewCookieStore([]byte("secret123"))
|
||||||
|
r.Use(sessions.Middleware("my_session", store))
|
||||||
|
|
||||||
{
|
{
|
||||||
/** 添加或修改用户 **/
|
/** 添加或修改用户 **/
|
||||||
r.POST("/api/user", controller.SetUser)
|
r.POST("/api/user", controller.SetUser)
|
||||||
|
@ -5,7 +5,7 @@ logs:
|
|||||||
dir: "/var/log/user"
|
dir: "/var/log/user"
|
||||||
file: "user.log"
|
file: "user.log"
|
||||||
level: 1
|
level: 1
|
||||||
savefile: true
|
savefile: false
|
||||||
redis:
|
redis:
|
||||||
addr: 118.24.238.198
|
addr: 118.24.238.198
|
||||||
password: 6379
|
password: 6379
|
||||||
|
202
vendor/cloud.google.com/go/LICENSE
generated
vendored
Normal file
202
vendor/cloud.google.com/go/LICENSE
generated
vendored
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
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.
|
2
vendor/cloud.google.com/go/civil/civil.go
generated
vendored
2
vendor/cloud.google.com/go/civil/civil.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
// Copyright 2016 Google LLC
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
136
vendor/git.jiaxianghudong.com/go/utils/bytebuffer.go
generated
vendored
136
vendor/git.jiaxianghudong.com/go/utils/bytebuffer.go
generated
vendored
@ -1,11 +1,20 @@
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
// 加入8字节
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
// "errors"
|
||||||
|
// "fmt"
|
||||||
|
// "reflect"
|
||||||
|
// "unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Put8bit 加入8字节到[]byte中
|
||||||
func Put8bit(buf []byte, n byte) []byte {
|
func Put8bit(buf []byte, n byte) []byte {
|
||||||
return append(buf, n)
|
return append(buf, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加入16字节
|
// Put16bit 加入16字节
|
||||||
func Put16bit(buf []byte, n uint16) []byte {
|
func Put16bit(buf []byte, n uint16) []byte {
|
||||||
var by [2]byte
|
var by [2]byte
|
||||||
|
|
||||||
@ -15,7 +24,7 @@ func Put16bit(buf []byte, n uint16) []byte {
|
|||||||
return append(buf, by[:]...)
|
return append(buf, by[:]...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加入32字节
|
// Put32bit 加入32字节
|
||||||
func Put32bit(buf []byte, n uint32) []byte {
|
func Put32bit(buf []byte, n uint32) []byte {
|
||||||
var by [4]byte
|
var by [4]byte
|
||||||
|
|
||||||
@ -27,7 +36,7 @@ func Put32bit(buf []byte, n uint32) []byte {
|
|||||||
return append(buf, by[:]...)
|
return append(buf, by[:]...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加入64字节
|
// Put64bit 加入64字节
|
||||||
func Put64bit(buf []byte, n uint64) []byte {
|
func Put64bit(buf []byte, n uint64) []byte {
|
||||||
var by [8]byte
|
var by [8]byte
|
||||||
|
|
||||||
@ -43,12 +52,12 @@ func Put64bit(buf []byte, n uint64) []byte {
|
|||||||
return append(buf, by[:]...)
|
return append(buf, by[:]...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取8bit
|
// Get8bit 获取8bit
|
||||||
func Get8bit(buf []byte, start int) byte {
|
func Get8bit(buf []byte, start int) byte {
|
||||||
return buf[start]
|
return buf[start]
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取16bit
|
// Get16bit 获取16bit
|
||||||
func Get16bit(buf []byte, start int) uint16 {
|
func Get16bit(buf []byte, start int) uint16 {
|
||||||
var ret uint16
|
var ret uint16
|
||||||
|
|
||||||
@ -58,7 +67,7 @@ func Get16bit(buf []byte, start int) uint16 {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取32big
|
// Get32bit 获取32big
|
||||||
func Get32bit(buf []byte, start int) uint32 {
|
func Get32bit(buf []byte, start int) uint32 {
|
||||||
var ret uint32
|
var ret uint32
|
||||||
|
|
||||||
@ -70,7 +79,7 @@ func Get32bit(buf []byte, start int) uint32 {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取64bit
|
// Get64bit 获取64bit
|
||||||
func Get64bit(buf []byte, start int) uint64 {
|
func Get64bit(buf []byte, start int) uint64 {
|
||||||
var ret uint64
|
var ret uint64
|
||||||
|
|
||||||
@ -85,3 +94,114 @@ func Get64bit(buf []byte, start int) uint64 {
|
|||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BytesToInt 字节数组转int
|
||||||
|
func BytesToInt(b []byte) int {
|
||||||
|
buf := bytes.NewBuffer(b)
|
||||||
|
var x int
|
||||||
|
binary.Read(buf, binary.BigEndian, &x)
|
||||||
|
|
||||||
|
return int(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IntToBytes int转字节数组
|
||||||
|
func IntToBytes(n int) []byte {
|
||||||
|
buf := bytes.NewBuffer([]byte{})
|
||||||
|
binary.Write(buf, binary.BigEndian, n)
|
||||||
|
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// BytesToInt16 字节数组转int16
|
||||||
|
func BytesToInt16(b []byte) int16 {
|
||||||
|
buf := bytes.NewBuffer(b)
|
||||||
|
var x int16
|
||||||
|
binary.Read(buf, binary.BigEndian, &x)
|
||||||
|
|
||||||
|
return int16(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int16ToBytes int16转字节数组
|
||||||
|
func Int16ToBytes(n int16) []byte {
|
||||||
|
x := int16(n)
|
||||||
|
buf := bytes.NewBuffer([]byte{})
|
||||||
|
binary.Write(buf, binary.BigEndian, x)
|
||||||
|
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// BytesToInt32 字节数组转int32
|
||||||
|
func BytesToInt32(b []byte) int32 {
|
||||||
|
buf := bytes.NewBuffer(b)
|
||||||
|
var x int32
|
||||||
|
binary.Read(buf, binary.BigEndian, &x)
|
||||||
|
|
||||||
|
return int32(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int32ToBytes int32转字节数组
|
||||||
|
func Int32ToBytes(n int32) []byte {
|
||||||
|
x := int32(n)
|
||||||
|
buf := bytes.NewBuffer([]byte{})
|
||||||
|
binary.Write(buf, binary.BigEndian, x)
|
||||||
|
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 字节数组转int64
|
||||||
|
func BytesToInt64(b []byte) int64 {
|
||||||
|
buf := bytes.NewBuffer(b)
|
||||||
|
var x int64
|
||||||
|
binary.Read(buf, binary.BigEndian, &x)
|
||||||
|
|
||||||
|
return int64(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int64ToBytes int64转字节数组
|
||||||
|
func Int64ToBytes(n int64) []byte {
|
||||||
|
buf := bytes.NewBuffer([]byte{})
|
||||||
|
binary.Write(buf, binary.BigEndian, n)
|
||||||
|
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// BytesToUInt64 字节数组转uint64
|
||||||
|
func BytesToUInt64(b []byte) uint64 {
|
||||||
|
buf := bytes.NewBuffer(b)
|
||||||
|
var x uint64
|
||||||
|
binary.Read(buf, binary.BigEndian, &x)
|
||||||
|
|
||||||
|
return uint64(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UInt64ToBytes uint64转字节数组
|
||||||
|
func UInt64ToBytes(n uint64) []byte {
|
||||||
|
buf := bytes.NewBuffer([]byte{})
|
||||||
|
binary.Write(buf, binary.BigEndian, n)
|
||||||
|
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UInt32ToBytes uint32转字节数组
|
||||||
|
func UInt32ToBytes(n uint32) []byte {
|
||||||
|
buf := bytes.NewBuffer([]byte{})
|
||||||
|
binary.Write(buf, binary.BigEndian, n)
|
||||||
|
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// BytesToBool 字节数组转bool
|
||||||
|
func BytesToBool(b []byte) bool {
|
||||||
|
buf := bytes.NewBuffer(b)
|
||||||
|
var x bool
|
||||||
|
binary.Read(buf, binary.BigEndian, &x)
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
// BoolToBytes bool转字节数组
|
||||||
|
func BoolToBytes(x bool) []byte {
|
||||||
|
buf := bytes.NewBuffer([]byte{})
|
||||||
|
binary.Write(buf, binary.BigEndian, x)
|
||||||
|
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
37
vendor/git.jiaxianghudong.com/go/utils/coding.go
generated
vendored
37
vendor/git.jiaxianghudong.com/go/utils/coding.go
generated
vendored
@ -52,6 +52,9 @@ func Authcode(text string, params ...interface{}) string {
|
|||||||
|
|
||||||
if l > 1 {
|
if l > 1 {
|
||||||
key = params[1].(string)
|
key = params[1].(string)
|
||||||
|
if key=="" {
|
||||||
|
key = "DH-Framework"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if l > 2 {
|
if l > 2 {
|
||||||
@ -169,18 +172,18 @@ func AuthcodeUrl(text string, params ...interface{}) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// JsonEncode 编码JSON
|
// JsonEncodeWithError 编码JSON
|
||||||
func JsonEncode(m interface{}) string {
|
func JsonEncodeWithError(m interface{}) (string, error) {
|
||||||
b, err := json.Marshal(m)
|
b, err := json.Marshal(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Json Encode[%#v] Error:%s", m, err.Error())
|
return "", err
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
return string(b)
|
return string(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// JsonDecode 解码JSON
|
|
||||||
func JsonDecode(str string, v ...interface{}) (interface{}, error) {
|
// JsonDecodeWithError 解码JSON
|
||||||
|
func JsonDecodeWithError(str string, v ...interface{}) (interface{}, error) {
|
||||||
var m interface{}
|
var m interface{}
|
||||||
if len(v) > 0 {
|
if len(v) > 0 {
|
||||||
m = v[0]
|
m = v[0]
|
||||||
@ -196,6 +199,26 @@ func JsonDecode(str string, v ...interface{}) (interface{}, error) {
|
|||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JsonEncode 编码JSON
|
||||||
|
func JsonEncode(m interface{}) string {
|
||||||
|
s, err := JsonEncodeWithError(m)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Json Encode[%#v] Error:%s", m, err.Error())
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// JsonDecode 解码JSON
|
||||||
|
func JsonDecode(str string, v ...interface{}) interface{} {
|
||||||
|
i, err := JsonDecodeWithError(str, v...)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Json Decode[%s] Error:%s", str, err.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
func Crc32(text string) string {
|
func Crc32(text string) string {
|
||||||
h := crc32.NewIEEE()
|
h := crc32.NewIEEE()
|
||||||
io.WriteString(h, text)
|
io.WriteString(h, text)
|
||||||
|
2
vendor/git.jiaxianghudong.com/go/utils/conf.go
generated
vendored
2
vendor/git.jiaxianghudong.com/go/utils/conf.go
generated
vendored
@ -6,6 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -16,6 +17,7 @@ const (
|
|||||||
|
|
||||||
// ReadTextFile 读取文件
|
// ReadTextFile 读取文件
|
||||||
func ReadTextFile(path string) string {
|
func ReadTextFile(path string) string {
|
||||||
|
fmt.Println("path:",path)
|
||||||
fp, err := os.Open(path)
|
fp, err := os.Open(path)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
return ""
|
return ""
|
||||||
|
29
vendor/git.jiaxianghudong.com/go/utils/convert.go
generated
vendored
29
vendor/git.jiaxianghudong.com/go/utils/convert.go
generated
vendored
@ -4,8 +4,10 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"net/url"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -308,6 +310,33 @@ func Long2ip(ip uint32) string {
|
|||||||
return fmt.Sprintf("%d.%d.%d.%d", ip>>24, ip<<8>>24, ip<<16>>24, ip<<24>>24)
|
return fmt.Sprintf("%d.%d.%d.%d", ip>>24, ip<<8>>24, ip<<16>>24, ip<<24>>24)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SignStrBuild
|
||||||
|
func MapToRawStr(data map[string]string) string {
|
||||||
|
|
||||||
|
str := ""
|
||||||
|
if len(data) > 0 {
|
||||||
|
keys := make([]string, 0)
|
||||||
|
for k, _ := range data {
|
||||||
|
if k != "sign" && k != "encode" && k != "v" {
|
||||||
|
keys = append(keys, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Strings(keys)
|
||||||
|
//
|
||||||
|
for _, k := range keys {
|
||||||
|
if data[k] != "" {
|
||||||
|
if str == "" {
|
||||||
|
str = fmt.Sprintf("%s=%s", k, url.QueryEscape(strings.Replace(data[k], " ", "+", -1)))
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("%s&%s=%s", str, k, url.QueryEscape(strings.Replace(data[k], " ", "+", -1)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
// GbkToUtf8 GBK转UTF-8
|
// GbkToUtf8 GBK转UTF-8
|
||||||
func GbkToUtf8(s []byte) ([]byte, error) {
|
func GbkToUtf8(s []byte) ([]byte, error) {
|
||||||
reader := transform.NewReader(bytes.NewReader(s), simplifiedchinese.GBK.NewDecoder())
|
reader := transform.NewReader(bytes.NewReader(s), simplifiedchinese.GBK.NewDecoder())
|
||||||
|
47
vendor/git.jiaxianghudong.com/go/utils/http_helper.go
generated
vendored
47
vendor/git.jiaxianghudong.com/go/utils/http_helper.go
generated
vendored
@ -27,7 +27,6 @@ func Get(apiUrl string, parm map[string]string, header map[string]string, isHttp
|
|||||||
}
|
}
|
||||||
apiUrl = fmt.Sprintf("%s%s", apiUrl, p)
|
apiUrl = fmt.Sprintf("%s%s", apiUrl, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
|
|
||||||
if isHttps {
|
if isHttps {
|
||||||
@ -35,8 +34,10 @@ func Get(apiUrl string, parm map[string]string, header map[string]string, isHttp
|
|||||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reqest, _ := http.NewRequest("GET", apiUrl, nil)
|
reqest, err := http.NewRequest("GET", apiUrl, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
for k, v := range header {
|
for k, v := range header {
|
||||||
reqest.Header.Set(k, v)
|
reqest.Header.Set(k, v)
|
||||||
}
|
}
|
||||||
@ -142,3 +143,43 @@ func GetRemoteIP(r *http.Request) string {
|
|||||||
|
|
||||||
return strings.Split(addr, ":")[0]
|
return strings.Split(addr, ":")[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseQuery 参数解析,兼容部分字段有encode部分没encode的情况
|
||||||
|
func ParseQuery(query string) (m url.Values, err error) {
|
||||||
|
m = make(url.Values)
|
||||||
|
for query != "" {
|
||||||
|
key := query
|
||||||
|
if i := strings.IndexAny(key, "&"); i >= 0 {
|
||||||
|
key, query = key[:i], key[i+1:]
|
||||||
|
} else {
|
||||||
|
query = ""
|
||||||
|
}
|
||||||
|
if key == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
value := ""
|
||||||
|
if i := strings.Index(key, "="); i >= 0 {
|
||||||
|
key, value = key[:i], key[i+1:]
|
||||||
|
}
|
||||||
|
key, err1 := url.QueryUnescape(key)
|
||||||
|
if err1 != nil {
|
||||||
|
if err == nil {
|
||||||
|
err = err1
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
value1, err1 := url.QueryUnescape(value)
|
||||||
|
if err1 != nil {
|
||||||
|
if !strings.HasPrefix(err1.Error(), "invalid URL escape") {
|
||||||
|
if err == nil {
|
||||||
|
err = err1
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
m[key] = append(m[key], value)
|
||||||
|
} else {
|
||||||
|
m[key] = append(m[key], value1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m, err
|
||||||
|
}
|
||||||
|
6
vendor/git.jiaxianghudong.com/go/utils/lua.go
generated
vendored
6
vendor/git.jiaxianghudong.com/go/utils/lua.go
generated
vendored
@ -4,6 +4,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// buildLuaResponse构造Lua响应结果
|
// buildLuaResponse构造Lua响应结果
|
||||||
@ -52,6 +53,11 @@ func BuildLuaResponse(m interface{}) string {
|
|||||||
vStr = "{" + Substr(vStr, 1) + "}"
|
vStr = "{" + Substr(vStr, 1) + "}"
|
||||||
case string:
|
case string:
|
||||||
vStr = `"` + strings.Replace(v, `"`, `\"`, -1) + `"`
|
vStr = `"` + strings.Replace(v, `"`, `\"`, -1) + `"`
|
||||||
|
case map[string]interface{}:
|
||||||
|
for ks, vs := range v {
|
||||||
|
vStr += `,` + ks + `=` + `"`+strings.Replace(fmt.Sprint(vs), `"`, `\"`, -1)+`"`
|
||||||
|
}
|
||||||
|
vStr = "{" + Substr(vStr, 1) + "}"
|
||||||
default:
|
default:
|
||||||
if vv, ok := v.(map[interface{}]interface{}); ok {
|
if vv, ok := v.(map[interface{}]interface{}); ok {
|
||||||
vStr = BuildLuaResponse(vv)
|
vStr = BuildLuaResponse(vv)
|
||||||
|
88
vendor/git.jiaxianghudong.com/go/utils/regexp.go
generated
vendored
88
vendor/git.jiaxianghudong.com/go/utils/regexp.go
generated
vendored
@ -12,12 +12,28 @@ const (
|
|||||||
regEmail = `^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$`
|
regEmail = `^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$`
|
||||||
regPhone = `^((\d3)|(\d{3}\-))?13[0-9]\d{8}|14[0-9]\d{8}|15[0-9]\d{8}|17[0-9]\d{8}|18[0-9]\d{8}`
|
regPhone = `^((\d3)|(\d{3}\-))?13[0-9]\d{8}|14[0-9]\d{8}|15[0-9]\d{8}|17[0-9]\d{8}|18[0-9]\d{8}`
|
||||||
regUrl = `^((https?|ftp|news|http):\/\/)?([a-z]([a-z0-9\-]*[\.。])+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel)|(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&]*)?)?(#[a-z][a-z0-9_]*)?$`
|
regUrl = `^((https?|ftp|news|http):\/\/)?([a-z]([a-z0-9\-]*[\.。])+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel)|(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&]*)?)?(#[a-z][a-z0-9_]*)?$`
|
||||||
regGuid = `[a-zA-Z0-9-_]{0,40}`
|
regGuid = `[a-zA-Z0-9-_]{1,40}`
|
||||||
regDescription = `^{0,64}$`
|
regDescription = `^{0,64}$`
|
||||||
regOutTypeDescription = `^{0,20}$`
|
regOutTypeDescription = `^{0,20}$`
|
||||||
regMac = `^{0,40}$`
|
regMac = `^{0,40}$`
|
||||||
regTradeNo = `^[a-zA-Z0-9_-]{1,40}$`
|
regTradeNo = `^[a-zA-Z0-9_-]{1,40}$`
|
||||||
regAttach = `^{0,127}$`
|
regAttach = `^{0,127}$`
|
||||||
|
|
||||||
|
// LT
|
||||||
|
regID = `^[0-9]{0,11}$`
|
||||||
|
regTitle = `^[\s\S]{0,40}$`
|
||||||
|
regIntro = `^[\s\S]{0,120}$`
|
||||||
|
regHash = `^[\S]{0,160}$`
|
||||||
|
reqAuthorName = `^{0,60}$`
|
||||||
|
reqAtType = `^[1-7]{1}$`
|
||||||
|
reqActionListAtType = `^[1,3]{1}$`
|
||||||
|
regContent = `^[\s\S]{0,255}$`
|
||||||
|
reqSrcType = `^[1,2,3]{1}$`
|
||||||
|
reqCommentActionAtType = `^[1,2,6]{1}$`
|
||||||
|
reqUserActionAtType = `^[1,2,3,4]{1}$`
|
||||||
|
reqKeyword = `^.{0,40}$`
|
||||||
|
regReason = `^[\s\S]{0,140}$`
|
||||||
|
regUserSuggestTitle = `^[\s\S]{0,120}$`
|
||||||
)
|
)
|
||||||
|
|
||||||
func CheckString(data string, pat string) bool {
|
func CheckString(data string, pat string) bool {
|
||||||
@ -87,3 +103,73 @@ func CheckTradeNo(tradeNo string) bool {
|
|||||||
func CheckAttach(attach string) bool {
|
func CheckAttach(attach string) bool {
|
||||||
return CheckString(attach, regAttach)
|
return CheckString(attach, regAttach)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检测资源id
|
||||||
|
func CheckID(anchorId string) bool {
|
||||||
|
return CheckString(anchorId, regID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测资源title
|
||||||
|
func CheckTitle(title string) bool {
|
||||||
|
return CheckString(title, regTitle)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测资源intro
|
||||||
|
func CheckIntro(intro string) bool {
|
||||||
|
return CheckString(intro, regIntro)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测资源Hash
|
||||||
|
func CheckHash(hash string) bool {
|
||||||
|
return CheckString(hash, regHash)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测资源AuthorName
|
||||||
|
func CheckAuthorName(authorName string) bool {
|
||||||
|
return CheckString(authorName, reqAuthorName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测资源atType
|
||||||
|
func CheckAtType(atType string) bool {
|
||||||
|
return CheckString(atType, reqAtType)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测资源atType
|
||||||
|
func CheckActionListAtType(atType string) bool {
|
||||||
|
return CheckString(atType, reqActionListAtType)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测资源atType
|
||||||
|
func CheckContent(content string) bool {
|
||||||
|
return CheckString(content, regContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测资源atType
|
||||||
|
func CheckSrcType(srcType string) bool {
|
||||||
|
return CheckString(srcType, reqSrcType)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测资源atType
|
||||||
|
func CheckCommentActionAtType(atType string) bool {
|
||||||
|
return CheckString(atType, reqCommentActionAtType)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测资源atType
|
||||||
|
func CheckUserActionAtType(atType string) bool {
|
||||||
|
return CheckString(atType, reqUserActionAtType)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测资源keyword
|
||||||
|
func CheckKeyword(keyword string) bool {
|
||||||
|
return CheckString(keyword, reqKeyword)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测资源Reason
|
||||||
|
func CheckReason(reason string) bool {
|
||||||
|
return CheckString(reason, regReason)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测资源SuggestTitle
|
||||||
|
func CheckSuggestTitle(title string) bool {
|
||||||
|
return CheckString(title, regUserSuggestTitle)
|
||||||
|
}
|
||||||
|
15
vendor/git.jiaxianghudong.com/go/utils/utils.go
generated
vendored
15
vendor/git.jiaxianghudong.com/go/utils/utils.go
generated
vendored
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -355,10 +356,22 @@ func LenSyncMap(m *sync.Map) int {
|
|||||||
return length
|
return length
|
||||||
}
|
}
|
||||||
|
|
||||||
// 模拟三元操作符
|
// Ternary 模拟三元操作符
|
||||||
func Ternary(b bool, trueVal, falseVal interface{}) interface{} {
|
func Ternary(b bool, trueVal, falseVal interface{}) interface{} {
|
||||||
if b {
|
if b {
|
||||||
return trueVal
|
return trueVal
|
||||||
}
|
}
|
||||||
return falseVal
|
return falseVal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMacAddr 获取本地mac地址
|
||||||
|
func GetLocalMacAddr() ([]byte, error) {
|
||||||
|
|
||||||
|
// 获取本机的MAC地址
|
||||||
|
interfaces, err := net.Interfaces()
|
||||||
|
if err != nil || len(interfaces) == 0 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return interfaces[0].HardwareAddr, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
41
vendor/github.com/denisenkom/go-mssqldb/mssql.go
generated
vendored
41
vendor/github.com/denisenkom/go-mssqldb/mssql.go
generated
vendored
@ -29,24 +29,19 @@ var driverInstanceNoProcess = &Driver{processQueryText: false}
|
|||||||
func init() {
|
func init() {
|
||||||
sql.Register("mssql", driverInstance)
|
sql.Register("mssql", driverInstance)
|
||||||
sql.Register("sqlserver", driverInstanceNoProcess)
|
sql.Register("sqlserver", driverInstanceNoProcess)
|
||||||
createDialer = func(p *connectParams) dialer {
|
createDialer = func(p *connectParams) Dialer {
|
||||||
return tcpDialer{&net.Dialer{KeepAlive: p.keepAlive}}
|
return netDialer{&net.Dialer{KeepAlive: p.keepAlive}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Abstract the dialer for testing and for non-TCP based connections.
|
var createDialer func(p *connectParams) Dialer
|
||||||
type dialer interface {
|
|
||||||
Dial(ctx context.Context, addr string) (net.Conn, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
var createDialer func(p *connectParams) dialer
|
type netDialer struct {
|
||||||
|
|
||||||
type tcpDialer struct {
|
|
||||||
nd *net.Dialer
|
nd *net.Dialer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d tcpDialer) Dial(ctx context.Context, addr string) (net.Conn, error) {
|
func (d netDialer) DialContext(ctx context.Context, network string, addr string) (net.Conn, error) {
|
||||||
return d.nd.DialContext(ctx, "tcp", addr)
|
return d.nd.DialContext(ctx, network, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Driver struct {
|
type Driver struct {
|
||||||
@ -125,6 +120,21 @@ type Connector struct {
|
|||||||
// SessionInitSQL is optional. The session will be reset even if
|
// SessionInitSQL is optional. The session will be reset even if
|
||||||
// SessionInitSQL is empty.
|
// SessionInitSQL is empty.
|
||||||
SessionInitSQL string
|
SessionInitSQL string
|
||||||
|
|
||||||
|
// Dialer sets a custom dialer for all network operations.
|
||||||
|
// If Dialer is not set, normal net dialers are used.
|
||||||
|
Dialer Dialer
|
||||||
|
}
|
||||||
|
|
||||||
|
type Dialer interface {
|
||||||
|
DialContext(ctx context.Context, network string, addr string) (net.Conn, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Connector) getDialer(p *connectParams) Dialer {
|
||||||
|
if c != nil && c.Dialer != nil {
|
||||||
|
return c.Dialer
|
||||||
|
}
|
||||||
|
return createDialer(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Conn struct {
|
type Conn struct {
|
||||||
@ -310,12 +320,12 @@ func (d *Driver) open(ctx context.Context, dsn string) (*Conn, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return d.connect(ctx, params)
|
return d.connect(ctx, nil, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
// connect to the server, using the provided context for dialing only.
|
// connect to the server, using the provided context for dialing only.
|
||||||
func (d *Driver) connect(ctx context.Context, params connectParams) (*Conn, error) {
|
func (d *Driver) connect(ctx context.Context, c *Connector, params connectParams) (*Conn, error) {
|
||||||
sess, err := connect(ctx, d.log, params)
|
sess, err := connect(ctx, c, d.log, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// main server failed, try fail-over partner
|
// main server failed, try fail-over partner
|
||||||
if params.failOverPartner == "" {
|
if params.failOverPartner == "" {
|
||||||
@ -327,7 +337,7 @@ func (d *Driver) connect(ctx context.Context, params connectParams) (*Conn, erro
|
|||||||
params.port = params.failOverPort
|
params.port = params.failOverPort
|
||||||
}
|
}
|
||||||
|
|
||||||
sess, err = connect(ctx, d.log, params)
|
sess, err = connect(ctx, c, d.log, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// fail-over partner also failed, now fail
|
// fail-over partner also failed, now fail
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -335,6 +345,7 @@ func (d *Driver) connect(ctx context.Context, params connectParams) (*Conn, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
conn := &Conn{
|
conn := &Conn{
|
||||||
|
connector: c,
|
||||||
sess: sess,
|
sess: sess,
|
||||||
transactionCtx: context.Background(),
|
transactionCtx: context.Background(),
|
||||||
processQueryText: d.processQueryText,
|
processQueryText: d.processQueryText,
|
||||||
|
5
vendor/github.com/denisenkom/go-mssqldb/mssql_go110.go
generated
vendored
5
vendor/github.com/denisenkom/go-mssqldb/mssql_go110.go
generated
vendored
@ -34,10 +34,7 @@ func (c *Conn) ResetSession(ctx context.Context) error {
|
|||||||
|
|
||||||
// Connect to the server and return a TDS connection.
|
// Connect to the server and return a TDS connection.
|
||||||
func (c *Connector) Connect(ctx context.Context) (driver.Conn, error) {
|
func (c *Connector) Connect(ctx context.Context) (driver.Conn, error) {
|
||||||
conn, err := c.driver.connect(ctx, c.params)
|
conn, err := c.driver.connect(ctx, c, c.params)
|
||||||
if conn != nil {
|
|
||||||
conn.connector = c
|
|
||||||
}
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = conn.ResetSession(ctx)
|
err = conn.ResetSession(ctx)
|
||||||
}
|
}
|
||||||
|
26
vendor/github.com/denisenkom/go-mssqldb/tds.go
generated
vendored
26
vendor/github.com/denisenkom/go-mssqldb/tds.go
generated
vendored
@ -50,12 +50,11 @@ func parseInstances(msg []byte) map[string]map[string]string {
|
|||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
func getInstances(ctx context.Context, address string) (map[string]map[string]string, error) {
|
func getInstances(ctx context.Context, d Dialer, address string) (map[string]map[string]string, error) {
|
||||||
maxTime := 5 * time.Second
|
maxTime := 5 * time.Second
|
||||||
dialer := &net.Dialer{
|
ctx, cancel := context.WithTimeout(ctx, maxTime)
|
||||||
Timeout: maxTime,
|
defer cancel()
|
||||||
}
|
conn, err := d.DialContext(ctx, "udp", address+":1434")
|
||||||
conn, err := dialer.DialContext(ctx, "udp", address+":1434")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1112,7 +1111,7 @@ type auth interface {
|
|||||||
// SQL Server AlwaysOn Availability Group Listeners are bound by DNS to a
|
// SQL Server AlwaysOn Availability Group Listeners are bound by DNS to a
|
||||||
// list of IP addresses. So if there is more than one, try them all and
|
// list of IP addresses. So if there is more than one, try them all and
|
||||||
// use the first one that allows a connection.
|
// use the first one that allows a connection.
|
||||||
func dialConnection(ctx context.Context, p connectParams) (conn net.Conn, err error) {
|
func dialConnection(ctx context.Context, c *Connector, p connectParams) (conn net.Conn, err error) {
|
||||||
var ips []net.IP
|
var ips []net.IP
|
||||||
ips, err = net.LookupIP(p.host)
|
ips, err = net.LookupIP(p.host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1123,9 +1122,9 @@ func dialConnection(ctx context.Context, p connectParams) (conn net.Conn, err er
|
|||||||
ips = []net.IP{ip}
|
ips = []net.IP{ip}
|
||||||
}
|
}
|
||||||
if len(ips) == 1 {
|
if len(ips) == 1 {
|
||||||
d := createDialer(&p)
|
d := c.getDialer(&p)
|
||||||
addr := net.JoinHostPort(ips[0].String(), strconv.Itoa(int(p.port)))
|
addr := net.JoinHostPort(ips[0].String(), strconv.Itoa(int(p.port)))
|
||||||
conn, err = d.Dial(ctx, addr)
|
conn, err = d.DialContext(ctx, "tcp", addr)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//Try Dials in parallel to avoid waiting for timeouts.
|
//Try Dials in parallel to avoid waiting for timeouts.
|
||||||
@ -1134,9 +1133,9 @@ func dialConnection(ctx context.Context, p connectParams) (conn net.Conn, err er
|
|||||||
portStr := strconv.Itoa(int(p.port))
|
portStr := strconv.Itoa(int(p.port))
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
go func(ip net.IP) {
|
go func(ip net.IP) {
|
||||||
d := createDialer(&p)
|
d := c.getDialer(&p)
|
||||||
addr := net.JoinHostPort(ip.String(), portStr)
|
addr := net.JoinHostPort(ip.String(), portStr)
|
||||||
conn, err := d.Dial(ctx, addr)
|
conn, err := d.DialContext(ctx, "tcp", addr)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
connChan <- conn
|
connChan <- conn
|
||||||
} else {
|
} else {
|
||||||
@ -1174,7 +1173,7 @@ func dialConnection(ctx context.Context, p connectParams) (conn net.Conn, err er
|
|||||||
return conn, err
|
return conn, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func connect(ctx context.Context, log optionalLogger, p connectParams) (res *tdsSession, err error) {
|
func connect(ctx context.Context, c *Connector, log optionalLogger, p connectParams) (res *tdsSession, err error) {
|
||||||
dialCtx := ctx
|
dialCtx := ctx
|
||||||
if p.dial_timeout > 0 {
|
if p.dial_timeout > 0 {
|
||||||
var cancel func()
|
var cancel func()
|
||||||
@ -1184,7 +1183,8 @@ func connect(ctx context.Context, log optionalLogger, p connectParams) (res *tds
|
|||||||
// if instance is specified use instance resolution service
|
// if instance is specified use instance resolution service
|
||||||
if p.instance != "" {
|
if p.instance != "" {
|
||||||
p.instance = strings.ToUpper(p.instance)
|
p.instance = strings.ToUpper(p.instance)
|
||||||
instances, err := getInstances(dialCtx, p.host)
|
d := c.getDialer(&p)
|
||||||
|
instances, err := getInstances(dialCtx, d, p.host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f := "Unable to get instances from Sql Server Browser on host %v: %v"
|
f := "Unable to get instances from Sql Server Browser on host %v: %v"
|
||||||
return nil, fmt.Errorf(f, p.host, err.Error())
|
return nil, fmt.Errorf(f, p.host, err.Error())
|
||||||
@ -1202,7 +1202,7 @@ func connect(ctx context.Context, log optionalLogger, p connectParams) (res *tds
|
|||||||
}
|
}
|
||||||
|
|
||||||
initiate_connection:
|
initiate_connection:
|
||||||
conn, err := dialConnection(dialCtx, p)
|
conn, err := dialConnection(dialCtx, c, p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
40
vendor/github.com/disintegration/imaging/resize.go
generated
vendored
40
vendor/github.com/disintegration/imaging/resize.go
generated
vendored
@ -116,25 +116,23 @@ func resizeHorizontal(img image.Image, width int, filter ResampleFilter) *image.
|
|||||||
for y := range ys {
|
for y := range ys {
|
||||||
src.scan(0, y, src.w, y+1, scanLine)
|
src.scan(0, y, src.w, y+1, scanLine)
|
||||||
j0 := y * dst.Stride
|
j0 := y * dst.Stride
|
||||||
for x := range weights {
|
for x := 0; x < width; x++ {
|
||||||
var r, g, b, a float64
|
var r, g, b, a float64
|
||||||
for _, w := range weights[x] {
|
for _, w := range weights[x] {
|
||||||
i := w.index * 4
|
i := w.index * 4
|
||||||
s := scanLine[i : i+4 : i+4]
|
aw := float64(scanLine[i+3]) * w.weight
|
||||||
aw := float64(s[3]) * w.weight
|
r += float64(scanLine[i+0]) * aw
|
||||||
r += float64(s[0]) * aw
|
g += float64(scanLine[i+1]) * aw
|
||||||
g += float64(s[1]) * aw
|
b += float64(scanLine[i+2]) * aw
|
||||||
b += float64(s[2]) * aw
|
|
||||||
a += aw
|
a += aw
|
||||||
}
|
}
|
||||||
if a != 0 {
|
if a != 0 {
|
||||||
aInv := 1 / a
|
aInv := 1 / a
|
||||||
j := j0 + x*4
|
j := j0 + x*4
|
||||||
d := dst.Pix[j : j+4 : j+4]
|
dst.Pix[j+0] = clamp(r * aInv)
|
||||||
d[0] = clamp(r * aInv)
|
dst.Pix[j+1] = clamp(g * aInv)
|
||||||
d[1] = clamp(g * aInv)
|
dst.Pix[j+2] = clamp(b * aInv)
|
||||||
d[2] = clamp(b * aInv)
|
dst.Pix[j+3] = clamp(a)
|
||||||
d[3] = clamp(a)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,25 +148,23 @@ func resizeVertical(img image.Image, height int, filter ResampleFilter) *image.N
|
|||||||
scanLine := make([]uint8, src.h*4)
|
scanLine := make([]uint8, src.h*4)
|
||||||
for x := range xs {
|
for x := range xs {
|
||||||
src.scan(x, 0, x+1, src.h, scanLine)
|
src.scan(x, 0, x+1, src.h, scanLine)
|
||||||
for y := range weights {
|
for y := 0; y < height; y++ {
|
||||||
var r, g, b, a float64
|
var r, g, b, a float64
|
||||||
for _, w := range weights[y] {
|
for _, w := range weights[y] {
|
||||||
i := w.index * 4
|
i := w.index * 4
|
||||||
s := scanLine[i : i+4 : i+4]
|
aw := float64(scanLine[i+3]) * w.weight
|
||||||
aw := float64(s[3]) * w.weight
|
r += float64(scanLine[i+0]) * aw
|
||||||
r += float64(s[0]) * aw
|
g += float64(scanLine[i+1]) * aw
|
||||||
g += float64(s[1]) * aw
|
b += float64(scanLine[i+2]) * aw
|
||||||
b += float64(s[2]) * aw
|
|
||||||
a += aw
|
a += aw
|
||||||
}
|
}
|
||||||
if a != 0 {
|
if a != 0 {
|
||||||
aInv := 1 / a
|
aInv := 1 / a
|
||||||
j := y*dst.Stride + x*4
|
j := y*dst.Stride + x*4
|
||||||
d := dst.Pix[j : j+4 : j+4]
|
dst.Pix[j+0] = clamp(r * aInv)
|
||||||
d[0] = clamp(r * aInv)
|
dst.Pix[j+1] = clamp(g * aInv)
|
||||||
d[1] = clamp(g * aInv)
|
dst.Pix[j+2] = clamp(b * aInv)
|
||||||
d[2] = clamp(b * aInv)
|
dst.Pix[j+3] = clamp(a)
|
||||||
d[3] = clamp(a)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
207
vendor/github.com/disintegration/imaging/scanner.go
generated
vendored
207
vendor/github.com/disintegration/imaging/scanner.go
generated
vendored
@ -33,36 +33,21 @@ func (s *scanner) scan(x1, y1, x2, y2 int, dst []uint8) {
|
|||||||
size := (x2 - x1) * 4
|
size := (x2 - x1) * 4
|
||||||
j := 0
|
j := 0
|
||||||
i := y1*img.Stride + x1*4
|
i := y1*img.Stride + x1*4
|
||||||
if size == 4 {
|
|
||||||
for y := y1; y < y2; y++ {
|
|
||||||
d := dst[j : j+4 : j+4]
|
|
||||||
s := img.Pix[i : i+4 : i+4]
|
|
||||||
d[0] = s[0]
|
|
||||||
d[1] = s[1]
|
|
||||||
d[2] = s[2]
|
|
||||||
d[3] = s[3]
|
|
||||||
j += size
|
|
||||||
i += img.Stride
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for y := y1; y < y2; y++ {
|
for y := y1; y < y2; y++ {
|
||||||
copy(dst[j:j+size], img.Pix[i:i+size])
|
copy(dst[j:j+size], img.Pix[i:i+size])
|
||||||
j += size
|
j += size
|
||||||
i += img.Stride
|
i += img.Stride
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
case *image.NRGBA64:
|
case *image.NRGBA64:
|
||||||
j := 0
|
j := 0
|
||||||
for y := y1; y < y2; y++ {
|
for y := y1; y < y2; y++ {
|
||||||
i := y*img.Stride + x1*8
|
i := y*img.Stride + x1*8
|
||||||
for x := x1; x < x2; x++ {
|
for x := x1; x < x2; x++ {
|
||||||
s := img.Pix[i : i+8 : i+8]
|
dst[j+0] = img.Pix[i+0]
|
||||||
d := dst[j : j+4 : j+4]
|
dst[j+1] = img.Pix[i+2]
|
||||||
d[0] = s[0]
|
dst[j+2] = img.Pix[i+4]
|
||||||
d[1] = s[2]
|
dst[j+3] = img.Pix[i+6]
|
||||||
d[2] = s[4]
|
|
||||||
d[3] = s[6]
|
|
||||||
j += 4
|
j += 4
|
||||||
i += 8
|
i += 8
|
||||||
}
|
}
|
||||||
@ -73,31 +58,26 @@ func (s *scanner) scan(x1, y1, x2, y2 int, dst []uint8) {
|
|||||||
for y := y1; y < y2; y++ {
|
for y := y1; y < y2; y++ {
|
||||||
i := y*img.Stride + x1*4
|
i := y*img.Stride + x1*4
|
||||||
for x := x1; x < x2; x++ {
|
for x := x1; x < x2; x++ {
|
||||||
d := dst[j : j+4 : j+4]
|
|
||||||
a := img.Pix[i+3]
|
a := img.Pix[i+3]
|
||||||
switch a {
|
switch a {
|
||||||
case 0:
|
case 0:
|
||||||
d[0] = 0
|
dst[j+0] = 0
|
||||||
d[1] = 0
|
dst[j+1] = 0
|
||||||
d[2] = 0
|
dst[j+2] = 0
|
||||||
d[3] = a
|
|
||||||
case 0xff:
|
case 0xff:
|
||||||
s := img.Pix[i : i+4 : i+4]
|
dst[j+0] = img.Pix[i+0]
|
||||||
d[0] = s[0]
|
dst[j+1] = img.Pix[i+1]
|
||||||
d[1] = s[1]
|
dst[j+2] = img.Pix[i+2]
|
||||||
d[2] = s[2]
|
|
||||||
d[3] = a
|
|
||||||
default:
|
default:
|
||||||
s := img.Pix[i : i+4 : i+4]
|
r16 := uint16(img.Pix[i+0])
|
||||||
r16 := uint16(s[0])
|
g16 := uint16(img.Pix[i+1])
|
||||||
g16 := uint16(s[1])
|
b16 := uint16(img.Pix[i+2])
|
||||||
b16 := uint16(s[2])
|
|
||||||
a16 := uint16(a)
|
a16 := uint16(a)
|
||||||
d[0] = uint8(r16 * 0xff / a16)
|
dst[j+0] = uint8(r16 * 0xff / a16)
|
||||||
d[1] = uint8(g16 * 0xff / a16)
|
dst[j+1] = uint8(g16 * 0xff / a16)
|
||||||
d[2] = uint8(b16 * 0xff / a16)
|
dst[j+2] = uint8(b16 * 0xff / a16)
|
||||||
d[3] = a
|
|
||||||
}
|
}
|
||||||
|
dst[j+3] = a
|
||||||
j += 4
|
j += 4
|
||||||
i += 4
|
i += 4
|
||||||
}
|
}
|
||||||
@ -108,28 +88,26 @@ func (s *scanner) scan(x1, y1, x2, y2 int, dst []uint8) {
|
|||||||
for y := y1; y < y2; y++ {
|
for y := y1; y < y2; y++ {
|
||||||
i := y*img.Stride + x1*8
|
i := y*img.Stride + x1*8
|
||||||
for x := x1; x < x2; x++ {
|
for x := x1; x < x2; x++ {
|
||||||
s := img.Pix[i : i+8 : i+8]
|
a := img.Pix[i+6]
|
||||||
d := dst[j : j+4 : j+4]
|
|
||||||
a := s[6]
|
|
||||||
switch a {
|
switch a {
|
||||||
case 0:
|
case 0:
|
||||||
d[0] = 0
|
dst[j+0] = 0
|
||||||
d[1] = 0
|
dst[j+1] = 0
|
||||||
d[2] = 0
|
dst[j+2] = 0
|
||||||
case 0xff:
|
case 0xff:
|
||||||
d[0] = s[0]
|
dst[j+0] = img.Pix[i+0]
|
||||||
d[1] = s[2]
|
dst[j+1] = img.Pix[i+2]
|
||||||
d[2] = s[4]
|
dst[j+2] = img.Pix[i+4]
|
||||||
default:
|
default:
|
||||||
r32 := uint32(s[0])<<8 | uint32(s[1])
|
r32 := uint32(img.Pix[i+0])<<8 | uint32(img.Pix[i+1])
|
||||||
g32 := uint32(s[2])<<8 | uint32(s[3])
|
g32 := uint32(img.Pix[i+2])<<8 | uint32(img.Pix[i+3])
|
||||||
b32 := uint32(s[4])<<8 | uint32(s[5])
|
b32 := uint32(img.Pix[i+4])<<8 | uint32(img.Pix[i+5])
|
||||||
a32 := uint32(s[6])<<8 | uint32(s[7])
|
a32 := uint32(img.Pix[i+6])<<8 | uint32(img.Pix[i+7])
|
||||||
d[0] = uint8((r32 * 0xffff / a32) >> 8)
|
dst[j+0] = uint8((r32 * 0xffff / a32) >> 8)
|
||||||
d[1] = uint8((g32 * 0xffff / a32) >> 8)
|
dst[j+1] = uint8((g32 * 0xffff / a32) >> 8)
|
||||||
d[2] = uint8((b32 * 0xffff / a32) >> 8)
|
dst[j+2] = uint8((b32 * 0xffff / a32) >> 8)
|
||||||
}
|
}
|
||||||
d[3] = a
|
dst[j+3] = a
|
||||||
j += 4
|
j += 4
|
||||||
i += 8
|
i += 8
|
||||||
}
|
}
|
||||||
@ -141,11 +119,10 @@ func (s *scanner) scan(x1, y1, x2, y2 int, dst []uint8) {
|
|||||||
i := y*img.Stride + x1
|
i := y*img.Stride + x1
|
||||||
for x := x1; x < x2; x++ {
|
for x := x1; x < x2; x++ {
|
||||||
c := img.Pix[i]
|
c := img.Pix[i]
|
||||||
d := dst[j : j+4 : j+4]
|
dst[j+0] = c
|
||||||
d[0] = c
|
dst[j+1] = c
|
||||||
d[1] = c
|
dst[j+2] = c
|
||||||
d[2] = c
|
dst[j+3] = 0xff
|
||||||
d[3] = 0xff
|
|
||||||
j += 4
|
j += 4
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
@ -157,11 +134,10 @@ func (s *scanner) scan(x1, y1, x2, y2 int, dst []uint8) {
|
|||||||
i := y*img.Stride + x1*2
|
i := y*img.Stride + x1*2
|
||||||
for x := x1; x < x2; x++ {
|
for x := x1; x < x2; x++ {
|
||||||
c := img.Pix[i]
|
c := img.Pix[i]
|
||||||
d := dst[j : j+4 : j+4]
|
dst[j+0] = c
|
||||||
d[0] = c
|
dst[j+1] = c
|
||||||
d[1] = c
|
dst[j+2] = c
|
||||||
d[2] = c
|
dst[j+3] = 0xff
|
||||||
d[3] = 0xff
|
|
||||||
j += 4
|
j += 4
|
||||||
i += 2
|
i += 2
|
||||||
}
|
}
|
||||||
@ -173,61 +149,52 @@ func (s *scanner) scan(x1, y1, x2, y2 int, dst []uint8) {
|
|||||||
x2 += img.Rect.Min.X
|
x2 += img.Rect.Min.X
|
||||||
y1 += img.Rect.Min.Y
|
y1 += img.Rect.Min.Y
|
||||||
y2 += img.Rect.Min.Y
|
y2 += img.Rect.Min.Y
|
||||||
|
|
||||||
hy := img.Rect.Min.Y / 2
|
|
||||||
hx := img.Rect.Min.X / 2
|
|
||||||
for y := y1; y < y2; y++ {
|
for y := y1; y < y2; y++ {
|
||||||
iy := (y-img.Rect.Min.Y)*img.YStride + (x1 - img.Rect.Min.X)
|
iy := (y-img.Rect.Min.Y)*img.YStride + (x1 - img.Rect.Min.X)
|
||||||
|
|
||||||
var yBase int
|
|
||||||
switch img.SubsampleRatio {
|
|
||||||
case image.YCbCrSubsampleRatio444, image.YCbCrSubsampleRatio422:
|
|
||||||
yBase = (y - img.Rect.Min.Y) * img.CStride
|
|
||||||
case image.YCbCrSubsampleRatio420, image.YCbCrSubsampleRatio440:
|
|
||||||
yBase = (y/2 - hy) * img.CStride
|
|
||||||
}
|
|
||||||
|
|
||||||
for x := x1; x < x2; x++ {
|
for x := x1; x < x2; x++ {
|
||||||
var ic int
|
var ic int
|
||||||
switch img.SubsampleRatio {
|
switch img.SubsampleRatio {
|
||||||
case image.YCbCrSubsampleRatio444, image.YCbCrSubsampleRatio440:
|
case image.YCbCrSubsampleRatio444:
|
||||||
ic = yBase + (x - img.Rect.Min.X)
|
ic = (y-img.Rect.Min.Y)*img.CStride + (x - img.Rect.Min.X)
|
||||||
case image.YCbCrSubsampleRatio422, image.YCbCrSubsampleRatio420:
|
case image.YCbCrSubsampleRatio422:
|
||||||
ic = yBase + (x/2 - hx)
|
ic = (y-img.Rect.Min.Y)*img.CStride + (x/2 - img.Rect.Min.X/2)
|
||||||
|
case image.YCbCrSubsampleRatio420:
|
||||||
|
ic = (y/2-img.Rect.Min.Y/2)*img.CStride + (x/2 - img.Rect.Min.X/2)
|
||||||
|
case image.YCbCrSubsampleRatio440:
|
||||||
|
ic = (y/2-img.Rect.Min.Y/2)*img.CStride + (x - img.Rect.Min.X)
|
||||||
default:
|
default:
|
||||||
ic = img.COffset(x, y)
|
ic = img.COffset(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
yy1 := int32(img.Y[iy]) * 0x10101
|
yy := int(img.Y[iy])
|
||||||
cb1 := int32(img.Cb[ic]) - 128
|
cb := int(img.Cb[ic]) - 128
|
||||||
cr1 := int32(img.Cr[ic]) - 128
|
cr := int(img.Cr[ic]) - 128
|
||||||
|
|
||||||
r := yy1 + 91881*cr1
|
r := (yy<<16 + 91881*cr + 1<<15) >> 16
|
||||||
if uint32(r)&0xff000000 == 0 {
|
if r > 0xff {
|
||||||
r >>= 16
|
r = 0xff
|
||||||
} else {
|
} else if r < 0 {
|
||||||
r = ^(r >> 31)
|
r = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
g := yy1 - 22554*cb1 - 46802*cr1
|
g := (yy<<16 - 22554*cb - 46802*cr + 1<<15) >> 16
|
||||||
if uint32(g)&0xff000000 == 0 {
|
if g > 0xff {
|
||||||
g >>= 16
|
g = 0xff
|
||||||
} else {
|
} else if g < 0 {
|
||||||
g = ^(g >> 31)
|
g = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
b := yy1 + 116130*cb1
|
b := (yy<<16 + 116130*cb + 1<<15) >> 16
|
||||||
if uint32(b)&0xff000000 == 0 {
|
if b > 0xff {
|
||||||
b >>= 16
|
b = 0xff
|
||||||
} else {
|
} else if b < 0 {
|
||||||
b = ^(b >> 31)
|
b = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
d := dst[j : j+4 : j+4]
|
dst[j+0] = uint8(r)
|
||||||
d[0] = uint8(r)
|
dst[j+1] = uint8(g)
|
||||||
d[1] = uint8(g)
|
dst[j+2] = uint8(b)
|
||||||
d[2] = uint8(b)
|
dst[j+3] = 0xff
|
||||||
d[3] = 0xff
|
|
||||||
|
|
||||||
iy++
|
iy++
|
||||||
j += 4
|
j += 4
|
||||||
@ -240,11 +207,10 @@ func (s *scanner) scan(x1, y1, x2, y2 int, dst []uint8) {
|
|||||||
i := y*img.Stride + x1
|
i := y*img.Stride + x1
|
||||||
for x := x1; x < x2; x++ {
|
for x := x1; x < x2; x++ {
|
||||||
c := s.palette[img.Pix[i]]
|
c := s.palette[img.Pix[i]]
|
||||||
d := dst[j : j+4 : j+4]
|
dst[j+0] = c.R
|
||||||
d[0] = c.R
|
dst[j+1] = c.G
|
||||||
d[1] = c.G
|
dst[j+2] = c.B
|
||||||
d[2] = c.B
|
dst[j+3] = c.A
|
||||||
d[3] = c.A
|
|
||||||
j += 4
|
j += 4
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
@ -260,23 +226,22 @@ func (s *scanner) scan(x1, y1, x2, y2 int, dst []uint8) {
|
|||||||
for y := y1; y < y2; y++ {
|
for y := y1; y < y2; y++ {
|
||||||
for x := x1; x < x2; x++ {
|
for x := x1; x < x2; x++ {
|
||||||
r16, g16, b16, a16 := s.image.At(x, y).RGBA()
|
r16, g16, b16, a16 := s.image.At(x, y).RGBA()
|
||||||
d := dst[j : j+4 : j+4]
|
|
||||||
switch a16 {
|
switch a16 {
|
||||||
case 0xffff:
|
case 0xffff:
|
||||||
d[0] = uint8(r16 >> 8)
|
dst[j+0] = uint8(r16 >> 8)
|
||||||
d[1] = uint8(g16 >> 8)
|
dst[j+1] = uint8(g16 >> 8)
|
||||||
d[2] = uint8(b16 >> 8)
|
dst[j+2] = uint8(b16 >> 8)
|
||||||
d[3] = 0xff
|
dst[j+3] = 0xff
|
||||||
case 0:
|
case 0:
|
||||||
d[0] = 0
|
dst[j+0] = 0
|
||||||
d[1] = 0
|
dst[j+1] = 0
|
||||||
d[2] = 0
|
dst[j+2] = 0
|
||||||
d[3] = 0
|
dst[j+3] = 0
|
||||||
default:
|
default:
|
||||||
d[0] = uint8(((r16 * 0xffff) / a16) >> 8)
|
dst[j+0] = uint8(((r16 * 0xffff) / a16) >> 8)
|
||||||
d[1] = uint8(((g16 * 0xffff) / a16) >> 8)
|
dst[j+1] = uint8(((g16 * 0xffff) / a16) >> 8)
|
||||||
d[2] = uint8(((b16 * 0xffff) / a16) >> 8)
|
dst[j+2] = uint8(((b16 * 0xffff) / a16) >> 8)
|
||||||
d[3] = uint8(a16 >> 8)
|
dst[j+3] = uint8(a16 >> 8)
|
||||||
}
|
}
|
||||||
j += 4
|
j += 4
|
||||||
}
|
}
|
||||||
|
39
vendor/github.com/gin-gonic/gin/Makefile
generated
vendored
39
vendor/github.com/gin-gonic/gin/Makefile
generated
vendored
@ -1,9 +1,7 @@
|
|||||||
GO ?= go
|
|
||||||
GOFMT ?= gofmt "-s"
|
GOFMT ?= gofmt "-s"
|
||||||
PACKAGES ?= $(shell $(GO) list ./... | grep -v /vendor/)
|
PACKAGES ?= $(shell go list ./... | grep -v /vendor/)
|
||||||
VETPACKAGES ?= $(shell $(GO) list ./... | grep -v /vendor/ | grep -v /examples/)
|
VETPACKAGES ?= $(shell go list ./... | grep -v /vendor/ | grep -v /examples/)
|
||||||
GOFILES := $(shell find . -name "*.go" -type f -not -path "./vendor/*")
|
GOFILES := $(shell find . -name "*.go" -type f -not -path "./vendor/*")
|
||||||
TESTFOLDER := $(shell $(GO) list ./... | grep -E 'gin$$|binding$$|render$$' | grep -v examples)
|
|
||||||
|
|
||||||
all: install
|
all: install
|
||||||
|
|
||||||
@ -12,19 +10,7 @@ install: deps
|
|||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test:
|
test:
|
||||||
echo "mode: count" > coverage.out
|
sh coverage.sh
|
||||||
for d in $(TESTFOLDER); do \
|
|
||||||
$(GO) test -v -covermode=count -coverprofile=profile.out $$d > tmp.out; \
|
|
||||||
cat tmp.out; \
|
|
||||||
if grep -q "^--- FAIL" tmp.out; then \
|
|
||||||
rm tmp.out; \
|
|
||||||
exit 1;\
|
|
||||||
fi; \
|
|
||||||
if [ -f profile.out ]; then \
|
|
||||||
cat profile.out | grep -v "mode:" >> coverage.out; \
|
|
||||||
rm profile.out; \
|
|
||||||
fi; \
|
|
||||||
done
|
|
||||||
|
|
||||||
.PHONY: fmt
|
.PHONY: fmt
|
||||||
fmt:
|
fmt:
|
||||||
@ -32,6 +18,7 @@ fmt:
|
|||||||
|
|
||||||
.PHONY: fmt-check
|
.PHONY: fmt-check
|
||||||
fmt-check:
|
fmt-check:
|
||||||
|
# get all go files and run go fmt on them
|
||||||
@diff=$$($(GOFMT) -d $(GOFILES)); \
|
@diff=$$($(GOFMT) -d $(GOFILES)); \
|
||||||
if [ -n "$$diff" ]; then \
|
if [ -n "$$diff" ]; then \
|
||||||
echo "Please run 'make fmt' and commit the result:"; \
|
echo "Please run 'make fmt' and commit the result:"; \
|
||||||
@ -40,14 +27,14 @@ fmt-check:
|
|||||||
fi;
|
fi;
|
||||||
|
|
||||||
vet:
|
vet:
|
||||||
$(GO) vet $(VETPACKAGES)
|
go vet $(VETPACKAGES)
|
||||||
|
|
||||||
deps:
|
deps:
|
||||||
@hash govendor > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash govendor > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) get -u github.com/kardianos/govendor; \
|
go get -u github.com/kardianos/govendor; \
|
||||||
fi
|
fi
|
||||||
@hash embedmd > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash embedmd > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) get -u github.com/campoy/embedmd; \
|
go get -u github.com/campoy/embedmd; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
embedmd:
|
embedmd:
|
||||||
@ -56,26 +43,20 @@ embedmd:
|
|||||||
.PHONY: lint
|
.PHONY: lint
|
||||||
lint:
|
lint:
|
||||||
@hash golint > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash golint > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) get -u golang.org/x/lint/golint; \
|
go get -u github.com/golang/lint/golint; \
|
||||||
fi
|
fi
|
||||||
for PKG in $(PACKAGES); do golint -set_exit_status $$PKG || exit 1; done;
|
for PKG in $(PACKAGES); do golint -set_exit_status $$PKG || exit 1; done;
|
||||||
|
|
||||||
.PHONY: misspell-check
|
.PHONY: misspell-check
|
||||||
misspell-check:
|
misspell-check:
|
||||||
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) get -u github.com/client9/misspell/cmd/misspell; \
|
go get -u github.com/client9/misspell/cmd/misspell; \
|
||||||
fi
|
fi
|
||||||
misspell -error $(GOFILES)
|
misspell -error $(GOFILES)
|
||||||
|
|
||||||
.PHONY: misspell
|
.PHONY: misspell
|
||||||
misspell:
|
misspell:
|
||||||
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) get -u github.com/client9/misspell/cmd/misspell; \
|
go get -u github.com/client9/misspell/cmd/misspell; \
|
||||||
fi
|
fi
|
||||||
misspell -w $(GOFILES)
|
misspell -w $(GOFILES)
|
||||||
|
|
||||||
.PHONY: tools
|
|
||||||
tools:
|
|
||||||
go install golang.org/x/lint/golint; \
|
|
||||||
go install github.com/client9/misspell/cmd/misspell; \
|
|
||||||
go install github.com/campoy/embedmd;
|
|
||||||
|
256
vendor/github.com/gin-gonic/gin/README.md
generated
vendored
256
vendor/github.com/gin-gonic/gin/README.md
generated
vendored
@ -9,7 +9,6 @@
|
|||||||
[](https://gitter.im/gin-gonic/gin?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://gitter.im/gin-gonic/gin?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
[](https://sourcegraph.com/github.com/gin-gonic/gin?badge)
|
[](https://sourcegraph.com/github.com/gin-gonic/gin?badge)
|
||||||
[](https://www.codetriage.com/gin-gonic/gin)
|
[](https://www.codetriage.com/gin-gonic/gin)
|
||||||
[](https://github.com/gin-gonic/gin/releases)
|
|
||||||
|
|
||||||
Gin is a web framework written in Go (Golang). It features a martini-like API with much better performance, up to 40 times faster thanks to [httprouter](https://github.com/julienschmidt/httprouter). If you need performance and good productivity, you will love Gin.
|
Gin is a web framework written in Go (Golang). It features a martini-like API with much better performance, up to 40 times faster thanks to [httprouter](https://github.com/julienschmidt/httprouter). If you need performance and good productivity, you will love Gin.
|
||||||
|
|
||||||
@ -39,10 +38,9 @@ Gin is a web framework written in Go (Golang). It features a martini-like API wi
|
|||||||
- [Custom Validators](#custom-validators)
|
- [Custom Validators](#custom-validators)
|
||||||
- [Only Bind Query String](#only-bind-query-string)
|
- [Only Bind Query String](#only-bind-query-string)
|
||||||
- [Bind Query String or Post Data](#bind-query-string-or-post-data)
|
- [Bind Query String or Post Data](#bind-query-string-or-post-data)
|
||||||
- [Bind Uri](#bind-uri)
|
|
||||||
- [Bind HTML checkboxes](#bind-html-checkboxes)
|
- [Bind HTML checkboxes](#bind-html-checkboxes)
|
||||||
- [Multipart/Urlencoded binding](#multiparturlencoded-binding)
|
- [Multipart/Urlencoded binding](#multiparturlencoded-binding)
|
||||||
- [XML, JSON, YAML and ProtoBuf rendering](#xml-json-yaml-and-protobuf-rendering)
|
- [XML, JSON and YAML rendering](#xml-json-and-yaml-rendering)
|
||||||
- [JSONP rendering](#jsonp)
|
- [JSONP rendering](#jsonp)
|
||||||
- [Serving static files](#serving-static-files)
|
- [Serving static files](#serving-static-files)
|
||||||
- [Serving data from reader](#serving-data-from-reader)
|
- [Serving data from reader](#serving-data-from-reader)
|
||||||
@ -60,10 +58,8 @@ Gin is a web framework written in Go (Golang). It features a martini-like API wi
|
|||||||
- [Bind form-data request with custom struct](#bind-form-data-request-with-custom-struct)
|
- [Bind form-data request with custom struct](#bind-form-data-request-with-custom-struct)
|
||||||
- [Try to bind body into different structs](#try-to-bind-body-into-different-structs)
|
- [Try to bind body into different structs](#try-to-bind-body-into-different-structs)
|
||||||
- [http2 server push](#http2-server-push)
|
- [http2 server push](#http2-server-push)
|
||||||
- [Define format for the log of routes](#define-format-for-the-log-of-routes)
|
|
||||||
- [Set and get a cookie](#set-and-get-a-cookie)
|
|
||||||
- [Testing](#testing)
|
- [Testing](#testing)
|
||||||
- [Users](#users)
|
- [Users](#users--)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@ -104,7 +100,7 @@ $ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ govendor init
|
$ govendor init
|
||||||
$ govendor fetch github.com/gin-gonic/gin@v1.3
|
$ govendor fetch github.com/gin-gonic/gin@v1.2
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Copy a starting template inside your project
|
4. Copy a starting template inside your project
|
||||||
@ -202,7 +198,7 @@ BenchmarkVulcan_GithubAll | 5000 | 394253 | 19894
|
|||||||
|
|
||||||
## Build with [jsoniter](https://github.com/json-iterator/go)
|
## Build with [jsoniter](https://github.com/json-iterator/go)
|
||||||
|
|
||||||
Gin uses `encoding/json` as default json package but you can change to [jsoniter](https://github.com/json-iterator/go) by build from other tags.
|
Gin use `encoding/json` as default json package but you can change to [jsoniter](https://github.com/json-iterator/go) by build from other tags.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ go build -tags=jsoniter .
|
$ go build -tags=jsoniter .
|
||||||
@ -530,7 +526,7 @@ func main() {
|
|||||||
|
|
||||||
### Model binding and validation
|
### Model binding and validation
|
||||||
|
|
||||||
To bind a request body into a type, use model binding. We currently support binding of JSON, XML, YAML and standard form values (foo=bar&boo=baz).
|
To bind a request body into a type, use model binding. We currently support binding of JSON, XML and standard form values (foo=bar&boo=baz).
|
||||||
|
|
||||||
Gin uses [**go-playground/validator.v8**](https://github.com/go-playground/validator) for validation. Check the full docs on tags usage [here](http://godoc.org/gopkg.in/go-playground/validator.v8#hdr-Baked_In_Validators_and_Tags).
|
Gin uses [**go-playground/validator.v8**](https://github.com/go-playground/validator) for validation. Check the full docs on tags usage [here](http://godoc.org/gopkg.in/go-playground/validator.v8#hdr-Baked_In_Validators_and_Tags).
|
||||||
|
|
||||||
@ -538,10 +534,10 @@ Note that you need to set the corresponding binding tag on all fields you want t
|
|||||||
|
|
||||||
Also, Gin provides two sets of methods for binding:
|
Also, Gin provides two sets of methods for binding:
|
||||||
- **Type** - Must bind
|
- **Type** - Must bind
|
||||||
- **Methods** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
|
- **Methods** - `Bind`, `BindJSON`, `BindQuery`
|
||||||
- **Behavior** - These methods use `MustBindWith` under the hood. If there is a binding error, the request is aborted with `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. This sets the response status code to 400 and the `Content-Type` header is set to `text/plain; charset=utf-8`. Note that if you try to set the response code after this, it will result in a warning `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. If you wish to have greater control over the behavior, consider using the `ShouldBind` equivalent method.
|
- **Behavior** - These methods use `MustBindWith` under the hood. If there is a binding error, the request is aborted with `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. This sets the response status code to 400 and the `Content-Type` header is set to `text/plain; charset=utf-8`. Note that if you try to set the response code after this, it will result in a warning `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. If you wish to have greater control over the behavior, consider using the `ShouldBind` equivalent method.
|
||||||
- **Type** - Should bind
|
- **Type** - Should bind
|
||||||
- **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
|
- **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindQuery`
|
||||||
- **Behavior** - These methods use `ShouldBindWith` under the hood. If there is a binding error, the error is returned and it is the developer's responsibility to handle the request and error appropriately.
|
- **Behavior** - These methods use `ShouldBindWith` under the hood. If there is a binding error, the error is returned and it is the developer's responsibility to handle the request and error appropriately.
|
||||||
|
|
||||||
When using the Bind-method, Gin tries to infer the binder depending on the Content-Type header. If you are sure what you are binding, you can use `MustBindWith` or `ShouldBindWith`.
|
When using the Bind-method, Gin tries to infer the binder depending on the Content-Type header. If you are sure what you are binding, you can use `MustBindWith` or `ShouldBindWith`.
|
||||||
@ -551,8 +547,8 @@ You can also specify that specific fields are required. If a field is decorated
|
|||||||
```go
|
```go
|
||||||
// Binding from JSON
|
// Binding from JSON
|
||||||
type Login struct {
|
type Login struct {
|
||||||
User string `form:"user" json:"user" xml:"user" binding:"required"`
|
User string `form:"user" json:"user" binding:"required"`
|
||||||
Password string `form:"password" json:"password" xml:"password" binding:"required"`
|
Password string `form:"password" json:"password" binding:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -561,55 +557,30 @@ func main() {
|
|||||||
// Example for binding JSON ({"user": "manu", "password": "123"})
|
// Example for binding JSON ({"user": "manu", "password": "123"})
|
||||||
router.POST("/loginJSON", func(c *gin.Context) {
|
router.POST("/loginJSON", func(c *gin.Context) {
|
||||||
var json Login
|
var json Login
|
||||||
if err := c.ShouldBindJSON(&json); err != nil {
|
if err := c.ShouldBindJSON(&json); err == nil {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
if json.User == "manu" && json.Password == "123" {
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if json.User != "manu" || json.Password != "123" {
|
|
||||||
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
|
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
|
||||||
})
|
} else {
|
||||||
|
|
||||||
// Example for binding XML (
|
|
||||||
// <?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
// <root>
|
|
||||||
// <user>user</user>
|
|
||||||
// <password>123</user>
|
|
||||||
// </root>)
|
|
||||||
router.POST("/loginXML", func(c *gin.Context) {
|
|
||||||
var xml Login
|
|
||||||
if err := c.ShouldBindXML(&xml); err != nil {
|
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if xml.User != "manu" || xml.Password != "123" {
|
|
||||||
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
|
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Example for binding a HTML form (user=manu&password=123)
|
// Example for binding a HTML form (user=manu&password=123)
|
||||||
router.POST("/loginForm", func(c *gin.Context) {
|
router.POST("/loginForm", func(c *gin.Context) {
|
||||||
var form Login
|
var form Login
|
||||||
// This will infer what binder to use depending on the content-type header.
|
// This will infer what binder to use depending on the content-type header.
|
||||||
if err := c.ShouldBind(&form); err != nil {
|
if err := c.ShouldBind(&form); err == nil {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
if form.User == "manu" && form.Password == "123" {
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if form.User != "manu" || form.Password != "123" {
|
|
||||||
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
|
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
|
||||||
|
} else {
|
||||||
|
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Listen and serve on 0.0.0.0:8080
|
// Listen and serve on 0.0.0.0:8080
|
||||||
@ -661,7 +632,6 @@ import (
|
|||||||
"gopkg.in/go-playground/validator.v8"
|
"gopkg.in/go-playground/validator.v8"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Booking contains binded and validated data.
|
|
||||||
type Booking struct {
|
type Booking struct {
|
||||||
CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
|
CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
|
||||||
CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn" time_format:"2006-01-02"`
|
CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn" time_format:"2006-01-02"`
|
||||||
@ -709,7 +679,7 @@ $ curl "localhost:8085/bookable?check_in=2018-03-08&check_out=2018-03-09"
|
|||||||
{"error":"Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'bookabledate' tag"}
|
{"error":"Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'bookabledate' tag"}
|
||||||
```
|
```
|
||||||
|
|
||||||
[Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) can also be registered this way.
|
[Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) can also be registed this way.
|
||||||
See the [struct-lvl-validation example](examples/struct-lvl-validations) to learn more.
|
See the [struct-lvl-validation example](examples/struct-lvl-validations) to learn more.
|
||||||
|
|
||||||
### Only Bind Query String
|
### Only Bind Query String
|
||||||
@ -755,12 +725,9 @@ See the [detail information](https://github.com/gin-gonic/gin/issues/742#issueco
|
|||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import "log"
|
||||||
"log"
|
import "github.com/gin-gonic/gin"
|
||||||
"time"
|
import "time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Person struct {
|
type Person struct {
|
||||||
Name string `form:"name"`
|
Name string `form:"name"`
|
||||||
@ -794,40 +761,6 @@ Test it with:
|
|||||||
$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
|
$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Bind Uri
|
|
||||||
|
|
||||||
See the [detail information](https://github.com/gin-gonic/gin/issues/846).
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "github.com/gin-gonic/gin"
|
|
||||||
|
|
||||||
type Person struct {
|
|
||||||
ID string `uri:"id" binding:"required,uuid"`
|
|
||||||
Name string `uri:"name" binding:"required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
route := gin.Default()
|
|
||||||
route.GET("/:name/:id", func(c *gin.Context) {
|
|
||||||
var person Person
|
|
||||||
if err := c.ShouldBindUri(&person); err != nil {
|
|
||||||
c.JSON(400, gin.H{"msg": err})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
|
|
||||||
})
|
|
||||||
route.Run(":8088")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Test it with:
|
|
||||||
```sh
|
|
||||||
$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
|
|
||||||
$ curl -v localhost:8088/thinkerou/not-uuid
|
|
||||||
```
|
|
||||||
|
|
||||||
### Bind HTML checkboxes
|
### Bind HTML checkboxes
|
||||||
|
|
||||||
See the [detail information](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)
|
See the [detail information](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)
|
||||||
@ -859,12 +792,12 @@ form.html
|
|||||||
<form action="/" method="POST">
|
<form action="/" method="POST">
|
||||||
<p>Check some colors</p>
|
<p>Check some colors</p>
|
||||||
<label for="red">Red</label>
|
<label for="red">Red</label>
|
||||||
<input type="checkbox" name="colors[]" value="red" id="red">
|
<input type="checkbox" name="colors[]" value="red" id="red" />
|
||||||
<label for="green">Green</label>
|
<label for="green">Green</label>
|
||||||
<input type="checkbox" name="colors[]" value="green" id="green">
|
<input type="checkbox" name="colors[]" value="green" id="green" />
|
||||||
<label for="blue">Blue</label>
|
<label for="blue">Blue</label>
|
||||||
<input type="checkbox" name="colors[]" value="blue" id="blue">
|
<input type="checkbox" name="colors[]" value="blue" id="blue" />
|
||||||
<input type="submit">
|
<input type="submit" />
|
||||||
</form>
|
</form>
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -913,7 +846,7 @@ Test it with:
|
|||||||
$ curl -v --form user=user --form password=password http://localhost:8080/login
|
$ curl -v --form user=user --form password=password http://localhost:8080/login
|
||||||
```
|
```
|
||||||
|
|
||||||
### XML, JSON, YAML and ProtoBuf rendering
|
### XML, JSON and YAML rendering
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func main() {
|
func main() {
|
||||||
@ -947,19 +880,6 @@ func main() {
|
|||||||
c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
|
c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
|
||||||
})
|
})
|
||||||
|
|
||||||
r.GET("/someProtoBuf", func(c *gin.Context) {
|
|
||||||
reps := []int64{int64(1), int64(2)}
|
|
||||||
label := "test"
|
|
||||||
// The specific definition of protobuf is written in the testdata/protoexample file.
|
|
||||||
data := &protoexample.Test{
|
|
||||||
Label: &label,
|
|
||||||
Reps: reps,
|
|
||||||
}
|
|
||||||
// Note that data becomes binary data in the response
|
|
||||||
// Will output protoexample.Test protobuf serialized data
|
|
||||||
c.ProtoBuf(http.StatusOK, data)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Listen and serve on 0.0.0.0:8080
|
// Listen and serve on 0.0.0.0:8080
|
||||||
r.Run(":8080")
|
r.Run(":8080")
|
||||||
}
|
}
|
||||||
@ -1033,34 +953,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### PureJSON
|
|
||||||
|
|
||||||
Normally, JSON replaces special HTML characters with their unicode entities, e.g. `<` becomes `\u003c`. If you want to encode such characters literally, you can use PureJSON instead.
|
|
||||||
This feature is unavailable in Go 1.6 and lower.
|
|
||||||
|
|
||||||
```go
|
|
||||||
func main() {
|
|
||||||
r := gin.Default()
|
|
||||||
|
|
||||||
// Serves unicode entities
|
|
||||||
r.GET("/json", func(c *gin.Context) {
|
|
||||||
c.JSON(200, gin.H{
|
|
||||||
"html": "<b>Hello, world!</b>",
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// Serves literal characters
|
|
||||||
r.GET("/purejson", func(c *gin.Context) {
|
|
||||||
c.PureJSON(200, gin.H{
|
|
||||||
"html": "<b>Hello, world!</b>",
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// listen and serve on 0.0.0.0:8080
|
|
||||||
r.Run(":8080")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Serving static files
|
### Serving static files
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@ -1195,7 +1087,7 @@ You may use custom delims
|
|||||||
```go
|
```go
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
r.Delims("{[{", "}]}")
|
r.Delims("{[{", "}]}")
|
||||||
r.LoadHTMLGlob("/path/to/templates")
|
r.LoadHTMLGlob("/path/to/templates"))
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Custom Template Funcs
|
#### Custom Template Funcs
|
||||||
@ -1757,11 +1649,11 @@ type StructX struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type StructY struct {
|
type StructY struct {
|
||||||
Y StructX `form:"name_y"` // HERE have form
|
Y StructX `form:"name_y"` // HERE hava form
|
||||||
}
|
}
|
||||||
|
|
||||||
type StructZ struct {
|
type StructZ struct {
|
||||||
Z *StructZ `form:"name_z"` // HERE have form
|
Z *StructZ `form:"name_z"` // HERE hava form
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -1874,78 +1766,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Define format for the log of routes
|
|
||||||
|
|
||||||
The default log of routes is:
|
|
||||||
```
|
|
||||||
[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
|
|
||||||
[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
|
|
||||||
[GIN-debug] GET /status --> main.main.func3 (3 handlers)
|
|
||||||
```
|
|
||||||
|
|
||||||
If you want to log this information in given format (e.g. JSON, key values or something else), then you can define this format with `gin.DebugPrintRouteFunc`.
|
|
||||||
In the example below, we log all routes with standard log package but you can use another log tools that suits of your needs.
|
|
||||||
```go
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
r := gin.Default()
|
|
||||||
gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
|
|
||||||
log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
|
|
||||||
}
|
|
||||||
|
|
||||||
r.POST("/foo", func(c *gin.Context) {
|
|
||||||
c.JSON(http.StatusOK, "foo")
|
|
||||||
})
|
|
||||||
|
|
||||||
r.GET("/bar", func(c *gin.Context) {
|
|
||||||
c.JSON(http.StatusOK, "bar")
|
|
||||||
})
|
|
||||||
|
|
||||||
r.GET("/status", func(c *gin.Context) {
|
|
||||||
c.JSON(http.StatusOK, "ok")
|
|
||||||
})
|
|
||||||
|
|
||||||
// Listen and Server in http://0.0.0.0:8080
|
|
||||||
r.Run()
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Set and get a cookie
|
|
||||||
|
|
||||||
```go
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
|
|
||||||
router := gin.Default()
|
|
||||||
|
|
||||||
router.GET("/cookie", func(c *gin.Context) {
|
|
||||||
|
|
||||||
cookie, err := c.Cookie("gin_cookie")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
cookie = "NotSet"
|
|
||||||
c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Cookie value: %s \n", cookie)
|
|
||||||
})
|
|
||||||
|
|
||||||
router.Run()
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
The `net/http/httptest` package is preferable way for HTTP testing.
|
The `net/http/httptest` package is preferable way for HTTP testing.
|
||||||
@ -1996,9 +1816,5 @@ func TestPingRoute(t *testing.T) {
|
|||||||
|
|
||||||
Awesome project lists using [Gin](https://github.com/gin-gonic/gin) web framework.
|
Awesome project lists using [Gin](https://github.com/gin-gonic/gin) web framework.
|
||||||
|
|
||||||
* [drone](https://github.com/drone/drone): Drone is a Continuous Delivery platform built on Docker, written in Go.
|
* [drone](https://github.com/drone/drone): Drone is a Continuous Delivery platform built on Docker, written in Go
|
||||||
* [gorush](https://github.com/appleboy/gorush): A push notification server written in Go.
|
* [gorush](https://github.com/appleboy/gorush): A push notification server written in Go.
|
||||||
* [fnproject](https://github.com/fnproject/fn): The container native, cloud agnostic serverless platform.
|
|
||||||
* [photoprism](https://github.com/photoprism/photoprism): Personal photo management powered by Go and Google TensorFlow.
|
|
||||||
* [krakend](https://github.com/devopsfaith/krakend): Ultra performant API Gateway with middlewares.
|
|
||||||
* [picfit](https://github.com/thoas/picfit): An image resizing server written in Go.
|
|
||||||
|
14
vendor/github.com/gin-gonic/gin/binding/binding.go
generated
vendored
14
vendor/github.com/gin-gonic/gin/binding/binding.go
generated
vendored
@ -18,7 +18,6 @@ const (
|
|||||||
MIMEPROTOBUF = "application/x-protobuf"
|
MIMEPROTOBUF = "application/x-protobuf"
|
||||||
MIMEMSGPACK = "application/x-msgpack"
|
MIMEMSGPACK = "application/x-msgpack"
|
||||||
MIMEMSGPACK2 = "application/msgpack"
|
MIMEMSGPACK2 = "application/msgpack"
|
||||||
MIMEYAML = "application/x-yaml"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Binding describes the interface which needs to be implemented for binding the
|
// Binding describes the interface which needs to be implemented for binding the
|
||||||
@ -36,16 +35,9 @@ type BindingBody interface {
|
|||||||
BindBody([]byte, interface{}) error
|
BindBody([]byte, interface{}) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// BindingUri adds BindUri method to Binding. BindUri is similar with Bind,
|
|
||||||
// but it read the Params.
|
|
||||||
type BindingUri interface {
|
|
||||||
Name() string
|
|
||||||
BindUri(map[string][]string, interface{}) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// StructValidator is the minimal interface which needs to be implemented in
|
// StructValidator is the minimal interface which needs to be implemented in
|
||||||
// order for it to be used as the validator engine for ensuring the correctness
|
// order for it to be used as the validator engine for ensuring the correctness
|
||||||
// of the request. Gin provides a default implementation for this using
|
// of the reqest. Gin provides a default implementation for this using
|
||||||
// https://github.com/go-playground/validator/tree/v8.18.2.
|
// https://github.com/go-playground/validator/tree/v8.18.2.
|
||||||
type StructValidator interface {
|
type StructValidator interface {
|
||||||
// ValidateStruct can receive any kind of type and it should never panic, even if the configuration is not right.
|
// ValidateStruct can receive any kind of type and it should never panic, even if the configuration is not right.
|
||||||
@ -76,8 +68,6 @@ var (
|
|||||||
FormMultipart = formMultipartBinding{}
|
FormMultipart = formMultipartBinding{}
|
||||||
ProtoBuf = protobufBinding{}
|
ProtoBuf = protobufBinding{}
|
||||||
MsgPack = msgpackBinding{}
|
MsgPack = msgpackBinding{}
|
||||||
YAML = yamlBinding{}
|
|
||||||
Uri = uriBinding{}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Default returns the appropriate Binding instance based on the HTTP method
|
// Default returns the appropriate Binding instance based on the HTTP method
|
||||||
@ -96,8 +86,6 @@ func Default(method, contentType string) Binding {
|
|||||||
return ProtoBuf
|
return ProtoBuf
|
||||||
case MIMEMSGPACK, MIMEMSGPACK2:
|
case MIMEMSGPACK, MIMEMSGPACK2:
|
||||||
return MsgPack
|
return MsgPack
|
||||||
case MIMEYAML:
|
|
||||||
return YAML
|
|
||||||
default: //case MIMEPOSTForm, MIMEMultipartPOSTForm:
|
default: //case MIMEPOSTForm, MIMEMultipartPOSTForm:
|
||||||
return Form
|
return Form
|
||||||
}
|
}
|
||||||
|
16
vendor/github.com/gin-gonic/gin/binding/form_mapping.go
generated
vendored
16
vendor/github.com/gin-gonic/gin/binding/form_mapping.go
generated
vendored
@ -12,15 +12,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func mapUri(ptr interface{}, m map[string][]string) error {
|
|
||||||
return mapFormByTag(ptr, m, "uri")
|
|
||||||
}
|
|
||||||
|
|
||||||
func mapForm(ptr interface{}, form map[string][]string) error {
|
func mapForm(ptr interface{}, form map[string][]string) error {
|
||||||
return mapFormByTag(ptr, form, "form")
|
|
||||||
}
|
|
||||||
|
|
||||||
func mapFormByTag(ptr interface{}, form map[string][]string, tag string) error {
|
|
||||||
typ := reflect.TypeOf(ptr).Elem()
|
typ := reflect.TypeOf(ptr).Elem()
|
||||||
val := reflect.ValueOf(ptr).Elem()
|
val := reflect.ValueOf(ptr).Elem()
|
||||||
for i := 0; i < typ.NumField(); i++ {
|
for i := 0; i < typ.NumField(); i++ {
|
||||||
@ -31,7 +23,7 @@ func mapFormByTag(ptr interface{}, form map[string][]string, tag string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
structFieldKind := structField.Kind()
|
structFieldKind := structField.Kind()
|
||||||
inputFieldName := typeField.Tag.Get(tag)
|
inputFieldName := typeField.Tag.Get("form")
|
||||||
inputFieldNameList := strings.Split(inputFieldName, ",")
|
inputFieldNameList := strings.Split(inputFieldName, ",")
|
||||||
inputFieldName = inputFieldNameList[0]
|
inputFieldName = inputFieldNameList[0]
|
||||||
var defaultValue string
|
var defaultValue string
|
||||||
@ -82,8 +74,7 @@ func mapFormByTag(ptr interface{}, form map[string][]string, tag string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val.Field(i).Set(slice)
|
val.Field(i).Set(slice)
|
||||||
continue
|
} else {
|
||||||
}
|
|
||||||
if _, isTime := structField.Interface().(time.Time); isTime {
|
if _, isTime := structField.Interface().(time.Time); isTime {
|
||||||
if err := setTimeField(inputValue[0], typeField, structField); err != nil {
|
if err := setTimeField(inputValue[0], typeField, structField); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -94,6 +85,7 @@ func mapFormByTag(ptr interface{}, form map[string][]string, tag string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +178,7 @@ func setFloatField(val string, bitSize int, field reflect.Value) error {
|
|||||||
func setTimeField(val string, structField reflect.StructField, value reflect.Value) error {
|
func setTimeField(val string, structField reflect.StructField, value reflect.Value) error {
|
||||||
timeFormat := structField.Tag.Get("time_format")
|
timeFormat := structField.Tag.Get("time_format")
|
||||||
if timeFormat == "" {
|
if timeFormat == "" {
|
||||||
timeFormat = time.RFC3339
|
return errors.New("Blank time format")
|
||||||
}
|
}
|
||||||
|
|
||||||
if val == "" {
|
if val == "" {
|
||||||
|
6
vendor/github.com/gin-gonic/gin/binding/json.go
generated
vendored
6
vendor/github.com/gin-gonic/gin/binding/json.go
generated
vendored
@ -6,11 +6,10 @@ package binding
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin/internal/json"
|
"github.com/gin-gonic/gin/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EnableDecoderUseNumber is used to call the UseNumber method on the JSON
|
// EnableDecoderUseNumber is used to call the UseNumber method on the JSON
|
||||||
@ -25,9 +24,6 @@ func (jsonBinding) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (jsonBinding) Bind(req *http.Request, obj interface{}) error {
|
func (jsonBinding) Bind(req *http.Request, obj interface{}) error {
|
||||||
if req == nil || req.Body == nil {
|
|
||||||
return fmt.Errorf("invalid request")
|
|
||||||
}
|
|
||||||
return decodeJSON(req.Body, obj)
|
return decodeJSON(req.Body, obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
vendor/github.com/gin-gonic/gin/binding/protobuf.go
generated
vendored
2
vendor/github.com/gin-gonic/gin/binding/protobuf.go
generated
vendored
@ -29,7 +29,7 @@ func (protobufBinding) BindBody(body []byte, obj interface{}) error {
|
|||||||
if err := proto.Unmarshal(body, obj.(proto.Message)); err != nil {
|
if err := proto.Unmarshal(body, obj.(proto.Message)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Here it's same to return validate(obj), but util now we can't add
|
// Here it's same to return validate(obj), but util now we cann't add
|
||||||
// `binding:""` to the struct which automatically generate by gen-proto
|
// `binding:""` to the struct which automatically generate by gen-proto
|
||||||
return nil
|
return nil
|
||||||
// return validate(obj)
|
// return validate(obj)
|
||||||
|
62
vendor/github.com/gin-gonic/gin/context.go
generated
vendored
62
vendor/github.com/gin-gonic/gin/context.go
generated
vendored
@ -31,7 +31,6 @@ const (
|
|||||||
MIMEPlain = binding.MIMEPlain
|
MIMEPlain = binding.MIMEPlain
|
||||||
MIMEPOSTForm = binding.MIMEPOSTForm
|
MIMEPOSTForm = binding.MIMEPOSTForm
|
||||||
MIMEMultipartPOSTForm = binding.MIMEMultipartPOSTForm
|
MIMEMultipartPOSTForm = binding.MIMEMultipartPOSTForm
|
||||||
MIMEYAML = binding.MIMEYAML
|
|
||||||
BodyBytesKey = "_gin-gonic/gin/bodybyteskey"
|
BodyBytesKey = "_gin-gonic/gin/bodybyteskey"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -415,6 +414,7 @@ func (c *Context) PostFormArray(key string) []string {
|
|||||||
// a boolean value whether at least one value exists for the given key.
|
// a boolean value whether at least one value exists for the given key.
|
||||||
func (c *Context) GetPostFormArray(key string) ([]string, bool) {
|
func (c *Context) GetPostFormArray(key string) ([]string, bool) {
|
||||||
req := c.Request
|
req := c.Request
|
||||||
|
req.ParseForm()
|
||||||
req.ParseMultipartForm(c.engine.MaxMultipartMemory)
|
req.ParseMultipartForm(c.engine.MaxMultipartMemory)
|
||||||
if values := req.PostForm[key]; len(values) > 0 {
|
if values := req.PostForm[key]; len(values) > 0 {
|
||||||
return values, true
|
return values, true
|
||||||
@ -437,6 +437,7 @@ func (c *Context) PostFormMap(key string) map[string]string {
|
|||||||
// whether at least one value exists for the given key.
|
// whether at least one value exists for the given key.
|
||||||
func (c *Context) GetPostFormMap(key string) (map[string]string, bool) {
|
func (c *Context) GetPostFormMap(key string) (map[string]string, bool) {
|
||||||
req := c.Request
|
req := c.Request
|
||||||
|
req.ParseForm()
|
||||||
req.ParseMultipartForm(c.engine.MaxMultipartMemory)
|
req.ParseMultipartForm(c.engine.MaxMultipartMemory)
|
||||||
dicts, exist := c.get(req.PostForm, key)
|
dicts, exist := c.get(req.PostForm, key)
|
||||||
|
|
||||||
@ -464,11 +465,6 @@ func (c *Context) get(m map[string][]string, key string) (map[string]string, boo
|
|||||||
|
|
||||||
// FormFile returns the first file for the provided form key.
|
// FormFile returns the first file for the provided form key.
|
||||||
func (c *Context) FormFile(name string) (*multipart.FileHeader, error) {
|
func (c *Context) FormFile(name string) (*multipart.FileHeader, error) {
|
||||||
if c.Request.MultipartForm == nil {
|
|
||||||
if err := c.Request.ParseMultipartForm(c.engine.MaxMultipartMemory); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_, fh, err := c.Request.FormFile(name)
|
_, fh, err := c.Request.FormFile(name)
|
||||||
return fh, err
|
return fh, err
|
||||||
}
|
}
|
||||||
@ -515,23 +511,13 @@ func (c *Context) BindJSON(obj interface{}) error {
|
|||||||
return c.MustBindWith(obj, binding.JSON)
|
return c.MustBindWith(obj, binding.JSON)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BindXML is a shortcut for c.MustBindWith(obj, binding.BindXML).
|
|
||||||
func (c *Context) BindXML(obj interface{}) error {
|
|
||||||
return c.MustBindWith(obj, binding.XML)
|
|
||||||
}
|
|
||||||
|
|
||||||
// BindQuery is a shortcut for c.MustBindWith(obj, binding.Query).
|
// BindQuery is a shortcut for c.MustBindWith(obj, binding.Query).
|
||||||
func (c *Context) BindQuery(obj interface{}) error {
|
func (c *Context) BindQuery(obj interface{}) error {
|
||||||
return c.MustBindWith(obj, binding.Query)
|
return c.MustBindWith(obj, binding.Query)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BindYAML is a shortcut for c.MustBindWith(obj, binding.YAML).
|
|
||||||
func (c *Context) BindYAML(obj interface{}) error {
|
|
||||||
return c.MustBindWith(obj, binding.YAML)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustBindWith binds the passed struct pointer using the specified binding engine.
|
// MustBindWith binds the passed struct pointer using the specified binding engine.
|
||||||
// It will abort the request with HTTP 400 if any error occurs.
|
// It will abort the request with HTTP 400 if any error ocurrs.
|
||||||
// See the binding package.
|
// See the binding package.
|
||||||
func (c *Context) MustBindWith(obj interface{}, b binding.Binding) (err error) {
|
func (c *Context) MustBindWith(obj interface{}, b binding.Binding) (err error) {
|
||||||
if err = c.ShouldBindWith(obj, b); err != nil {
|
if err = c.ShouldBindWith(obj, b); err != nil {
|
||||||
@ -559,30 +545,11 @@ func (c *Context) ShouldBindJSON(obj interface{}) error {
|
|||||||
return c.ShouldBindWith(obj, binding.JSON)
|
return c.ShouldBindWith(obj, binding.JSON)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShouldBindXML is a shortcut for c.ShouldBindWith(obj, binding.XML).
|
|
||||||
func (c *Context) ShouldBindXML(obj interface{}) error {
|
|
||||||
return c.ShouldBindWith(obj, binding.XML)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShouldBindQuery is a shortcut for c.ShouldBindWith(obj, binding.Query).
|
// ShouldBindQuery is a shortcut for c.ShouldBindWith(obj, binding.Query).
|
||||||
func (c *Context) ShouldBindQuery(obj interface{}) error {
|
func (c *Context) ShouldBindQuery(obj interface{}) error {
|
||||||
return c.ShouldBindWith(obj, binding.Query)
|
return c.ShouldBindWith(obj, binding.Query)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShouldBindYAML is a shortcut for c.ShouldBindWith(obj, binding.YAML).
|
|
||||||
func (c *Context) ShouldBindYAML(obj interface{}) error {
|
|
||||||
return c.ShouldBindWith(obj, binding.YAML)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShouldBindUri binds the passed struct pointer using the specified binding engine.
|
|
||||||
func (c *Context) ShouldBindUri(obj interface{}) error {
|
|
||||||
m := make(map[string][]string)
|
|
||||||
for _, v := range c.Params {
|
|
||||||
m[v.Key] = []string{v.Value}
|
|
||||||
}
|
|
||||||
return binding.Uri.BindUri(m, obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShouldBindWith binds the passed struct pointer using the specified binding engine.
|
// ShouldBindWith binds the passed struct pointer using the specified binding engine.
|
||||||
// See the binding package.
|
// See the binding package.
|
||||||
func (c *Context) ShouldBindWith(obj interface{}, b binding.Binding) error {
|
func (c *Context) ShouldBindWith(obj interface{}, b binding.Binding) error {
|
||||||
@ -594,7 +561,9 @@ func (c *Context) ShouldBindWith(obj interface{}, b binding.Binding) error {
|
|||||||
//
|
//
|
||||||
// NOTE: This method reads the body before binding. So you should use
|
// NOTE: This method reads the body before binding. So you should use
|
||||||
// ShouldBindWith for better performance if you need to call only once.
|
// ShouldBindWith for better performance if you need to call only once.
|
||||||
func (c *Context) ShouldBindBodyWith(obj interface{}, bb binding.BindingBody) (err error) {
|
func (c *Context) ShouldBindBodyWith(
|
||||||
|
obj interface{}, bb binding.BindingBody,
|
||||||
|
) (err error) {
|
||||||
var body []byte
|
var body []byte
|
||||||
if cb, ok := c.Get(BodyBytesKey); ok {
|
if cb, ok := c.Get(BodyBytesKey); ok {
|
||||||
if cbb, ok := cb.([]byte); ok {
|
if cbb, ok := cb.([]byte); ok {
|
||||||
@ -686,10 +655,10 @@ func (c *Context) Status(code int) {
|
|||||||
func (c *Context) Header(key, value string) {
|
func (c *Context) Header(key, value string) {
|
||||||
if value == "" {
|
if value == "" {
|
||||||
c.Writer.Header().Del(key)
|
c.Writer.Header().Del(key)
|
||||||
return
|
} else {
|
||||||
}
|
|
||||||
c.Writer.Header().Set(key, value)
|
c.Writer.Header().Set(key, value)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GetHeader returns value from request headers.
|
// GetHeader returns value from request headers.
|
||||||
func (c *Context) GetHeader(key string) string {
|
func (c *Context) GetHeader(key string) string {
|
||||||
@ -732,7 +701,6 @@ func (c *Context) Cookie(name string) (string, error) {
|
|||||||
return val, nil
|
return val, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render writes the response headers and calls render.Render to render data.
|
|
||||||
func (c *Context) Render(code int, r render.Render) {
|
func (c *Context) Render(code int, r render.Render) {
|
||||||
c.Status(code)
|
c.Status(code)
|
||||||
|
|
||||||
@ -777,10 +745,10 @@ func (c *Context) JSONP(code int, obj interface{}) {
|
|||||||
callback := c.DefaultQuery("callback", "")
|
callback := c.DefaultQuery("callback", "")
|
||||||
if callback == "" {
|
if callback == "" {
|
||||||
c.Render(code, render.JSON{Data: obj})
|
c.Render(code, render.JSON{Data: obj})
|
||||||
return
|
} else {
|
||||||
}
|
|
||||||
c.Render(code, render.JsonpJSON{Callback: callback, Data: obj})
|
c.Render(code, render.JsonpJSON{Callback: callback, Data: obj})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// JSON serializes the given struct as JSON into the response body.
|
// JSON serializes the given struct as JSON into the response body.
|
||||||
// It also sets the Content-Type as "application/json".
|
// It also sets the Content-Type as "application/json".
|
||||||
@ -805,11 +773,6 @@ func (c *Context) YAML(code int, obj interface{}) {
|
|||||||
c.Render(code, render.YAML{Data: obj})
|
c.Render(code, render.YAML{Data: obj})
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProtoBuf serializes the given struct as ProtoBuf into the response body.
|
|
||||||
func (c *Context) ProtoBuf(code int, obj interface{}) {
|
|
||||||
c.Render(code, render.ProtoBuf{Data: obj})
|
|
||||||
}
|
|
||||||
|
|
||||||
// String writes the given string into the response body.
|
// String writes the given string into the response body.
|
||||||
func (c *Context) String(code int, format string, values ...interface{}) {
|
func (c *Context) String(code int, format string, values ...interface{}) {
|
||||||
c.Render(code, render.String{Format: format, Data: values})
|
c.Render(code, render.String{Format: format, Data: values})
|
||||||
@ -855,7 +818,6 @@ func (c *Context) SSEvent(name string, message interface{}) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stream sends a streaming response.
|
|
||||||
func (c *Context) Stream(step func(w io.Writer) bool) {
|
func (c *Context) Stream(step func(w io.Writer) bool) {
|
||||||
w := c.Writer
|
w := c.Writer
|
||||||
clientGone := w.CloseNotify()
|
clientGone := w.CloseNotify()
|
||||||
@ -877,7 +839,6 @@ func (c *Context) Stream(step func(w io.Writer) bool) {
|
|||||||
/******** CONTENT NEGOTIATION *******/
|
/******** CONTENT NEGOTIATION *******/
|
||||||
/************************************/
|
/************************************/
|
||||||
|
|
||||||
// Negotiate contains all negotiations data.
|
|
||||||
type Negotiate struct {
|
type Negotiate struct {
|
||||||
Offered []string
|
Offered []string
|
||||||
HTMLName string
|
HTMLName string
|
||||||
@ -887,7 +848,6 @@ type Negotiate struct {
|
|||||||
Data interface{}
|
Data interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Negotiate calls different Render according acceptable Accept format.
|
|
||||||
func (c *Context) Negotiate(code int, config Negotiate) {
|
func (c *Context) Negotiate(code int, config Negotiate) {
|
||||||
switch c.NegotiateFormat(config.Offered...) {
|
switch c.NegotiateFormat(config.Offered...) {
|
||||||
case binding.MIMEJSON:
|
case binding.MIMEJSON:
|
||||||
@ -907,7 +867,6 @@ func (c *Context) Negotiate(code int, config Negotiate) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NegotiateFormat returns an acceptable Accept format.
|
|
||||||
func (c *Context) NegotiateFormat(offered ...string) string {
|
func (c *Context) NegotiateFormat(offered ...string) string {
|
||||||
assert1(len(offered) > 0, "you must provide at least one offer")
|
assert1(len(offered) > 0, "you must provide at least one offer")
|
||||||
|
|
||||||
@ -927,7 +886,6 @@ func (c *Context) NegotiateFormat(offered ...string) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAccepted sets Accept header data.
|
|
||||||
func (c *Context) SetAccepted(formats ...string) {
|
func (c *Context) SetAccepted(formats ...string) {
|
||||||
c.Accepted = formats
|
c.Accepted = formats
|
||||||
}
|
}
|
||||||
|
13
vendor/github.com/gin-gonic/gin/coverage.sh
generated
vendored
Normal file
13
vendor/github.com/gin-gonic/gin/coverage.sh
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "mode: count" > coverage.out
|
||||||
|
|
||||||
|
for d in $(go list ./... | grep -E 'gin$|binding$|render$' | grep -v 'examples'); do
|
||||||
|
go test -v -covermode=count -coverprofile=profile.out $d
|
||||||
|
if [ -f profile.out ]; then
|
||||||
|
cat profile.out | grep -v "mode:" >> coverage.out
|
||||||
|
rm profile.out
|
||||||
|
fi
|
||||||
|
done
|
33
vendor/github.com/gin-gonic/gin/debug.go
generated
vendored
33
vendor/github.com/gin-gonic/gin/debug.go
generated
vendored
@ -6,15 +6,13 @@ package gin
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"os"
|
"log"
|
||||||
"runtime"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const ginSupportMinGoVer = 6
|
func init() {
|
||||||
|
log.SetFlags(0)
|
||||||
|
}
|
||||||
|
|
||||||
// IsDebugging returns true if the framework is running in debug mode.
|
// IsDebugging returns true if the framework is running in debug mode.
|
||||||
// Use SetMode(gin.ReleaseMode) to disable debug mode.
|
// Use SetMode(gin.ReleaseMode) to disable debug mode.
|
||||||
@ -22,18 +20,11 @@ func IsDebugging() bool {
|
|||||||
return ginMode == debugCode
|
return ginMode == debugCode
|
||||||
}
|
}
|
||||||
|
|
||||||
// DebugPrintRouteFunc indicates debug log output format.
|
|
||||||
var DebugPrintRouteFunc func(httpMethod, absolutePath, handlerName string, nuHandlers int)
|
|
||||||
|
|
||||||
func debugPrintRoute(httpMethod, absolutePath string, handlers HandlersChain) {
|
func debugPrintRoute(httpMethod, absolutePath string, handlers HandlersChain) {
|
||||||
if IsDebugging() {
|
if IsDebugging() {
|
||||||
nuHandlers := len(handlers)
|
nuHandlers := len(handlers)
|
||||||
handlerName := nameOfFunction(handlers.Last())
|
handlerName := nameOfFunction(handlers.Last())
|
||||||
if DebugPrintRouteFunc == nil {
|
|
||||||
debugPrint("%-6s %-25s --> %s (%d handlers)\n", httpMethod, absolutePath, handlerName, nuHandlers)
|
debugPrint("%-6s %-25s --> %s (%d handlers)\n", httpMethod, absolutePath, handlerName, nuHandlers)
|
||||||
} else {
|
|
||||||
DebugPrintRouteFunc(httpMethod, absolutePath, handlerName, nuHandlers)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,28 +42,14 @@ func debugPrintLoadTemplate(tmpl *template.Template) {
|
|||||||
|
|
||||||
func debugPrint(format string, values ...interface{}) {
|
func debugPrint(format string, values ...interface{}) {
|
||||||
if IsDebugging() {
|
if IsDebugging() {
|
||||||
if !strings.HasSuffix(format, "\n") {
|
log.Printf("[GIN-debug] "+format, values...)
|
||||||
format += "\n"
|
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "[GIN-debug] "+format, values...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getMinVer(v string) (uint64, error) {
|
|
||||||
first := strings.IndexByte(v, '.')
|
|
||||||
last := strings.LastIndexByte(v, '.')
|
|
||||||
if first == last {
|
|
||||||
return strconv.ParseUint(v[first+1:], 10, 64)
|
|
||||||
}
|
|
||||||
return strconv.ParseUint(v[first+1:last], 10, 64)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func debugPrintWARNINGDefault() {
|
func debugPrintWARNINGDefault() {
|
||||||
if v, e := getMinVer(runtime.Version()); e == nil && v <= ginSupportMinGoVer {
|
|
||||||
debugPrint(`[WARNING] Now Gin requires Go 1.6 or later and Go 1.7 will be required soon.
|
debugPrint(`[WARNING] Now Gin requires Go 1.6 or later and Go 1.7 will be required soon.
|
||||||
|
|
||||||
`)
|
`)
|
||||||
}
|
|
||||||
debugPrint(`[WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
|
debugPrint(`[WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
|
||||||
|
|
||||||
`)
|
`)
|
||||||
|
22
vendor/github.com/gin-gonic/gin/errors.go
generated
vendored
22
vendor/github.com/gin-gonic/gin/errors.go
generated
vendored
@ -9,28 +9,21 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin/internal/json"
|
"github.com/gin-gonic/gin/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrorType is an unsigned 64-bit error code as defined in the gin spec.
|
|
||||||
type ErrorType uint64
|
type ErrorType uint64
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// ErrorTypeBind is used when Context.Bind() fails.
|
ErrorTypeBind ErrorType = 1 << 63 // used when c.Bind() fails
|
||||||
ErrorTypeBind ErrorType = 1 << 63
|
ErrorTypeRender ErrorType = 1 << 62 // used when c.Render() fails
|
||||||
// ErrorTypeRender is used when Context.Render() fails.
|
|
||||||
ErrorTypeRender ErrorType = 1 << 62
|
|
||||||
// ErrorTypePrivate indicates a private error.
|
|
||||||
ErrorTypePrivate ErrorType = 1 << 0
|
ErrorTypePrivate ErrorType = 1 << 0
|
||||||
// ErrorTypePublic indicates a public error.
|
|
||||||
ErrorTypePublic ErrorType = 1 << 1
|
ErrorTypePublic ErrorType = 1 << 1
|
||||||
// ErrorTypeAny indicates any other error.
|
|
||||||
ErrorTypeAny ErrorType = 1<<64 - 1
|
ErrorTypeAny ErrorType = 1<<64 - 1
|
||||||
// ErrorTypeNu indicates any other error.
|
|
||||||
ErrorTypeNu = 2
|
ErrorTypeNu = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
// Error represents a error's specification.
|
|
||||||
type Error struct {
|
type Error struct {
|
||||||
Err error
|
Err error
|
||||||
Type ErrorType
|
Type ErrorType
|
||||||
@ -41,19 +34,16 @@ type errorMsgs []*Error
|
|||||||
|
|
||||||
var _ error = &Error{}
|
var _ error = &Error{}
|
||||||
|
|
||||||
// SetType sets the error's type.
|
|
||||||
func (msg *Error) SetType(flags ErrorType) *Error {
|
func (msg *Error) SetType(flags ErrorType) *Error {
|
||||||
msg.Type = flags
|
msg.Type = flags
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMeta sets the error's meta data.
|
|
||||||
func (msg *Error) SetMeta(data interface{}) *Error {
|
func (msg *Error) SetMeta(data interface{}) *Error {
|
||||||
msg.Meta = data
|
msg.Meta = data
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSON creates a properly formated JSON
|
|
||||||
func (msg *Error) JSON() interface{} {
|
func (msg *Error) JSON() interface{} {
|
||||||
json := H{}
|
json := H{}
|
||||||
if msg.Meta != nil {
|
if msg.Meta != nil {
|
||||||
@ -80,12 +70,11 @@ func (msg *Error) MarshalJSON() ([]byte, error) {
|
|||||||
return json.Marshal(msg.JSON())
|
return json.Marshal(msg.JSON())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error implements the error interface.
|
// Error implements the error interface
|
||||||
func (msg Error) Error() string {
|
func (msg Error) Error() string {
|
||||||
return msg.Err.Error()
|
return msg.Err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsType judges one error.
|
|
||||||
func (msg *Error) IsType(flags ErrorType) bool {
|
func (msg *Error) IsType(flags ErrorType) bool {
|
||||||
return (msg.Type & flags) > 0
|
return (msg.Type & flags) > 0
|
||||||
}
|
}
|
||||||
@ -149,7 +138,6 @@ func (a errorMsgs) JSON() interface{} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON implements the json.Marshaller interface.
|
|
||||||
func (a errorMsgs) MarshalJSON() ([]byte, error) {
|
func (a errorMsgs) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(a.JSON())
|
return json.Marshal(a.JSON())
|
||||||
}
|
}
|
||||||
|
36
vendor/github.com/gin-gonic/gin/gin.go
generated
vendored
36
vendor/github.com/gin-gonic/gin/gin.go
generated
vendored
@ -5,7 +5,6 @@
|
|||||||
package gin
|
package gin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -15,7 +14,11 @@ import (
|
|||||||
"github.com/gin-gonic/gin/render"
|
"github.com/gin-gonic/gin/render"
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultMultipartMemory = 32 << 20 // 32 MB
|
const (
|
||||||
|
// Version is Framework's version.
|
||||||
|
Version = "v1.3.0"
|
||||||
|
defaultMultipartMemory = 32 << 20 // 32 MB
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
default404Body = []byte("404 page not found")
|
default404Body = []byte("404 page not found")
|
||||||
@ -23,10 +26,7 @@ var (
|
|||||||
defaultAppEngine bool
|
defaultAppEngine bool
|
||||||
)
|
)
|
||||||
|
|
||||||
// HandlerFunc defines the handler used by gin middleware as return value.
|
|
||||||
type HandlerFunc func(*Context)
|
type HandlerFunc func(*Context)
|
||||||
|
|
||||||
// HandlersChain defines a HandlerFunc array.
|
|
||||||
type HandlersChain []HandlerFunc
|
type HandlersChain []HandlerFunc
|
||||||
|
|
||||||
// Last returns the last handler in the chain. ie. the last handler is the main own.
|
// Last returns the last handler in the chain. ie. the last handler is the main own.
|
||||||
@ -37,15 +37,12 @@ func (c HandlersChain) Last() HandlerFunc {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RouteInfo represents a request route's specification which contains method and path and its handler.
|
|
||||||
type RouteInfo struct {
|
type RouteInfo struct {
|
||||||
Method string
|
Method string
|
||||||
Path string
|
Path string
|
||||||
Handler string
|
Handler string
|
||||||
HandlerFunc HandlerFunc
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RoutesInfo defines a RouteInfo array.
|
|
||||||
type RoutesInfo []RouteInfo
|
type RoutesInfo []RouteInfo
|
||||||
|
|
||||||
// Engine is the framework's instance, it contains the muxer, middleware and configuration settings.
|
// Engine is the framework's instance, it contains the muxer, middleware and configuration settings.
|
||||||
@ -158,7 +155,6 @@ func (engine *Engine) allocateContext() *Context {
|
|||||||
return &Context{engine: engine}
|
return &Context{engine: engine}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delims sets template left and right delims and returns a Engine instance.
|
|
||||||
func (engine *Engine) Delims(left, right string) *Engine {
|
func (engine *Engine) Delims(left, right string) *Engine {
|
||||||
engine.delims = render.Delims{Left: left, Right: right}
|
engine.delims = render.Delims{Left: left, Right: right}
|
||||||
return engine
|
return engine
|
||||||
@ -268,12 +264,10 @@ func (engine *Engine) Routes() (routes RoutesInfo) {
|
|||||||
func iterate(path, method string, routes RoutesInfo, root *node) RoutesInfo {
|
func iterate(path, method string, routes RoutesInfo, root *node) RoutesInfo {
|
||||||
path += root.path
|
path += root.path
|
||||||
if len(root.handlers) > 0 {
|
if len(root.handlers) > 0 {
|
||||||
handlerFunc := root.handlers.Last()
|
|
||||||
routes = append(routes, RouteInfo{
|
routes = append(routes, RouteInfo{
|
||||||
Method: method,
|
Method: method,
|
||||||
Path: path,
|
Path: path,
|
||||||
Handler: nameOfFunction(handlerFunc),
|
Handler: nameOfFunction(root.handlers.Last()),
|
||||||
HandlerFunc: handlerFunc,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
for _, child := range root.children {
|
for _, child := range root.children {
|
||||||
@ -322,23 +316,6 @@ func (engine *Engine) RunUnix(file string) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunFd attaches the router to a http.Server and starts listening and serving HTTP requests
|
|
||||||
// through the specified file descriptor.
|
|
||||||
// Note: this method will block the calling goroutine indefinitely unless an error happens.
|
|
||||||
func (engine *Engine) RunFd(fd int) (err error) {
|
|
||||||
debugPrint("Listening and serving HTTP on fd@%d", fd)
|
|
||||||
defer func() { debugPrintError(err) }()
|
|
||||||
|
|
||||||
f := os.NewFile(uintptr(fd), fmt.Sprintf("fd@%d", fd))
|
|
||||||
listener, err := net.FileListener(f)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer listener.Close()
|
|
||||||
err = http.Serve(listener, engine)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// ServeHTTP conforms to the http.Handler interface.
|
// ServeHTTP conforms to the http.Handler interface.
|
||||||
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
c := engine.pool.Get().(*Context)
|
c := engine.pool.Get().(*Context)
|
||||||
@ -357,6 +334,7 @@ func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
func (engine *Engine) HandleContext(c *Context) {
|
func (engine *Engine) HandleContext(c *Context) {
|
||||||
c.reset()
|
c.reset()
|
||||||
engine.handleHTTPRequest(c)
|
engine.handleHTTPRequest(c)
|
||||||
|
engine.pool.Put(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (engine *Engine) handleHTTPRequest(c *Context) {
|
func (engine *Engine) handleHTTPRequest(c *Context) {
|
||||||
|
15
vendor/github.com/gin-gonic/gin/json/json.go
generated
vendored
Normal file
15
vendor/github.com/gin-gonic/gin/json/json.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright 2017 Bo-Yi Wu. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !jsoniter
|
||||||
|
|
||||||
|
package json
|
||||||
|
|
||||||
|
import "encoding/json"
|
||||||
|
|
||||||
|
var (
|
||||||
|
Marshal = json.Marshal
|
||||||
|
MarshalIndent = json.MarshalIndent
|
||||||
|
NewDecoder = json.NewDecoder
|
||||||
|
)
|
16
vendor/github.com/gin-gonic/gin/json/jsoniter.go
generated
vendored
Normal file
16
vendor/github.com/gin-gonic/gin/json/jsoniter.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2017 Bo-Yi Wu. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build jsoniter
|
||||||
|
|
||||||
|
package json
|
||||||
|
|
||||||
|
import "github.com/json-iterator/go"
|
||||||
|
|
||||||
|
var (
|
||||||
|
json = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||||
|
Marshal = json.Marshal
|
||||||
|
MarshalIndent = json.MarshalIndent
|
||||||
|
NewDecoder = json.NewDecoder
|
||||||
|
)
|
4
vendor/github.com/gin-gonic/gin/logger.go
generated
vendored
4
vendor/github.com/gin-gonic/gin/logger.go
generated
vendored
@ -17,7 +17,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
green = string([]byte{27, 91, 57, 55, 59, 52, 50, 109})
|
green = string([]byte{27, 91, 57, 55, 59, 52, 50, 109})
|
||||||
white = string([]byte{27, 91, 57, 48, 59, 52, 55, 109})
|
white = string([]byte{27, 91, 57, 48, 59, 52, 55, 109})
|
||||||
yellow = string([]byte{27, 91, 57, 48, 59, 52, 51, 109})
|
yellow = string([]byte{27, 91, 57, 55, 59, 52, 51, 109})
|
||||||
red = string([]byte{27, 91, 57, 55, 59, 52, 49, 109})
|
red = string([]byte{27, 91, 57, 55, 59, 52, 49, 109})
|
||||||
blue = string([]byte{27, 91, 57, 55, 59, 52, 52, 109})
|
blue = string([]byte{27, 91, 57, 55, 59, 52, 52, 109})
|
||||||
magenta = string([]byte{27, 91, 57, 55, 59, 52, 53, 109})
|
magenta = string([]byte{27, 91, 57, 55, 59, 52, 53, 109})
|
||||||
@ -53,7 +53,7 @@ func Logger() HandlerFunc {
|
|||||||
return LoggerWithWriter(DefaultWriter)
|
return LoggerWithWriter(DefaultWriter)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoggerWithWriter instance a Logger middleware with the specified writer buffer.
|
// LoggerWithWriter instance a Logger middleware with the specified writter buffer.
|
||||||
// Example: os.Stdout, a file opened in write mode, a socket...
|
// Example: os.Stdout, a file opened in write mode, a socket...
|
||||||
func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc {
|
func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc {
|
||||||
isTerm := true
|
isTerm := true
|
||||||
|
13
vendor/github.com/gin-gonic/gin/mode.go
generated
vendored
13
vendor/github.com/gin-gonic/gin/mode.go
generated
vendored
@ -11,15 +11,11 @@ import (
|
|||||||
"github.com/gin-gonic/gin/binding"
|
"github.com/gin-gonic/gin/binding"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ENV_GIN_MODE indicates environment name for gin mode.
|
|
||||||
const ENV_GIN_MODE = "GIN_MODE"
|
const ENV_GIN_MODE = "GIN_MODE"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// DebugMode indicates gin mode is debug.
|
|
||||||
DebugMode = "debug"
|
DebugMode = "debug"
|
||||||
// ReleaseMode indicates gin mode is release.
|
|
||||||
ReleaseMode = "release"
|
ReleaseMode = "release"
|
||||||
// TestMode indicates gin mode is test.
|
|
||||||
TestMode = "test"
|
TestMode = "test"
|
||||||
)
|
)
|
||||||
const (
|
const (
|
||||||
@ -28,7 +24,7 @@ const (
|
|||||||
testCode
|
testCode
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultWriter is the default io.Writer used by Gin for debug output and
|
// DefaultWriter is the default io.Writer used the Gin for debug output and
|
||||||
// middleware output like Logger() or Recovery().
|
// middleware output like Logger() or Recovery().
|
||||||
// Note that both Logger and Recovery provides custom ways to configure their
|
// Note that both Logger and Recovery provides custom ways to configure their
|
||||||
// output io.Writer.
|
// output io.Writer.
|
||||||
@ -36,8 +32,6 @@ const (
|
|||||||
// import "github.com/mattn/go-colorable"
|
// import "github.com/mattn/go-colorable"
|
||||||
// gin.DefaultWriter = colorable.NewColorableStdout()
|
// gin.DefaultWriter = colorable.NewColorableStdout()
|
||||||
var DefaultWriter io.Writer = os.Stdout
|
var DefaultWriter io.Writer = os.Stdout
|
||||||
|
|
||||||
// DefaultErrorWriter is the default io.Writer used by Gin to debug errors
|
|
||||||
var DefaultErrorWriter io.Writer = os.Stderr
|
var DefaultErrorWriter io.Writer = os.Stderr
|
||||||
|
|
||||||
var ginMode = debugCode
|
var ginMode = debugCode
|
||||||
@ -48,7 +42,6 @@ func init() {
|
|||||||
SetMode(mode)
|
SetMode(mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMode sets gin mode according to input string.
|
|
||||||
func SetMode(value string) {
|
func SetMode(value string) {
|
||||||
switch value {
|
switch value {
|
||||||
case DebugMode, "":
|
case DebugMode, "":
|
||||||
@ -66,18 +59,14 @@ func SetMode(value string) {
|
|||||||
modeName = value
|
modeName = value
|
||||||
}
|
}
|
||||||
|
|
||||||
// DisableBindValidation closes the default validator.
|
|
||||||
func DisableBindValidation() {
|
func DisableBindValidation() {
|
||||||
binding.Validator = nil
|
binding.Validator = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnableJsonDecoderUseNumber sets true for binding.EnableDecoderUseNumberto to
|
|
||||||
// call the UseNumber method on the JSON Decoder instance.
|
|
||||||
func EnableJsonDecoderUseNumber() {
|
func EnableJsonDecoderUseNumber() {
|
||||||
binding.EnableDecoderUseNumber = true
|
binding.EnableDecoderUseNumber = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mode returns currently gin mode.
|
|
||||||
func Mode() string {
|
func Mode() string {
|
||||||
return modeName
|
return modeName
|
||||||
}
|
}
|
||||||
|
30
vendor/github.com/gin-gonic/gin/recovery.go
generated
vendored
30
vendor/github.com/gin-gonic/gin/recovery.go
generated
vendored
@ -10,12 +10,9 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
"os"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -40,38 +37,13 @@ func RecoveryWithWriter(out io.Writer) HandlerFunc {
|
|||||||
return func(c *Context) {
|
return func(c *Context) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
// Check for a broken connection, as it is not really a
|
|
||||||
// condition that warrants a panic stack trace.
|
|
||||||
var brokenPipe bool
|
|
||||||
if ne, ok := err.(*net.OpError); ok {
|
|
||||||
if se, ok := ne.Err.(*os.SyscallError); ok {
|
|
||||||
if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
|
|
||||||
brokenPipe = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if logger != nil {
|
if logger != nil {
|
||||||
stack := stack(3)
|
stack := stack(3)
|
||||||
httprequest, _ := httputil.DumpRequest(c.Request, false)
|
httprequest, _ := httputil.DumpRequest(c.Request, false)
|
||||||
if brokenPipe {
|
logger.Printf("[Recovery] %s panic recovered:\n%s\n%s\n%s%s", timeFormat(time.Now()), string(httprequest), err, stack, reset)
|
||||||
logger.Printf("%s\n%s%s", err, string(httprequest), reset)
|
|
||||||
} else if IsDebugging() {
|
|
||||||
logger.Printf("[Recovery] %s panic recovered:\n%s\n%s\n%s%s",
|
|
||||||
timeFormat(time.Now()), string(httprequest), err, stack, reset)
|
|
||||||
} else {
|
|
||||||
logger.Printf("[Recovery] %s panic recovered:\n%s\n%s%s",
|
|
||||||
timeFormat(time.Now()), err, stack, reset)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If the connection is dead, we can't write a status to it.
|
|
||||||
if brokenPipe {
|
|
||||||
c.Error(err.(error))
|
|
||||||
c.Abort()
|
|
||||||
} else {
|
|
||||||
c.AbortWithStatus(http.StatusInternalServerError)
|
c.AbortWithStatus(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}()
|
}()
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/gin-gonic/gin/render/data.go
generated
vendored
2
vendor/github.com/gin-gonic/gin/render/data.go
generated
vendored
@ -6,7 +6,6 @@ package render
|
|||||||
|
|
||||||
import "net/http"
|
import "net/http"
|
||||||
|
|
||||||
// Data contains ContentType and bytes data.
|
|
||||||
type Data struct {
|
type Data struct {
|
||||||
ContentType string
|
ContentType string
|
||||||
Data []byte
|
Data []byte
|
||||||
@ -19,7 +18,6 @@ func (r Data) Render(w http.ResponseWriter) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteContentType (Data) writes custom ContentType.
|
|
||||||
func (r Data) WriteContentType(w http.ResponseWriter) {
|
func (r Data) WriteContentType(w http.ResponseWriter) {
|
||||||
writeContentType(w, []string{r.ContentType})
|
writeContentType(w, []string{r.ContentType})
|
||||||
}
|
}
|
||||||
|
12
vendor/github.com/gin-gonic/gin/render/html.go
generated
vendored
12
vendor/github.com/gin-gonic/gin/render/html.go
generated
vendored
@ -9,27 +9,20 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Delims represents a set of Left and Right delimiters for HTML template rendering.
|
|
||||||
type Delims struct {
|
type Delims struct {
|
||||||
// Left delimiter, defaults to {{.
|
|
||||||
Left string
|
Left string
|
||||||
// Right delimiter, defaults to }}.
|
|
||||||
Right string
|
Right string
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTMLRender interface is to be implemented by HTMLProduction and HTMLDebug.
|
|
||||||
type HTMLRender interface {
|
type HTMLRender interface {
|
||||||
// Instance returns an HTML instance.
|
|
||||||
Instance(string, interface{}) Render
|
Instance(string, interface{}) Render
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTMLProduction contains template reference and its delims.
|
|
||||||
type HTMLProduction struct {
|
type HTMLProduction struct {
|
||||||
Template *template.Template
|
Template *template.Template
|
||||||
Delims Delims
|
Delims Delims
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTMLDebug contains template delims and pattern and function with file list.
|
|
||||||
type HTMLDebug struct {
|
type HTMLDebug struct {
|
||||||
Files []string
|
Files []string
|
||||||
Glob string
|
Glob string
|
||||||
@ -37,7 +30,6 @@ type HTMLDebug struct {
|
|||||||
FuncMap template.FuncMap
|
FuncMap template.FuncMap
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTML contains template reference and its name with given interface object.
|
|
||||||
type HTML struct {
|
type HTML struct {
|
||||||
Template *template.Template
|
Template *template.Template
|
||||||
Name string
|
Name string
|
||||||
@ -46,7 +38,6 @@ type HTML struct {
|
|||||||
|
|
||||||
var htmlContentType = []string{"text/html; charset=utf-8"}
|
var htmlContentType = []string{"text/html; charset=utf-8"}
|
||||||
|
|
||||||
// Instance (HTMLProduction) returns an HTML instance which it realizes Render interface.
|
|
||||||
func (r HTMLProduction) Instance(name string, data interface{}) Render {
|
func (r HTMLProduction) Instance(name string, data interface{}) Render {
|
||||||
return HTML{
|
return HTML{
|
||||||
Template: r.Template,
|
Template: r.Template,
|
||||||
@ -55,7 +46,6 @@ func (r HTMLProduction) Instance(name string, data interface{}) Render {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instance (HTMLDebug) returns an HTML instance which it realizes Render interface.
|
|
||||||
func (r HTMLDebug) Instance(name string, data interface{}) Render {
|
func (r HTMLDebug) Instance(name string, data interface{}) Render {
|
||||||
return HTML{
|
return HTML{
|
||||||
Template: r.loadTemplate(),
|
Template: r.loadTemplate(),
|
||||||
@ -76,7 +66,6 @@ func (r HTMLDebug) loadTemplate() *template.Template {
|
|||||||
panic("the HTML debug render was created without files or glob pattern")
|
panic("the HTML debug render was created without files or glob pattern")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render (HTML) executes template and writes its result with custom ContentType for response.
|
|
||||||
func (r HTML) Render(w http.ResponseWriter) error {
|
func (r HTML) Render(w http.ResponseWriter) error {
|
||||||
r.WriteContentType(w)
|
r.WriteContentType(w)
|
||||||
|
|
||||||
@ -86,7 +75,6 @@ func (r HTML) Render(w http.ResponseWriter) error {
|
|||||||
return r.Template.ExecuteTemplate(w, r.Name, r.Data)
|
return r.Template.ExecuteTemplate(w, r.Name, r.Data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteContentType (HTML) writes HTML ContentType.
|
|
||||||
func (r HTML) WriteContentType(w http.ResponseWriter) {
|
func (r HTML) WriteContentType(w http.ResponseWriter) {
|
||||||
writeContentType(w, htmlContentType)
|
writeContentType(w, htmlContentType)
|
||||||
}
|
}
|
||||||
|
25
vendor/github.com/gin-gonic/gin/render/json.go
generated
vendored
25
vendor/github.com/gin-gonic/gin/render/json.go
generated
vendored
@ -10,44 +10,37 @@ import (
|
|||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin/internal/json"
|
"github.com/gin-gonic/gin/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// JSON contains the given interface object.
|
|
||||||
type JSON struct {
|
type JSON struct {
|
||||||
Data interface{}
|
Data interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IndentedJSON contains the given interface object.
|
|
||||||
type IndentedJSON struct {
|
type IndentedJSON struct {
|
||||||
Data interface{}
|
Data interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SecureJSON contains the given interface object and its prefix.
|
|
||||||
type SecureJSON struct {
|
type SecureJSON struct {
|
||||||
Prefix string
|
Prefix string
|
||||||
Data interface{}
|
Data interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// JsonpJSON contains the given interface object its callback.
|
|
||||||
type JsonpJSON struct {
|
type JsonpJSON struct {
|
||||||
Callback string
|
Callback string
|
||||||
Data interface{}
|
Data interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AsciiJSON contains the given interface object.
|
|
||||||
type AsciiJSON struct {
|
type AsciiJSON struct {
|
||||||
Data interface{}
|
Data interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SecureJSONPrefix is a string which represents SecureJSON prefix.
|
|
||||||
type SecureJSONPrefix string
|
type SecureJSONPrefix string
|
||||||
|
|
||||||
var jsonContentType = []string{"application/json; charset=utf-8"}
|
var jsonContentType = []string{"application/json; charset=utf-8"}
|
||||||
var jsonpContentType = []string{"application/javascript; charset=utf-8"}
|
var jsonpContentType = []string{"application/javascript; charset=utf-8"}
|
||||||
var jsonAsciiContentType = []string{"application/json"}
|
var jsonAsciiContentType = []string{"application/json"}
|
||||||
|
|
||||||
// Render (JSON) writes data with custom ContentType.
|
|
||||||
func (r JSON) Render(w http.ResponseWriter) (err error) {
|
func (r JSON) Render(w http.ResponseWriter) (err error) {
|
||||||
if err = WriteJSON(w, r.Data); err != nil {
|
if err = WriteJSON(w, r.Data); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -55,12 +48,10 @@ func (r JSON) Render(w http.ResponseWriter) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteContentType (JSON) writes JSON ContentType.
|
|
||||||
func (r JSON) WriteContentType(w http.ResponseWriter) {
|
func (r JSON) WriteContentType(w http.ResponseWriter) {
|
||||||
writeContentType(w, jsonContentType)
|
writeContentType(w, jsonContentType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteJSON marshals the given interface object and writes it with custom ContentType.
|
|
||||||
func WriteJSON(w http.ResponseWriter, obj interface{}) error {
|
func WriteJSON(w http.ResponseWriter, obj interface{}) error {
|
||||||
writeContentType(w, jsonContentType)
|
writeContentType(w, jsonContentType)
|
||||||
jsonBytes, err := json.Marshal(obj)
|
jsonBytes, err := json.Marshal(obj)
|
||||||
@ -71,7 +62,6 @@ func WriteJSON(w http.ResponseWriter, obj interface{}) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render (IndentedJSON) marshals the given interface object and writes it with custom ContentType.
|
|
||||||
func (r IndentedJSON) Render(w http.ResponseWriter) error {
|
func (r IndentedJSON) Render(w http.ResponseWriter) error {
|
||||||
r.WriteContentType(w)
|
r.WriteContentType(w)
|
||||||
jsonBytes, err := json.MarshalIndent(r.Data, "", " ")
|
jsonBytes, err := json.MarshalIndent(r.Data, "", " ")
|
||||||
@ -82,12 +72,10 @@ func (r IndentedJSON) Render(w http.ResponseWriter) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteContentType (IndentedJSON) writes JSON ContentType.
|
|
||||||
func (r IndentedJSON) WriteContentType(w http.ResponseWriter) {
|
func (r IndentedJSON) WriteContentType(w http.ResponseWriter) {
|
||||||
writeContentType(w, jsonContentType)
|
writeContentType(w, jsonContentType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render (SecureJSON) marshals the given interface object and writes it with custom ContentType.
|
|
||||||
func (r SecureJSON) Render(w http.ResponseWriter) error {
|
func (r SecureJSON) Render(w http.ResponseWriter) error {
|
||||||
r.WriteContentType(w)
|
r.WriteContentType(w)
|
||||||
jsonBytes, err := json.Marshal(r.Data)
|
jsonBytes, err := json.Marshal(r.Data)
|
||||||
@ -102,12 +90,10 @@ func (r SecureJSON) Render(w http.ResponseWriter) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteContentType (SecureJSON) writes JSON ContentType.
|
|
||||||
func (r SecureJSON) WriteContentType(w http.ResponseWriter) {
|
func (r SecureJSON) WriteContentType(w http.ResponseWriter) {
|
||||||
writeContentType(w, jsonContentType)
|
writeContentType(w, jsonContentType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render (JsonpJSON) marshals the given interface object and writes it and its callback with custom ContentType.
|
|
||||||
func (r JsonpJSON) Render(w http.ResponseWriter) (err error) {
|
func (r JsonpJSON) Render(w http.ResponseWriter) (err error) {
|
||||||
r.WriteContentType(w)
|
r.WriteContentType(w)
|
||||||
ret, err := json.Marshal(r.Data)
|
ret, err := json.Marshal(r.Data)
|
||||||
@ -129,12 +115,10 @@ func (r JsonpJSON) Render(w http.ResponseWriter) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteContentType (JsonpJSON) writes Javascript ContentType.
|
|
||||||
func (r JsonpJSON) WriteContentType(w http.ResponseWriter) {
|
func (r JsonpJSON) WriteContentType(w http.ResponseWriter) {
|
||||||
writeContentType(w, jsonpContentType)
|
writeContentType(w, jsonpContentType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render (AsciiJSON) marshals the given interface object and writes it with custom ContentType.
|
|
||||||
func (r AsciiJSON) Render(w http.ResponseWriter) (err error) {
|
func (r AsciiJSON) Render(w http.ResponseWriter) (err error) {
|
||||||
r.WriteContentType(w)
|
r.WriteContentType(w)
|
||||||
ret, err := json.Marshal(r.Data)
|
ret, err := json.Marshal(r.Data)
|
||||||
@ -144,8 +128,10 @@ func (r AsciiJSON) Render(w http.ResponseWriter) (err error) {
|
|||||||
|
|
||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
for _, r := range string(ret) {
|
for _, r := range string(ret) {
|
||||||
cvt := string(r)
|
cvt := ""
|
||||||
if r >= 128 {
|
if r < 128 {
|
||||||
|
cvt = string(r)
|
||||||
|
} else {
|
||||||
cvt = fmt.Sprintf("\\u%04x", int64(r))
|
cvt = fmt.Sprintf("\\u%04x", int64(r))
|
||||||
}
|
}
|
||||||
buffer.WriteString(cvt)
|
buffer.WriteString(cvt)
|
||||||
@ -155,7 +141,6 @@ func (r AsciiJSON) Render(w http.ResponseWriter) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteContentType (AsciiJSON) writes JSON ContentType.
|
|
||||||
func (r AsciiJSON) WriteContentType(w http.ResponseWriter) {
|
func (r AsciiJSON) WriteContentType(w http.ResponseWriter) {
|
||||||
writeContentType(w, jsonAsciiContentType)
|
writeContentType(w, jsonAsciiContentType)
|
||||||
}
|
}
|
||||||
|
8
vendor/github.com/gin-gonic/gin/render/msgpack.go
generated
vendored
8
vendor/github.com/gin-gonic/gin/render/msgpack.go
generated
vendored
@ -10,26 +10,22 @@ import (
|
|||||||
"github.com/ugorji/go/codec"
|
"github.com/ugorji/go/codec"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgPack contains the given interface object.
|
|
||||||
type MsgPack struct {
|
type MsgPack struct {
|
||||||
Data interface{}
|
Data interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
var msgpackContentType = []string{"application/msgpack; charset=utf-8"}
|
var msgpackContentType = []string{"application/msgpack; charset=utf-8"}
|
||||||
|
|
||||||
// WriteContentType (MsgPack) writes MsgPack ContentType.
|
|
||||||
func (r MsgPack) WriteContentType(w http.ResponseWriter) {
|
func (r MsgPack) WriteContentType(w http.ResponseWriter) {
|
||||||
writeContentType(w, msgpackContentType)
|
writeContentType(w, msgpackContentType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render (MsgPack) encodes the given interface object and writes data with custom ContentType.
|
|
||||||
func (r MsgPack) Render(w http.ResponseWriter) error {
|
func (r MsgPack) Render(w http.ResponseWriter) error {
|
||||||
return WriteMsgPack(w, r.Data)
|
return WriteMsgPack(w, r.Data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMsgPack writes MsgPack ContentType and encodes the given interface object.
|
|
||||||
func WriteMsgPack(w http.ResponseWriter, obj interface{}) error {
|
func WriteMsgPack(w http.ResponseWriter, obj interface{}) error {
|
||||||
writeContentType(w, msgpackContentType)
|
writeContentType(w, msgpackContentType)
|
||||||
var mh codec.MsgpackHandle
|
var h codec.Handle = new(codec.MsgpackHandle)
|
||||||
return codec.NewEncoder(w, &mh).Encode(obj)
|
return codec.NewEncoder(w, h).Encode(obj)
|
||||||
}
|
}
|
||||||
|
7
vendor/github.com/gin-gonic/gin/render/reader.go
generated
vendored
7
vendor/github.com/gin-gonic/gin/render/reader.go
generated
vendored
@ -1,7 +1,3 @@
|
|||||||
// Copyright 2018 Gin Core Team. All rights reserved.
|
|
||||||
// Use of this source code is governed by a MIT style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package render
|
package render
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -10,7 +6,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Reader contains the IO reader and its length, and custom ContentType and other headers.
|
|
||||||
type Reader struct {
|
type Reader struct {
|
||||||
ContentType string
|
ContentType string
|
||||||
ContentLength int64
|
ContentLength int64
|
||||||
@ -27,12 +22,10 @@ func (r Reader) Render(w http.ResponseWriter) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteContentType (Reader) writes custom ContentType.
|
|
||||||
func (r Reader) WriteContentType(w http.ResponseWriter) {
|
func (r Reader) WriteContentType(w http.ResponseWriter) {
|
||||||
writeContentType(w, []string{r.ContentType})
|
writeContentType(w, []string{r.ContentType})
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeHeaders writes custom Header.
|
|
||||||
func (r Reader) writeHeaders(w http.ResponseWriter, headers map[string]string) {
|
func (r Reader) writeHeaders(w http.ResponseWriter, headers map[string]string) {
|
||||||
header := w.Header()
|
header := w.Header()
|
||||||
for k, v := range headers {
|
for k, v := range headers {
|
||||||
|
3
vendor/github.com/gin-gonic/gin/render/redirect.go
generated
vendored
3
vendor/github.com/gin-gonic/gin/render/redirect.go
generated
vendored
@ -9,14 +9,12 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Redirect contains the http request reference and redirects status code and location.
|
|
||||||
type Redirect struct {
|
type Redirect struct {
|
||||||
Code int
|
Code int
|
||||||
Request *http.Request
|
Request *http.Request
|
||||||
Location string
|
Location string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render (Redirect) redirects the http request to new location and writes redirect response.
|
|
||||||
func (r Redirect) Render(w http.ResponseWriter) error {
|
func (r Redirect) Render(w http.ResponseWriter) error {
|
||||||
// todo(thinkerou): go1.6 not support StatusPermanentRedirect(308)
|
// todo(thinkerou): go1.6 not support StatusPermanentRedirect(308)
|
||||||
// when we upgrade go version we can use http.StatusPermanentRedirect
|
// when we upgrade go version we can use http.StatusPermanentRedirect
|
||||||
@ -27,5 +25,4 @@ func (r Redirect) Render(w http.ResponseWriter) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteContentType (Redirect) don't write any ContentType.
|
|
||||||
func (r Redirect) WriteContentType(http.ResponseWriter) {}
|
func (r Redirect) WriteContentType(http.ResponseWriter) {}
|
||||||
|
4
vendor/github.com/gin-gonic/gin/render/render.go
generated
vendored
4
vendor/github.com/gin-gonic/gin/render/render.go
generated
vendored
@ -6,11 +6,8 @@ package render
|
|||||||
|
|
||||||
import "net/http"
|
import "net/http"
|
||||||
|
|
||||||
// Render interface is to be implemented by JSON, XML, HTML, YAML and so on.
|
|
||||||
type Render interface {
|
type Render interface {
|
||||||
// Render writes data with custom ContentType.
|
|
||||||
Render(http.ResponseWriter) error
|
Render(http.ResponseWriter) error
|
||||||
// WriteContentType writes custom ContentType.
|
|
||||||
WriteContentType(w http.ResponseWriter)
|
WriteContentType(w http.ResponseWriter)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,7 +27,6 @@ var (
|
|||||||
_ Render = MsgPack{}
|
_ Render = MsgPack{}
|
||||||
_ Render = Reader{}
|
_ Render = Reader{}
|
||||||
_ Render = AsciiJSON{}
|
_ Render = AsciiJSON{}
|
||||||
_ Render = ProtoBuf{}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func writeContentType(w http.ResponseWriter, value []string) {
|
func writeContentType(w http.ResponseWriter, value []string) {
|
||||||
|
8
vendor/github.com/gin-gonic/gin/render/text.go
generated
vendored
8
vendor/github.com/gin-gonic/gin/render/text.go
generated
vendored
@ -10,7 +10,6 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
// String contains the given interface object slice and its format.
|
|
||||||
type String struct {
|
type String struct {
|
||||||
Format string
|
Format string
|
||||||
Data []interface{}
|
Data []interface{}
|
||||||
@ -18,23 +17,20 @@ type String struct {
|
|||||||
|
|
||||||
var plainContentType = []string{"text/plain; charset=utf-8"}
|
var plainContentType = []string{"text/plain; charset=utf-8"}
|
||||||
|
|
||||||
// Render (String) writes data with custom ContentType.
|
|
||||||
func (r String) Render(w http.ResponseWriter) error {
|
func (r String) Render(w http.ResponseWriter) error {
|
||||||
WriteString(w, r.Format, r.Data)
|
WriteString(w, r.Format, r.Data)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteContentType (String) writes Plain ContentType.
|
|
||||||
func (r String) WriteContentType(w http.ResponseWriter) {
|
func (r String) WriteContentType(w http.ResponseWriter) {
|
||||||
writeContentType(w, plainContentType)
|
writeContentType(w, plainContentType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteString writes data according to its format and write custom ContentType.
|
|
||||||
func WriteString(w http.ResponseWriter, format string, data []interface{}) {
|
func WriteString(w http.ResponseWriter, format string, data []interface{}) {
|
||||||
writeContentType(w, plainContentType)
|
writeContentType(w, plainContentType)
|
||||||
if len(data) > 0 {
|
if len(data) > 0 {
|
||||||
fmt.Fprintf(w, format, data...)
|
fmt.Fprintf(w, format, data...)
|
||||||
return
|
} else {
|
||||||
}
|
|
||||||
io.WriteString(w, format)
|
io.WriteString(w, format)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
3
vendor/github.com/gin-gonic/gin/render/xml.go
generated
vendored
3
vendor/github.com/gin-gonic/gin/render/xml.go
generated
vendored
@ -9,20 +9,17 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
// XML contains the given interface object.
|
|
||||||
type XML struct {
|
type XML struct {
|
||||||
Data interface{}
|
Data interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
var xmlContentType = []string{"application/xml; charset=utf-8"}
|
var xmlContentType = []string{"application/xml; charset=utf-8"}
|
||||||
|
|
||||||
// Render (XML) encodes the given interface object and writes data with custom ContentType.
|
|
||||||
func (r XML) Render(w http.ResponseWriter) error {
|
func (r XML) Render(w http.ResponseWriter) error {
|
||||||
r.WriteContentType(w)
|
r.WriteContentType(w)
|
||||||
return xml.NewEncoder(w).Encode(r.Data)
|
return xml.NewEncoder(w).Encode(r.Data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteContentType (XML) writes XML ContentType for response.
|
|
||||||
func (r XML) WriteContentType(w http.ResponseWriter) {
|
func (r XML) WriteContentType(w http.ResponseWriter) {
|
||||||
writeContentType(w, xmlContentType)
|
writeContentType(w, xmlContentType)
|
||||||
}
|
}
|
||||||
|
3
vendor/github.com/gin-gonic/gin/render/yaml.go
generated
vendored
3
vendor/github.com/gin-gonic/gin/render/yaml.go
generated
vendored
@ -10,14 +10,12 @@ import (
|
|||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// YAML contains the given interface object.
|
|
||||||
type YAML struct {
|
type YAML struct {
|
||||||
Data interface{}
|
Data interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
var yamlContentType = []string{"application/x-yaml; charset=utf-8"}
|
var yamlContentType = []string{"application/x-yaml; charset=utf-8"}
|
||||||
|
|
||||||
// Render (YAML) marshals the given interface object and writes data with custom ContentType.
|
|
||||||
func (r YAML) Render(w http.ResponseWriter) error {
|
func (r YAML) Render(w http.ResponseWriter) error {
|
||||||
r.WriteContentType(w)
|
r.WriteContentType(w)
|
||||||
|
|
||||||
@ -30,7 +28,6 @@ func (r YAML) Render(w http.ResponseWriter) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteContentType (YAML) writes YAML ContentType for response.
|
|
||||||
func (r YAML) WriteContentType(w http.ResponseWriter) {
|
func (r YAML) WriteContentType(w http.ResponseWriter) {
|
||||||
writeContentType(w, yamlContentType)
|
writeContentType(w, yamlContentType)
|
||||||
}
|
}
|
||||||
|
27
vendor/github.com/gin-gonic/gin/routergroup.go
generated
vendored
27
vendor/github.com/gin-gonic/gin/routergroup.go
generated
vendored
@ -11,13 +11,11 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IRouter defines all router handle interface includes single and group router.
|
|
||||||
type IRouter interface {
|
type IRouter interface {
|
||||||
IRoutes
|
IRoutes
|
||||||
Group(string, ...HandlerFunc) *RouterGroup
|
Group(string, ...HandlerFunc) *RouterGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
// IRoutes defines all router handle interface.
|
|
||||||
type IRoutes interface {
|
type IRoutes interface {
|
||||||
Use(...HandlerFunc) IRoutes
|
Use(...HandlerFunc) IRoutes
|
||||||
|
|
||||||
@ -36,8 +34,8 @@ type IRoutes interface {
|
|||||||
StaticFS(string, http.FileSystem) IRoutes
|
StaticFS(string, http.FileSystem) IRoutes
|
||||||
}
|
}
|
||||||
|
|
||||||
// RouterGroup is used internally to configure router, a RouterGroup is associated with
|
// RouterGroup is used internally to configure router, a RouterGroup is associated with a prefix
|
||||||
// a prefix and an array of handlers (middleware).
|
// and an array of handlers (middleware).
|
||||||
type RouterGroup struct {
|
type RouterGroup struct {
|
||||||
Handlers HandlersChain
|
Handlers HandlersChain
|
||||||
basePath string
|
basePath string
|
||||||
@ -53,8 +51,8 @@ func (group *RouterGroup) Use(middleware ...HandlerFunc) IRoutes {
|
|||||||
return group.returnObj()
|
return group.returnObj()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group creates a new router group. You should add all the routes that have common middlewares or the same path prefix.
|
// Group creates a new router group. You should add all the routes that have common middlwares or the same path prefix.
|
||||||
// For example, all the routes that use a common middleware for authorization could be grouped.
|
// For example, all the routes that use a common middlware for authorization could be grouped.
|
||||||
func (group *RouterGroup) Group(relativePath string, handlers ...HandlerFunc) *RouterGroup {
|
func (group *RouterGroup) Group(relativePath string, handlers ...HandlerFunc) *RouterGroup {
|
||||||
return &RouterGroup{
|
return &RouterGroup{
|
||||||
Handlers: group.combineHandlers(handlers),
|
Handlers: group.combineHandlers(handlers),
|
||||||
@ -63,8 +61,6 @@ func (group *RouterGroup) Group(relativePath string, handlers ...HandlerFunc) *R
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BasePath returns the base path of router group.
|
|
||||||
// For example, if v := router.Group("/rest/n/v1/api"), v.BasePath() is "/rest/n/v1/api".
|
|
||||||
func (group *RouterGroup) BasePath() string {
|
func (group *RouterGroup) BasePath() string {
|
||||||
return group.basePath
|
return group.basePath
|
||||||
}
|
}
|
||||||
@ -185,22 +181,11 @@ func (group *RouterGroup) StaticFS(relativePath string, fs http.FileSystem) IRou
|
|||||||
func (group *RouterGroup) createStaticHandler(relativePath string, fs http.FileSystem) HandlerFunc {
|
func (group *RouterGroup) createStaticHandler(relativePath string, fs http.FileSystem) HandlerFunc {
|
||||||
absolutePath := group.calculateAbsolutePath(relativePath)
|
absolutePath := group.calculateAbsolutePath(relativePath)
|
||||||
fileServer := http.StripPrefix(absolutePath, http.FileServer(fs))
|
fileServer := http.StripPrefix(absolutePath, http.FileServer(fs))
|
||||||
|
_, nolisting := fs.(*onlyfilesFS)
|
||||||
return func(c *Context) {
|
return func(c *Context) {
|
||||||
if _, nolisting := fs.(*onlyfilesFS); nolisting {
|
if nolisting {
|
||||||
c.Writer.WriteHeader(http.StatusNotFound)
|
c.Writer.WriteHeader(http.StatusNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
file := c.Param("filepath")
|
|
||||||
// Check if file exists and/or if we have permission to access it
|
|
||||||
if _, err := fs.Open(file); err != nil {
|
|
||||||
c.Writer.WriteHeader(http.StatusNotFound)
|
|
||||||
c.handlers = group.engine.allNoRoute
|
|
||||||
// Reset index
|
|
||||||
c.index = -1
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fileServer.ServeHTTP(c.Writer, c.Request)
|
fileServer.ServeHTTP(c.Writer, c.Request)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
11
vendor/github.com/gin-gonic/gin/tree.go
generated
vendored
11
vendor/github.com/gin-gonic/gin/tree.go
generated
vendored
@ -193,16 +193,9 @@ func (n *node) addRoute(path string, handlers HandlersChain) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pathSeg := path
|
panic("path segment '" + path +
|
||||||
if n.nType != catchAll {
|
|
||||||
pathSeg = strings.SplitN(path, "/", 2)[0]
|
|
||||||
}
|
|
||||||
prefix := fullPath[:strings.Index(fullPath, pathSeg)] + n.path
|
|
||||||
panic("'" + pathSeg +
|
|
||||||
"' in new path '" + fullPath +
|
|
||||||
"' conflicts with existing wildcard '" + n.path +
|
"' conflicts with existing wildcard '" + n.path +
|
||||||
"' in existing prefix '" + prefix +
|
"' in path '" + fullPath + "'")
|
||||||
"'")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c := path[0]
|
c := path[0]
|
||||||
|
8
vendor/github.com/gin-gonic/gin/utils.go
generated
vendored
8
vendor/github.com/gin-gonic/gin/utils.go
generated
vendored
@ -14,10 +14,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BindKey indicates a default bind key.
|
|
||||||
const BindKey = "_gin-gonic/gin/bindkey"
|
const BindKey = "_gin-gonic/gin/bindkey"
|
||||||
|
|
||||||
// Bind is a helper function for given interface object and returns a Gin middleware.
|
|
||||||
func Bind(val interface{}) HandlerFunc {
|
func Bind(val interface{}) HandlerFunc {
|
||||||
value := reflect.ValueOf(val)
|
value := reflect.ValueOf(val)
|
||||||
if value.Kind() == reflect.Ptr {
|
if value.Kind() == reflect.Ptr {
|
||||||
@ -35,14 +33,16 @@ func Bind(val interface{}) HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WrapF is a helper function for wrapping http.HandlerFunc and returns a Gin middleware.
|
// WrapF is a helper function for wrapping http.HandlerFunc
|
||||||
|
// Returns a Gin middleware
|
||||||
func WrapF(f http.HandlerFunc) HandlerFunc {
|
func WrapF(f http.HandlerFunc) HandlerFunc {
|
||||||
return func(c *Context) {
|
return func(c *Context) {
|
||||||
f(c.Writer, c.Request)
|
f(c.Writer, c.Request)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WrapH is a helper function for wrapping http.Handler and returns a Gin middleware.
|
// WrapH is a helper function for wrapping http.Handler
|
||||||
|
// Returns a Gin middleware
|
||||||
func WrapH(h http.Handler) HandlerFunc {
|
func WrapH(h http.Handler) HandlerFunc {
|
||||||
return func(c *Context) {
|
return func(c *Context) {
|
||||||
h.ServeHTTP(c.Writer, c.Request)
|
h.ServeHTTP(c.Writer, c.Request)
|
||||||
|
1
vendor/github.com/gin-gonic/gin/wercker.yml
generated
vendored
Normal file
1
vendor/github.com/gin-gonic/gin/wercker.yml
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
box: wercker/default
|
5
vendor/github.com/go-sql-driver/mysql/AUTHORS
generated
vendored
5
vendor/github.com/go-sql-driver/mysql/AUTHORS
generated
vendored
@ -35,7 +35,6 @@ Hanno Braun <mail at hannobraun.com>
|
|||||||
Henri Yandell <flamefew at gmail.com>
|
Henri Yandell <flamefew at gmail.com>
|
||||||
Hirotaka Yamamoto <ymmt2005 at gmail.com>
|
Hirotaka Yamamoto <ymmt2005 at gmail.com>
|
||||||
ICHINOSE Shogo <shogo82148 at gmail.com>
|
ICHINOSE Shogo <shogo82148 at gmail.com>
|
||||||
Ilia Cimpoes <ichimpoesh at gmail.com>
|
|
||||||
INADA Naoki <songofacandy at gmail.com>
|
INADA Naoki <songofacandy at gmail.com>
|
||||||
Jacek Szwec <szwec.jacek at gmail.com>
|
Jacek Szwec <szwec.jacek at gmail.com>
|
||||||
James Harr <james.harr at gmail.com>
|
James Harr <james.harr at gmail.com>
|
||||||
@ -73,9 +72,6 @@ Shuode Li <elemount at qq.com>
|
|||||||
Soroush Pour <me at soroushjp.com>
|
Soroush Pour <me at soroushjp.com>
|
||||||
Stan Putrya <root.vagner at gmail.com>
|
Stan Putrya <root.vagner at gmail.com>
|
||||||
Stanley Gunawan <gunawan.stanley at gmail.com>
|
Stanley Gunawan <gunawan.stanley at gmail.com>
|
||||||
Steven Hartland <steven.hartland at multiplay.co.uk>
|
|
||||||
Thomas Wodarek <wodarekwebpage at gmail.com>
|
|
||||||
Tom Jenkinson <tom at tjenkinson.me>
|
|
||||||
Xiangyu Hu <xiangyu.hu at outlook.com>
|
Xiangyu Hu <xiangyu.hu at outlook.com>
|
||||||
Xiaobing Jiang <s7v7nislands at gmail.com>
|
Xiaobing Jiang <s7v7nislands at gmail.com>
|
||||||
Xiuming Chen <cc at cxm.cc>
|
Xiuming Chen <cc at cxm.cc>
|
||||||
@ -91,4 +87,3 @@ Keybase Inc.
|
|||||||
Percona LLC
|
Percona LLC
|
||||||
Pivotal Inc.
|
Pivotal Inc.
|
||||||
Stripe Inc.
|
Stripe Inc.
|
||||||
Multiplay Ltd.
|
|
||||||
|
11
vendor/github.com/go-sql-driver/mysql/CHANGELOG.md
generated
vendored
11
vendor/github.com/go-sql-driver/mysql/CHANGELOG.md
generated
vendored
@ -1,3 +1,14 @@
|
|||||||
|
## Version 1.4.1 (2018-11-14)
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
|
||||||
|
- Fix TIME format for binary columns (#818)
|
||||||
|
- Fix handling of empty auth plugin names (#835)
|
||||||
|
- Fix caching_sha2_password with empty password (#826)
|
||||||
|
- Fix canceled context broke mysqlConn (#862)
|
||||||
|
- Fix OldAuthSwitchRequest support (#870)
|
||||||
|
- Fix Auth Response packet for cleartext password (#887)
|
||||||
|
|
||||||
## Version 1.4 (2018-06-03)
|
## Version 1.4 (2018-06-03)
|
||||||
|
|
||||||
Changes:
|
Changes:
|
||||||
|
2
vendor/github.com/go-sql-driver/mysql/README.md
generated
vendored
2
vendor/github.com/go-sql-driver/mysql/README.md
generated
vendored
@ -40,7 +40,7 @@ A MySQL-Driver for Go's [database/sql](https://golang.org/pkg/database/sql/) pac
|
|||||||
* Optional placeholder interpolation
|
* Optional placeholder interpolation
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
* Go 1.8 or higher. We aim to support the 3 latest versions of Go.
|
* Go 1.7 or higher. We aim to support the 3 latest versions of Go.
|
||||||
* MySQL (4.1+), MariaDB, Percona Server, Google CloudSQL or Sphinx (2.2.3+)
|
* MySQL (4.1+), MariaDB, Percona Server, Google CloudSQL or Sphinx (2.2.3+)
|
||||||
|
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
8
vendor/github.com/go-sql-driver/mysql/auth.go
generated
vendored
8
vendor/github.com/go-sql-driver/mysql/auth.go
generated
vendored
@ -360,15 +360,13 @@ func (mc *mysqlConn) handleAuthResult(oldAuthData []byte, plugin string) error {
|
|||||||
pubKey := mc.cfg.pubKey
|
pubKey := mc.cfg.pubKey
|
||||||
if pubKey == nil {
|
if pubKey == nil {
|
||||||
// request public key from server
|
// request public key from server
|
||||||
data, err := mc.buf.takeSmallBuffer(4 + 1)
|
data := mc.buf.takeSmallBuffer(4 + 1)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
data[4] = cachingSha2PasswordRequestPublicKey
|
data[4] = cachingSha2PasswordRequestPublicKey
|
||||||
mc.writePacket(data)
|
mc.writePacket(data)
|
||||||
|
|
||||||
// parse public key
|
// parse public key
|
||||||
if data, err = mc.readPacket(); err != nil {
|
data, err := mc.readPacket()
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
51
vendor/github.com/go-sql-driver/mysql/buffer.go
generated
vendored
51
vendor/github.com/go-sql-driver/mysql/buffer.go
generated
vendored
@ -22,17 +22,17 @@ const defaultBufSize = 4096
|
|||||||
// The buffer is similar to bufio.Reader / Writer but zero-copy-ish
|
// The buffer is similar to bufio.Reader / Writer but zero-copy-ish
|
||||||
// Also highly optimized for this particular use case.
|
// Also highly optimized for this particular use case.
|
||||||
type buffer struct {
|
type buffer struct {
|
||||||
buf []byte // buf is a byte buffer who's length and capacity are equal.
|
buf []byte
|
||||||
nc net.Conn
|
nc net.Conn
|
||||||
idx int
|
idx int
|
||||||
length int
|
length int
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// newBuffer allocates and returns a new buffer.
|
|
||||||
func newBuffer(nc net.Conn) buffer {
|
func newBuffer(nc net.Conn) buffer {
|
||||||
|
var b [defaultBufSize]byte
|
||||||
return buffer{
|
return buffer{
|
||||||
buf: make([]byte, defaultBufSize),
|
buf: b[:],
|
||||||
nc: nc,
|
nc: nc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,56 +105,43 @@ func (b *buffer) readNext(need int) ([]byte, error) {
|
|||||||
return b.buf[offset:b.idx], nil
|
return b.buf[offset:b.idx], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// takeBuffer returns a buffer with the requested size.
|
// returns a buffer with the requested size.
|
||||||
// If possible, a slice from the existing buffer is returned.
|
// If possible, a slice from the existing buffer is returned.
|
||||||
// Otherwise a bigger buffer is made.
|
// Otherwise a bigger buffer is made.
|
||||||
// Only one buffer (total) can be used at a time.
|
// Only one buffer (total) can be used at a time.
|
||||||
func (b *buffer) takeBuffer(length int) ([]byte, error) {
|
func (b *buffer) takeBuffer(length int) []byte {
|
||||||
if b.length > 0 {
|
if b.length > 0 {
|
||||||
return nil, ErrBusyBuffer
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// test (cheap) general case first
|
// test (cheap) general case first
|
||||||
if length <= cap(b.buf) {
|
if length <= defaultBufSize || length <= cap(b.buf) {
|
||||||
return b.buf[:length], nil
|
return b.buf[:length]
|
||||||
}
|
}
|
||||||
|
|
||||||
if length < maxPacketSize {
|
if length < maxPacketSize {
|
||||||
b.buf = make([]byte, length)
|
b.buf = make([]byte, length)
|
||||||
return b.buf, nil
|
return b.buf
|
||||||
|
}
|
||||||
|
return make([]byte, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
// buffer is larger than we want to store.
|
// shortcut which can be used if the requested buffer is guaranteed to be
|
||||||
return make([]byte, length), nil
|
// smaller than defaultBufSize
|
||||||
}
|
|
||||||
|
|
||||||
// takeSmallBuffer is shortcut which can be used if length is
|
|
||||||
// known to be smaller than defaultBufSize.
|
|
||||||
// Only one buffer (total) can be used at a time.
|
// Only one buffer (total) can be used at a time.
|
||||||
func (b *buffer) takeSmallBuffer(length int) ([]byte, error) {
|
func (b *buffer) takeSmallBuffer(length int) []byte {
|
||||||
if b.length > 0 {
|
if b.length > 0 {
|
||||||
return nil, ErrBusyBuffer
|
return nil
|
||||||
}
|
}
|
||||||
return b.buf[:length], nil
|
return b.buf[:length]
|
||||||
}
|
}
|
||||||
|
|
||||||
// takeCompleteBuffer returns the complete existing buffer.
|
// takeCompleteBuffer returns the complete existing buffer.
|
||||||
// This can be used if the necessary buffer size is unknown.
|
// This can be used if the necessary buffer size is unknown.
|
||||||
// cap and len of the returned buffer will be equal.
|
|
||||||
// Only one buffer (total) can be used at a time.
|
// Only one buffer (total) can be used at a time.
|
||||||
func (b *buffer) takeCompleteBuffer() ([]byte, error) {
|
func (b *buffer) takeCompleteBuffer() []byte {
|
||||||
if b.length > 0 {
|
if b.length > 0 {
|
||||||
return nil, ErrBusyBuffer
|
|
||||||
}
|
|
||||||
return b.buf, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// store stores buf, an updated buffer, if its suitable to do so.
|
|
||||||
func (b *buffer) store(buf []byte) error {
|
|
||||||
if b.length > 0 {
|
|
||||||
return ErrBusyBuffer
|
|
||||||
} else if cap(buf) <= maxPacketSize && cap(buf) > cap(b.buf) {
|
|
||||||
b.buf = buf[:cap(buf)]
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
return b.buf
|
||||||
|
}
|
||||||
|
210
vendor/github.com/go-sql-driver/mysql/connection.go
generated
vendored
210
vendor/github.com/go-sql-driver/mysql/connection.go
generated
vendored
@ -9,8 +9,6 @@
|
|||||||
package mysql
|
package mysql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"database/sql"
|
|
||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
@ -19,6 +17,16 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// a copy of context.Context for Go 1.7 and earlier
|
||||||
|
type mysqlContext interface {
|
||||||
|
Done() <-chan struct{}
|
||||||
|
Err() error
|
||||||
|
|
||||||
|
// defined in context.Context, but not used in this driver:
|
||||||
|
// Deadline() (deadline time.Time, ok bool)
|
||||||
|
// Value(key interface{}) interface{}
|
||||||
|
}
|
||||||
|
|
||||||
type mysqlConn struct {
|
type mysqlConn struct {
|
||||||
buf buffer
|
buf buffer
|
||||||
netConn net.Conn
|
netConn net.Conn
|
||||||
@ -35,7 +43,7 @@ type mysqlConn struct {
|
|||||||
|
|
||||||
// for context support (Go 1.8+)
|
// for context support (Go 1.8+)
|
||||||
watching bool
|
watching bool
|
||||||
watcher chan<- context.Context
|
watcher chan<- mysqlContext
|
||||||
closech chan struct{}
|
closech chan struct{}
|
||||||
finished chan<- struct{}
|
finished chan<- struct{}
|
||||||
canceled atomicError // set non-nil if conn is canceled
|
canceled atomicError // set non-nil if conn is canceled
|
||||||
@ -182,10 +190,10 @@ func (mc *mysqlConn) interpolateParams(query string, args []driver.Value) (strin
|
|||||||
return "", driver.ErrSkip
|
return "", driver.ErrSkip
|
||||||
}
|
}
|
||||||
|
|
||||||
buf, err := mc.buf.takeCompleteBuffer()
|
buf := mc.buf.takeCompleteBuffer()
|
||||||
if err != nil {
|
if buf == nil {
|
||||||
// can not take the buffer. Something must be wrong with the connection
|
// can not take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(err)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return "", ErrInvalidConn
|
return "", ErrInvalidConn
|
||||||
}
|
}
|
||||||
buf = buf[:0]
|
buf = buf[:0]
|
||||||
@ -451,193 +459,3 @@ func (mc *mysqlConn) finish() {
|
|||||||
case <-mc.closech:
|
case <-mc.closech:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ping implements driver.Pinger interface
|
|
||||||
func (mc *mysqlConn) Ping(ctx context.Context) (err error) {
|
|
||||||
if mc.closed.IsSet() {
|
|
||||||
errLog.Print(ErrInvalidConn)
|
|
||||||
return driver.ErrBadConn
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = mc.watchCancel(ctx); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer mc.finish()
|
|
||||||
|
|
||||||
if err = mc.writeCommandPacket(comPing); err != nil {
|
|
||||||
return mc.markBadConn(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return mc.readResultOK()
|
|
||||||
}
|
|
||||||
|
|
||||||
// BeginTx implements driver.ConnBeginTx interface
|
|
||||||
func (mc *mysqlConn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
|
|
||||||
if err := mc.watchCancel(ctx); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer mc.finish()
|
|
||||||
|
|
||||||
if sql.IsolationLevel(opts.Isolation) != sql.LevelDefault {
|
|
||||||
level, err := mapIsolationLevel(opts.Isolation)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = mc.exec("SET TRANSACTION ISOLATION LEVEL " + level)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return mc.begin(opts.ReadOnly)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mc *mysqlConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
|
|
||||||
dargs, err := namedValueToValue(args)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := mc.watchCancel(ctx); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
rows, err := mc.query(query, dargs)
|
|
||||||
if err != nil {
|
|
||||||
mc.finish()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
rows.finish = mc.finish
|
|
||||||
return rows, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mc *mysqlConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
|
|
||||||
dargs, err := namedValueToValue(args)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := mc.watchCancel(ctx); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer mc.finish()
|
|
||||||
|
|
||||||
return mc.Exec(query, dargs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mc *mysqlConn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
|
|
||||||
if err := mc.watchCancel(ctx); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
stmt, err := mc.Prepare(query)
|
|
||||||
mc.finish()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
default:
|
|
||||||
case <-ctx.Done():
|
|
||||||
stmt.Close()
|
|
||||||
return nil, ctx.Err()
|
|
||||||
}
|
|
||||||
return stmt, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (stmt *mysqlStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
|
|
||||||
dargs, err := namedValueToValue(args)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := stmt.mc.watchCancel(ctx); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
rows, err := stmt.query(dargs)
|
|
||||||
if err != nil {
|
|
||||||
stmt.mc.finish()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
rows.finish = stmt.mc.finish
|
|
||||||
return rows, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (stmt *mysqlStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
|
|
||||||
dargs, err := namedValueToValue(args)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := stmt.mc.watchCancel(ctx); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer stmt.mc.finish()
|
|
||||||
|
|
||||||
return stmt.Exec(dargs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mc *mysqlConn) watchCancel(ctx context.Context) error {
|
|
||||||
if mc.watching {
|
|
||||||
// Reach here if canceled,
|
|
||||||
// so the connection is already invalid
|
|
||||||
mc.cleanup()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// When ctx is already cancelled, don't watch it.
|
|
||||||
if err := ctx.Err(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// When ctx is not cancellable, don't watch it.
|
|
||||||
if ctx.Done() == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// When watcher is not alive, can't watch it.
|
|
||||||
if mc.watcher == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
mc.watching = true
|
|
||||||
mc.watcher <- ctx
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mc *mysqlConn) startWatcher() {
|
|
||||||
watcher := make(chan context.Context, 1)
|
|
||||||
mc.watcher = watcher
|
|
||||||
finished := make(chan struct{})
|
|
||||||
mc.finished = finished
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
var ctx context.Context
|
|
||||||
select {
|
|
||||||
case ctx = <-watcher:
|
|
||||||
case <-mc.closech:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
mc.cancel(ctx.Err())
|
|
||||||
case <-finished:
|
|
||||||
case <-mc.closech:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mc *mysqlConn) CheckNamedValue(nv *driver.NamedValue) (err error) {
|
|
||||||
nv.Value, err = converter{}.ConvertValue(nv.Value)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResetSession implements driver.SessionResetter.
|
|
||||||
// (From Go 1.10)
|
|
||||||
func (mc *mysqlConn) ResetSession(ctx context.Context) error {
|
|
||||||
if mc.closed.IsSet() {
|
|
||||||
return driver.ErrBadConn
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
207
vendor/github.com/go-sql-driver/mysql/connection_go18.go
generated
vendored
Normal file
207
vendor/github.com/go-sql-driver/mysql/connection_go18.go
generated
vendored
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
|
||||||
|
//
|
||||||
|
// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
// +build go1.8
|
||||||
|
|
||||||
|
package mysql
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"database/sql/driver"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Ping implements driver.Pinger interface
|
||||||
|
func (mc *mysqlConn) Ping(ctx context.Context) (err error) {
|
||||||
|
if mc.closed.IsSet() {
|
||||||
|
errLog.Print(ErrInvalidConn)
|
||||||
|
return driver.ErrBadConn
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = mc.watchCancel(ctx); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer mc.finish()
|
||||||
|
|
||||||
|
if err = mc.writeCommandPacket(comPing); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return mc.readResultOK()
|
||||||
|
}
|
||||||
|
|
||||||
|
// BeginTx implements driver.ConnBeginTx interface
|
||||||
|
func (mc *mysqlConn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
|
||||||
|
if err := mc.watchCancel(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer mc.finish()
|
||||||
|
|
||||||
|
if sql.IsolationLevel(opts.Isolation) != sql.LevelDefault {
|
||||||
|
level, err := mapIsolationLevel(opts.Isolation)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = mc.exec("SET TRANSACTION ISOLATION LEVEL " + level)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mc.begin(opts.ReadOnly)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *mysqlConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
|
||||||
|
dargs, err := namedValueToValue(args)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := mc.watchCancel(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := mc.query(query, dargs)
|
||||||
|
if err != nil {
|
||||||
|
mc.finish()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rows.finish = mc.finish
|
||||||
|
return rows, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *mysqlConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
|
||||||
|
dargs, err := namedValueToValue(args)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := mc.watchCancel(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer mc.finish()
|
||||||
|
|
||||||
|
return mc.Exec(query, dargs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *mysqlConn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
|
||||||
|
if err := mc.watchCancel(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt, err := mc.Prepare(query)
|
||||||
|
mc.finish()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
default:
|
||||||
|
case <-ctx.Done():
|
||||||
|
stmt.Close()
|
||||||
|
return nil, ctx.Err()
|
||||||
|
}
|
||||||
|
return stmt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (stmt *mysqlStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
|
||||||
|
dargs, err := namedValueToValue(args)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := stmt.mc.watchCancel(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := stmt.query(dargs)
|
||||||
|
if err != nil {
|
||||||
|
stmt.mc.finish()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rows.finish = stmt.mc.finish
|
||||||
|
return rows, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (stmt *mysqlStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
|
||||||
|
dargs, err := namedValueToValue(args)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := stmt.mc.watchCancel(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer stmt.mc.finish()
|
||||||
|
|
||||||
|
return stmt.Exec(dargs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *mysqlConn) watchCancel(ctx context.Context) error {
|
||||||
|
if mc.watching {
|
||||||
|
// Reach here if canceled,
|
||||||
|
// so the connection is already invalid
|
||||||
|
mc.cleanup()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// When ctx is already cancelled, don't watch it.
|
||||||
|
if err := ctx.Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// When ctx is not cancellable, don't watch it.
|
||||||
|
if ctx.Done() == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// When watcher is not alive, can't watch it.
|
||||||
|
if mc.watcher == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
mc.watching = true
|
||||||
|
mc.watcher <- ctx
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *mysqlConn) startWatcher() {
|
||||||
|
watcher := make(chan mysqlContext, 1)
|
||||||
|
mc.watcher = watcher
|
||||||
|
finished := make(chan struct{})
|
||||||
|
mc.finished = finished
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
var ctx mysqlContext
|
||||||
|
select {
|
||||||
|
case ctx = <-watcher:
|
||||||
|
case <-mc.closech:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
mc.cancel(ctx.Err())
|
||||||
|
case <-finished:
|
||||||
|
case <-mc.closech:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *mysqlConn) CheckNamedValue(nv *driver.NamedValue) (err error) {
|
||||||
|
nv.Value, err = converter{}.ConvertValue(nv.Value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetSession implements driver.SessionResetter.
|
||||||
|
// (From Go 1.10)
|
||||||
|
func (mc *mysqlConn) ResetSession(ctx context.Context) error {
|
||||||
|
if mc.closed.IsSet() {
|
||||||
|
return driver.ErrBadConn
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
15
vendor/github.com/go-sql-driver/mysql/driver.go
generated
vendored
15
vendor/github.com/go-sql-driver/mysql/driver.go
generated
vendored
@ -23,6 +23,11 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// watcher interface is used for context support (From Go 1.8)
|
||||||
|
type watcher interface {
|
||||||
|
startWatcher()
|
||||||
|
}
|
||||||
|
|
||||||
// MySQLDriver is exported to make the driver directly accessible.
|
// MySQLDriver is exported to make the driver directly accessible.
|
||||||
// In general the driver is used via the database/sql package.
|
// In general the driver is used via the database/sql package.
|
||||||
type MySQLDriver struct{}
|
type MySQLDriver struct{}
|
||||||
@ -50,7 +55,7 @@ func RegisterDial(net string, dial DialFunc) {
|
|||||||
|
|
||||||
// Open new Connection.
|
// Open new Connection.
|
||||||
// See https://github.com/go-sql-driver/mysql#dsn-data-source-name for how
|
// See https://github.com/go-sql-driver/mysql#dsn-data-source-name for how
|
||||||
// the DSN string is formatted
|
// the DSN string is formated
|
||||||
func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
|
func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@ -77,10 +82,6 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
|
|||||||
mc.netConn, err = nd.Dial(mc.cfg.Net, mc.cfg.Addr)
|
mc.netConn, err = nd.Dial(mc.cfg.Net, mc.cfg.Addr)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
|
|
||||||
errLog.Print("net.Error from Dial()': ", nerr.Error())
|
|
||||||
return nil, driver.ErrBadConn
|
|
||||||
}
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +96,9 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call startWatcher for context support (From Go 1.8)
|
// Call startWatcher for context support (From Go 1.8)
|
||||||
mc.startWatcher()
|
if s, ok := interface{}(mc).(watcher); ok {
|
||||||
|
s.startWatcher()
|
||||||
|
}
|
||||||
|
|
||||||
mc.buf = newBuffer(mc.netConn)
|
mc.buf = newBuffer(mc.netConn)
|
||||||
|
|
||||||
|
54
vendor/github.com/go-sql-driver/mysql/packets.go
generated
vendored
54
vendor/github.com/go-sql-driver/mysql/packets.go
generated
vendored
@ -51,7 +51,7 @@ func (mc *mysqlConn) readPacket() ([]byte, error) {
|
|||||||
mc.sequence++
|
mc.sequence++
|
||||||
|
|
||||||
// packets with length 0 terminate a previous packet which is a
|
// packets with length 0 terminate a previous packet which is a
|
||||||
// multiple of (2^24)-1 bytes long
|
// multiple of (2^24)−1 bytes long
|
||||||
if pktLen == 0 {
|
if pktLen == 0 {
|
||||||
// there was no previous packet
|
// there was no previous packet
|
||||||
if prevData == nil {
|
if prevData == nil {
|
||||||
@ -286,10 +286,10 @@ func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, plugin string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculate packet length and get buffer with that size
|
// Calculate packet length and get buffer with that size
|
||||||
data, err := mc.buf.takeSmallBuffer(pktLen + 4)
|
data := mc.buf.takeSmallBuffer(pktLen + 4)
|
||||||
if err != nil {
|
if data == nil {
|
||||||
// cannot take the buffer. Something must be wrong with the connection
|
// cannot take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(err)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return errBadConnNoWrite
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,10 +367,10 @@ func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, plugin string
|
|||||||
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse
|
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse
|
||||||
func (mc *mysqlConn) writeAuthSwitchPacket(authData []byte) error {
|
func (mc *mysqlConn) writeAuthSwitchPacket(authData []byte) error {
|
||||||
pktLen := 4 + len(authData)
|
pktLen := 4 + len(authData)
|
||||||
data, err := mc.buf.takeSmallBuffer(pktLen)
|
data := mc.buf.takeSmallBuffer(pktLen)
|
||||||
if err != nil {
|
if data == nil {
|
||||||
// cannot take the buffer. Something must be wrong with the connection
|
// cannot take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(err)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return errBadConnNoWrite
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,10 +387,10 @@ func (mc *mysqlConn) writeCommandPacket(command byte) error {
|
|||||||
// Reset Packet Sequence
|
// Reset Packet Sequence
|
||||||
mc.sequence = 0
|
mc.sequence = 0
|
||||||
|
|
||||||
data, err := mc.buf.takeSmallBuffer(4 + 1)
|
data := mc.buf.takeSmallBuffer(4 + 1)
|
||||||
if err != nil {
|
if data == nil {
|
||||||
// cannot take the buffer. Something must be wrong with the connection
|
// cannot take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(err)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return errBadConnNoWrite
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,10 +406,10 @@ func (mc *mysqlConn) writeCommandPacketStr(command byte, arg string) error {
|
|||||||
mc.sequence = 0
|
mc.sequence = 0
|
||||||
|
|
||||||
pktLen := 1 + len(arg)
|
pktLen := 1 + len(arg)
|
||||||
data, err := mc.buf.takeBuffer(pktLen + 4)
|
data := mc.buf.takeBuffer(pktLen + 4)
|
||||||
if err != nil {
|
if data == nil {
|
||||||
// cannot take the buffer. Something must be wrong with the connection
|
// cannot take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(err)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return errBadConnNoWrite
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,10 +427,10 @@ func (mc *mysqlConn) writeCommandPacketUint32(command byte, arg uint32) error {
|
|||||||
// Reset Packet Sequence
|
// Reset Packet Sequence
|
||||||
mc.sequence = 0
|
mc.sequence = 0
|
||||||
|
|
||||||
data, err := mc.buf.takeSmallBuffer(4 + 1 + 4)
|
data := mc.buf.takeSmallBuffer(4 + 1 + 4)
|
||||||
if err != nil {
|
if data == nil {
|
||||||
// cannot take the buffer. Something must be wrong with the connection
|
// cannot take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(err)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return errBadConnNoWrite
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -883,7 +883,7 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
|
|||||||
const minPktLen = 4 + 1 + 4 + 1 + 4
|
const minPktLen = 4 + 1 + 4 + 1 + 4
|
||||||
mc := stmt.mc
|
mc := stmt.mc
|
||||||
|
|
||||||
// Determine threshold dynamically to avoid packet size shortage.
|
// Determine threshould dynamically to avoid packet size shortage.
|
||||||
longDataSize := mc.maxAllowedPacket / (stmt.paramCount + 1)
|
longDataSize := mc.maxAllowedPacket / (stmt.paramCount + 1)
|
||||||
if longDataSize < 64 {
|
if longDataSize < 64 {
|
||||||
longDataSize = 64
|
longDataSize = 64
|
||||||
@ -893,17 +893,15 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
|
|||||||
mc.sequence = 0
|
mc.sequence = 0
|
||||||
|
|
||||||
var data []byte
|
var data []byte
|
||||||
var err error
|
|
||||||
|
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
data, err = mc.buf.takeBuffer(minPktLen)
|
data = mc.buf.takeBuffer(minPktLen)
|
||||||
} else {
|
} else {
|
||||||
data, err = mc.buf.takeCompleteBuffer()
|
data = mc.buf.takeCompleteBuffer()
|
||||||
// In this case the len(data) == cap(data) which is used to optimise the flow below.
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
if data == nil {
|
||||||
// cannot take the buffer. Something must be wrong with the connection
|
// cannot take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(err)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return errBadConnNoWrite
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -929,7 +927,7 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
|
|||||||
pos := minPktLen
|
pos := minPktLen
|
||||||
|
|
||||||
var nullMask []byte
|
var nullMask []byte
|
||||||
if maskLen, typesLen := (len(args)+7)/8, 1+2*len(args); pos+maskLen+typesLen >= cap(data) {
|
if maskLen, typesLen := (len(args)+7)/8, 1+2*len(args); pos+maskLen+typesLen >= len(data) {
|
||||||
// buffer has to be extended but we don't know by how much so
|
// buffer has to be extended but we don't know by how much so
|
||||||
// we depend on append after all data with known sizes fit.
|
// we depend on append after all data with known sizes fit.
|
||||||
// We stop at that because we deal with a lot of columns here
|
// We stop at that because we deal with a lot of columns here
|
||||||
@ -938,11 +936,10 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
|
|||||||
copy(tmp[:pos], data[:pos])
|
copy(tmp[:pos], data[:pos])
|
||||||
data = tmp
|
data = tmp
|
||||||
nullMask = data[pos : pos+maskLen]
|
nullMask = data[pos : pos+maskLen]
|
||||||
// No need to clean nullMask as make ensures that.
|
|
||||||
pos += maskLen
|
pos += maskLen
|
||||||
} else {
|
} else {
|
||||||
nullMask = data[pos : pos+maskLen]
|
nullMask = data[pos : pos+maskLen]
|
||||||
for i := range nullMask {
|
for i := 0; i < maskLen; i++ {
|
||||||
nullMask[i] = 0
|
nullMask[i] = 0
|
||||||
}
|
}
|
||||||
pos += maskLen
|
pos += maskLen
|
||||||
@ -1079,10 +1076,7 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
|
|||||||
// In that case we must build the data packet with the new values buffer
|
// In that case we must build the data packet with the new values buffer
|
||||||
if valuesCap != cap(paramValues) {
|
if valuesCap != cap(paramValues) {
|
||||||
data = append(data[:pos], paramValues...)
|
data = append(data[:pos], paramValues...)
|
||||||
if err = mc.buf.store(data); err != nil {
|
mc.buf.buf = data
|
||||||
errLog.Print(err)
|
|
||||||
return errBadConnNoWrite
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pos += len(paramValues)
|
pos += len(paramValues)
|
||||||
|
31
vendor/github.com/go-sql-driver/mysql/utils.go
generated
vendored
31
vendor/github.com/go-sql-driver/mysql/utils.go
generated
vendored
@ -10,10 +10,8 @@ package mysql
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"database/sql"
|
|
||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -82,7 +80,7 @@ func DeregisterTLSConfig(key string) {
|
|||||||
func getTLSConfigClone(key string) (config *tls.Config) {
|
func getTLSConfigClone(key string) (config *tls.Config) {
|
||||||
tlsConfigLock.RLock()
|
tlsConfigLock.RLock()
|
||||||
if v, ok := tlsConfigRegistry[key]; ok {
|
if v, ok := tlsConfigRegistry[key]; ok {
|
||||||
config = v.Clone()
|
config = cloneTLSConfig(v)
|
||||||
}
|
}
|
||||||
tlsConfigLock.RUnlock()
|
tlsConfigLock.RUnlock()
|
||||||
return
|
return
|
||||||
@ -726,30 +724,3 @@ func (ae *atomicError) Value() error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func namedValueToValue(named []driver.NamedValue) ([]driver.Value, error) {
|
|
||||||
dargs := make([]driver.Value, len(named))
|
|
||||||
for n, param := range named {
|
|
||||||
if len(param.Name) > 0 {
|
|
||||||
// TODO: support the use of Named Parameters #561
|
|
||||||
return nil, errors.New("mysql: driver does not support the use of Named Parameters")
|
|
||||||
}
|
|
||||||
dargs[n] = param.Value
|
|
||||||
}
|
|
||||||
return dargs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func mapIsolationLevel(level driver.IsolationLevel) (string, error) {
|
|
||||||
switch sql.IsolationLevel(level) {
|
|
||||||
case sql.LevelRepeatableRead:
|
|
||||||
return "REPEATABLE READ", nil
|
|
||||||
case sql.LevelReadCommitted:
|
|
||||||
return "READ COMMITTED", nil
|
|
||||||
case sql.LevelReadUncommitted:
|
|
||||||
return "READ UNCOMMITTED", nil
|
|
||||||
case sql.LevelSerializable:
|
|
||||||
return "SERIALIZABLE", nil
|
|
||||||
default:
|
|
||||||
return "", fmt.Errorf("mysql: unsupported isolation level: %v", level)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
40
vendor/github.com/go-sql-driver/mysql/utils_go17.go
generated
vendored
Normal file
40
vendor/github.com/go-sql-driver/mysql/utils_go17.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
|
||||||
|
//
|
||||||
|
// Copyright 2017 The Go-MySQL-Driver Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
// +build go1.7
|
||||||
|
// +build !go1.8
|
||||||
|
|
||||||
|
package mysql
|
||||||
|
|
||||||
|
import "crypto/tls"
|
||||||
|
|
||||||
|
func cloneTLSConfig(c *tls.Config) *tls.Config {
|
||||||
|
return &tls.Config{
|
||||||
|
Rand: c.Rand,
|
||||||
|
Time: c.Time,
|
||||||
|
Certificates: c.Certificates,
|
||||||
|
NameToCertificate: c.NameToCertificate,
|
||||||
|
GetCertificate: c.GetCertificate,
|
||||||
|
RootCAs: c.RootCAs,
|
||||||
|
NextProtos: c.NextProtos,
|
||||||
|
ServerName: c.ServerName,
|
||||||
|
ClientAuth: c.ClientAuth,
|
||||||
|
ClientCAs: c.ClientCAs,
|
||||||
|
InsecureSkipVerify: c.InsecureSkipVerify,
|
||||||
|
CipherSuites: c.CipherSuites,
|
||||||
|
PreferServerCipherSuites: c.PreferServerCipherSuites,
|
||||||
|
SessionTicketsDisabled: c.SessionTicketsDisabled,
|
||||||
|
SessionTicketKey: c.SessionTicketKey,
|
||||||
|
ClientSessionCache: c.ClientSessionCache,
|
||||||
|
MinVersion: c.MinVersion,
|
||||||
|
MaxVersion: c.MaxVersion,
|
||||||
|
CurvePreferences: c.CurvePreferences,
|
||||||
|
DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled,
|
||||||
|
Renegotiation: c.Renegotiation,
|
||||||
|
}
|
||||||
|
}
|
50
vendor/github.com/go-sql-driver/mysql/utils_go18.go
generated
vendored
Normal file
50
vendor/github.com/go-sql-driver/mysql/utils_go18.go
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
|
||||||
|
//
|
||||||
|
// Copyright 2017 The Go-MySQL-Driver Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
// +build go1.8
|
||||||
|
|
||||||
|
package mysql
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"database/sql"
|
||||||
|
"database/sql/driver"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func cloneTLSConfig(c *tls.Config) *tls.Config {
|
||||||
|
return c.Clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
func namedValueToValue(named []driver.NamedValue) ([]driver.Value, error) {
|
||||||
|
dargs := make([]driver.Value, len(named))
|
||||||
|
for n, param := range named {
|
||||||
|
if len(param.Name) > 0 {
|
||||||
|
// TODO: support the use of Named Parameters #561
|
||||||
|
return nil, errors.New("mysql: driver does not support the use of Named Parameters")
|
||||||
|
}
|
||||||
|
dargs[n] = param.Value
|
||||||
|
}
|
||||||
|
return dargs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func mapIsolationLevel(level driver.IsolationLevel) (string, error) {
|
||||||
|
switch sql.IsolationLevel(level) {
|
||||||
|
case sql.LevelRepeatableRead:
|
||||||
|
return "REPEATABLE READ", nil
|
||||||
|
case sql.LevelReadCommitted:
|
||||||
|
return "READ COMMITTED", nil
|
||||||
|
case sql.LevelReadUncommitted:
|
||||||
|
return "READ UNCOMMITTED", nil
|
||||||
|
case sql.LevelSerializable:
|
||||||
|
return "SERIALIZABLE", nil
|
||||||
|
default:
|
||||||
|
return "", fmt.Errorf("mysql: unsupported isolation level: %v", level)
|
||||||
|
}
|
||||||
|
}
|
1
vendor/github.com/golang/protobuf/proto/decode.go
generated
vendored
1
vendor/github.com/golang/protobuf/proto/decode.go
generated
vendored
@ -186,6 +186,7 @@ func (p *Buffer) DecodeVarint() (x uint64, err error) {
|
|||||||
if b&0x80 == 0 {
|
if b&0x80 == 0 {
|
||||||
goto done
|
goto done
|
||||||
}
|
}
|
||||||
|
// x -= 0x80 << 63 // Always zero.
|
||||||
|
|
||||||
return 0, errOverflow
|
return 0, errOverflow
|
||||||
|
|
||||||
|
3
vendor/github.com/golang/protobuf/proto/equal.go
generated
vendored
3
vendor/github.com/golang/protobuf/proto/equal.go
generated
vendored
@ -246,8 +246,7 @@ func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
m1 := extensionAsLegacyType(e1.value)
|
m1, m2 := e1.value, e2.value
|
||||||
m2 := extensionAsLegacyType(e2.value)
|
|
||||||
|
|
||||||
if m1 == nil && m2 == nil {
|
if m1 == nil && m2 == nil {
|
||||||
// Both have only encoded form.
|
// Both have only encoded form.
|
||||||
|
74
vendor/github.com/golang/protobuf/proto/extensions.go
generated
vendored
74
vendor/github.com/golang/protobuf/proto/extensions.go
generated
vendored
@ -186,23 +186,7 @@ type Extension struct {
|
|||||||
// accessed using GetExtension (or GetExtensions) desc and value
|
// accessed using GetExtension (or GetExtensions) desc and value
|
||||||
// will be set.
|
// will be set.
|
||||||
desc *ExtensionDesc
|
desc *ExtensionDesc
|
||||||
|
|
||||||
// value is a concrete value for the extension field. Let the type of
|
|
||||||
// desc.ExtensionType be the "API type" and the type of Extension.value
|
|
||||||
// be the "storage type". The API type and storage type are the same except:
|
|
||||||
// * For scalars (except []byte), the API type uses *T,
|
|
||||||
// while the storage type uses T.
|
|
||||||
// * For repeated fields, the API type uses []T, while the storage type
|
|
||||||
// uses *[]T.
|
|
||||||
//
|
|
||||||
// The reason for the divergence is so that the storage type more naturally
|
|
||||||
// matches what is expected of when retrieving the values through the
|
|
||||||
// protobuf reflection APIs.
|
|
||||||
//
|
|
||||||
// The value may only be populated if desc is also populated.
|
|
||||||
value interface{}
|
value interface{}
|
||||||
|
|
||||||
// enc is the raw bytes for the extension field.
|
|
||||||
enc []byte
|
enc []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,7 +334,7 @@ func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
|
|||||||
// descriptors with the same field number.
|
// descriptors with the same field number.
|
||||||
return nil, errors.New("proto: descriptor conflict")
|
return nil, errors.New("proto: descriptor conflict")
|
||||||
}
|
}
|
||||||
return extensionAsLegacyType(e.value), nil
|
return e.value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if extension.ExtensionType == nil {
|
if extension.ExtensionType == nil {
|
||||||
@ -365,11 +349,11 @@ func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
|
|||||||
|
|
||||||
// Remember the decoded version and drop the encoded version.
|
// Remember the decoded version and drop the encoded version.
|
||||||
// That way it is safe to mutate what we return.
|
// That way it is safe to mutate what we return.
|
||||||
e.value = extensionAsStorageType(v)
|
e.value = v
|
||||||
e.desc = extension
|
e.desc = extension
|
||||||
e.enc = nil
|
e.enc = nil
|
||||||
emap[extension.Field] = e
|
emap[extension.Field] = e
|
||||||
return extensionAsLegacyType(e.value), nil
|
return e.value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// defaultExtensionValue returns the default value for extension.
|
// defaultExtensionValue returns the default value for extension.
|
||||||
@ -504,7 +488,7 @@ func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error
|
|||||||
}
|
}
|
||||||
typ := reflect.TypeOf(extension.ExtensionType)
|
typ := reflect.TypeOf(extension.ExtensionType)
|
||||||
if typ != reflect.TypeOf(value) {
|
if typ != reflect.TypeOf(value) {
|
||||||
return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", value, extension.ExtensionType)
|
return errors.New("proto: bad extension value type")
|
||||||
}
|
}
|
||||||
// nil extension values need to be caught early, because the
|
// nil extension values need to be caught early, because the
|
||||||
// encoder can't distinguish an ErrNil due to a nil extension
|
// encoder can't distinguish an ErrNil due to a nil extension
|
||||||
@ -516,7 +500,7 @@ func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
extmap := epb.extensionsWrite()
|
extmap := epb.extensionsWrite()
|
||||||
extmap[extension.Field] = Extension{desc: extension, value: extensionAsStorageType(value)}
|
extmap[extension.Field] = Extension{desc: extension, value: value}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -557,51 +541,3 @@ func RegisterExtension(desc *ExtensionDesc) {
|
|||||||
func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {
|
func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {
|
||||||
return extensionMaps[reflect.TypeOf(pb).Elem()]
|
return extensionMaps[reflect.TypeOf(pb).Elem()]
|
||||||
}
|
}
|
||||||
|
|
||||||
// extensionAsLegacyType converts an value in the storage type as the API type.
|
|
||||||
// See Extension.value.
|
|
||||||
func extensionAsLegacyType(v interface{}) interface{} {
|
|
||||||
switch rv := reflect.ValueOf(v); rv.Kind() {
|
|
||||||
case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:
|
|
||||||
// Represent primitive types as a pointer to the value.
|
|
||||||
rv2 := reflect.New(rv.Type())
|
|
||||||
rv2.Elem().Set(rv)
|
|
||||||
v = rv2.Interface()
|
|
||||||
case reflect.Ptr:
|
|
||||||
// Represent slice types as the value itself.
|
|
||||||
switch rv.Type().Elem().Kind() {
|
|
||||||
case reflect.Slice:
|
|
||||||
if rv.IsNil() {
|
|
||||||
v = reflect.Zero(rv.Type().Elem()).Interface()
|
|
||||||
} else {
|
|
||||||
v = rv.Elem().Interface()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// extensionAsStorageType converts an value in the API type as the storage type.
|
|
||||||
// See Extension.value.
|
|
||||||
func extensionAsStorageType(v interface{}) interface{} {
|
|
||||||
switch rv := reflect.ValueOf(v); rv.Kind() {
|
|
||||||
case reflect.Ptr:
|
|
||||||
// Represent slice types as the value itself.
|
|
||||||
switch rv.Type().Elem().Kind() {
|
|
||||||
case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:
|
|
||||||
if rv.IsNil() {
|
|
||||||
v = reflect.Zero(rv.Type().Elem()).Interface()
|
|
||||||
} else {
|
|
||||||
v = rv.Elem().Interface()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.Slice:
|
|
||||||
// Represent slice types as a pointer to the value.
|
|
||||||
if rv.Type().Elem().Kind() != reflect.Uint8 {
|
|
||||||
rv2 := reflect.New(rv.Type())
|
|
||||||
rv2.Elem().Set(rv)
|
|
||||||
v = rv2.Interface()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
30
vendor/github.com/golang/protobuf/proto/lib.go
generated
vendored
30
vendor/github.com/golang/protobuf/proto/lib.go
generated
vendored
@ -341,6 +341,26 @@ type Message interface {
|
|||||||
ProtoMessage()
|
ProtoMessage()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stats records allocation details about the protocol buffer encoders
|
||||||
|
// and decoders. Useful for tuning the library itself.
|
||||||
|
type Stats struct {
|
||||||
|
Emalloc uint64 // mallocs in encode
|
||||||
|
Dmalloc uint64 // mallocs in decode
|
||||||
|
Encode uint64 // number of encodes
|
||||||
|
Decode uint64 // number of decodes
|
||||||
|
Chit uint64 // number of cache hits
|
||||||
|
Cmiss uint64 // number of cache misses
|
||||||
|
Size uint64 // number of sizes
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set to true to enable stats collection.
|
||||||
|
const collectStats = false
|
||||||
|
|
||||||
|
var stats Stats
|
||||||
|
|
||||||
|
// GetStats returns a copy of the global Stats structure.
|
||||||
|
func GetStats() Stats { return stats }
|
||||||
|
|
||||||
// A Buffer is a buffer manager for marshaling and unmarshaling
|
// A Buffer is a buffer manager for marshaling and unmarshaling
|
||||||
// protocol buffers. It may be reused between invocations to
|
// protocol buffers. It may be reused between invocations to
|
||||||
// reduce memory usage. It is not necessary to use a Buffer;
|
// reduce memory usage. It is not necessary to use a Buffer;
|
||||||
@ -940,19 +960,13 @@ func isProto3Zero(v reflect.Value) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
|
||||||
// ProtoPackageIsVersion3 is referenced from generated protocol buffer files
|
|
||||||
// to assert that that code is compatible with this version of the proto package.
|
|
||||||
ProtoPackageIsVersion3 = true
|
|
||||||
|
|
||||||
// ProtoPackageIsVersion2 is referenced from generated protocol buffer files
|
// ProtoPackageIsVersion2 is referenced from generated protocol buffer files
|
||||||
// to assert that that code is compatible with this version of the proto package.
|
// to assert that that code is compatible with this version of the proto package.
|
||||||
ProtoPackageIsVersion2 = true
|
const ProtoPackageIsVersion2 = true
|
||||||
|
|
||||||
// ProtoPackageIsVersion1 is referenced from generated protocol buffer files
|
// ProtoPackageIsVersion1 is referenced from generated protocol buffer files
|
||||||
// to assert that that code is compatible with this version of the proto package.
|
// to assert that that code is compatible with this version of the proto package.
|
||||||
ProtoPackageIsVersion1 = true
|
const ProtoPackageIsVersion1 = true
|
||||||
)
|
|
||||||
|
|
||||||
// InternalMessageInfo is a type used internally by generated .pb.go files.
|
// InternalMessageInfo is a type used internally by generated .pb.go files.
|
||||||
// This type is not intended to be used by non-generated code.
|
// This type is not intended to be used by non-generated code.
|
||||||
|
137
vendor/github.com/golang/protobuf/proto/message_set.go
generated
vendored
137
vendor/github.com/golang/protobuf/proto/message_set.go
generated
vendored
@ -36,7 +36,13 @@ package proto
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID.
|
// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID.
|
||||||
@ -139,9 +145,46 @@ func skipVarint(buf []byte) []byte {
|
|||||||
return buf[i+1:]
|
return buf[i+1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
// unmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
|
// MarshalMessageSet encodes the extension map represented by m in the message set wire format.
|
||||||
|
// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option.
|
||||||
|
func MarshalMessageSet(exts interface{}) ([]byte, error) {
|
||||||
|
return marshalMessageSet(exts, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// marshaMessageSet implements above function, with the opt to turn on / off deterministic during Marshal.
|
||||||
|
func marshalMessageSet(exts interface{}, deterministic bool) ([]byte, error) {
|
||||||
|
switch exts := exts.(type) {
|
||||||
|
case *XXX_InternalExtensions:
|
||||||
|
var u marshalInfo
|
||||||
|
siz := u.sizeMessageSet(exts)
|
||||||
|
b := make([]byte, 0, siz)
|
||||||
|
return u.appendMessageSet(b, exts, deterministic)
|
||||||
|
|
||||||
|
case map[int32]Extension:
|
||||||
|
// This is an old-style extension map.
|
||||||
|
// Wrap it in a new-style XXX_InternalExtensions.
|
||||||
|
ie := XXX_InternalExtensions{
|
||||||
|
p: &struct {
|
||||||
|
mu sync.Mutex
|
||||||
|
extensionMap map[int32]Extension
|
||||||
|
}{
|
||||||
|
extensionMap: exts,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var u marshalInfo
|
||||||
|
siz := u.sizeMessageSet(&ie)
|
||||||
|
b := make([]byte, 0, siz)
|
||||||
|
return u.appendMessageSet(b, &ie, deterministic)
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil, errors.New("proto: not an extension map")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
|
||||||
// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
|
// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
|
||||||
func unmarshalMessageSet(buf []byte, exts interface{}) error {
|
func UnmarshalMessageSet(buf []byte, exts interface{}) error {
|
||||||
var m map[int32]Extension
|
var m map[int32]Extension
|
||||||
switch exts := exts.(type) {
|
switch exts := exts.(type) {
|
||||||
case *XXX_InternalExtensions:
|
case *XXX_InternalExtensions:
|
||||||
@ -179,3 +222,93 @@ func unmarshalMessageSet(buf []byte, exts interface{}) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarshalMessageSetJSON encodes the extension map represented by m in JSON format.
|
||||||
|
// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
|
||||||
|
func MarshalMessageSetJSON(exts interface{}) ([]byte, error) {
|
||||||
|
var m map[int32]Extension
|
||||||
|
switch exts := exts.(type) {
|
||||||
|
case *XXX_InternalExtensions:
|
||||||
|
var mu sync.Locker
|
||||||
|
m, mu = exts.extensionsRead()
|
||||||
|
if m != nil {
|
||||||
|
// Keep the extensions map locked until we're done marshaling to prevent
|
||||||
|
// races between marshaling and unmarshaling the lazily-{en,de}coded
|
||||||
|
// values.
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
}
|
||||||
|
case map[int32]Extension:
|
||||||
|
m = exts
|
||||||
|
default:
|
||||||
|
return nil, errors.New("proto: not an extension map")
|
||||||
|
}
|
||||||
|
var b bytes.Buffer
|
||||||
|
b.WriteByte('{')
|
||||||
|
|
||||||
|
// Process the map in key order for deterministic output.
|
||||||
|
ids := make([]int32, 0, len(m))
|
||||||
|
for id := range m {
|
||||||
|
ids = append(ids, id)
|
||||||
|
}
|
||||||
|
sort.Sort(int32Slice(ids)) // int32Slice defined in text.go
|
||||||
|
|
||||||
|
for i, id := range ids {
|
||||||
|
ext := m[id]
|
||||||
|
msd, ok := messageSetMap[id]
|
||||||
|
if !ok {
|
||||||
|
// Unknown type; we can't render it, so skip it.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if i > 0 && b.Len() > 1 {
|
||||||
|
b.WriteByte(',')
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(&b, `"[%s]":`, msd.name)
|
||||||
|
|
||||||
|
x := ext.value
|
||||||
|
if x == nil {
|
||||||
|
x = reflect.New(msd.t.Elem()).Interface()
|
||||||
|
if err := Unmarshal(ext.enc, x.(Message)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d, err := json.Marshal(x)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
b.Write(d)
|
||||||
|
}
|
||||||
|
b.WriteByte('}')
|
||||||
|
return b.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format.
|
||||||
|
// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
|
||||||
|
func UnmarshalMessageSetJSON(buf []byte, exts interface{}) error {
|
||||||
|
// Common-case fast path.
|
||||||
|
if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is fairly tricky, and it's not clear that it is needed.
|
||||||
|
return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// A global registry of types that can be used in a MessageSet.
|
||||||
|
|
||||||
|
var messageSetMap = make(map[int32]messageSetDesc)
|
||||||
|
|
||||||
|
type messageSetDesc struct {
|
||||||
|
t reflect.Type // pointer to struct
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterMessageSetType is called from the generated code.
|
||||||
|
func RegisterMessageSetType(m Message, fieldNum int32, name string) {
|
||||||
|
messageSetMap[fieldNum] = messageSetDesc{
|
||||||
|
t: reflect.TypeOf(m),
|
||||||
|
name: name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
5
vendor/github.com/golang/protobuf/proto/pointer_reflect.go
generated
vendored
5
vendor/github.com/golang/protobuf/proto/pointer_reflect.go
generated
vendored
@ -79,13 +79,10 @@ func toPointer(i *Message) pointer {
|
|||||||
|
|
||||||
// toAddrPointer converts an interface to a pointer that points to
|
// toAddrPointer converts an interface to a pointer that points to
|
||||||
// the interface data.
|
// the interface data.
|
||||||
func toAddrPointer(i *interface{}, isptr, deref bool) pointer {
|
func toAddrPointer(i *interface{}, isptr bool) pointer {
|
||||||
v := reflect.ValueOf(*i)
|
v := reflect.ValueOf(*i)
|
||||||
u := reflect.New(v.Type())
|
u := reflect.New(v.Type())
|
||||||
u.Elem().Set(v)
|
u.Elem().Set(v)
|
||||||
if deref {
|
|
||||||
u = u.Elem()
|
|
||||||
}
|
|
||||||
return pointer{v: u}
|
return pointer{v: u}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
vendor/github.com/golang/protobuf/proto/pointer_unsafe.go
generated
vendored
13
vendor/github.com/golang/protobuf/proto/pointer_unsafe.go
generated
vendored
@ -85,21 +85,16 @@ func toPointer(i *Message) pointer {
|
|||||||
|
|
||||||
// toAddrPointer converts an interface to a pointer that points to
|
// toAddrPointer converts an interface to a pointer that points to
|
||||||
// the interface data.
|
// the interface data.
|
||||||
func toAddrPointer(i *interface{}, isptr, deref bool) (p pointer) {
|
func toAddrPointer(i *interface{}, isptr bool) pointer {
|
||||||
// Super-tricky - read or get the address of data word of interface value.
|
// Super-tricky - read or get the address of data word of interface value.
|
||||||
if isptr {
|
if isptr {
|
||||||
// The interface is of pointer type, thus it is a direct interface.
|
// The interface is of pointer type, thus it is a direct interface.
|
||||||
// The data word is the pointer data itself. We take its address.
|
// The data word is the pointer data itself. We take its address.
|
||||||
p = pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)}
|
return pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)}
|
||||||
} else {
|
}
|
||||||
// The interface is not of pointer type. The data word is the pointer
|
// The interface is not of pointer type. The data word is the pointer
|
||||||
// to the data.
|
// to the data.
|
||||||
p = pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
|
return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
|
||||||
}
|
|
||||||
if deref {
|
|
||||||
p.p = *(*unsafe.Pointer)(p.p)
|
|
||||||
}
|
|
||||||
return p
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// valToPointer converts v to a pointer. v must be of pointer type.
|
// valToPointer converts v to a pointer. v must be of pointer type.
|
||||||
|
31
vendor/github.com/golang/protobuf/proto/properties.go
generated
vendored
31
vendor/github.com/golang/protobuf/proto/properties.go
generated
vendored
@ -334,6 +334,9 @@ func GetProperties(t reflect.Type) *StructProperties {
|
|||||||
sprop, ok := propertiesMap[t]
|
sprop, ok := propertiesMap[t]
|
||||||
propertiesMu.RUnlock()
|
propertiesMu.RUnlock()
|
||||||
if ok {
|
if ok {
|
||||||
|
if collectStats {
|
||||||
|
stats.Chit++
|
||||||
|
}
|
||||||
return sprop
|
return sprop
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,20 +346,17 @@ func GetProperties(t reflect.Type) *StructProperties {
|
|||||||
return sprop
|
return sprop
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
|
||||||
oneofFuncsIface interface {
|
|
||||||
XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
|
|
||||||
}
|
|
||||||
oneofWrappersIface interface {
|
|
||||||
XXX_OneofWrappers() []interface{}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// getPropertiesLocked requires that propertiesMu is held.
|
// getPropertiesLocked requires that propertiesMu is held.
|
||||||
func getPropertiesLocked(t reflect.Type) *StructProperties {
|
func getPropertiesLocked(t reflect.Type) *StructProperties {
|
||||||
if prop, ok := propertiesMap[t]; ok {
|
if prop, ok := propertiesMap[t]; ok {
|
||||||
|
if collectStats {
|
||||||
|
stats.Chit++
|
||||||
|
}
|
||||||
return prop
|
return prop
|
||||||
}
|
}
|
||||||
|
if collectStats {
|
||||||
|
stats.Cmiss++
|
||||||
|
}
|
||||||
|
|
||||||
prop := new(StructProperties)
|
prop := new(StructProperties)
|
||||||
// in case of recursive protos, fill this in now.
|
// in case of recursive protos, fill this in now.
|
||||||
@ -391,14 +391,13 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
|
|||||||
// Re-order prop.order.
|
// Re-order prop.order.
|
||||||
sort.Sort(prop)
|
sort.Sort(prop)
|
||||||
|
|
||||||
var oots []interface{}
|
type oneofMessage interface {
|
||||||
switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {
|
XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
|
||||||
case oneofFuncsIface:
|
|
||||||
_, _, _, oots = m.XXX_OneofFuncs()
|
|
||||||
case oneofWrappersIface:
|
|
||||||
oots = m.XXX_OneofWrappers()
|
|
||||||
}
|
}
|
||||||
if len(oots) > 0 {
|
if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok {
|
||||||
|
var oots []interface{}
|
||||||
|
_, _, _, oots = om.XXX_OneofFuncs()
|
||||||
|
|
||||||
// Interpret oneof metadata.
|
// Interpret oneof metadata.
|
||||||
prop.OneofTypes = make(map[string]*OneofProperties)
|
prop.OneofTypes = make(map[string]*OneofProperties)
|
||||||
for _, oot := range oots {
|
for _, oot := range oots {
|
||||||
|
45
vendor/github.com/golang/protobuf/proto/table_marshal.go
generated
vendored
45
vendor/github.com/golang/protobuf/proto/table_marshal.go
generated
vendored
@ -87,7 +87,6 @@ type marshalElemInfo struct {
|
|||||||
sizer sizer
|
sizer sizer
|
||||||
marshaler marshaler
|
marshaler marshaler
|
||||||
isptr bool // elem is pointer typed, thus interface of this type is a direct interface (extension only)
|
isptr bool // elem is pointer typed, thus interface of this type is a direct interface (extension only)
|
||||||
deref bool // dereference the pointer before operating on it; implies isptr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -321,11 +320,8 @@ func (u *marshalInfo) computeMarshalInfo() {
|
|||||||
|
|
||||||
// get oneof implementers
|
// get oneof implementers
|
||||||
var oneofImplementers []interface{}
|
var oneofImplementers []interface{}
|
||||||
switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {
|
if m, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok {
|
||||||
case oneofFuncsIface:
|
|
||||||
_, _, _, oneofImplementers = m.XXX_OneofFuncs()
|
_, _, _, oneofImplementers = m.XXX_OneofFuncs()
|
||||||
case oneofWrappersIface:
|
|
||||||
oneofImplementers = m.XXX_OneofWrappers()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
n := t.NumField()
|
n := t.NumField()
|
||||||
@ -411,22 +407,13 @@ func (u *marshalInfo) getExtElemInfo(desc *ExtensionDesc) *marshalElemInfo {
|
|||||||
panic("tag is not an integer")
|
panic("tag is not an integer")
|
||||||
}
|
}
|
||||||
wt := wiretype(tags[0])
|
wt := wiretype(tags[0])
|
||||||
if t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct {
|
|
||||||
t = t.Elem()
|
|
||||||
}
|
|
||||||
sizer, marshaler := typeMarshaler(t, tags, false, false)
|
sizer, marshaler := typeMarshaler(t, tags, false, false)
|
||||||
var deref bool
|
|
||||||
if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 {
|
|
||||||
t = reflect.PtrTo(t)
|
|
||||||
deref = true
|
|
||||||
}
|
|
||||||
e = &marshalElemInfo{
|
e = &marshalElemInfo{
|
||||||
wiretag: uint64(tag)<<3 | wt,
|
wiretag: uint64(tag)<<3 | wt,
|
||||||
tagsize: SizeVarint(uint64(tag) << 3),
|
tagsize: SizeVarint(uint64(tag) << 3),
|
||||||
sizer: sizer,
|
sizer: sizer,
|
||||||
marshaler: marshaler,
|
marshaler: marshaler,
|
||||||
isptr: t.Kind() == reflect.Ptr,
|
isptr: t.Kind() == reflect.Ptr,
|
||||||
deref: deref,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// update cache
|
// update cache
|
||||||
@ -461,7 +448,7 @@ func (fi *marshalFieldInfo) computeMarshalFieldInfo(f *reflect.StructField) {
|
|||||||
|
|
||||||
func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) {
|
func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) {
|
||||||
fi.field = toField(f)
|
fi.field = toField(f)
|
||||||
fi.wiretag = math.MaxInt32 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire.
|
fi.wiretag = 1<<31 - 1 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire.
|
||||||
fi.isPointer = true
|
fi.isPointer = true
|
||||||
fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f)
|
fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f)
|
||||||
fi.oneofElems = make(map[reflect.Type]*marshalElemInfo)
|
fi.oneofElems = make(map[reflect.Type]*marshalElemInfo)
|
||||||
@ -489,6 +476,10 @@ func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type oneofMessage interface {
|
||||||
|
XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
|
||||||
|
}
|
||||||
|
|
||||||
// wiretype returns the wire encoding of the type.
|
// wiretype returns the wire encoding of the type.
|
||||||
func wiretype(encoding string) uint64 {
|
func wiretype(encoding string) uint64 {
|
||||||
switch encoding {
|
switch encoding {
|
||||||
@ -2319,8 +2310,8 @@ func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) {
|
|||||||
for _, k := range m.MapKeys() {
|
for _, k := range m.MapKeys() {
|
||||||
ki := k.Interface()
|
ki := k.Interface()
|
||||||
vi := m.MapIndex(k).Interface()
|
vi := m.MapIndex(k).Interface()
|
||||||
kaddr := toAddrPointer(&ki, false, false) // pointer to key
|
kaddr := toAddrPointer(&ki, false) // pointer to key
|
||||||
vaddr := toAddrPointer(&vi, valIsPtr, false) // pointer to value
|
vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value
|
||||||
siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
|
siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
|
||||||
n += siz + SizeVarint(uint64(siz)) + tagsize
|
n += siz + SizeVarint(uint64(siz)) + tagsize
|
||||||
}
|
}
|
||||||
@ -2338,8 +2329,8 @@ func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) {
|
|||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
ki := k.Interface()
|
ki := k.Interface()
|
||||||
vi := m.MapIndex(k).Interface()
|
vi := m.MapIndex(k).Interface()
|
||||||
kaddr := toAddrPointer(&ki, false, false) // pointer to key
|
kaddr := toAddrPointer(&ki, false) // pointer to key
|
||||||
vaddr := toAddrPointer(&vi, valIsPtr, false) // pointer to value
|
vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value
|
||||||
b = appendVarint(b, tag)
|
b = appendVarint(b, tag)
|
||||||
siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
|
siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
|
||||||
b = appendVarint(b, uint64(siz))
|
b = appendVarint(b, uint64(siz))
|
||||||
@ -2408,7 +2399,7 @@ func (u *marshalInfo) sizeExtensions(ext *XXX_InternalExtensions) int {
|
|||||||
// the last time this function was called.
|
// the last time this function was called.
|
||||||
ei := u.getExtElemInfo(e.desc)
|
ei := u.getExtElemInfo(e.desc)
|
||||||
v := e.value
|
v := e.value
|
||||||
p := toAddrPointer(&v, ei.isptr, ei.deref)
|
p := toAddrPointer(&v, ei.isptr)
|
||||||
n += ei.sizer(p, ei.tagsize)
|
n += ei.sizer(p, ei.tagsize)
|
||||||
}
|
}
|
||||||
mu.Unlock()
|
mu.Unlock()
|
||||||
@ -2443,7 +2434,7 @@ func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, de
|
|||||||
|
|
||||||
ei := u.getExtElemInfo(e.desc)
|
ei := u.getExtElemInfo(e.desc)
|
||||||
v := e.value
|
v := e.value
|
||||||
p := toAddrPointer(&v, ei.isptr, ei.deref)
|
p := toAddrPointer(&v, ei.isptr)
|
||||||
b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
|
b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
|
||||||
if !nerr.Merge(err) {
|
if !nerr.Merge(err) {
|
||||||
return b, err
|
return b, err
|
||||||
@ -2474,7 +2465,7 @@ func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, de
|
|||||||
|
|
||||||
ei := u.getExtElemInfo(e.desc)
|
ei := u.getExtElemInfo(e.desc)
|
||||||
v := e.value
|
v := e.value
|
||||||
p := toAddrPointer(&v, ei.isptr, ei.deref)
|
p := toAddrPointer(&v, ei.isptr)
|
||||||
b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
|
b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
|
||||||
if !nerr.Merge(err) {
|
if !nerr.Merge(err) {
|
||||||
return b, err
|
return b, err
|
||||||
@ -2519,7 +2510,7 @@ func (u *marshalInfo) sizeMessageSet(ext *XXX_InternalExtensions) int {
|
|||||||
|
|
||||||
ei := u.getExtElemInfo(e.desc)
|
ei := u.getExtElemInfo(e.desc)
|
||||||
v := e.value
|
v := e.value
|
||||||
p := toAddrPointer(&v, ei.isptr, ei.deref)
|
p := toAddrPointer(&v, ei.isptr)
|
||||||
n += ei.sizer(p, 1) // message, tag = 3 (size=1)
|
n += ei.sizer(p, 1) // message, tag = 3 (size=1)
|
||||||
}
|
}
|
||||||
mu.Unlock()
|
mu.Unlock()
|
||||||
@ -2562,7 +2553,7 @@ func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, de
|
|||||||
|
|
||||||
ei := u.getExtElemInfo(e.desc)
|
ei := u.getExtElemInfo(e.desc)
|
||||||
v := e.value
|
v := e.value
|
||||||
p := toAddrPointer(&v, ei.isptr, ei.deref)
|
p := toAddrPointer(&v, ei.isptr)
|
||||||
b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
|
b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
|
||||||
if !nerr.Merge(err) {
|
if !nerr.Merge(err) {
|
||||||
return b, err
|
return b, err
|
||||||
@ -2600,7 +2591,7 @@ func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, de
|
|||||||
|
|
||||||
ei := u.getExtElemInfo(e.desc)
|
ei := u.getExtElemInfo(e.desc)
|
||||||
v := e.value
|
v := e.value
|
||||||
p := toAddrPointer(&v, ei.isptr, ei.deref)
|
p := toAddrPointer(&v, ei.isptr)
|
||||||
b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
|
b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
|
||||||
b = append(b, 1<<3|WireEndGroup)
|
b = append(b, 1<<3|WireEndGroup)
|
||||||
if !nerr.Merge(err) {
|
if !nerr.Merge(err) {
|
||||||
@ -2630,7 +2621,7 @@ func (u *marshalInfo) sizeV1Extensions(m map[int32]Extension) int {
|
|||||||
|
|
||||||
ei := u.getExtElemInfo(e.desc)
|
ei := u.getExtElemInfo(e.desc)
|
||||||
v := e.value
|
v := e.value
|
||||||
p := toAddrPointer(&v, ei.isptr, ei.deref)
|
p := toAddrPointer(&v, ei.isptr)
|
||||||
n += ei.sizer(p, ei.tagsize)
|
n += ei.sizer(p, ei.tagsize)
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
@ -2665,7 +2656,7 @@ func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, determ
|
|||||||
|
|
||||||
ei := u.getExtElemInfo(e.desc)
|
ei := u.getExtElemInfo(e.desc)
|
||||||
v := e.value
|
v := e.value
|
||||||
p := toAddrPointer(&v, ei.isptr, ei.deref)
|
p := toAddrPointer(&v, ei.isptr)
|
||||||
b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
|
b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
|
||||||
if !nerr.Merge(err) {
|
if !nerr.Merge(err) {
|
||||||
return b, err
|
return b, err
|
||||||
|
24
vendor/github.com/golang/protobuf/proto/table_unmarshal.go
generated
vendored
24
vendor/github.com/golang/protobuf/proto/table_unmarshal.go
generated
vendored
@ -136,7 +136,7 @@ func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {
|
|||||||
u.computeUnmarshalInfo()
|
u.computeUnmarshalInfo()
|
||||||
}
|
}
|
||||||
if u.isMessageSet {
|
if u.isMessageSet {
|
||||||
return unmarshalMessageSet(b, m.offset(u.extensions).toExtensions())
|
return UnmarshalMessageSet(b, m.offset(u.extensions).toExtensions())
|
||||||
}
|
}
|
||||||
var reqMask uint64 // bitmask of required fields we've seen.
|
var reqMask uint64 // bitmask of required fields we've seen.
|
||||||
var errLater error
|
var errLater error
|
||||||
@ -362,15 +362,13 @@ func (u *unmarshalInfo) computeUnmarshalInfo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find any types associated with oneof fields.
|
// Find any types associated with oneof fields.
|
||||||
var oneofImplementers []interface{}
|
// TODO: XXX_OneofFuncs returns more info than we need. Get rid of some of it?
|
||||||
switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {
|
fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("XXX_OneofFuncs")
|
||||||
case oneofFuncsIface:
|
if fn.IsValid() {
|
||||||
_, _, _, oneofImplementers = m.XXX_OneofFuncs()
|
res := fn.Call(nil)[3] // last return value from XXX_OneofFuncs: []interface{}
|
||||||
case oneofWrappersIface:
|
for i := res.Len() - 1; i >= 0; i-- {
|
||||||
oneofImplementers = m.XXX_OneofWrappers()
|
v := res.Index(i) // interface{}
|
||||||
}
|
tptr := reflect.ValueOf(v.Interface()).Type() // *Msg_X
|
||||||
for _, v := range oneofImplementers {
|
|
||||||
tptr := reflect.TypeOf(v) // *Msg_X
|
|
||||||
typ := tptr.Elem() // Msg_X
|
typ := tptr.Elem() // Msg_X
|
||||||
|
|
||||||
f := typ.Field(0) // oneof implementers have one field
|
f := typ.Field(0) // oneof implementers have one field
|
||||||
@ -399,11 +397,11 @@ func (u *unmarshalInfo) computeUnmarshalInfo() {
|
|||||||
u.setTag(fieldNum, of.field, unmarshal, 0, name)
|
u.setTag(fieldNum, of.field, unmarshal, 0, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get extension ranges, if any.
|
// Get extension ranges, if any.
|
||||||
fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray")
|
fn = reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray")
|
||||||
if fn.IsValid() {
|
if fn.IsValid() {
|
||||||
if !u.extensions.IsValid() && !u.oldExtensions.IsValid() {
|
if !u.extensions.IsValid() && !u.oldExtensions.IsValid() {
|
||||||
panic("a message with extensions, but no extensions field in " + t.Name())
|
panic("a message with extensions, but no extensions field in " + t.Name())
|
||||||
@ -1950,7 +1948,7 @@ func encodeVarint(b []byte, x uint64) []byte {
|
|||||||
// If there is an error, it returns 0,0.
|
// If there is an error, it returns 0,0.
|
||||||
func decodeVarint(b []byte) (uint64, int) {
|
func decodeVarint(b []byte) (uint64, int) {
|
||||||
var x, y uint64
|
var x, y uint64
|
||||||
if len(b) == 0 {
|
if len(b) <= 0 {
|
||||||
goto bad
|
goto bad
|
||||||
}
|
}
|
||||||
x = uint64(b[0])
|
x = uint64(b[0])
|
||||||
|
14
vendor/github.com/gorilla/sessions/README.md
generated
vendored
14
vendor/github.com/gorilla/sessions/README.md
generated
vendored
@ -31,7 +31,7 @@ Let's start with an example that shows the sessions API in a nutshell:
|
|||||||
// environmental variable, or flag (or both), and don't accidentally commit it
|
// environmental variable, or flag (or both), and don't accidentally commit it
|
||||||
// alongside your code. Ensure your key is sufficiently random - i.e. use Go's
|
// alongside your code. Ensure your key is sufficiently random - i.e. use Go's
|
||||||
// crypto/rand or securecookie.GenerateRandomKey(32) and persist the result.
|
// crypto/rand or securecookie.GenerateRandomKey(32) and persist the result.
|
||||||
var store = sessions.NewCookieStore(os.Getenv("SESSION_KEY"))
|
var store = sessions.NewCookieStore([]byte(os.Getenv("SESSION_KEY")))
|
||||||
|
|
||||||
func MyHandler(w http.ResponseWriter, r *http.Request) {
|
func MyHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
// Get a session. We're ignoring the error resulted from decoding an
|
// Get a session. We're ignoring the error resulted from decoding an
|
||||||
@ -51,18 +51,6 @@ secret key used to authenticate the session. Inside the handler, we call
|
|||||||
some session values in session.Values, which is a `map[interface{}]interface{}`.
|
some session values in session.Values, which is a `map[interface{}]interface{}`.
|
||||||
And finally we call `session.Save()` to save the session in the response.
|
And finally we call `session.Save()` to save the session in the response.
|
||||||
|
|
||||||
Important Note: If you aren't using gorilla/mux, you need to wrap your handlers
|
|
||||||
with
|
|
||||||
[`context.ClearHandler`](https://www.gorillatoolkit.org/pkg/context#ClearHandler)
|
|
||||||
or else you will leak memory! An easy way to do this is to wrap the top-level
|
|
||||||
mux when calling http.ListenAndServe:
|
|
||||||
|
|
||||||
```go
|
|
||||||
http.ListenAndServe(":8080", context.ClearHandler(http.DefaultServeMux))
|
|
||||||
```
|
|
||||||
|
|
||||||
The ClearHandler function is provided by the gorilla/context package.
|
|
||||||
|
|
||||||
More examples are available [on the Gorilla
|
More examples are available [on the Gorilla
|
||||||
website](https://www.gorillatoolkit.org/pkg/sessions).
|
website](https://www.gorillatoolkit.org/pkg/sessions).
|
||||||
|
|
||||||
|
8
vendor/github.com/gorilla/sessions/doc.go
generated
vendored
8
vendor/github.com/gorilla/sessions/doc.go
generated
vendored
@ -59,14 +59,6 @@ session.Save(r, w), and either display an error message or otherwise handle it.
|
|||||||
Save must be called before writing to the response, otherwise the session
|
Save must be called before writing to the response, otherwise the session
|
||||||
cookie will not be sent to the client.
|
cookie will not be sent to the client.
|
||||||
|
|
||||||
Important Note: If you aren't using gorilla/mux, you need to wrap your handlers
|
|
||||||
with context.ClearHandler as or else you will leak memory! An easy way to do this
|
|
||||||
is to wrap the top-level mux when calling http.ListenAndServe:
|
|
||||||
|
|
||||||
http.ListenAndServe(":8080", context.ClearHandler(http.DefaultServeMux))
|
|
||||||
|
|
||||||
The ClearHandler function is provided by the gorilla/context package.
|
|
||||||
|
|
||||||
That's all you need to know for the basic usage. Let's take a look at other
|
That's all you need to know for the basic usage. Let's take a look at other
|
||||||
options, starting with flash messages.
|
options, starting with flash messages.
|
||||||
|
|
||||||
|
8
vendor/github.com/gorilla/sessions/sessions.go
generated
vendored
8
vendor/github.com/gorilla/sessions/sessions.go
generated
vendored
@ -5,12 +5,11 @@
|
|||||||
package sessions
|
package sessions
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/context"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Default flashes key.
|
// Default flashes key.
|
||||||
@ -108,7 +107,8 @@ const registryKey contextKey = 0
|
|||||||
|
|
||||||
// GetRegistry returns a registry instance for the current request.
|
// GetRegistry returns a registry instance for the current request.
|
||||||
func GetRegistry(r *http.Request) *Registry {
|
func GetRegistry(r *http.Request) *Registry {
|
||||||
registry := context.Get(r, registryKey)
|
var ctx = r.Context()
|
||||||
|
registry := ctx.Value(registryKey)
|
||||||
if registry != nil {
|
if registry != nil {
|
||||||
return registry.(*Registry)
|
return registry.(*Registry)
|
||||||
}
|
}
|
||||||
@ -116,7 +116,7 @@ func GetRegistry(r *http.Request) *Registry {
|
|||||||
request: r,
|
request: r,
|
||||||
sessions: make(map[string]sessionInfo),
|
sessions: make(map[string]sessionInfo),
|
||||||
}
|
}
|
||||||
context.Set(r, registryKey, newRegistry)
|
*r = *r.WithContext(context.WithValue(ctx, registryKey, newRegistry))
|
||||||
return newRegistry
|
return newRegistry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
21
vendor/github.com/json-iterator/go/Gopkg.lock
generated
vendored
Normal file
21
vendor/github.com/json-iterator/go/Gopkg.lock
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||||
|
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/modern-go/concurrent"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "e0a39a4cb4216ea8db28e22a69f4ec25610d513a"
|
||||||
|
version = "1.0.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/modern-go/reflect2"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd"
|
||||||
|
version = "1.0.1"
|
||||||
|
|
||||||
|
[solve-meta]
|
||||||
|
analyzer-name = "dep"
|
||||||
|
analyzer-version = 1
|
||||||
|
inputs-digest = "ea54a775e5a354cb015502d2e7aa4b74230fc77e894f34a838b268c25ec8eeb8"
|
||||||
|
solver-name = "gps-cdcl"
|
||||||
|
solver-version = 1
|
26
vendor/github.com/json-iterator/go/Gopkg.toml
generated
vendored
Normal file
26
vendor/github.com/json-iterator/go/Gopkg.toml
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Gopkg.toml example
|
||||||
|
#
|
||||||
|
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||||
|
# for detailed Gopkg.toml documentation.
|
||||||
|
#
|
||||||
|
# required = ["github.com/user/thing/cmd/thing"]
|
||||||
|
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||||
|
#
|
||||||
|
# [[constraint]]
|
||||||
|
# name = "github.com/user/project"
|
||||||
|
# version = "1.0.0"
|
||||||
|
#
|
||||||
|
# [[constraint]]
|
||||||
|
# name = "github.com/user/project2"
|
||||||
|
# branch = "dev"
|
||||||
|
# source = "github.com/myfork/project2"
|
||||||
|
#
|
||||||
|
# [[override]]
|
||||||
|
# name = "github.com/x/y"
|
||||||
|
# version = "2.4.0"
|
||||||
|
|
||||||
|
ignored = ["github.com/davecgh/go-spew*","github.com/google/gofuzz*","github.com/stretchr/testify*"]
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/modern-go/reflect2"
|
||||||
|
version = "1.0.1"
|
21
vendor/github.com/json-iterator/go/LICENSE
generated
vendored
Normal file
21
vendor/github.com/json-iterator/go/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2016 json-iterator
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
91
vendor/github.com/json-iterator/go/README.md
generated
vendored
Normal file
91
vendor/github.com/json-iterator/go/README.md
generated
vendored
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
[](https://sourcegraph.com/github.com/json-iterator/go?badge)
|
||||||
|
[](http://godoc.org/github.com/json-iterator/go)
|
||||||
|
[](https://travis-ci.org/json-iterator/go)
|
||||||
|
[](https://codecov.io/gh/json-iterator/go)
|
||||||
|
[](https://goreportcard.com/report/github.com/json-iterator/go)
|
||||||
|
[](https://raw.githubusercontent.com/json-iterator/go/master/LICENSE)
|
||||||
|
[](https://gitter.im/json-iterator/Lobby)
|
||||||
|
|
||||||
|
A high-performance 100% compatible drop-in replacement of "encoding/json"
|
||||||
|
|
||||||
|
You can also use thrift like JSON using [thrift-iterator](https://github.com/thrift-iterator/go)
|
||||||
|
|
||||||
|
```
|
||||||
|
Go开发者们请加入我们,滴滴出行平台技术部 taowen@didichuxing.com
|
||||||
|
```
|
||||||
|
|
||||||
|
# Benchmark
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Source code: https://github.com/json-iterator/go-benchmark/blob/master/src/github.com/json-iterator/go-benchmark/benchmark_medium_payload_test.go
|
||||||
|
|
||||||
|
Raw Result (easyjson requires static code generation)
|
||||||
|
|
||||||
|
| | ns/op | allocation bytes | allocation times |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| std decode | 35510 ns/op | 1960 B/op | 99 allocs/op |
|
||||||
|
| easyjson decode | 8499 ns/op | 160 B/op | 4 allocs/op |
|
||||||
|
| jsoniter decode | 5623 ns/op | 160 B/op | 3 allocs/op |
|
||||||
|
| std encode | 2213 ns/op | 712 B/op | 5 allocs/op |
|
||||||
|
| easyjson encode | 883 ns/op | 576 B/op | 3 allocs/op |
|
||||||
|
| jsoniter encode | 837 ns/op | 384 B/op | 4 allocs/op |
|
||||||
|
|
||||||
|
Always benchmark with your own workload.
|
||||||
|
The result depends heavily on the data input.
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
100% compatibility with standard lib
|
||||||
|
|
||||||
|
Replace
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "encoding/json"
|
||||||
|
json.Marshal(&data)
|
||||||
|
```
|
||||||
|
|
||||||
|
with
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/json-iterator/go"
|
||||||
|
|
||||||
|
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||||
|
json.Marshal(&data)
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "encoding/json"
|
||||||
|
json.Unmarshal(input, &data)
|
||||||
|
```
|
||||||
|
|
||||||
|
with
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/json-iterator/go"
|
||||||
|
|
||||||
|
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||||
|
json.Unmarshal(input, &data)
|
||||||
|
```
|
||||||
|
|
||||||
|
[More documentation](http://jsoniter.com/migrate-from-go-std.html)
|
||||||
|
|
||||||
|
# How to get
|
||||||
|
|
||||||
|
```
|
||||||
|
go get github.com/json-iterator/go
|
||||||
|
```
|
||||||
|
|
||||||
|
# Contribution Welcomed !
|
||||||
|
|
||||||
|
Contributors
|
||||||
|
|
||||||
|
* [thockin](https://github.com/thockin)
|
||||||
|
* [mattn](https://github.com/mattn)
|
||||||
|
* [cch123](https://github.com/cch123)
|
||||||
|
* [Oleg Shaldybin](https://github.com/olegshaldybin)
|
||||||
|
* [Jason Toffaletti](https://github.com/toffaletti)
|
||||||
|
|
||||||
|
Report issue or pull request, or email taowen@gmail.com, or [](https://gitter.im/json-iterator/Lobby)
|
150
vendor/github.com/json-iterator/go/adapter.go
generated
vendored
Normal file
150
vendor/github.com/json-iterator/go/adapter.go
generated
vendored
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
package jsoniter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RawMessage to make replace json with jsoniter
|
||||||
|
type RawMessage []byte
|
||||||
|
|
||||||
|
// Unmarshal adapts to json/encoding Unmarshal API
|
||||||
|
//
|
||||||
|
// Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v.
|
||||||
|
// Refer to https://godoc.org/encoding/json#Unmarshal for more information
|
||||||
|
func Unmarshal(data []byte, v interface{}) error {
|
||||||
|
return ConfigDefault.Unmarshal(data, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalFromString convenient method to read from string instead of []byte
|
||||||
|
func UnmarshalFromString(str string, v interface{}) error {
|
||||||
|
return ConfigDefault.UnmarshalFromString(str, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get quick method to get value from deeply nested JSON structure
|
||||||
|
func Get(data []byte, path ...interface{}) Any {
|
||||||
|
return ConfigDefault.Get(data, path...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marshal adapts to json/encoding Marshal API
|
||||||
|
//
|
||||||
|
// Marshal returns the JSON encoding of v, adapts to json/encoding Marshal API
|
||||||
|
// Refer to https://godoc.org/encoding/json#Marshal for more information
|
||||||
|
func Marshal(v interface{}) ([]byte, error) {
|
||||||
|
return ConfigDefault.Marshal(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalIndent same as json.MarshalIndent. Prefix is not supported.
|
||||||
|
func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
|
||||||
|
return ConfigDefault.MarshalIndent(v, prefix, indent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalToString convenient method to write as string instead of []byte
|
||||||
|
func MarshalToString(v interface{}) (string, error) {
|
||||||
|
return ConfigDefault.MarshalToString(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDecoder adapts to json/stream NewDecoder API.
|
||||||
|
//
|
||||||
|
// NewDecoder returns a new decoder that reads from r.
|
||||||
|
//
|
||||||
|
// Instead of a json/encoding Decoder, an Decoder is returned
|
||||||
|
// Refer to https://godoc.org/encoding/json#NewDecoder for more information
|
||||||
|
func NewDecoder(reader io.Reader) *Decoder {
|
||||||
|
return ConfigDefault.NewDecoder(reader)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decoder reads and decodes JSON values from an input stream.
|
||||||
|
// Decoder provides identical APIs with json/stream Decoder (Token() and UseNumber() are in progress)
|
||||||
|
type Decoder struct {
|
||||||
|
iter *Iterator
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode decode JSON into interface{}
|
||||||
|
func (adapter *Decoder) Decode(obj interface{}) error {
|
||||||
|
if adapter.iter.head == adapter.iter.tail && adapter.iter.reader != nil {
|
||||||
|
if !adapter.iter.loadMore() {
|
||||||
|
return io.EOF
|
||||||
|
}
|
||||||
|
}
|
||||||
|
adapter.iter.ReadVal(obj)
|
||||||
|
err := adapter.iter.Error
|
||||||
|
if err == io.EOF {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return adapter.iter.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// More is there more?
|
||||||
|
func (adapter *Decoder) More() bool {
|
||||||
|
iter := adapter.iter
|
||||||
|
if iter.Error != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
c := iter.nextToken()
|
||||||
|
if c == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
iter.unreadByte()
|
||||||
|
return c != ']' && c != '}'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffered remaining buffer
|
||||||
|
func (adapter *Decoder) Buffered() io.Reader {
|
||||||
|
remaining := adapter.iter.buf[adapter.iter.head:adapter.iter.tail]
|
||||||
|
return bytes.NewReader(remaining)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UseNumber causes the Decoder to unmarshal a number into an interface{} as a
|
||||||
|
// Number instead of as a float64.
|
||||||
|
func (adapter *Decoder) UseNumber() {
|
||||||
|
cfg := adapter.iter.cfg.configBeforeFrozen
|
||||||
|
cfg.UseNumber = true
|
||||||
|
adapter.iter.cfg = cfg.frozeWithCacheReuse(adapter.iter.cfg.extraExtensions)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisallowUnknownFields causes the Decoder to return an error when the destination
|
||||||
|
// is a struct and the input contains object keys which do not match any
|
||||||
|
// non-ignored, exported fields in the destination.
|
||||||
|
func (adapter *Decoder) DisallowUnknownFields() {
|
||||||
|
cfg := adapter.iter.cfg.configBeforeFrozen
|
||||||
|
cfg.DisallowUnknownFields = true
|
||||||
|
adapter.iter.cfg = cfg.frozeWithCacheReuse(adapter.iter.cfg.extraExtensions)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEncoder same as json.NewEncoder
|
||||||
|
func NewEncoder(writer io.Writer) *Encoder {
|
||||||
|
return ConfigDefault.NewEncoder(writer)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encoder same as json.Encoder
|
||||||
|
type Encoder struct {
|
||||||
|
stream *Stream
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode encode interface{} as JSON to io.Writer
|
||||||
|
func (adapter *Encoder) Encode(val interface{}) error {
|
||||||
|
adapter.stream.WriteVal(val)
|
||||||
|
adapter.stream.WriteRaw("\n")
|
||||||
|
adapter.stream.Flush()
|
||||||
|
return adapter.stream.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetIndent set the indention. Prefix is not supported
|
||||||
|
func (adapter *Encoder) SetIndent(prefix, indent string) {
|
||||||
|
config := adapter.stream.cfg.configBeforeFrozen
|
||||||
|
config.IndentionStep = len(indent)
|
||||||
|
adapter.stream.cfg = config.frozeWithCacheReuse(adapter.stream.cfg.extraExtensions)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetEscapeHTML escape html by default, set to false to disable
|
||||||
|
func (adapter *Encoder) SetEscapeHTML(escapeHTML bool) {
|
||||||
|
config := adapter.stream.cfg.configBeforeFrozen
|
||||||
|
config.EscapeHTML = escapeHTML
|
||||||
|
adapter.stream.cfg = config.frozeWithCacheReuse(adapter.stream.cfg.extraExtensions)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid reports whether data is a valid JSON encoding.
|
||||||
|
func Valid(data []byte) bool {
|
||||||
|
return ConfigDefault.Valid(data)
|
||||||
|
}
|
321
vendor/github.com/json-iterator/go/any.go
generated
vendored
Normal file
321
vendor/github.com/json-iterator/go/any.go
generated
vendored
Normal file
@ -0,0 +1,321 @@
|
|||||||
|
package jsoniter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Any generic object representation.
|
||||||
|
// The lazy json implementation holds []byte and parse lazily.
|
||||||
|
type Any interface {
|
||||||
|
LastError() error
|
||||||
|
ValueType() ValueType
|
||||||
|
MustBeValid() Any
|
||||||
|
ToBool() bool
|
||||||
|
ToInt() int
|
||||||
|
ToInt32() int32
|
||||||
|
ToInt64() int64
|
||||||
|
ToUint() uint
|
||||||
|
ToUint32() uint32
|
||||||
|
ToUint64() uint64
|
||||||
|
ToFloat32() float32
|
||||||
|
ToFloat64() float64
|
||||||
|
ToString() string
|
||||||
|
ToVal(val interface{})
|
||||||
|
Get(path ...interface{}) Any
|
||||||
|
Size() int
|
||||||
|
Keys() []string
|
||||||
|
GetInterface() interface{}
|
||||||
|
WriteTo(stream *Stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
type baseAny struct{}
|
||||||
|
|
||||||
|
func (any *baseAny) Get(path ...interface{}) Any {
|
||||||
|
return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *baseAny) Size() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *baseAny) Keys() []string {
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *baseAny) ToVal(obj interface{}) {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// WrapInt32 turn int32 into Any interface
|
||||||
|
func WrapInt32(val int32) Any {
|
||||||
|
return &int32Any{baseAny{}, val}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WrapInt64 turn int64 into Any interface
|
||||||
|
func WrapInt64(val int64) Any {
|
||||||
|
return &int64Any{baseAny{}, val}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WrapUint32 turn uint32 into Any interface
|
||||||
|
func WrapUint32(val uint32) Any {
|
||||||
|
return &uint32Any{baseAny{}, val}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WrapUint64 turn uint64 into Any interface
|
||||||
|
func WrapUint64(val uint64) Any {
|
||||||
|
return &uint64Any{baseAny{}, val}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WrapFloat64 turn float64 into Any interface
|
||||||
|
func WrapFloat64(val float64) Any {
|
||||||
|
return &floatAny{baseAny{}, val}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WrapString turn string into Any interface
|
||||||
|
func WrapString(val string) Any {
|
||||||
|
return &stringAny{baseAny{}, val}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap turn a go object into Any interface
|
||||||
|
func Wrap(val interface{}) Any {
|
||||||
|
if val == nil {
|
||||||
|
return &nilAny{}
|
||||||
|
}
|
||||||
|
asAny, isAny := val.(Any)
|
||||||
|
if isAny {
|
||||||
|
return asAny
|
||||||
|
}
|
||||||
|
typ := reflect2.TypeOf(val)
|
||||||
|
switch typ.Kind() {
|
||||||
|
case reflect.Slice:
|
||||||
|
return wrapArray(val)
|
||||||
|
case reflect.Struct:
|
||||||
|
return wrapStruct(val)
|
||||||
|
case reflect.Map:
|
||||||
|
return wrapMap(val)
|
||||||
|
case reflect.String:
|
||||||
|
return WrapString(val.(string))
|
||||||
|
case reflect.Int:
|
||||||
|
if strconv.IntSize == 32 {
|
||||||
|
return WrapInt32(int32(val.(int)))
|
||||||
|
}
|
||||||
|
return WrapInt64(int64(val.(int)))
|
||||||
|
case reflect.Int8:
|
||||||
|
return WrapInt32(int32(val.(int8)))
|
||||||
|
case reflect.Int16:
|
||||||
|
return WrapInt32(int32(val.(int16)))
|
||||||
|
case reflect.Int32:
|
||||||
|
return WrapInt32(val.(int32))
|
||||||
|
case reflect.Int64:
|
||||||
|
return WrapInt64(val.(int64))
|
||||||
|
case reflect.Uint:
|
||||||
|
if strconv.IntSize == 32 {
|
||||||
|
return WrapUint32(uint32(val.(uint)))
|
||||||
|
}
|
||||||
|
return WrapUint64(uint64(val.(uint)))
|
||||||
|
case reflect.Uintptr:
|
||||||
|
if ptrSize == 32 {
|
||||||
|
return WrapUint32(uint32(val.(uintptr)))
|
||||||
|
}
|
||||||
|
return WrapUint64(uint64(val.(uintptr)))
|
||||||
|
case reflect.Uint8:
|
||||||
|
return WrapUint32(uint32(val.(uint8)))
|
||||||
|
case reflect.Uint16:
|
||||||
|
return WrapUint32(uint32(val.(uint16)))
|
||||||
|
case reflect.Uint32:
|
||||||
|
return WrapUint32(uint32(val.(uint32)))
|
||||||
|
case reflect.Uint64:
|
||||||
|
return WrapUint64(val.(uint64))
|
||||||
|
case reflect.Float32:
|
||||||
|
return WrapFloat64(float64(val.(float32)))
|
||||||
|
case reflect.Float64:
|
||||||
|
return WrapFloat64(val.(float64))
|
||||||
|
case reflect.Bool:
|
||||||
|
if val.(bool) == true {
|
||||||
|
return &trueAny{}
|
||||||
|
}
|
||||||
|
return &falseAny{}
|
||||||
|
}
|
||||||
|
return &invalidAny{baseAny{}, fmt.Errorf("unsupported type: %v", typ)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadAny read next JSON element as an Any object. It is a better json.RawMessage.
|
||||||
|
func (iter *Iterator) ReadAny() Any {
|
||||||
|
return iter.readAny()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) readAny() Any {
|
||||||
|
c := iter.nextToken()
|
||||||
|
switch c {
|
||||||
|
case '"':
|
||||||
|
iter.unreadByte()
|
||||||
|
return &stringAny{baseAny{}, iter.ReadString()}
|
||||||
|
case 'n':
|
||||||
|
iter.skipThreeBytes('u', 'l', 'l') // null
|
||||||
|
return &nilAny{}
|
||||||
|
case 't':
|
||||||
|
iter.skipThreeBytes('r', 'u', 'e') // true
|
||||||
|
return &trueAny{}
|
||||||
|
case 'f':
|
||||||
|
iter.skipFourBytes('a', 'l', 's', 'e') // false
|
||||||
|
return &falseAny{}
|
||||||
|
case '{':
|
||||||
|
return iter.readObjectAny()
|
||||||
|
case '[':
|
||||||
|
return iter.readArrayAny()
|
||||||
|
case '-':
|
||||||
|
return iter.readNumberAny(false)
|
||||||
|
case 0:
|
||||||
|
return &invalidAny{baseAny{}, errors.New("input is empty")}
|
||||||
|
default:
|
||||||
|
return iter.readNumberAny(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) readNumberAny(positive bool) Any {
|
||||||
|
iter.startCapture(iter.head - 1)
|
||||||
|
iter.skipNumber()
|
||||||
|
lazyBuf := iter.stopCapture()
|
||||||
|
return &numberLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) readObjectAny() Any {
|
||||||
|
iter.startCapture(iter.head - 1)
|
||||||
|
iter.skipObject()
|
||||||
|
lazyBuf := iter.stopCapture()
|
||||||
|
return &objectLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) readArrayAny() Any {
|
||||||
|
iter.startCapture(iter.head - 1)
|
||||||
|
iter.skipArray()
|
||||||
|
lazyBuf := iter.stopCapture()
|
||||||
|
return &arrayLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
|
||||||
|
}
|
||||||
|
|
||||||
|
func locateObjectField(iter *Iterator, target string) []byte {
|
||||||
|
var found []byte
|
||||||
|
iter.ReadObjectCB(func(iter *Iterator, field string) bool {
|
||||||
|
if field == target {
|
||||||
|
found = iter.SkipAndReturnBytes()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
iter.Skip()
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return found
|
||||||
|
}
|
||||||
|
|
||||||
|
func locateArrayElement(iter *Iterator, target int) []byte {
|
||||||
|
var found []byte
|
||||||
|
n := 0
|
||||||
|
iter.ReadArrayCB(func(iter *Iterator) bool {
|
||||||
|
if n == target {
|
||||||
|
found = iter.SkipAndReturnBytes()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
iter.Skip()
|
||||||
|
n++
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return found
|
||||||
|
}
|
||||||
|
|
||||||
|
func locatePath(iter *Iterator, path []interface{}) Any {
|
||||||
|
for i, pathKeyObj := range path {
|
||||||
|
switch pathKey := pathKeyObj.(type) {
|
||||||
|
case string:
|
||||||
|
valueBytes := locateObjectField(iter, pathKey)
|
||||||
|
if valueBytes == nil {
|
||||||
|
return newInvalidAny(path[i:])
|
||||||
|
}
|
||||||
|
iter.ResetBytes(valueBytes)
|
||||||
|
case int:
|
||||||
|
valueBytes := locateArrayElement(iter, pathKey)
|
||||||
|
if valueBytes == nil {
|
||||||
|
return newInvalidAny(path[i:])
|
||||||
|
}
|
||||||
|
iter.ResetBytes(valueBytes)
|
||||||
|
case int32:
|
||||||
|
if '*' == pathKey {
|
||||||
|
return iter.readAny().Get(path[i:]...)
|
||||||
|
}
|
||||||
|
return newInvalidAny(path[i:])
|
||||||
|
default:
|
||||||
|
return newInvalidAny(path[i:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
|
return &invalidAny{baseAny{}, iter.Error}
|
||||||
|
}
|
||||||
|
return iter.readAny()
|
||||||
|
}
|
||||||
|
|
||||||
|
var anyType = reflect2.TypeOfPtr((*Any)(nil)).Elem()
|
||||||
|
|
||||||
|
func createDecoderOfAny(ctx *ctx, typ reflect2.Type) ValDecoder {
|
||||||
|
if typ == anyType {
|
||||||
|
return &directAnyCodec{}
|
||||||
|
}
|
||||||
|
if typ.Implements(anyType) {
|
||||||
|
return &anyCodec{
|
||||||
|
valType: typ,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createEncoderOfAny(ctx *ctx, typ reflect2.Type) ValEncoder {
|
||||||
|
if typ == anyType {
|
||||||
|
return &directAnyCodec{}
|
||||||
|
}
|
||||||
|
if typ.Implements(anyType) {
|
||||||
|
return &anyCodec{
|
||||||
|
valType: typ,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type anyCodec struct {
|
||||||
|
valType reflect2.Type
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *anyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *anyCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
|
||||||
|
obj := codec.valType.UnsafeIndirect(ptr)
|
||||||
|
any := obj.(Any)
|
||||||
|
any.WriteTo(stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *anyCodec) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
obj := codec.valType.UnsafeIndirect(ptr)
|
||||||
|
any := obj.(Any)
|
||||||
|
return any.Size() == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type directAnyCodec struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *directAnyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||||
|
*(*Any)(ptr) = iter.readAny()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *directAnyCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
|
||||||
|
any := *(*Any)(ptr)
|
||||||
|
any.WriteTo(stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *directAnyCodec) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
any := *(*Any)(ptr)
|
||||||
|
return any.Size() == 0
|
||||||
|
}
|
278
vendor/github.com/json-iterator/go/any_array.go
generated
vendored
Normal file
278
vendor/github.com/json-iterator/go/any_array.go
generated
vendored
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
package jsoniter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
type arrayLazyAny struct {
|
||||||
|
baseAny
|
||||||
|
cfg *frozenConfig
|
||||||
|
buf []byte
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) ValueType() ValueType {
|
||||||
|
return ArrayValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) MustBeValid() Any {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) LastError() error {
|
||||||
|
return any.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) ToBool() bool {
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
return iter.ReadArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) ToInt() int {
|
||||||
|
if any.ToBool() {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) ToInt32() int32 {
|
||||||
|
if any.ToBool() {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) ToInt64() int64 {
|
||||||
|
if any.ToBool() {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) ToUint() uint {
|
||||||
|
if any.ToBool() {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) ToUint32() uint32 {
|
||||||
|
if any.ToBool() {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) ToUint64() uint64 {
|
||||||
|
if any.ToBool() {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) ToFloat32() float32 {
|
||||||
|
if any.ToBool() {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) ToFloat64() float64 {
|
||||||
|
if any.ToBool() {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) ToString() string {
|
||||||
|
return *(*string)(unsafe.Pointer(&any.buf))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) ToVal(val interface{}) {
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
iter.ReadVal(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) Get(path ...interface{}) Any {
|
||||||
|
if len(path) == 0 {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
switch firstPath := path[0].(type) {
|
||||||
|
case int:
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
valueBytes := locateArrayElement(iter, firstPath)
|
||||||
|
if valueBytes == nil {
|
||||||
|
return newInvalidAny(path)
|
||||||
|
}
|
||||||
|
iter.ResetBytes(valueBytes)
|
||||||
|
return locatePath(iter, path[1:])
|
||||||
|
case int32:
|
||||||
|
if '*' == firstPath {
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
arr := make([]Any, 0)
|
||||||
|
iter.ReadArrayCB(func(iter *Iterator) bool {
|
||||||
|
found := iter.readAny().Get(path[1:]...)
|
||||||
|
if found.ValueType() != InvalidValue {
|
||||||
|
arr = append(arr, found)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return wrapArray(arr)
|
||||||
|
}
|
||||||
|
return newInvalidAny(path)
|
||||||
|
default:
|
||||||
|
return newInvalidAny(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) Size() int {
|
||||||
|
size := 0
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
iter.ReadArrayCB(func(iter *Iterator) bool {
|
||||||
|
size++
|
||||||
|
iter.Skip()
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) WriteTo(stream *Stream) {
|
||||||
|
stream.Write(any.buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) GetInterface() interface{} {
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
return iter.Read()
|
||||||
|
}
|
||||||
|
|
||||||
|
type arrayAny struct {
|
||||||
|
baseAny
|
||||||
|
val reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func wrapArray(val interface{}) *arrayAny {
|
||||||
|
return &arrayAny{baseAny{}, reflect.ValueOf(val)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayAny) ValueType() ValueType {
|
||||||
|
return ArrayValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayAny) MustBeValid() Any {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayAny) LastError() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayAny) ToBool() bool {
|
||||||
|
return any.val.Len() != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayAny) ToInt() int {
|
||||||
|
if any.val.Len() == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayAny) ToInt32() int32 {
|
||||||
|
if any.val.Len() == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayAny) ToInt64() int64 {
|
||||||
|
if any.val.Len() == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayAny) ToUint() uint {
|
||||||
|
if any.val.Len() == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayAny) ToUint32() uint32 {
|
||||||
|
if any.val.Len() == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayAny) ToUint64() uint64 {
|
||||||
|
if any.val.Len() == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayAny) ToFloat32() float32 {
|
||||||
|
if any.val.Len() == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayAny) ToFloat64() float64 {
|
||||||
|
if any.val.Len() == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayAny) ToString() string {
|
||||||
|
str, _ := MarshalToString(any.val.Interface())
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayAny) Get(path ...interface{}) Any {
|
||||||
|
if len(path) == 0 {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
switch firstPath := path[0].(type) {
|
||||||
|
case int:
|
||||||
|
if firstPath < 0 || firstPath >= any.val.Len() {
|
||||||
|
return newInvalidAny(path)
|
||||||
|
}
|
||||||
|
return Wrap(any.val.Index(firstPath).Interface())
|
||||||
|
case int32:
|
||||||
|
if '*' == firstPath {
|
||||||
|
mappedAll := make([]Any, 0)
|
||||||
|
for i := 0; i < any.val.Len(); i++ {
|
||||||
|
mapped := Wrap(any.val.Index(i).Interface()).Get(path[1:]...)
|
||||||
|
if mapped.ValueType() != InvalidValue {
|
||||||
|
mappedAll = append(mappedAll, mapped)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return wrapArray(mappedAll)
|
||||||
|
}
|
||||||
|
return newInvalidAny(path)
|
||||||
|
default:
|
||||||
|
return newInvalidAny(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayAny) Size() int {
|
||||||
|
return any.val.Len()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayAny) WriteTo(stream *Stream) {
|
||||||
|
stream.WriteVal(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *arrayAny) GetInterface() interface{} {
|
||||||
|
return any.val.Interface()
|
||||||
|
}
|
137
vendor/github.com/json-iterator/go/any_bool.go
generated
vendored
Normal file
137
vendor/github.com/json-iterator/go/any_bool.go
generated
vendored
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
package jsoniter
|
||||||
|
|
||||||
|
type trueAny struct {
|
||||||
|
baseAny
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *trueAny) LastError() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *trueAny) ToBool() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *trueAny) ToInt() int {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *trueAny) ToInt32() int32 {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *trueAny) ToInt64() int64 {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *trueAny) ToUint() uint {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *trueAny) ToUint32() uint32 {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *trueAny) ToUint64() uint64 {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *trueAny) ToFloat32() float32 {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *trueAny) ToFloat64() float64 {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *trueAny) ToString() string {
|
||||||
|
return "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *trueAny) WriteTo(stream *Stream) {
|
||||||
|
stream.WriteTrue()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *trueAny) Parse() *Iterator {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *trueAny) GetInterface() interface{} {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *trueAny) ValueType() ValueType {
|
||||||
|
return BoolValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *trueAny) MustBeValid() Any {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
type falseAny struct {
|
||||||
|
baseAny
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *falseAny) LastError() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *falseAny) ToBool() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *falseAny) ToInt() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *falseAny) ToInt32() int32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *falseAny) ToInt64() int64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *falseAny) ToUint() uint {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *falseAny) ToUint32() uint32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *falseAny) ToUint64() uint64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *falseAny) ToFloat32() float32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *falseAny) ToFloat64() float64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *falseAny) ToString() string {
|
||||||
|
return "false"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *falseAny) WriteTo(stream *Stream) {
|
||||||
|
stream.WriteFalse()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *falseAny) Parse() *Iterator {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *falseAny) GetInterface() interface{} {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *falseAny) ValueType() ValueType {
|
||||||
|
return BoolValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *falseAny) MustBeValid() Any {
|
||||||
|
return any
|
||||||
|
}
|
83
vendor/github.com/json-iterator/go/any_float.go
generated
vendored
Normal file
83
vendor/github.com/json-iterator/go/any_float.go
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package jsoniter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type floatAny struct {
|
||||||
|
baseAny
|
||||||
|
val float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *floatAny) Parse() *Iterator {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *floatAny) ValueType() ValueType {
|
||||||
|
return NumberValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *floatAny) MustBeValid() Any {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *floatAny) LastError() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *floatAny) ToBool() bool {
|
||||||
|
return any.ToFloat64() != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *floatAny) ToInt() int {
|
||||||
|
return int(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *floatAny) ToInt32() int32 {
|
||||||
|
return int32(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *floatAny) ToInt64() int64 {
|
||||||
|
return int64(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *floatAny) ToUint() uint {
|
||||||
|
if any.val > 0 {
|
||||||
|
return uint(any.val)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *floatAny) ToUint32() uint32 {
|
||||||
|
if any.val > 0 {
|
||||||
|
return uint32(any.val)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *floatAny) ToUint64() uint64 {
|
||||||
|
if any.val > 0 {
|
||||||
|
return uint64(any.val)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *floatAny) ToFloat32() float32 {
|
||||||
|
return float32(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *floatAny) ToFloat64() float64 {
|
||||||
|
return any.val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *floatAny) ToString() string {
|
||||||
|
return strconv.FormatFloat(any.val, 'E', -1, 64)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *floatAny) WriteTo(stream *Stream) {
|
||||||
|
stream.WriteFloat64(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *floatAny) GetInterface() interface{} {
|
||||||
|
return any.val
|
||||||
|
}
|
74
vendor/github.com/json-iterator/go/any_int32.go
generated
vendored
Normal file
74
vendor/github.com/json-iterator/go/any_int32.go
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package jsoniter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type int32Any struct {
|
||||||
|
baseAny
|
||||||
|
val int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int32Any) LastError() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int32Any) ValueType() ValueType {
|
||||||
|
return NumberValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int32Any) MustBeValid() Any {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int32Any) ToBool() bool {
|
||||||
|
return any.val != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int32Any) ToInt() int {
|
||||||
|
return int(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int32Any) ToInt32() int32 {
|
||||||
|
return any.val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int32Any) ToInt64() int64 {
|
||||||
|
return int64(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int32Any) ToUint() uint {
|
||||||
|
return uint(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int32Any) ToUint32() uint32 {
|
||||||
|
return uint32(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int32Any) ToUint64() uint64 {
|
||||||
|
return uint64(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int32Any) ToFloat32() float32 {
|
||||||
|
return float32(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int32Any) ToFloat64() float64 {
|
||||||
|
return float64(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int32Any) ToString() string {
|
||||||
|
return strconv.FormatInt(int64(any.val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int32Any) WriteTo(stream *Stream) {
|
||||||
|
stream.WriteInt32(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int32Any) Parse() *Iterator {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int32Any) GetInterface() interface{} {
|
||||||
|
return any.val
|
||||||
|
}
|
74
vendor/github.com/json-iterator/go/any_int64.go
generated
vendored
Normal file
74
vendor/github.com/json-iterator/go/any_int64.go
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package jsoniter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type int64Any struct {
|
||||||
|
baseAny
|
||||||
|
val int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int64Any) LastError() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int64Any) ValueType() ValueType {
|
||||||
|
return NumberValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int64Any) MustBeValid() Any {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int64Any) ToBool() bool {
|
||||||
|
return any.val != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int64Any) ToInt() int {
|
||||||
|
return int(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int64Any) ToInt32() int32 {
|
||||||
|
return int32(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int64Any) ToInt64() int64 {
|
||||||
|
return any.val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int64Any) ToUint() uint {
|
||||||
|
return uint(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int64Any) ToUint32() uint32 {
|
||||||
|
return uint32(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int64Any) ToUint64() uint64 {
|
||||||
|
return uint64(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int64Any) ToFloat32() float32 {
|
||||||
|
return float32(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int64Any) ToFloat64() float64 {
|
||||||
|
return float64(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int64Any) ToString() string {
|
||||||
|
return strconv.FormatInt(any.val, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int64Any) WriteTo(stream *Stream) {
|
||||||
|
stream.WriteInt64(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int64Any) Parse() *Iterator {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *int64Any) GetInterface() interface{} {
|
||||||
|
return any.val
|
||||||
|
}
|
82
vendor/github.com/json-iterator/go/any_invalid.go
generated
vendored
Normal file
82
vendor/github.com/json-iterator/go/any_invalid.go
generated
vendored
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
package jsoniter
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type invalidAny struct {
|
||||||
|
baseAny
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func newInvalidAny(path []interface{}) *invalidAny {
|
||||||
|
return &invalidAny{baseAny{}, fmt.Errorf("%v not found", path)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *invalidAny) LastError() error {
|
||||||
|
return any.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *invalidAny) ValueType() ValueType {
|
||||||
|
return InvalidValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *invalidAny) MustBeValid() Any {
|
||||||
|
panic(any.err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *invalidAny) ToBool() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *invalidAny) ToInt() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *invalidAny) ToInt32() int32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *invalidAny) ToInt64() int64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *invalidAny) ToUint() uint {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *invalidAny) ToUint32() uint32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *invalidAny) ToUint64() uint64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *invalidAny) ToFloat32() float32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *invalidAny) ToFloat64() float64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *invalidAny) ToString() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *invalidAny) WriteTo(stream *Stream) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *invalidAny) Get(path ...interface{}) Any {
|
||||||
|
if any.err == nil {
|
||||||
|
return &invalidAny{baseAny{}, fmt.Errorf("get %v from invalid", path)}
|
||||||
|
}
|
||||||
|
return &invalidAny{baseAny{}, fmt.Errorf("%v, get %v from invalid", any.err, path)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *invalidAny) Parse() *Iterator {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *invalidAny) GetInterface() interface{} {
|
||||||
|
return nil
|
||||||
|
}
|
69
vendor/github.com/json-iterator/go/any_nil.go
generated
vendored
Normal file
69
vendor/github.com/json-iterator/go/any_nil.go
generated
vendored
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
package jsoniter
|
||||||
|
|
||||||
|
type nilAny struct {
|
||||||
|
baseAny
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *nilAny) LastError() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *nilAny) ValueType() ValueType {
|
||||||
|
return NilValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *nilAny) MustBeValid() Any {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *nilAny) ToBool() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *nilAny) ToInt() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *nilAny) ToInt32() int32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *nilAny) ToInt64() int64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *nilAny) ToUint() uint {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *nilAny) ToUint32() uint32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *nilAny) ToUint64() uint64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *nilAny) ToFloat32() float32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *nilAny) ToFloat64() float64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *nilAny) ToString() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *nilAny) WriteTo(stream *Stream) {
|
||||||
|
stream.WriteNil()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *nilAny) Parse() *Iterator {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *nilAny) GetInterface() interface{} {
|
||||||
|
return nil
|
||||||
|
}
|
123
vendor/github.com/json-iterator/go/any_number.go
generated
vendored
Normal file
123
vendor/github.com/json-iterator/go/any_number.go
generated
vendored
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
package jsoniter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
type numberLazyAny struct {
|
||||||
|
baseAny
|
||||||
|
cfg *frozenConfig
|
||||||
|
buf []byte
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *numberLazyAny) ValueType() ValueType {
|
||||||
|
return NumberValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *numberLazyAny) MustBeValid() Any {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *numberLazyAny) LastError() error {
|
||||||
|
return any.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *numberLazyAny) ToBool() bool {
|
||||||
|
return any.ToFloat64() != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *numberLazyAny) ToInt() int {
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
val := iter.ReadInt()
|
||||||
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
|
any.err = iter.Error
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *numberLazyAny) ToInt32() int32 {
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
val := iter.ReadInt32()
|
||||||
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
|
any.err = iter.Error
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *numberLazyAny) ToInt64() int64 {
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
val := iter.ReadInt64()
|
||||||
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
|
any.err = iter.Error
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *numberLazyAny) ToUint() uint {
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
val := iter.ReadUint()
|
||||||
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
|
any.err = iter.Error
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *numberLazyAny) ToUint32() uint32 {
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
val := iter.ReadUint32()
|
||||||
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
|
any.err = iter.Error
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *numberLazyAny) ToUint64() uint64 {
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
val := iter.ReadUint64()
|
||||||
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
|
any.err = iter.Error
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *numberLazyAny) ToFloat32() float32 {
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
val := iter.ReadFloat32()
|
||||||
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
|
any.err = iter.Error
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *numberLazyAny) ToFloat64() float64 {
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
val := iter.ReadFloat64()
|
||||||
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
|
any.err = iter.Error
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *numberLazyAny) ToString() string {
|
||||||
|
return *(*string)(unsafe.Pointer(&any.buf))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *numberLazyAny) WriteTo(stream *Stream) {
|
||||||
|
stream.Write(any.buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *numberLazyAny) GetInterface() interface{} {
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
return iter.Read()
|
||||||
|
}
|
374
vendor/github.com/json-iterator/go/any_object.go
generated
vendored
Normal file
374
vendor/github.com/json-iterator/go/any_object.go
generated
vendored
Normal file
@ -0,0 +1,374 @@
|
|||||||
|
package jsoniter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
type objectLazyAny struct {
|
||||||
|
baseAny
|
||||||
|
cfg *frozenConfig
|
||||||
|
buf []byte
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) ValueType() ValueType {
|
||||||
|
return ObjectValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) MustBeValid() Any {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) LastError() error {
|
||||||
|
return any.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) ToBool() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) ToInt() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) ToInt32() int32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) ToInt64() int64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) ToUint() uint {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) ToUint32() uint32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) ToUint64() uint64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) ToFloat32() float32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) ToFloat64() float64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) ToString() string {
|
||||||
|
return *(*string)(unsafe.Pointer(&any.buf))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) ToVal(obj interface{}) {
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
iter.ReadVal(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) Get(path ...interface{}) Any {
|
||||||
|
if len(path) == 0 {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
switch firstPath := path[0].(type) {
|
||||||
|
case string:
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
valueBytes := locateObjectField(iter, firstPath)
|
||||||
|
if valueBytes == nil {
|
||||||
|
return newInvalidAny(path)
|
||||||
|
}
|
||||||
|
iter.ResetBytes(valueBytes)
|
||||||
|
return locatePath(iter, path[1:])
|
||||||
|
case int32:
|
||||||
|
if '*' == firstPath {
|
||||||
|
mappedAll := map[string]Any{}
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
iter.ReadMapCB(func(iter *Iterator, field string) bool {
|
||||||
|
mapped := locatePath(iter, path[1:])
|
||||||
|
if mapped.ValueType() != InvalidValue {
|
||||||
|
mappedAll[field] = mapped
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return wrapMap(mappedAll)
|
||||||
|
}
|
||||||
|
return newInvalidAny(path)
|
||||||
|
default:
|
||||||
|
return newInvalidAny(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) Keys() []string {
|
||||||
|
keys := []string{}
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
iter.ReadMapCB(func(iter *Iterator, field string) bool {
|
||||||
|
iter.Skip()
|
||||||
|
keys = append(keys, field)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return keys
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) Size() int {
|
||||||
|
size := 0
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
iter.ReadObjectCB(func(iter *Iterator, field string) bool {
|
||||||
|
iter.Skip()
|
||||||
|
size++
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) WriteTo(stream *Stream) {
|
||||||
|
stream.Write(any.buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) GetInterface() interface{} {
|
||||||
|
iter := any.cfg.BorrowIterator(any.buf)
|
||||||
|
defer any.cfg.ReturnIterator(iter)
|
||||||
|
return iter.Read()
|
||||||
|
}
|
||||||
|
|
||||||
|
type objectAny struct {
|
||||||
|
baseAny
|
||||||
|
err error
|
||||||
|
val reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func wrapStruct(val interface{}) *objectAny {
|
||||||
|
return &objectAny{baseAny{}, nil, reflect.ValueOf(val)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectAny) ValueType() ValueType {
|
||||||
|
return ObjectValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectAny) MustBeValid() Any {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectAny) Parse() *Iterator {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectAny) LastError() error {
|
||||||
|
return any.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectAny) ToBool() bool {
|
||||||
|
return any.val.NumField() != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectAny) ToInt() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectAny) ToInt32() int32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectAny) ToInt64() int64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectAny) ToUint() uint {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectAny) ToUint32() uint32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectAny) ToUint64() uint64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectAny) ToFloat32() float32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectAny) ToFloat64() float64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectAny) ToString() string {
|
||||||
|
str, err := MarshalToString(any.val.Interface())
|
||||||
|
any.err = err
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectAny) Get(path ...interface{}) Any {
|
||||||
|
if len(path) == 0 {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
switch firstPath := path[0].(type) {
|
||||||
|
case string:
|
||||||
|
field := any.val.FieldByName(firstPath)
|
||||||
|
if !field.IsValid() {
|
||||||
|
return newInvalidAny(path)
|
||||||
|
}
|
||||||
|
return Wrap(field.Interface())
|
||||||
|
case int32:
|
||||||
|
if '*' == firstPath {
|
||||||
|
mappedAll := map[string]Any{}
|
||||||
|
for i := 0; i < any.val.NumField(); i++ {
|
||||||
|
field := any.val.Field(i)
|
||||||
|
if field.CanInterface() {
|
||||||
|
mapped := Wrap(field.Interface()).Get(path[1:]...)
|
||||||
|
if mapped.ValueType() != InvalidValue {
|
||||||
|
mappedAll[any.val.Type().Field(i).Name] = mapped
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return wrapMap(mappedAll)
|
||||||
|
}
|
||||||
|
return newInvalidAny(path)
|
||||||
|
default:
|
||||||
|
return newInvalidAny(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectAny) Keys() []string {
|
||||||
|
keys := make([]string, 0, any.val.NumField())
|
||||||
|
for i := 0; i < any.val.NumField(); i++ {
|
||||||
|
keys = append(keys, any.val.Type().Field(i).Name)
|
||||||
|
}
|
||||||
|
return keys
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectAny) Size() int {
|
||||||
|
return any.val.NumField()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectAny) WriteTo(stream *Stream) {
|
||||||
|
stream.WriteVal(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *objectAny) GetInterface() interface{} {
|
||||||
|
return any.val.Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
type mapAny struct {
|
||||||
|
baseAny
|
||||||
|
err error
|
||||||
|
val reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func wrapMap(val interface{}) *mapAny {
|
||||||
|
return &mapAny{baseAny{}, nil, reflect.ValueOf(val)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *mapAny) ValueType() ValueType {
|
||||||
|
return ObjectValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *mapAny) MustBeValid() Any {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *mapAny) Parse() *Iterator {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *mapAny) LastError() error {
|
||||||
|
return any.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *mapAny) ToBool() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *mapAny) ToInt() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *mapAny) ToInt32() int32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *mapAny) ToInt64() int64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *mapAny) ToUint() uint {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *mapAny) ToUint32() uint32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *mapAny) ToUint64() uint64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *mapAny) ToFloat32() float32 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *mapAny) ToFloat64() float64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *mapAny) ToString() string {
|
||||||
|
str, err := MarshalToString(any.val.Interface())
|
||||||
|
any.err = err
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *mapAny) Get(path ...interface{}) Any {
|
||||||
|
if len(path) == 0 {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
switch firstPath := path[0].(type) {
|
||||||
|
case int32:
|
||||||
|
if '*' == firstPath {
|
||||||
|
mappedAll := map[string]Any{}
|
||||||
|
for _, key := range any.val.MapKeys() {
|
||||||
|
keyAsStr := key.String()
|
||||||
|
element := Wrap(any.val.MapIndex(key).Interface())
|
||||||
|
mapped := element.Get(path[1:]...)
|
||||||
|
if mapped.ValueType() != InvalidValue {
|
||||||
|
mappedAll[keyAsStr] = mapped
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return wrapMap(mappedAll)
|
||||||
|
}
|
||||||
|
return newInvalidAny(path)
|
||||||
|
default:
|
||||||
|
value := any.val.MapIndex(reflect.ValueOf(firstPath))
|
||||||
|
if !value.IsValid() {
|
||||||
|
return newInvalidAny(path)
|
||||||
|
}
|
||||||
|
return Wrap(value.Interface())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *mapAny) Keys() []string {
|
||||||
|
keys := make([]string, 0, any.val.Len())
|
||||||
|
for _, key := range any.val.MapKeys() {
|
||||||
|
keys = append(keys, key.String())
|
||||||
|
}
|
||||||
|
return keys
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *mapAny) Size() int {
|
||||||
|
return any.val.Len()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *mapAny) WriteTo(stream *Stream) {
|
||||||
|
stream.WriteVal(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *mapAny) GetInterface() interface{} {
|
||||||
|
return any.val.Interface()
|
||||||
|
}
|
166
vendor/github.com/json-iterator/go/any_str.go
generated
vendored
Normal file
166
vendor/github.com/json-iterator/go/any_str.go
generated
vendored
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
package jsoniter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type stringAny struct {
|
||||||
|
baseAny
|
||||||
|
val string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *stringAny) Get(path ...interface{}) Any {
|
||||||
|
if len(path) == 0 {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *stringAny) Parse() *Iterator {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *stringAny) ValueType() ValueType {
|
||||||
|
return StringValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *stringAny) MustBeValid() Any {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *stringAny) LastError() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *stringAny) ToBool() bool {
|
||||||
|
str := any.ToString()
|
||||||
|
if str == "0" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, c := range str {
|
||||||
|
switch c {
|
||||||
|
case ' ', '\n', '\r', '\t':
|
||||||
|
default:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *stringAny) ToInt() int {
|
||||||
|
return int(any.ToInt64())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *stringAny) ToInt32() int32 {
|
||||||
|
return int32(any.ToInt64())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *stringAny) ToInt64() int64 {
|
||||||
|
if any.val == "" {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
flag := 1
|
||||||
|
startPos := 0
|
||||||
|
endPos := 0
|
||||||
|
if any.val[0] == '+' || any.val[0] == '-' {
|
||||||
|
startPos = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if any.val[0] == '-' {
|
||||||
|
flag = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := startPos; i < len(any.val); i++ {
|
||||||
|
if any.val[i] >= '0' && any.val[i] <= '9' {
|
||||||
|
endPos = i + 1
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parsed, _ := strconv.ParseInt(any.val[startPos:endPos], 10, 64)
|
||||||
|
return int64(flag) * parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *stringAny) ToUint() uint {
|
||||||
|
return uint(any.ToUint64())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *stringAny) ToUint32() uint32 {
|
||||||
|
return uint32(any.ToUint64())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *stringAny) ToUint64() uint64 {
|
||||||
|
if any.val == "" {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
startPos := 0
|
||||||
|
endPos := 0
|
||||||
|
|
||||||
|
if any.val[0] == '-' {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if any.val[0] == '+' {
|
||||||
|
startPos = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := startPos; i < len(any.val); i++ {
|
||||||
|
if any.val[i] >= '0' && any.val[i] <= '9' {
|
||||||
|
endPos = i + 1
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parsed, _ := strconv.ParseUint(any.val[startPos:endPos], 10, 64)
|
||||||
|
return parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *stringAny) ToFloat32() float32 {
|
||||||
|
return float32(any.ToFloat64())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *stringAny) ToFloat64() float64 {
|
||||||
|
if len(any.val) == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// first char invalid
|
||||||
|
if any.val[0] != '+' && any.val[0] != '-' && (any.val[0] > '9' || any.val[0] < '0') {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract valid num expression from string
|
||||||
|
// eg 123true => 123, -12.12xxa => -12.12
|
||||||
|
endPos := 1
|
||||||
|
for i := 1; i < len(any.val); i++ {
|
||||||
|
if any.val[i] == '.' || any.val[i] == 'e' || any.val[i] == 'E' || any.val[i] == '+' || any.val[i] == '-' {
|
||||||
|
endPos = i + 1
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// end position is the first char which is not digit
|
||||||
|
if any.val[i] >= '0' && any.val[i] <= '9' {
|
||||||
|
endPos = i + 1
|
||||||
|
} else {
|
||||||
|
endPos = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parsed, _ := strconv.ParseFloat(any.val[:endPos], 64)
|
||||||
|
return parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *stringAny) ToString() string {
|
||||||
|
return any.val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *stringAny) WriteTo(stream *Stream) {
|
||||||
|
stream.WriteString(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *stringAny) GetInterface() interface{} {
|
||||||
|
return any.val
|
||||||
|
}
|
74
vendor/github.com/json-iterator/go/any_uint32.go
generated
vendored
Normal file
74
vendor/github.com/json-iterator/go/any_uint32.go
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package jsoniter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type uint32Any struct {
|
||||||
|
baseAny
|
||||||
|
val uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint32Any) LastError() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint32Any) ValueType() ValueType {
|
||||||
|
return NumberValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint32Any) MustBeValid() Any {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint32Any) ToBool() bool {
|
||||||
|
return any.val != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint32Any) ToInt() int {
|
||||||
|
return int(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint32Any) ToInt32() int32 {
|
||||||
|
return int32(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint32Any) ToInt64() int64 {
|
||||||
|
return int64(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint32Any) ToUint() uint {
|
||||||
|
return uint(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint32Any) ToUint32() uint32 {
|
||||||
|
return any.val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint32Any) ToUint64() uint64 {
|
||||||
|
return uint64(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint32Any) ToFloat32() float32 {
|
||||||
|
return float32(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint32Any) ToFloat64() float64 {
|
||||||
|
return float64(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint32Any) ToString() string {
|
||||||
|
return strconv.FormatInt(int64(any.val), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint32Any) WriteTo(stream *Stream) {
|
||||||
|
stream.WriteUint32(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint32Any) Parse() *Iterator {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint32Any) GetInterface() interface{} {
|
||||||
|
return any.val
|
||||||
|
}
|
74
vendor/github.com/json-iterator/go/any_uint64.go
generated
vendored
Normal file
74
vendor/github.com/json-iterator/go/any_uint64.go
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package jsoniter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type uint64Any struct {
|
||||||
|
baseAny
|
||||||
|
val uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint64Any) LastError() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint64Any) ValueType() ValueType {
|
||||||
|
return NumberValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint64Any) MustBeValid() Any {
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint64Any) ToBool() bool {
|
||||||
|
return any.val != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint64Any) ToInt() int {
|
||||||
|
return int(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint64Any) ToInt32() int32 {
|
||||||
|
return int32(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint64Any) ToInt64() int64 {
|
||||||
|
return int64(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint64Any) ToUint() uint {
|
||||||
|
return uint(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint64Any) ToUint32() uint32 {
|
||||||
|
return uint32(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint64Any) ToUint64() uint64 {
|
||||||
|
return any.val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint64Any) ToFloat32() float32 {
|
||||||
|
return float32(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint64Any) ToFloat64() float64 {
|
||||||
|
return float64(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint64Any) ToString() string {
|
||||||
|
return strconv.FormatUint(any.val, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint64Any) WriteTo(stream *Stream) {
|
||||||
|
stream.WriteUint64(any.val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint64Any) Parse() *Iterator {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *uint64Any) GetInterface() interface{} {
|
||||||
|
return any.val
|
||||||
|
}
|
12
vendor/github.com/json-iterator/go/build.sh
generated
vendored
Normal file
12
vendor/github.com/json-iterator/go/build.sh
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
if [ ! -d /tmp/build-golang/src/github.com/json-iterator ]; then
|
||||||
|
mkdir -p /tmp/build-golang/src/github.com/json-iterator
|
||||||
|
ln -s $PWD /tmp/build-golang/src/github.com/json-iterator/go
|
||||||
|
fi
|
||||||
|
export GOPATH=/tmp/build-golang
|
||||||
|
go get -u github.com/golang/dep/cmd/dep
|
||||||
|
cd /tmp/build-golang/src/github.com/json-iterator/go
|
||||||
|
exec $GOPATH/bin/dep ensure -update
|
375
vendor/github.com/json-iterator/go/config.go
generated
vendored
Normal file
375
vendor/github.com/json-iterator/go/config.go
generated
vendored
Normal file
@ -0,0 +1,375 @@
|
|||||||
|
package jsoniter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
"sync"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/modern-go/concurrent"
|
||||||
|
"github.com/modern-go/reflect2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config customize how the API should behave.
|
||||||
|
// The API is created from Config by Froze.
|
||||||
|
type Config struct {
|
||||||
|
IndentionStep int
|
||||||
|
MarshalFloatWith6Digits bool
|
||||||
|
EscapeHTML bool
|
||||||
|
SortMapKeys bool
|
||||||
|
UseNumber bool
|
||||||
|
DisallowUnknownFields bool
|
||||||
|
TagKey string
|
||||||
|
OnlyTaggedField bool
|
||||||
|
ValidateJsonRawMessage bool
|
||||||
|
ObjectFieldMustBeSimpleString bool
|
||||||
|
CaseSensitive bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// API the public interface of this package.
|
||||||
|
// Primary Marshal and Unmarshal.
|
||||||
|
type API interface {
|
||||||
|
IteratorPool
|
||||||
|
StreamPool
|
||||||
|
MarshalToString(v interface{}) (string, error)
|
||||||
|
Marshal(v interface{}) ([]byte, error)
|
||||||
|
MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
|
||||||
|
UnmarshalFromString(str string, v interface{}) error
|
||||||
|
Unmarshal(data []byte, v interface{}) error
|
||||||
|
Get(data []byte, path ...interface{}) Any
|
||||||
|
NewEncoder(writer io.Writer) *Encoder
|
||||||
|
NewDecoder(reader io.Reader) *Decoder
|
||||||
|
Valid(data []byte) bool
|
||||||
|
RegisterExtension(extension Extension)
|
||||||
|
DecoderOf(typ reflect2.Type) ValDecoder
|
||||||
|
EncoderOf(typ reflect2.Type) ValEncoder
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigDefault the default API
|
||||||
|
var ConfigDefault = Config{
|
||||||
|
EscapeHTML: true,
|
||||||
|
}.Froze()
|
||||||
|
|
||||||
|
// ConfigCompatibleWithStandardLibrary tries to be 100% compatible with standard library behavior
|
||||||
|
var ConfigCompatibleWithStandardLibrary = Config{
|
||||||
|
EscapeHTML: true,
|
||||||
|
SortMapKeys: true,
|
||||||
|
ValidateJsonRawMessage: true,
|
||||||
|
}.Froze()
|
||||||
|
|
||||||
|
// ConfigFastest marshals float with only 6 digits precision
|
||||||
|
var ConfigFastest = Config{
|
||||||
|
EscapeHTML: false,
|
||||||
|
MarshalFloatWith6Digits: true, // will lose precession
|
||||||
|
ObjectFieldMustBeSimpleString: true, // do not unescape object field
|
||||||
|
}.Froze()
|
||||||
|
|
||||||
|
type frozenConfig struct {
|
||||||
|
configBeforeFrozen Config
|
||||||
|
sortMapKeys bool
|
||||||
|
indentionStep int
|
||||||
|
objectFieldMustBeSimpleString bool
|
||||||
|
onlyTaggedField bool
|
||||||
|
disallowUnknownFields bool
|
||||||
|
decoderCache *concurrent.Map
|
||||||
|
encoderCache *concurrent.Map
|
||||||
|
encoderExtension Extension
|
||||||
|
decoderExtension Extension
|
||||||
|
extraExtensions []Extension
|
||||||
|
streamPool *sync.Pool
|
||||||
|
iteratorPool *sync.Pool
|
||||||
|
caseSensitive bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) initCache() {
|
||||||
|
cfg.decoderCache = concurrent.NewMap()
|
||||||
|
cfg.encoderCache = concurrent.NewMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) addDecoderToCache(cacheKey uintptr, decoder ValDecoder) {
|
||||||
|
cfg.decoderCache.Store(cacheKey, decoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) addEncoderToCache(cacheKey uintptr, encoder ValEncoder) {
|
||||||
|
cfg.encoderCache.Store(cacheKey, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) getDecoderFromCache(cacheKey uintptr) ValDecoder {
|
||||||
|
decoder, found := cfg.decoderCache.Load(cacheKey)
|
||||||
|
if found {
|
||||||
|
return decoder.(ValDecoder)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder {
|
||||||
|
encoder, found := cfg.encoderCache.Load(cacheKey)
|
||||||
|
if found {
|
||||||
|
return encoder.(ValEncoder)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var cfgCache = concurrent.NewMap()
|
||||||
|
|
||||||
|
func getFrozenConfigFromCache(cfg Config) *frozenConfig {
|
||||||
|
obj, found := cfgCache.Load(cfg)
|
||||||
|
if found {
|
||||||
|
return obj.(*frozenConfig)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) {
|
||||||
|
cfgCache.Store(cfg, frozenConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Froze forge API from config
|
||||||
|
func (cfg Config) Froze() API {
|
||||||
|
api := &frozenConfig{
|
||||||
|
sortMapKeys: cfg.SortMapKeys,
|
||||||
|
indentionStep: cfg.IndentionStep,
|
||||||
|
objectFieldMustBeSimpleString: cfg.ObjectFieldMustBeSimpleString,
|
||||||
|
onlyTaggedField: cfg.OnlyTaggedField,
|
||||||
|
disallowUnknownFields: cfg.DisallowUnknownFields,
|
||||||
|
caseSensitive: cfg.CaseSensitive,
|
||||||
|
}
|
||||||
|
api.streamPool = &sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return NewStream(api, nil, 512)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
api.iteratorPool = &sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return NewIterator(api)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
api.initCache()
|
||||||
|
encoderExtension := EncoderExtension{}
|
||||||
|
decoderExtension := DecoderExtension{}
|
||||||
|
if cfg.MarshalFloatWith6Digits {
|
||||||
|
api.marshalFloatWith6Digits(encoderExtension)
|
||||||
|
}
|
||||||
|
if cfg.EscapeHTML {
|
||||||
|
api.escapeHTML(encoderExtension)
|
||||||
|
}
|
||||||
|
if cfg.UseNumber {
|
||||||
|
api.useNumber(decoderExtension)
|
||||||
|
}
|
||||||
|
if cfg.ValidateJsonRawMessage {
|
||||||
|
api.validateJsonRawMessage(encoderExtension)
|
||||||
|
}
|
||||||
|
api.encoderExtension = encoderExtension
|
||||||
|
api.decoderExtension = decoderExtension
|
||||||
|
api.configBeforeFrozen = cfg
|
||||||
|
return api
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg Config) frozeWithCacheReuse(extraExtensions []Extension) *frozenConfig {
|
||||||
|
api := getFrozenConfigFromCache(cfg)
|
||||||
|
if api != nil {
|
||||||
|
return api
|
||||||
|
}
|
||||||
|
api = cfg.Froze().(*frozenConfig)
|
||||||
|
for _, extension := range extraExtensions {
|
||||||
|
api.RegisterExtension(extension)
|
||||||
|
}
|
||||||
|
addFrozenConfigToCache(cfg, api)
|
||||||
|
return api
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) validateJsonRawMessage(extension EncoderExtension) {
|
||||||
|
encoder := &funcEncoder{func(ptr unsafe.Pointer, stream *Stream) {
|
||||||
|
rawMessage := *(*json.RawMessage)(ptr)
|
||||||
|
iter := cfg.BorrowIterator([]byte(rawMessage))
|
||||||
|
iter.Read()
|
||||||
|
if iter.Error != nil {
|
||||||
|
stream.WriteRaw("null")
|
||||||
|
} else {
|
||||||
|
cfg.ReturnIterator(iter)
|
||||||
|
stream.WriteRaw(string(rawMessage))
|
||||||
|
}
|
||||||
|
}, func(ptr unsafe.Pointer) bool {
|
||||||
|
return len(*((*json.RawMessage)(ptr))) == 0
|
||||||
|
}}
|
||||||
|
extension[reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem()] = encoder
|
||||||
|
extension[reflect2.TypeOfPtr((*RawMessage)(nil)).Elem()] = encoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) useNumber(extension DecoderExtension) {
|
||||||
|
extension[reflect2.TypeOfPtr((*interface{})(nil)).Elem()] = &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) {
|
||||||
|
exitingValue := *((*interface{})(ptr))
|
||||||
|
if exitingValue != nil && reflect.TypeOf(exitingValue).Kind() == reflect.Ptr {
|
||||||
|
iter.ReadVal(exitingValue)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if iter.WhatIsNext() == NumberValue {
|
||||||
|
*((*interface{})(ptr)) = json.Number(iter.readNumberAsString())
|
||||||
|
} else {
|
||||||
|
*((*interface{})(ptr)) = iter.Read()
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
func (cfg *frozenConfig) getTagKey() string {
|
||||||
|
tagKey := cfg.configBeforeFrozen.TagKey
|
||||||
|
if tagKey == "" {
|
||||||
|
return "json"
|
||||||
|
}
|
||||||
|
return tagKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) RegisterExtension(extension Extension) {
|
||||||
|
cfg.extraExtensions = append(cfg.extraExtensions, extension)
|
||||||
|
copied := cfg.configBeforeFrozen
|
||||||
|
cfg.configBeforeFrozen = copied
|
||||||
|
}
|
||||||
|
|
||||||
|
type lossyFloat32Encoder struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *lossyFloat32Encoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
||||||
|
stream.WriteFloat32Lossy(*((*float32)(ptr)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *lossyFloat32Encoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return *((*float32)(ptr)) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type lossyFloat64Encoder struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *lossyFloat64Encoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
||||||
|
stream.WriteFloat64Lossy(*((*float64)(ptr)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *lossyFloat64Encoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return *((*float64)(ptr)) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnableLossyFloatMarshalling keeps 10**(-6) precision
|
||||||
|
// for float variables for better performance.
|
||||||
|
func (cfg *frozenConfig) marshalFloatWith6Digits(extension EncoderExtension) {
|
||||||
|
// for better performance
|
||||||
|
extension[reflect2.TypeOfPtr((*float32)(nil)).Elem()] = &lossyFloat32Encoder{}
|
||||||
|
extension[reflect2.TypeOfPtr((*float64)(nil)).Elem()] = &lossyFloat64Encoder{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type htmlEscapedStringEncoder struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *htmlEscapedStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
||||||
|
str := *((*string)(ptr))
|
||||||
|
stream.WriteStringWithHTMLEscaped(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *htmlEscapedStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return *((*string)(ptr)) == ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) escapeHTML(encoderExtension EncoderExtension) {
|
||||||
|
encoderExtension[reflect2.TypeOfPtr((*string)(nil)).Elem()] = &htmlEscapedStringEncoder{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) cleanDecoders() {
|
||||||
|
typeDecoders = map[string]ValDecoder{}
|
||||||
|
fieldDecoders = map[string]ValDecoder{}
|
||||||
|
*cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) cleanEncoders() {
|
||||||
|
typeEncoders = map[string]ValEncoder{}
|
||||||
|
fieldEncoders = map[string]ValEncoder{}
|
||||||
|
*cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) MarshalToString(v interface{}) (string, error) {
|
||||||
|
stream := cfg.BorrowStream(nil)
|
||||||
|
defer cfg.ReturnStream(stream)
|
||||||
|
stream.WriteVal(v)
|
||||||
|
if stream.Error != nil {
|
||||||
|
return "", stream.Error
|
||||||
|
}
|
||||||
|
return string(stream.Buffer()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) Marshal(v interface{}) ([]byte, error) {
|
||||||
|
stream := cfg.BorrowStream(nil)
|
||||||
|
defer cfg.ReturnStream(stream)
|
||||||
|
stream.WriteVal(v)
|
||||||
|
if stream.Error != nil {
|
||||||
|
return nil, stream.Error
|
||||||
|
}
|
||||||
|
result := stream.Buffer()
|
||||||
|
copied := make([]byte, len(result))
|
||||||
|
copy(copied, result)
|
||||||
|
return copied, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
|
||||||
|
if prefix != "" {
|
||||||
|
panic("prefix is not supported")
|
||||||
|
}
|
||||||
|
for _, r := range indent {
|
||||||
|
if r != ' ' {
|
||||||
|
panic("indent can only be space")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newCfg := cfg.configBeforeFrozen
|
||||||
|
newCfg.IndentionStep = len(indent)
|
||||||
|
return newCfg.frozeWithCacheReuse(cfg.extraExtensions).Marshal(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) UnmarshalFromString(str string, v interface{}) error {
|
||||||
|
data := []byte(str)
|
||||||
|
iter := cfg.BorrowIterator(data)
|
||||||
|
defer cfg.ReturnIterator(iter)
|
||||||
|
iter.ReadVal(v)
|
||||||
|
c := iter.nextToken()
|
||||||
|
if c == 0 {
|
||||||
|
if iter.Error == io.EOF {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return iter.Error
|
||||||
|
}
|
||||||
|
iter.ReportError("Unmarshal", "there are bytes left after unmarshal")
|
||||||
|
return iter.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) Get(data []byte, path ...interface{}) Any {
|
||||||
|
iter := cfg.BorrowIterator(data)
|
||||||
|
defer cfg.ReturnIterator(iter)
|
||||||
|
return locatePath(iter, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) Unmarshal(data []byte, v interface{}) error {
|
||||||
|
iter := cfg.BorrowIterator(data)
|
||||||
|
defer cfg.ReturnIterator(iter)
|
||||||
|
iter.ReadVal(v)
|
||||||
|
c := iter.nextToken()
|
||||||
|
if c == 0 {
|
||||||
|
if iter.Error == io.EOF {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return iter.Error
|
||||||
|
}
|
||||||
|
iter.ReportError("Unmarshal", "there are bytes left after unmarshal")
|
||||||
|
return iter.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) NewEncoder(writer io.Writer) *Encoder {
|
||||||
|
stream := NewStream(cfg, writer, 512)
|
||||||
|
return &Encoder{stream}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) NewDecoder(reader io.Reader) *Decoder {
|
||||||
|
iter := Parse(cfg, reader, 512)
|
||||||
|
return &Decoder{iter}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *frozenConfig) Valid(data []byte) bool {
|
||||||
|
iter := cfg.BorrowIterator(data)
|
||||||
|
defer cfg.ReturnIterator(iter)
|
||||||
|
iter.Skip()
|
||||||
|
return iter.Error == nil
|
||||||
|
}
|
7
vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md
generated
vendored
Normal file
7
vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
| json type \ dest type | bool | int | uint | float |string|
|
||||||
|
| --- | --- | --- | --- |--|--|
|
||||||
|
| number | positive => true <br/> negative => true <br/> zero => false| 23.2 => 23 <br/> -32.1 => -32| 12.1 => 12 <br/> -12.1 => 0|as normal|same as origin|
|
||||||
|
| string | empty string => false <br/> string "0" => false <br/> other strings => true | "123.32" => 123 <br/> "-123.4" => -123 <br/> "123.23xxxw" => 123 <br/> "abcde12" => 0 <br/> "-32.1" => -32| 13.2 => 13 <br/> -1.1 => 0 |12.1 => 12.1 <br/> -12.3 => -12.3<br/> 12.4xxa => 12.4 <br/> +1.1e2 =>110 |same as origin|
|
||||||
|
| bool | true => true <br/> false => false| true => 1 <br/> false => 0 | true => 1 <br/> false => 0 |true => 1 <br/>false => 0|true => "true" <br/> false => "false"|
|
||||||
|
| object | true | 0 | 0 |0|originnal json|
|
||||||
|
| array | empty array => false <br/> nonempty array => true| [] => 0 <br/> [1,2] => 1 | [] => 0 <br/> [1,2] => 1 |[] => 0<br/>[1,2] => 1|original json|
|
322
vendor/github.com/json-iterator/go/iter.go
generated
vendored
Normal file
322
vendor/github.com/json-iterator/go/iter.go
generated
vendored
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
package jsoniter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ValueType the type for JSON element
|
||||||
|
type ValueType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// InvalidValue invalid JSON element
|
||||||
|
InvalidValue ValueType = iota
|
||||||
|
// StringValue JSON element "string"
|
||||||
|
StringValue
|
||||||
|
// NumberValue JSON element 100 or 0.10
|
||||||
|
NumberValue
|
||||||
|
// NilValue JSON element null
|
||||||
|
NilValue
|
||||||
|
// BoolValue JSON element true or false
|
||||||
|
BoolValue
|
||||||
|
// ArrayValue JSON element []
|
||||||
|
ArrayValue
|
||||||
|
// ObjectValue JSON element {}
|
||||||
|
ObjectValue
|
||||||
|
)
|
||||||
|
|
||||||
|
var hexDigits []byte
|
||||||
|
var valueTypes []ValueType
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
hexDigits = make([]byte, 256)
|
||||||
|
for i := 0; i < len(hexDigits); i++ {
|
||||||
|
hexDigits[i] = 255
|
||||||
|
}
|
||||||
|
for i := '0'; i <= '9'; i++ {
|
||||||
|
hexDigits[i] = byte(i - '0')
|
||||||
|
}
|
||||||
|
for i := 'a'; i <= 'f'; i++ {
|
||||||
|
hexDigits[i] = byte((i - 'a') + 10)
|
||||||
|
}
|
||||||
|
for i := 'A'; i <= 'F'; i++ {
|
||||||
|
hexDigits[i] = byte((i - 'A') + 10)
|
||||||
|
}
|
||||||
|
valueTypes = make([]ValueType, 256)
|
||||||
|
for i := 0; i < len(valueTypes); i++ {
|
||||||
|
valueTypes[i] = InvalidValue
|
||||||
|
}
|
||||||
|
valueTypes['"'] = StringValue
|
||||||
|
valueTypes['-'] = NumberValue
|
||||||
|
valueTypes['0'] = NumberValue
|
||||||
|
valueTypes['1'] = NumberValue
|
||||||
|
valueTypes['2'] = NumberValue
|
||||||
|
valueTypes['3'] = NumberValue
|
||||||
|
valueTypes['4'] = NumberValue
|
||||||
|
valueTypes['5'] = NumberValue
|
||||||
|
valueTypes['6'] = NumberValue
|
||||||
|
valueTypes['7'] = NumberValue
|
||||||
|
valueTypes['8'] = NumberValue
|
||||||
|
valueTypes['9'] = NumberValue
|
||||||
|
valueTypes['t'] = BoolValue
|
||||||
|
valueTypes['f'] = BoolValue
|
||||||
|
valueTypes['n'] = NilValue
|
||||||
|
valueTypes['['] = ArrayValue
|
||||||
|
valueTypes['{'] = ObjectValue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterator is a io.Reader like object, with JSON specific read functions.
|
||||||
|
// Error is not returned as return value, but stored as Error member on this iterator instance.
|
||||||
|
type Iterator struct {
|
||||||
|
cfg *frozenConfig
|
||||||
|
reader io.Reader
|
||||||
|
buf []byte
|
||||||
|
head int
|
||||||
|
tail int
|
||||||
|
captureStartedAt int
|
||||||
|
captured []byte
|
||||||
|
Error error
|
||||||
|
Attachment interface{} // open for customized decoder
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewIterator creates an empty Iterator instance
|
||||||
|
func NewIterator(cfg API) *Iterator {
|
||||||
|
return &Iterator{
|
||||||
|
cfg: cfg.(*frozenConfig),
|
||||||
|
reader: nil,
|
||||||
|
buf: nil,
|
||||||
|
head: 0,
|
||||||
|
tail: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse creates an Iterator instance from io.Reader
|
||||||
|
func Parse(cfg API, reader io.Reader, bufSize int) *Iterator {
|
||||||
|
return &Iterator{
|
||||||
|
cfg: cfg.(*frozenConfig),
|
||||||
|
reader: reader,
|
||||||
|
buf: make([]byte, bufSize),
|
||||||
|
head: 0,
|
||||||
|
tail: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseBytes creates an Iterator instance from byte array
|
||||||
|
func ParseBytes(cfg API, input []byte) *Iterator {
|
||||||
|
return &Iterator{
|
||||||
|
cfg: cfg.(*frozenConfig),
|
||||||
|
reader: nil,
|
||||||
|
buf: input,
|
||||||
|
head: 0,
|
||||||
|
tail: len(input),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseString creates an Iterator instance from string
|
||||||
|
func ParseString(cfg API, input string) *Iterator {
|
||||||
|
return ParseBytes(cfg, []byte(input))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pool returns a pool can provide more iterator with same configuration
|
||||||
|
func (iter *Iterator) Pool() IteratorPool {
|
||||||
|
return iter.cfg
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset reuse iterator instance by specifying another reader
|
||||||
|
func (iter *Iterator) Reset(reader io.Reader) *Iterator {
|
||||||
|
iter.reader = reader
|
||||||
|
iter.head = 0
|
||||||
|
iter.tail = 0
|
||||||
|
return iter
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetBytes reuse iterator instance by specifying another byte array as input
|
||||||
|
func (iter *Iterator) ResetBytes(input []byte) *Iterator {
|
||||||
|
iter.reader = nil
|
||||||
|
iter.buf = input
|
||||||
|
iter.head = 0
|
||||||
|
iter.tail = len(input)
|
||||||
|
return iter
|
||||||
|
}
|
||||||
|
|
||||||
|
// WhatIsNext gets ValueType of relatively next json element
|
||||||
|
func (iter *Iterator) WhatIsNext() ValueType {
|
||||||
|
valueType := valueTypes[iter.nextToken()]
|
||||||
|
iter.unreadByte()
|
||||||
|
return valueType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool {
|
||||||
|
for i := iter.head; i < iter.tail; i++ {
|
||||||
|
c := iter.buf[i]
|
||||||
|
switch c {
|
||||||
|
case ' ', '\n', '\t', '\r':
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
iter.head = i
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) isObjectEnd() bool {
|
||||||
|
c := iter.nextToken()
|
||||||
|
if c == ',' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if c == '}' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c}))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) nextToken() byte {
|
||||||
|
// a variation of skip whitespaces, returning the next non-whitespace token
|
||||||
|
for {
|
||||||
|
for i := iter.head; i < iter.tail; i++ {
|
||||||
|
c := iter.buf[i]
|
||||||
|
switch c {
|
||||||
|
case ' ', '\n', '\t', '\r':
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
iter.head = i + 1
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
if !iter.loadMore() {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReportError record a error in iterator instance with current position.
|
||||||
|
func (iter *Iterator) ReportError(operation string, msg string) {
|
||||||
|
if iter.Error != nil {
|
||||||
|
if iter.Error != io.EOF {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
peekStart := iter.head - 10
|
||||||
|
if peekStart < 0 {
|
||||||
|
peekStart = 0
|
||||||
|
}
|
||||||
|
peekEnd := iter.head + 10
|
||||||
|
if peekEnd > iter.tail {
|
||||||
|
peekEnd = iter.tail
|
||||||
|
}
|
||||||
|
parsing := string(iter.buf[peekStart:peekEnd])
|
||||||
|
contextStart := iter.head - 50
|
||||||
|
if contextStart < 0 {
|
||||||
|
contextStart = 0
|
||||||
|
}
|
||||||
|
contextEnd := iter.head + 50
|
||||||
|
if contextEnd > iter.tail {
|
||||||
|
contextEnd = iter.tail
|
||||||
|
}
|
||||||
|
context := string(iter.buf[contextStart:contextEnd])
|
||||||
|
iter.Error = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...",
|
||||||
|
operation, msg, iter.head-peekStart, parsing, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CurrentBuffer gets current buffer as string for debugging purpose
|
||||||
|
func (iter *Iterator) CurrentBuffer() string {
|
||||||
|
peekStart := iter.head - 10
|
||||||
|
if peekStart < 0 {
|
||||||
|
peekStart = 0
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("parsing #%v byte, around ...|%s|..., whole buffer ...|%s|...", iter.head,
|
||||||
|
string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) readByte() (ret byte) {
|
||||||
|
if iter.head == iter.tail {
|
||||||
|
if iter.loadMore() {
|
||||||
|
ret = iter.buf[iter.head]
|
||||||
|
iter.head++
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
ret = iter.buf[iter.head]
|
||||||
|
iter.head++
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) loadMore() bool {
|
||||||
|
if iter.reader == nil {
|
||||||
|
if iter.Error == nil {
|
||||||
|
iter.head = iter.tail
|
||||||
|
iter.Error = io.EOF
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if iter.captured != nil {
|
||||||
|
iter.captured = append(iter.captured,
|
||||||
|
iter.buf[iter.captureStartedAt:iter.tail]...)
|
||||||
|
iter.captureStartedAt = 0
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
n, err := iter.reader.Read(iter.buf)
|
||||||
|
if n == 0 {
|
||||||
|
if err != nil {
|
||||||
|
if iter.Error == nil {
|
||||||
|
iter.Error = err
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
iter.head = 0
|
||||||
|
iter.tail = n
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iter *Iterator) unreadByte() {
|
||||||
|
if iter.Error != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
iter.head--
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read read the next JSON element as generic interface{}.
|
||||||
|
func (iter *Iterator) Read() interface{} {
|
||||||
|
valueType := iter.WhatIsNext()
|
||||||
|
switch valueType {
|
||||||
|
case StringValue:
|
||||||
|
return iter.ReadString()
|
||||||
|
case NumberValue:
|
||||||
|
if iter.cfg.configBeforeFrozen.UseNumber {
|
||||||
|
return json.Number(iter.readNumberAsString())
|
||||||
|
}
|
||||||
|
return iter.ReadFloat64()
|
||||||
|
case NilValue:
|
||||||
|
iter.skipFourBytes('n', 'u', 'l', 'l')
|
||||||
|
return nil
|
||||||
|
case BoolValue:
|
||||||
|
return iter.ReadBool()
|
||||||
|
case ArrayValue:
|
||||||
|
arr := []interface{}{}
|
||||||
|
iter.ReadArrayCB(func(iter *Iterator) bool {
|
||||||
|
var elem interface{}
|
||||||
|
iter.ReadVal(&elem)
|
||||||
|
arr = append(arr, elem)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return arr
|
||||||
|
case ObjectValue:
|
||||||
|
obj := map[string]interface{}{}
|
||||||
|
iter.ReadMapCB(func(Iter *Iterator, field string) bool {
|
||||||
|
var elem interface{}
|
||||||
|
iter.ReadVal(&elem)
|
||||||
|
obj[field] = elem
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return obj
|
||||||
|
default:
|
||||||
|
iter.ReportError("Read", fmt.Sprintf("unexpected value type: %v", valueType))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user