Add sjson

pull/6/head
Fenny 2020-01-29 14:51:29 -05:00
parent a146f71f01
commit 5fa195bd4e
7 changed files with 71 additions and 53 deletions

View File

@ -15,7 +15,7 @@ import (
const (
// Version for debugging
Version = "1.1.0"
Version = "1.2.0"
// https://play.golang.org/p/r6GNeV1gbH
banner = "" +
" \x1b[1;32m _____ _ _\n" +

View File

@ -19,7 +19,7 @@
<script>
window.$docsify = {
name: 'Fiber v1.1.0',
name: 'Fiber v1.2.0',
repo: 'gofiber/fiber',
loadSidebar: "sidebar.md",
homepage: 'getting_started.md',

2
go.mod
View File

@ -4,5 +4,7 @@ go 1.13
require (
github.com/json-iterator/go v1.1.9
github.com/tidwall/gjson v1.4.0 // indirect
github.com/tidwall/sjson v1.0.4
github.com/valyala/fasthttp v1.8.0
)

8
go.sum
View File

@ -14,6 +14,14 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/tidwall/gjson v1.4.0 h1:w6iOJZt9BJOzz4VD9CSnRCX/oleCsAZWi+1FFzZA+SA=
github.com/tidwall/gjson v1.4.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc=
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tidwall/sjson v1.0.4 h1:UcdIRXff12Lpnu3OLtZvnc03g4vH2suXDXhBwBqmzYg=
github.com/tidwall/sjson v1.0.4/go.mod h1:bURseu1nuBkFpIES5cz6zBtjmYeOQmEESshn7VpF15Y=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.8.0 h1:actnGGBYtGQmxVaZxyZpp57Vcc2NhcO7mMN0IMwCC0w=

View File

@ -143,7 +143,7 @@ func (ctx *Ctx) BasicAuth() (user, pass string, ok bool) {
if err != nil {
return
}
cs := b2s(c)
cs := B2S(c)
s := strings.IndexByte(cs, ':')
if s < 0 {
return
@ -158,18 +158,18 @@ func (ctx *Ctx) BasicAuth() (user, pass string, ok bool) {
// -d john=doe
func (ctx *Ctx) Body(args ...interface{}) string {
if len(args) == 0 {
return b2s(ctx.Fasthttp.Request.Body())
return B2S(ctx.Fasthttp.Request.Body())
}
if len(args) == 1 {
switch arg := args[0].(type) {
case string:
return b2s(ctx.Fasthttp.Request.PostArgs().Peek(arg))
return B2S(ctx.Fasthttp.Request.PostArgs().Peek(arg))
case func(string, string):
ctx.Fasthttp.Request.PostArgs().VisitAll(func(k []byte, v []byte) {
arg(b2s(k), b2s(v))
arg(B2S(k), B2S(v))
})
default:
return b2s(ctx.Fasthttp.Request.Body())
return B2S(ctx.Fasthttp.Request.Body())
}
}
return ""
@ -178,15 +178,15 @@ func (ctx *Ctx) Body(args ...interface{}) string {
// Cookies : https://gofiber.github.io/fiber/#/context?id=cookies
func (ctx *Ctx) Cookies(args ...interface{}) string {
if len(args) == 0 {
//return b2s(ctx.Fasthttp.Response.Header.Peek("Cookie"))
//return B2S(ctx.Fasthttp.Response.Header.Peek("Cookie"))
return ctx.Get("Cookie")
}
switch arg := args[0].(type) {
case string:
return b2s(ctx.Fasthttp.Request.Header.Cookie(arg))
return B2S(ctx.Fasthttp.Request.Header.Cookie(arg))
case func(string, string):
ctx.Fasthttp.Request.Header.VisitAllCookie(func(k, v []byte) {
arg(b2s(k), b2s(v))
arg(B2S(k), B2S(v))
})
default:
panic("Argument must be a string or func(string, string)")
@ -201,7 +201,7 @@ func (ctx *Ctx) FormFile(key string) (*multipart.FileHeader, error) {
// FormValue : https://gofiber.github.io/fiber/#/context?id=formvalue
func (ctx *Ctx) FormValue(key string) string {
return b2s(ctx.Fasthttp.FormValue(key))
return B2S(ctx.Fasthttp.FormValue(key))
}
// Fresh : https://gofiber.github.io/fiber/#/context?id=fresh
@ -215,12 +215,12 @@ func (ctx *Ctx) Get(key string) string {
if key == "referrer" {
key = "referer"
}
return b2s(ctx.Fasthttp.Request.Header.Peek(key))
return B2S(ctx.Fasthttp.Request.Header.Peek(key))
}
// Hostname : https://gofiber.github.io/fiber/#/context?id=hostname
func (ctx *Ctx) Hostname() string {
return b2s(ctx.Fasthttp.URI().Host())
return B2S(ctx.Fasthttp.URI().Host())
}
// Ip : https://gofiber.github.io/fiber/#/context?id=Ip
@ -265,7 +265,7 @@ func (ctx *Ctx) Locals(key string, val ...interface{}) interface{} {
// Method : https://gofiber.github.io/fiber/#/context?id=method
func (ctx *Ctx) Method() string {
return b2s(ctx.Fasthttp.Request.Header.Method())
return B2S(ctx.Fasthttp.Request.Header.Method())
}
// MultipartForm : https://gofiber.github.io/fiber/#/context?id=multipartform
@ -275,7 +275,7 @@ func (ctx *Ctx) MultipartForm() (*multipart.Form, error) {
// OriginalUrl : https://gofiber.github.io/fiber/#/context?id=originalurl
func (ctx *Ctx) OriginalUrl() string {
return b2s(ctx.Fasthttp.Request.Header.RequestURI())
return B2S(ctx.Fasthttp.Request.Header.RequestURI())
}
// Params : https://gofiber.github.io/fiber/#/context?id=params
@ -293,7 +293,7 @@ func (ctx *Ctx) Params(key string) string {
// Path : https://gofiber.github.io/fiber/#/context?id=path
func (ctx *Ctx) Path() string {
return b2s(ctx.Fasthttp.URI().Path())
return B2S(ctx.Fasthttp.URI().Path())
}
// Protocol : https://gofiber.github.io/fiber/#/context?id=protocol
@ -306,7 +306,7 @@ func (ctx *Ctx) Protocol() string {
// Query : https://gofiber.github.io/fiber/#/context?id=query
func (ctx *Ctx) Query(key string) string {
return b2s(ctx.Fasthttp.QueryArgs().Peek(key))
return B2S(ctx.Fasthttp.QueryArgs().Peek(key))
}
// Range : https://gofiber.github.io/fiber/#/context?id=range

View File

@ -15,6 +15,7 @@ import (
"time"
jsoniter "github.com/json-iterator/go"
"github.com/tidwall/sjson"
"github.com/valyala/fasthttp"
)
@ -49,7 +50,7 @@ func (ctx *Ctx) ClearCookie(name ...string) {
return
}
ctx.Fasthttp.Request.Header.VisitAllCookie(func(k, v []byte) {
ctx.Fasthttp.Response.Header.DelClientCookie(b2s(k))
ctx.Fasthttp.Response.Header.DelClientCookie(B2S(k))
})
}
@ -124,7 +125,7 @@ func (ctx *Ctx) Format(args ...interface{}) {
case string:
body = b
case []byte:
body = b2s(b)
body = B2S(b)
default:
panic("Body must be a string or []byte")
}
@ -151,7 +152,7 @@ func (ctx *Ctx) Json(v interface{}) error {
if err != nil {
return err
}
ctx.Set("Content-Type", "application/json")
ctx.Fasthttp.Response.Header.SetContentTypeBytes(applicationjson)
ctx.Fasthttp.Response.SetBodyString(raw)
return nil
}
@ -165,7 +166,7 @@ func (ctx *Ctx) Jsonp(v interface{}, cb ...string) error {
var builder strings.Builder
if len(cb) > 0 {
builder.Write(s2b(cb[0]))
builder.Write(S2B(cb[0]))
} else {
builder.Write([]byte("callback"))
}
@ -231,11 +232,11 @@ func (ctx *Ctx) Send(args ...interface{}) {
}
switch body := args[0].(type) {
case string:
//ctx.Fasthttp.Response.SetBodyRaw(s2b(body))
//ctx.Fasthttp.Response.SetBodyRaw(S2B(body))
ctx.Fasthttp.Response.SetBodyString(body)
case []byte:
//ctx.Fasthttp.Response.SetBodyRaw(body)
ctx.Fasthttp.Response.SetBodyString(b2s(body))
ctx.Fasthttp.Response.SetBodyString(B2S(body))
default:
panic("body must be a string or []byte")
}
@ -243,7 +244,7 @@ func (ctx *Ctx) Send(args ...interface{}) {
// SendBytes : https://gofiber.github.io/fiber/#/context?id=sendbytes
func (ctx *Ctx) SendBytes(body []byte) {
ctx.Fasthttp.Response.SetBodyString(b2s(body))
ctx.Fasthttp.Response.SetBodyString(B2S(body))
}
// SendFile : https://gofiber.github.io/fiber/#/context?id=sendfile
@ -277,7 +278,33 @@ func (ctx *Ctx) SendString(body string) {
// Set : https://gofiber.github.io/fiber/#/context?id=set
func (ctx *Ctx) Set(key string, val string) {
ctx.Fasthttp.Response.Header.SetCanonical(s2b(key), s2b(val))
ctx.Fasthttp.Response.Header.SetCanonical(S2B(key), S2B(val))
}
// Sjson : https://github.com/tidwall/sjson
func (ctx *Ctx) Sjson(json, path string, value interface{}) error {
raw, err := sjson.SetBytesOptions(S2B(json), path, value, &sjson.Options{
Optimistic: true,
})
if err != nil {
return err
}
ctx.Fasthttp.Response.Header.SetContentTypeBytes(applicationjson)
ctx.Fasthttp.Response.SetBodyString(B2S(raw))
return nil
}
// SjsonString : https://github.com/tidwall/sjson
func (ctx *Ctx) SjsonStr(json, path, value string) error {
raw, err := sjson.SetBytesOptions(S2B(json), path, S2B(value), &sjson.Options{
Optimistic: true,
})
if err != nil {
return err
}
ctx.Fasthttp.Response.Header.SetContentTypeBytes(applicationjson)
ctx.Fasthttp.Response.SetBodyString(B2S(raw))
return nil
}
// Status : https://gofiber.github.io/fiber/#/context?id=status
@ -318,7 +345,7 @@ func (ctx *Ctx) Write(args ...interface{}) {
case string:
ctx.Fasthttp.Response.SetBodyString(body)
case []byte:
ctx.Fasthttp.Response.AppendBodyString(b2s(body))
ctx.Fasthttp.Response.AppendBodyString(B2S(body))
default:
panic("body must be a string or []byte")
}

View File

@ -10,12 +10,15 @@ package fiber
import (
"os"
"path/filepath"
"reflect"
"regexp"
"strings"
"unsafe"
)
var (
applicationjson = []byte("application/json")
)
var replacer = strings.NewReplacer(":", "", "?", "")
func getParams(path string) (params []string) {
@ -73,33 +76,11 @@ func walkDir(root string) (files []string, isDir bool, err error) {
return files, isDir, err
}
// b2s converts byte slice to a string without memory allocation.
// See https://groups.google.com/forum/#!msg/Golang-Nuts/ENgbUzYvCuU/90yGx7GUAgAJ .
//
// Note it may break if string and/or slice header will change
// in the future go versions.
func b2s(b []byte) string {
sh := (*reflect.StringHeader)(unsafe.Pointer(&b))
bh := reflect.SliceHeader{
Data: sh.Data,
Len: sh.Len,
Cap: sh.Len,
}
return *(*string)(unsafe.Pointer(&bh))
func B2S(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
// s2b converts string to a byte slice without memory allocation.
//
// Note it may break if string and/or slice header will change
// in the future go versions.
func s2b(s string) []byte {
sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
bh := reflect.SliceHeader{
Data: sh.Data,
Len: sh.Len,
Cap: sh.Len,
}
return *(*[]byte)(unsafe.Pointer(&bh))
func S2B(s string) []byte {
return *(*[]byte)(unsafe.Pointer(&s))
}
// NoCopy embed this type into a struct, which mustn't be copied,