Compare commits

...

19 Commits

Author SHA1 Message Date
Wim
88d371c71c Release v1.18.2 (#1212) 2020-08-25 13:21:53 +02:00
Sandro
b339524613 Add Dockerimage for tgs conversion (#1211)
* Add Dockerfile with tgs to png conversion support

* Add .dockerignore to keep cache busts while testing low
2020-08-25 13:15:24 +02:00
Wim
d5feda5c8a Fix error loop (zulip) (#1210)
Fixes #1047
2020-08-25 00:12:13 +02:00
Wim
2f506425c2 Update whatsapp vendor and fix a panic (#1209)
* Fix another whatsapp panic

* Update whatsapp vendor
2020-08-24 23:35:08 +02:00
Wim
e8167ee3d7 Add link to nctalk in README 2020-08-24 00:50:32 +02:00
Wim
2f5e211065 Bump version 2020-08-24 00:40:26 +02:00
Wim
39f4fb3446 Release v1.18.1 (#1207) 2020-08-24 00:25:30 +02:00
Wim
56159b9bce Sleep when ratelimited on joins (matrix). Fixes #1201 (#1206) 2020-08-24 00:12:30 +02:00
Ben Wiederhake
b2af76e7dc Support Telegram animated stickers (tgs) format (#1173)
This is half a fix for #874

This patch introduces a new config flag:
- MediaConvertTgs

These need to be treated independently from the existing
MediaConvertWebPToPNG flag because Tgs→WebP results in an
*animated* WebP, and the WebP→PNG converter can't handle
animated WebP files yet.

Furthermore, some platforms (like discord) don't even support
animated WebP files, so the user may want to fall back to
static PNGs (not APNGs).

The final reason why this is only half a fix is that this
introduces an external dependency, namely lottie, to be
installed like this:

$ pip3 install lottie cairosvg

This patch works by writing the tgs to a temporary file in /tmp,
calling lottie to convert it (this conversion may take several seconds!),
and then deleting the temporary file.
The temporary file is absolutely necessary, as lottie refuses to
work on non-seekable files.
If anyone comes up with a reasonable use case where /tmp is
unavailable, I can add yet another config option for that, if desired.

Telegram will bail out if the option is configured but lottie isn't found.
2020-08-23 22:34:28 +02:00
Wim
491fe35397 Update workflow builds to go 1.15 2020-08-21 00:29:59 +02:00
Wim
b451285af7 Sync with upstream gozulipbot fixes (#1202) 2020-08-21 00:14:33 +02:00
Dellle
63a1847cdc Remove HTML formatting for push messages (#1188) (#1189)
When there is a valid HTML formatting then remove this in the cleartext
field of the matrix client. This leads to nicer push messages on
smartphone apps.

Fix #1188
2020-08-20 22:41:53 +02:00
Wim
4e50fd8649 Use mattermost v5 module (#1192) 2020-08-10 00:29:54 +02:00
Wim
dfdffa0027 Add EnableAllEvents
Add option to have all events send to the messagechan
2020-08-09 21:46:45 +02:00
Wim
ebd2073144 Handle panic in whatsapp. Fixes #1180 (#1184) 2020-07-30 23:55:31 +02:00
Wim
1e94b716fb Fix typo in documentation (#1183) 2020-07-30 23:46:03 +02:00
Wim
2a41abb3d1 Update linter config 2020-07-26 15:05:52 +02:00
Gary Kim
2d2bebe976 Fix Nextcloud Talk connection failure (#1179)
Fix #1177

Signed-off-by: Gary Kim <gary@garykim.dev>
2020-07-26 14:51:07 +02:00
Wim
e1629994bd Bump version 2020-07-24 21:31:28 +02:00
640 changed files with 85986 additions and 25910 deletions

2
.dockerignore Normal file
View File

@@ -0,0 +1,2 @@
Dockerfile
tgs.Dockerfile

View File

@@ -9,14 +9,14 @@ jobs:
with:
fetch-depth: 20
- name: Run golangci-lint
uses: golangci/golangci-lint-action@v1
uses: golangci/golangci-lint-action@v2
with:
version: v1.27
args: "-v --new-from-rev HEAD~1"
version: v1.29
args: "-v --new-from-rev HEAD~5"
test-build-upload:
strategy:
matrix:
go-version: [1.13.x, 1.14.x]
go-version: [1.14.x, 1.15.x]
platform: [ubuntu-latest]
runs-on: ${{ matrix.platform }}
steps:
@@ -38,19 +38,19 @@ jobs:
GOOS=windows GOARCH=amd64 go build -mod=vendor -ldflags "-s -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o output/win/matterbridge-$VERSION-windows-amd64.exe
GOOS=darwin GOARCH=amd64 go build -mod=vendor -ldflags "-s -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o output/mac/matterbridge-$VERSION-darwin-amd64
- name: Upload linux 64-bit
if: startsWith(matrix.go-version,'1.14')
if: startsWith(matrix.go-version,'1.15')
uses: actions/upload-artifact@v2
with:
name: matterbridge-linux-64bit
path: output/lin
- name: Upload windows 64-bit
if: startsWith(matrix.go-version,'1.14')
if: startsWith(matrix.go-version,'1.15')
uses: actions/upload-artifact@v2
with:
name: matterbridge-windows-64bit
path: output/win
- name: Upload darwin 64-bit
if: startsWith(matrix.go-version,'1.14')
if: startsWith(matrix.go-version,'1.15')
uses: actions/upload-artifact@v2
with:
name: matterbridge-darwin-64bit

View File

@@ -180,7 +180,9 @@ linters:
- goerr113
- testpackage
- godot
- interfacer
- goheader
- noctx
# rules to deal with reported isues
issues:

View File

@@ -146,13 +146,13 @@ Questions or want to test on your favorite platform? Join below:
## Screenshots
See https://github.com/42wim/matterbridge/wiki
See <https://github.com/42wim/matterbridge/wiki>
## Installing / upgrading
### Binaries
- Latest stable release [v1.18.0](https://github.com/42wim/matterbridge/releases/latest)
- Latest stable release [v1.18.2](https://github.com/42wim/matterbridge/releases/latest)
- Development releases (follows master) can be downloaded [here](https://github.com/42wim/matterbridge/actions) selecting the latest green build and then artifacts.
To install or upgrade just download the latest [binary](https://github.com/42wim/matterbridge/releases/latest) and follow the instructions on the [howto](https://github.com/42wim/matterbridge/wiki/How-to-create-your-config) for a step by step walkthrough for creating your configuration.
@@ -169,14 +169,13 @@ Most people just want to use binaries, you can find those [here](https://github.
If you really want to build from source, follow these instructions:
Go 1.12+ is required. Make sure you have [Go](https://golang.org/doc/install) properly installed.
```
```bash
go get github.com/42wim/matterbridge
```
You should now have matterbridge binary in the ~/go/bin directory:
```
```bash
$ ls ~/go/bin/
matterbridge
```
@@ -259,7 +258,7 @@ RemoteNickFormat="[{PROTOCOL}/{BRIDGE}] <{NICK}> "
See [howto](https://github.com/42wim/matterbridge/wiki/How-to-create-your-config) for a step by step walkthrough for creating your configuration.
```
```bash
Usage of ./matterbridge:
-conf string
config file (default "matterbridge.toml")
@@ -300,15 +299,15 @@ See [FAQ](https://github.com/42wim/matterbridge/wiki/FAQ)
## Articles
- [matterbridge on kubernetes](https://medium.freecodecamp.org/using-kubernetes-to-deploy-a-chat-gateway-or-when-technology-works-like-its-supposed-to-a169a8cd69a3)
- https://mattermost.com/blog/connect-irc-to-mattermost/
- https://blog.valvin.fr/2016/09/17/mattermost-et-un-channel-irc-cest-possible/
- https://blog.brightscout.com/top-10-mattermost-integrations/
- http://bencey.co.nz/2018/09/17/bridge/
- https://www.algoo.fr/blog/2018/01/19/recouvrez-votre-liberte-en-quittant-slack-pour-un-mattermost-auto-heberge/
- https://kopano.com/blog/matterbridge-bridging-mattermost-chat/
- https://www.stitcher.com/s/?eid=52382713
- https://daniele.tech/2019/02/how-to-use-matterbridge-to-connect-2-different-slack-workspaces/
- https://userlinux.net/mattermost-and-matterbridge.html
- <https://mattermost.com/blog/connect-irc-to-mattermost/>
- <https://blog.valvin.fr/2016/09/17/mattermost-et-un-channel-irc-cest-possible/>
- <https://blog.brightscout.com/top-10-mattermost-integrations/>
- <http://bencey.co.nz/2018/09/17/bridge/>
- <https://www.algoo.fr/blog/2018/01/19/recouvrez-votre-liberte-en-quittant-slack-pour-un-mattermost-auto-heberge/>
- <https://kopano.com/blog/matterbridge-bridging-mattermost-chat/>
- <https://www.stitcher.com/s/?eid=52382713>
- <https://daniele.tech/2019/02/how-to-use-matterbridge-to-connect-2-different-slack-workspaces/>
- <https://userlinux.net/mattermost-and-matterbridge.html>
## Thanks
@@ -321,24 +320,25 @@ See [FAQ](https://github.com/42wim/matterbridge/wiki/FAQ)
Matterbridge wouldn't exist without these libraries:
- discord - https://github.com/bwmarrin/discordgo
- echo - https://github.com/labstack/echo
- gitter - https://github.com/sromku/go-gitter
- gops - https://github.com/google/gops
- gozulipbot - https://github.com/ifo/gozulipbot
- irc - https://github.com/lrstanley/girc
- keybase - https://github.com/keybase/go-keybase-chat-bot
- matrix - https://github.com/matrix-org/gomatrix
- mattermost - https://github.com/mattermost/mattermost-server
- msgraph.go - https://github.com/yaegashi/msgraph.go
- slack - https://github.com/nlopes/slack
- sshchat - https://github.com/shazow/ssh-chat
- steam - https://github.com/Philipp15b/go-steam
- telegram - https://github.com/go-telegram-bot-api/telegram-bot-api
- tengo - https://github.com/d5/tengo
- whatsapp - https://github.com/Rhymen/go-whatsapp/
- xmpp - https://github.com/mattn/go-xmpp
- zulip - https://github.com/ifo/gozulipbot
- discord - <https://github.com/bwmarrin/discordgo>
- echo - <https://github.com/labstack/echo>
- gitter - <https://github.com/sromku/go-gitter>
- gops - <https://github.com/google/gops>
- gozulipbot - <https://github.com/ifo/gozulipbot>
- irc - <https://github.com/lrstanley/girc>
- keybase - <https://github.com/keybase/go-keybase-chat-bot>
- matrix - <https://github.com/matrix-org/gomatrix>
- mattermost - <https://github.com/mattermost/mattermost-server>
- msgraph.go - <https://github.com/yaegashi/msgraph.go>
- nctalk - <https://github.com/gary-kim/go-nc-talk>
- slack - <https://github.com/nlopes/slack>
- sshchat - <https://github.com/shazow/ssh-chat>
- steam - <https://github.com/Philipp15b/go-steam>
- telegram - <https://github.com/go-telegram-bot-api/telegram-bot-api>
- tengo - <https://github.com/d5/tengo>
- whatsapp - <https://github.com/Rhymen/go-whatsapp>
- xmpp - <https://github.com/mattn/go-xmpp>
- zulip - <https://github.com/ifo/gozulipbot>
<!-- Links -->

View File

@@ -100,6 +100,7 @@ type Protocol struct {
MediaDownloadSize int // all protocols
MediaServerDownload string
MediaServerUpload string
MediaConvertTgs string // telegram
MediaConvertWebPToPNG bool // telegram
MessageDelay int // IRC, time in millisecond to wait between messages
MessageFormat string // telegram

View File

@@ -5,7 +5,10 @@ import (
"fmt"
"image/png"
"io"
"io/ioutil"
"net/http"
"os"
"os/exec"
"regexp"
"strings"
"time"
@@ -192,7 +195,7 @@ func ParseMarkdown(input string) string {
return res
}
// ConvertWebPToPNG convert input data (which should be WebP format to PNG format)
// ConvertWebPToPNG converts input data (which should be WebP format) to PNG format
func ConvertWebPToPNG(data *[]byte) error {
r := bytes.NewReader(*data)
m, err := webp.Decode(r)
@@ -207,3 +210,49 @@ func ConvertWebPToPNG(data *[]byte) error {
*data = w.Bytes()
return nil
}
// CanConvertTgsToX Checks whether the external command necessary for ConvertTgsToX works.
func CanConvertTgsToX() error {
// We depend on the fact that `lottie_convert.py --help` has exit status 0.
// Hyrum's Law predicted this, and Murphy's Law predicts that this will break eventually.
// However, there is no alternative like `lottie_convert.py --is-properly-installed`
cmd := exec.Command("lottie_convert.py", "--help")
return cmd.Run()
}
// ConvertTgsToWebP convert input data (which should be tgs format) to WebP format
// This relies on an external command, which is ugly, but works.
func ConvertTgsToX(data *[]byte, outputFormat string, logger *logrus.Entry) error {
// lottie can't handle input from a pipe, so write to a temporary file:
tmpFile, err := ioutil.TempFile(os.TempDir(), "matterbridge-lottie-*.tgs")
if err != nil {
return err
}
tmpFileName := tmpFile.Name()
defer func() {
if removeErr := os.Remove(tmpFileName); removeErr != nil {
logger.Errorf("Could not delete temporary file %s: %v", tmpFileName, removeErr)
}
}()
if _, writeErr := tmpFile.Write(*data); writeErr != nil {
return writeErr
}
// Must close before calling lottie to avoid data races:
if closeErr := tmpFile.Close(); closeErr != nil {
return closeErr
}
// Call lottie to transform:
cmd := exec.Command("lottie_convert.py", "--input-format", "lottie", "--output-format", outputFormat, tmpFileName, "/dev/stdout")
cmd.Stderr = nil
// NB: lottie writes progress into to stderr in all cases.
stdout, stderr := cmd.Output()
if stderr != nil {
// 'stderr' already contains some parts of Stderr, because it was set to 'nil'.
return stderr
}
*data = stdout
return nil
}

View File

@@ -2,12 +2,14 @@ package bmatrix
import (
"bytes"
"encoding/json"
"fmt"
"html"
"mime"
"regexp"
"strings"
"sync"
"time"
"github.com/42wim/matterbridge/bridge"
"github.com/42wim/matterbridge/bridge/config"
@@ -20,13 +22,21 @@ type Bmatrix struct {
UserID string
RoomMap map[string]string
sync.RWMutex
htmlTag *regexp.Regexp
htmlTag *regexp.Regexp
htmlReplacementTag *regexp.Regexp
*bridge.Config
}
type httpError struct {
Errcode string `json:"errcode"`
Err string `json:"error"`
RetryAfterMs int `json:"retry_after_ms"`
}
func New(cfg *bridge.Config) bridge.Bridger {
b := &Bmatrix{Config: cfg}
b.htmlTag = regexp.MustCompile("</.*?>")
b.htmlReplacementTag = regexp.MustCompile("<[^>]*>")
b.RoomMap = make(map[string]string)
return b
}
@@ -58,14 +68,25 @@ func (b *Bmatrix) Disconnect() error {
}
func (b *Bmatrix) JoinChannel(channel config.ChannelInfo) error {
retry:
resp, err := b.mc.JoinRoom(channel.Name, "", nil)
if err != nil {
httpErr := handleError(err)
if httpErr.Errcode == "M_LIMIT_EXCEEDED" {
b.Log.Infof("getting ratelimited by matrix, sleeping approx %d seconds before joining %s", httpErr.RetryAfterMs/1000, channel.Name)
time.Sleep((time.Duration(httpErr.RetryAfterMs) * time.Millisecond))
goto retry
}
return err
}
b.Lock()
b.RoomMap[resp.RoomID] = channel.Name
b.Unlock()
return err
return nil
}
func (b *Bmatrix) Send(msg config.Message) (string, error) {
@@ -132,13 +153,20 @@ func (b *Bmatrix) Send(msg config.Message) (string, error) {
return resp.EventID, err
}
username := html.EscapeString(msg.Username)
var username string
var plainUsername string
// check if we have a </tag>. if we have, we don't escape HTML. #696
if b.htmlTag.MatchString(msg.Username) {
username = msg.Username
// remove the HTML formatting for beautiful push messages #1188
plainUsername = b.htmlReplacementTag.ReplaceAllString(msg.Username, "")
} else {
username = html.EscapeString(msg.Username)
plainUsername = msg.Username
}
// Post normal message with HTML support (eg riot.im)
resp, err := b.mc.SendHTML(channel, msg.Username+msg.Text, username+helper.ParseMarkdown(msg.Text))
resp, err := b.mc.SendHTML(channel, plainUsername+msg.Text, username+helper.ParseMarkdown(msg.Text))
if err != nil {
return "", err
}
@@ -385,3 +413,22 @@ func (b *Bmatrix) getAvatarURL(sender string) string {
}
return url
}
func handleError(err error) *httpError {
mErr, ok := err.(matrix.HTTPError)
if !ok {
return &httpError{
Err: "not a HTTPError",
}
}
var httpErr httpError
if err := json.Unmarshal(mErr.Contents, &httpErr); err != nil {
return &httpError{
Err: "unmarshal failed",
}
}
return &httpErr
}

View File

@@ -4,7 +4,7 @@ import (
"github.com/42wim/matterbridge/bridge/config"
"github.com/42wim/matterbridge/bridge/helper"
"github.com/42wim/matterbridge/matterclient"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/v5/model"
)
// handleDownloadAvatar downloads the avatar of userid from channel

View File

@@ -7,7 +7,7 @@ import (
"github.com/42wim/matterbridge/bridge/helper"
"github.com/42wim/matterbridge/matterclient"
"github.com/42wim/matterbridge/matterhook"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/v5/model"
)
func (b *Bmattermost) doConnectWebhookBind() error {

View File

@@ -217,6 +217,46 @@ func (b *Btelegram) handleDownloadAvatar(userid int, channel string) {
}
}
func (b *Btelegram) maybeConvertTgs(name *string, data *[]byte) {
var format string
switch b.GetString("MediaConvertTgs") {
case FormatWebp:
b.Log.Debugf("Tgs to WebP conversion enabled, converting %v", name)
format = FormatWebp
case FormatPng:
// The WebP to PNG converter can't handle animated webp files yet,
// and I'm not going to write a path for x/image/webp.
// The error message would be:
// conversion failed: webp: non-Alpha VP8X is not implemented
// So instead, we tell lottie to directly go to PNG.
b.Log.Debugf("Tgs to PNG conversion enabled, converting %v", name)
format = FormatPng
default:
// Otherwise, no conversion was requested. Trying to run the usual webp
// converter would fail, because '.tgs.webp' is actually a gzipped JSON
// file, and has nothing to do with WebP.
return
}
err := helper.ConvertTgsToX(data, format, b.Log)
if err != nil {
b.Log.Errorf("conversion failed: %v", err)
} else {
*name = strings.Replace(*name, "tgs.webp", format, 1)
}
}
func (b *Btelegram) maybeConvertWebp(name *string, data *[]byte) {
if b.GetBool("MediaConvertWebPToPNG") {
b.Log.Debugf("WebP to PNG conversion enabled, converting %v", name)
err := helper.ConvertWebPToPNG(data)
if err != nil {
b.Log.Errorf("conversion failed: %v", err)
} else {
*name = strings.Replace(*name, ".webp", ".png", 1)
}
}
}
// handleDownloadFile handles file download
func (b *Btelegram) handleDownload(rmsg *config.Message, message *tgbotapi.Message) error {
size := 0
@@ -264,15 +304,13 @@ func (b *Btelegram) handleDownload(rmsg *config.Message, message *tgbotapi.Messa
if err != nil {
return err
}
if strings.HasSuffix(name, ".webp") && b.GetBool("MediaConvertWebPToPNG") {
b.Log.Debugf("WebP to PNG conversion enabled, converting %s", name)
err := helper.ConvertWebPToPNG(data)
if err != nil {
b.Log.Errorf("conversion failed: %s", err)
} else {
name = strings.Replace(name, ".webp", ".png", 1)
}
if strings.HasSuffix(name, ".tgs.webp") {
b.maybeConvertTgs(&name, data)
} else if strings.HasSuffix(name, ".webp") {
b.maybeConvertWebp(&name, data)
}
helper.HandleDownloadData(b.Log, rmsg, name, message.Caption, "", data, b.General)
return nil
}

View File

@@ -2,6 +2,7 @@ package btelegram
import (
"html"
"log"
"strconv"
"strings"
@@ -16,6 +17,8 @@ const (
HTMLFormat = "HTML"
HTMLNick = "htmlnick"
MarkdownV2 = "MarkdownV2"
FormatPng = "png"
FormatWebp = "webp"
)
type Btelegram struct {
@@ -25,6 +28,16 @@ type Btelegram struct {
}
func New(cfg *bridge.Config) bridge.Bridger {
tgsConvertFormat := cfg.GetString("MediaConvertTgs")
if tgsConvertFormat != "" {
err := helper.CanConvertTgsToX()
if err != nil {
log.Fatalf("Telegram bridge configured to convert .tgs files to '%s', but lottie does not appear to work:\n%#v", tgsConvertFormat, err)
}
if tgsConvertFormat != FormatPng && tgsConvertFormat != FormatWebp {
log.Fatalf("Telegram bridge configured to convert .tgs files to '%s', but only '%s' and '%s' are supported.", FormatPng, FormatWebp, tgsConvertFormat)
}
}
return &Btelegram{Config: cfg, avatarMap: make(map[string]string)}
}

View File

@@ -78,7 +78,9 @@ func (b *Bwhatsapp) HandleTextMessage(message whatsapp.TextMessage) {
senderJID := message.Info.SenderJid
if len(senderJID) == 0 {
// TODO workaround till https://github.com/Rhymen/go-whatsapp/issues/86 resolved
senderJID = *message.Info.Source.Participant
if message.Info.Source != nil && message.Info.Source.Participant != nil {
senderJID = *message.Info.Source.Participant
}
}
// translate sender's JID to the nicest username we can get

View File

@@ -146,8 +146,8 @@ func (b *Bzulip) handleQueue() error {
b.Log.Debugf("<= Sending message from %s on %s to gateway", rmsg.Username, b.Account)
b.Log.Debugf("<= Message is %#v", rmsg)
b.Remote <- rmsg
b.q.LastEventID = m.ID
}
time.Sleep(time.Second * 3)
}
}

View File

@@ -1,3 +1,33 @@
# v1.18.2
## Bugfix
- zulip: Fix error loop (zulip) (#1210)
- whatsapp: Update whatsapp vendor and fix a panic (#1209)
This release couldn't exist without the following contributors:
@SuperSandro2000, @42wim
# v1.18.1
## New features
- telegram: Support Telegram animated stickers (tgs) format (#1173). See https://github.com/42wim/matterbridge/wiki/Settings#mediaConverttgs for more info
## Enhancements
- matrix: Remove HTML formatting for push messages (#1188) (#1189)
- mattermost: Use mattermost v5 module (#1192)
## Bugfix
- whatsapp: Handle panic in whatsapp. Fixes #1180 (#1184)
- nctalk: Fix Nextcloud Talk connection failure (#1179)
- matrix: Sleep when ratelimited on joins (matrix). Fixes #1201 (#1206)
This release couldn't exist without the following contributors:
@42wim, @BenWiederhake, @Dellle, @gary-kim
# v1.18.0
## New features

16
go.mod
View File

@@ -5,7 +5,7 @@ require (
github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f
github.com/Jeffail/gabs v1.1.1 // indirect
github.com/Philipp15b/go-steam v1.0.1-0.20190816133340-b04c5a83c1c0
github.com/Rhymen/go-whatsapp v0.1.1-0.20200421062035-31e8111ac334
github.com/Rhymen/go-whatsapp v0.1.1-0.20200818115958-f07a700b9819
github.com/d5/tengo/v2 v2.6.0
github.com/davecgh/go-spew v1.1.1
github.com/fsnotify/fsnotify v1.4.9
@@ -16,7 +16,6 @@ require (
github.com/gorilla/schema v1.1.0
github.com/gorilla/websocket v1.4.2
github.com/hashicorp/golang-lru v0.5.4
github.com/hpcloud/tail v1.0.0 // indirect
github.com/jpillora/backoff v1.0.0
github.com/keybase/go-keybase-chat-bot v0.0.0-20200505163032-5cacf52379da
github.com/labstack/echo/v4 v4.1.16
@@ -26,20 +25,16 @@ require (
github.com/matterbridge/emoji v2.1.1-0.20191117213217-af507f6b02db+incompatible
github.com/matterbridge/go-xmpp v0.0.0-20200418225040-c8a3a57b4050
github.com/matterbridge/gomatrix v0.0.0-20200209224845-c2104d7936a6
github.com/matterbridge/gozulipbot v0.0.0-20190212232658-7aa251978a18
github.com/matterbridge/gozulipbot v0.0.0-20200820220548-be5824faa913
github.com/matterbridge/logrus-prefixed-formatter v0.5.3-0.20200523233437-d971309a77ba
github.com/mattermost/mattermost-server v5.5.0+incompatible
github.com/mattermost/mattermost-server/v5 v5.25.2
github.com/mattn/godown v0.0.0-20200217152941-afc959f6a561
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
github.com/missdeer/golib v1.0.3
github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474 // indirect
github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff // indirect
github.com/nelsonken/gomf v0.0.0-20180504123937-a9dd2f9deae9
github.com/nicksnyder/go-i18n v1.4.0 // indirect
github.com/onsi/ginkgo v1.6.0 // indirect
github.com/onsi/gomega v1.4.1 // indirect
github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c
github.com/pborman/uuid v0.0.0-20160216163710-c55201b03606 // indirect
github.com/rs/xid v1.2.1
github.com/russross/blackfriday v1.5.2
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca
@@ -54,10 +49,7 @@ require (
github.com/zfjagann/golang-ring v0.0.0-20190304061218-d34796e0a6c2
golang.org/x/image v0.0.0-20200618115811-c13761719519
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
gomod.garykim.dev/nc-talk v0.0.1
gopkg.in/fsnotify.v1 v1.4.7 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gomod.garykim.dev/nc-talk v0.0.2
)
go 1.13

484
go.sum
View File

@@ -1,5 +1,8 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo=
cloud.google.com/go v0.37.1/go.mod h1:SAbnLi6YTSPKSI0dTUEOVLCkyPfKXK8n4ibqiMoj4ok=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
@@ -10,44 +13,108 @@ cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
contrib.go.opencensus.io/exporter/ocagent v0.4.9/go.mod h1:ueLzZcP7LPhPulEBukGn4aLh7Mx9YJwpVJ9nL2FYltw=
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
git.apache.org/thrift.git v0.12.0/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
github.com/42wim/go-gitter v0.0.0-20170828205020-017310c2d557 h1:IZtuWGfzQnKnCSu+vl8WGLhpVQ5Uvy3rlSwqXSg+sQg=
github.com/42wim/go-gitter v0.0.0-20170828205020-017310c2d557/go.mod h1:jL0YSXMs/txjtGJ4PWrmETOk6KUHMDPMshgQZlTeB3Y=
github.com/Azure/azure-sdk-for-go v26.5.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/go-autorest v11.5.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f h1:2dk3eOnYllh+wUOuDhOoC2vUVoJF/5z478ryJ+wzEII=
github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f/go.mod h1:4a58ifQTEe2uwwsaqbh3i2un5/CBPg+At/qHpt18Tmk=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/Jeffail/gabs v1.1.1 h1:V0uzR08Hj22EX8+8QMhyI9sX2hwRu+/RJhJUmnwda/E=
github.com/Jeffail/gabs v1.1.1/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc=
github.com/Masterminds/glide v0.13.2/go.mod h1:STyF5vcenH/rUqTEv+/hBXlSTo7KYwg2oc2f4tzPWic=
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/squirrel v1.2.0/go.mod h1:yaPeOnPG5ZRwL9oKdTsO/prlkPbXWZlRVMQ/gGlzIuA=
github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PaulARoy/azurestoragecache v0.0.0-20170906084534-3c249a3ba788/go.mod h1:lY1dZd8HBzJ10eqKERHn3CU59tfhzcAVb2c0ZhIWSOk=
github.com/Philipp15b/go-steam v1.0.1-0.20190816133340-b04c5a83c1c0 h1:TO7d4rocnNFng6ZQrPe7U6WqHtK5eHEMrgrnnM/72IQ=
github.com/Philipp15b/go-steam v1.0.1-0.20190816133340-b04c5a83c1c0/go.mod h1:HuVM+sZFzumUdKPWiz+IlCMb4RdsKdT3T+nQBKL+sYg=
github.com/Rhymen/go-whatsapp v0.0.0/go.mod h1:rdQr95g2C1xcOfM7QGOhza58HeI3I+tZ/bbluv7VazA=
github.com/Rhymen/go-whatsapp v0.1.1-0.20200421062035-31e8111ac334 h1:kb1zvD+xd+XbPUdQ0lMxnRaQ76N5C9vMAClLi8Dyw1Y=
github.com/Rhymen/go-whatsapp v0.1.1-0.20200421062035-31e8111ac334/go.mod h1:o7jjkvKnigfu432dMbQ/w4PH0Yp5u4Y6ysCNjUlcYCk=
github.com/Rhymen/go-whatsapp v0.1.1-0.20200818115958-f07a700b9819 h1:LthbEFUDcL9ZSRIs9m9JjThBSKrW6aIj8YGIT7G/SSk=
github.com/Rhymen/go-whatsapp v0.1.1-0.20200818115958-f07a700b9819/go.mod h1:o7jjkvKnigfu432dMbQ/w4PH0Yp5u4Y6ysCNjUlcYCk=
github.com/Rhymen/go-whatsapp/examples/echo v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:zgCiQtBtZ4P4gFWvwl9aashsdwOcbb/EHOGRmSzM8ME=
github.com/Rhymen/go-whatsapp/examples/restoreSession v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:5sCUSpG616ZoSJhlt9iBNI/KXBqrVLcNUJqg7J9+8pU=
github.com/Rhymen/go-whatsapp/examples/sendImage v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:RdiyhanVEGXTam+mZ3k6Y3VDCCvXYCwReOoxGozqhHw=
github.com/Rhymen/go-whatsapp/examples/sendTextMessages v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:suwzklatySS3Q0+NCxCDh5hYfgXdQUWU1DNcxwAxStM=
github.com/RoaringBitmap/roaring v0.4.21/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alexcesaro/log v0.0.0-20150915221235-61e686294e58/go.mod h1:YNfsMyWSs+h+PaYkxGeMVmVCX75Zj/pqdjbu12ciCYE=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/avct/uasurfer v0.0.0-20191028135549-26b5daa857f1/go.mod h1:noBAuukeYOXa0aXGqxr24tADqkwDO2KRD15FsuaZ5a8=
github.com/aws/aws-sdk-go v1.19.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blevesearch/bleve v1.0.7/go.mod h1:3xvmBtaw12Y4C9iA1RTzwWCof5j5HjydjCTiDE2TeE0=
github.com/blevesearch/blevex v0.0.0-20190916190636-152f0fe5c040/go.mod h1:WH+MU2F4T0VmSdaPX+Wu5GYoZBrYWdOZWSjzvYcDmqQ=
github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+7LMvAB5IbSA=
github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ=
github.com/blevesearch/snowballstem v0.9.0/go.mod h1:PivSj3JMc8WuaFkTSRDW2SlrulNWPl4ABg1tC/hlgLs=
github.com/blevesearch/zap/v11 v11.0.7/go.mod h1:bJoY56fdU2m/IP4LLz/1h4jY2thBoREvoqbuJ8zhm9k=
github.com/blevesearch/zap/v12 v12.0.7/go.mod h1:70DNK4ZN4tb42LubeDbfpp6xnm8g3ROYVvvZ6pEoXD8=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/codegangsta/cli v1.20.0/go.mod h1:/qJNoX69yVSKu5o4jLyXAENLRyk1uhi7zkbQ3slBdOA=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/corpix/uarand v0.1.1/go.mod h1:SFKZvkcRoLqVRFZ4u25xPmp6m9ktANfbpXZ7SJ0/FNU=
github.com/couchbase/ghistogram v0.1.0/go.mod h1:s1Jhy76zqfEecpNWJfWUiKZookAFaiGOEoyzgHt9i7k=
github.com/couchbase/moss v0.1.0/go.mod h1:9MaHIaRuy9pvLPUJxB8sh8OrLfyDczECVL37grCIubs=
github.com/couchbase/vellum v1.0.1/go.mod h1:FcwrEivFpNi24R3jLOs3n+fs5RnuQnQqCLBJ1uAg1W4=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8=
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
github.com/cznic/strutil v0.0.0-20181122101858-275e90344537/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc=
github.com/d5/tengo/v2 v2.6.0 h1:D0cJtpiBzaLJ/Smv6nnUc/LIfO46oKwDx85NZtIRNRI=
github.com/d5/tengo/v2 v2.6.0/go.mod h1:XRGjEs5I9jYIKTxly6HCF8oiiilk5E/RYXOZ5b0DZC8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -55,26 +122,65 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/dgoogauth v0.0.0-20190221195224-5a805980a5f3/go.mod h1:hEfFauPHz7+NnjR/yHJGhrKo1Za+zStgwUETx3yzqgY=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/die-net/lrucache v0.0.0-20181227122439-19a39ef22a11/go.mod h1:ew0MSjCVDdtGMjF3kzLK9hwdgF5mOE8SbYVF3Rc7mkU=
github.com/disintegration/imaging v1.6.0/go.mod h1:xuIt+sRxDFrHS0drzXUlCJthkJ8k7lkkUojDSR247MQ=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dyatlov/go-opengraph v0.0.0-20180429202543-816b6608b3c8 h1:6muCmMJat6z7qptVrIf/+OWPxsjAfvhw5/6t+FwEkgg=
github.com/dyatlov/go-opengraph v0.0.0-20180429202543-816b6608b3c8/go.mod h1:nYia/MIs9OyvXXYboPmNOj0gVWo97Wx0sde+ZuKkoM4=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
github.com/go-asn1-ber/asn1-ber v1.3.2-0.20191121212151-29be175fc3a3/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-asn1-ber/asn1-ber v1.4.1 h1:qP/QDxOtmMoJVgXHCXNzDpA0+wkgYB2x5QoLMVOciyw=
github.com/go-asn1-ber/asn1-ber v1.4.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gorp/gorp v2.0.0+incompatible/go.mod h1:7IfkAQnO7jfT/9IQ3R9wL1dFhukN6aQxzKTHnkxzA/E=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-telegram-bot-api/telegram-bot-api v1.0.1-0.20200524105306-7434b0456e81 h1:FdZThbRF0R+2qgyBl3KCVNWWBmKm68E+stT3rnQ02Ww=
github.com/go-telegram-bot-api/telegram-bot-api v1.0.1-0.20200524105306-7434b0456e81/go.mod h1:lDm2E64X4OjFdBUA4hlN4mEvbSitvhJdKw7rsA8KHgI=
github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho=
github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
@@ -83,43 +189,88 @@ github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomarkdown/markdown v0.0.0-20200609195525-3f9352745725 h1:X6sZdr+t2E2jwajTy/FfXbmAKPFTYxEq9hiFgzMiuPQ=
github.com/gomarkdown/markdown v0.0.0-20200609195525-3f9352745725/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU=
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gops v0.3.10 h1:M2XZYgfUW+P7AOCLiu4CRb0rQfwnslLyB4B9Mp0vXmE=
github.com/google/gops v0.3.10/go.mod h1:38bMPVKFh+1X106CPpbLAWtZIR1+xwgzT9gew0kn6w4=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 h1:4EZlYQIiyecYJlUbVkFXCXHz1QPhVXcHnQKAzBTPfQo=
github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4/go.mod h1:lEO7XoHJ/xNRBCxrn4h/CEB67h0kW1B0t4ooP2yrjUA=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99 h1:twflg0XRTjwKpxb/jFExr4HGq6on2dEOmnL6FV+fgPw=
github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY=
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
github.com/grpc-ecosystem/grpc-gateway v1.6.2/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c/go.mod h1:ObS/W+h8RYb1Y7fYivughjxojTmIu5iAIjSrSLCLeqE=
github.com/hako/durafmt v0.0.0-20191009132224-3f39dc1ed9f4/go.mod h1:5Scbynm8dF1XAPwIwkGPqzkM/shndPm79Jd1003hTjE=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
github.com/hashicorp/go-hclog v0.12.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-immutable-radix v1.2.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-msgpack v1.1.5/go.mod h1:gWVc3sv/wbDmR3rQsj1CAktEZzoz1YNK9NfGLXJ69/4=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/go-plugin v1.2.2/go.mod h1:F9eH4LrE/ZsRdbwhfjs9k9HoDUwAHnYtXdgmf1AVNs0=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
@@ -133,15 +284,28 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20190923154419-df201c70410d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428/go.mod h1:uhpZMVGznybq1itEKXj6RYw9I71qK4kH+OGMjRC4KEo=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jamiealquiza/envy v1.1.0/go.mod h1:MP36BriGCLwEHhi1OU8E9569JNZrjWfCvzG7RsPnHus=
github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
@@ -151,23 +315,35 @@ github.com/keybase/go-keybase-chat-bot v0.0.0-20200505163032-5cacf52379da/go.mod
github.com/keybase/go-ps v0.0.0-20190827175125-91aafc93ba19/go.mod h1:hY+WOq6m2FpbvyrI93sMaypsttvaIL5nhVR92dTMUcQ=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kljensen/snowball v0.6.0/go.mod h1:27N7E8fVU5H68RlUmnWwZCfxgt4POBJfENGMvNRhldw=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/labstack/echo/v4 v4.1.16 h1:8swiwjE5Jkai3RPfZoahp8kjVCRNq+y7Q0hPji2Kz0o=
github.com/labstack/echo/v4 v4.1.16/go.mod h1:awO+5TzAjvL8XpibdsfXxPgHr+orhtXZJZIQCVjogKI=
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.4.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lrstanley/girc v0.0.0-20190801035559-4fc93959e1a7 h1:BS9tqL0OCiOGuy/CYYk2gc33fxqaqh5/rhqMKu4tcYA=
github.com/lrstanley/girc v0.0.0-20190801035559-4fc93959e1a7/go.mod h1:liX5MxHPrwgHaKowoLkYGwbXfYABh1jbZ6FpElbGF1I=
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/marstr/guid v0.0.0-20170427235115-8bdf7d1a087c/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20200411204219-d5c18ce75048 h1:B9HaistmV+MD8/33BXmZe1zPIn+RImAFVXNNSOrwU2E=
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20200411204219-d5c18ce75048/go.mod h1:c6MxwqHD+0HvtAJjsHMIdPCiAwGiQwPRPTp69ACMg8A=
github.com/matterbridge/discordgo v0.21.2-0.20200718144317-01fe5db6c78d h1:NBckP4nw7qVspbt7cOZYsrOrEbq7tATdMjSjc1hW63A=
@@ -178,42 +354,71 @@ github.com/matterbridge/go-xmpp v0.0.0-20200418225040-c8a3a57b4050 h1:kWkP1lXpkv
github.com/matterbridge/go-xmpp v0.0.0-20200418225040-c8a3a57b4050/go.mod h1:ECDRehsR9TYTKCAsRS8/wLeOk6UUqDydw47ln7wG41Q=
github.com/matterbridge/gomatrix v0.0.0-20200209224845-c2104d7936a6 h1:Kl65VJv38HjYFnnwH+MP6Z8hcJT5UHuSpHVU5vW1HH0=
github.com/matterbridge/gomatrix v0.0.0-20200209224845-c2104d7936a6/go.mod h1:+jWeaaUtXQbBRdKYWfjW6JDDYiI2XXE+3NnTjW5kg8g=
github.com/matterbridge/gozulipbot v0.0.0-20190212232658-7aa251978a18 h1:fLhwXtWGtfTgZVxHG1lcKjv+re7dRwyyuYFNu69xdho=
github.com/matterbridge/gozulipbot v0.0.0-20190212232658-7aa251978a18/go.mod h1:yAjnZ34DuDyPHMPHHjOsTk/FefW4JJjoMMCGt/8uuQA=
github.com/matterbridge/gozulipbot v0.0.0-20200820220548-be5824faa913 h1:5UGr9fLsvAvhjP6i5XJmd0ZIwYVR2gZCzU1lJZ7wfLY=
github.com/matterbridge/gozulipbot v0.0.0-20200820220548-be5824faa913/go.mod h1:yAjnZ34DuDyPHMPHHjOsTk/FefW4JJjoMMCGt/8uuQA=
github.com/matterbridge/logrus-prefixed-formatter v0.5.3-0.20200523233437-d971309a77ba h1:XleOY4IjAEIcxAh+IFwT5JT5Ze3RHiYz6m+4ZfZ0rc0=
github.com/matterbridge/logrus-prefixed-formatter v0.5.3-0.20200523233437-d971309a77ba/go.mod h1:iXGEotOvwI1R1SjLxRc+BF5rUORTMtE0iMZBT2lxqAU=
github.com/mattermost/mattermost-server v5.5.0+incompatible h1:0wcLGgYtd+YImtLDPf2AOfpBHxbU4suATx+6XKw1XbU=
github.com/mattermost/mattermost-server v5.5.0+incompatible/go.mod h1:5L6MjAec+XXQwMIt791Ganu45GKsSiM+I0tLR9wUj8Y=
github.com/mattermost/go-i18n v1.11.0 h1:1hLKqn/ZvhZ80OekjVPGYcCrBfMz+YxNNgqS+beL7zE=
github.com/mattermost/go-i18n v1.11.0/go.mod h1:RyS7FDNQlzF1PsjbJWHRI35exqaKGSO9qD4iv8QjE34=
github.com/mattermost/gorp v2.0.1-0.20190301154413-3b31e9a39d05+incompatible/go.mod h1:0kX1qa3DOpaPJyOdMLeo7TcBN0QmUszj9a/VygOhDe0=
github.com/mattermost/gosaml2 v0.3.2/go.mod h1:Z429EIOiEi9kbq6yHoApfzlcXpa6dzRDc6pO+Vy2Ksk=
github.com/mattermost/ldap v0.0.0-20191128190019-9f62ba4b8d4d h1:2DV7VIlEv6J5R5o6tUcb3ZMKJYeeZuWZL7Rv1m23TgQ=
github.com/mattermost/ldap v0.0.0-20191128190019-9f62ba4b8d4d/go.mod h1:HLbgMEI5K131jpxGazJ97AxfPDt31osq36YS1oxFQPQ=
github.com/mattermost/mattermost-server/v5 v5.25.2 h1:A1nyhIbRgY6NoSqg5zQP47F3zt2KEDEBcQs0sy5fAmw=
github.com/mattermost/mattermost-server/v5 v5.25.2/go.mod h1:TVkOfVyk4wGw8j5J2IX3PDCP5R7j20IEP4FAezDK8Wk=
github.com/mattermost/rsc v0.0.0-20160330161541-bbaefb05eaa0/go.mod h1:nV5bfVpT//+B1RPD2JvRnxbkLmJEYXmRaaVl15fsXjs=
github.com/mattermost/viper v1.0.4/go.mod h1:uc5hKG9lv4/KRwPOt2c1omOyirS/UnuA2TytiZQSFHM=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.8 h1:3tS41NlGYSmhhe/8fhGRzc+z3AYCw1Fe1WAyLuujKs0=
github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/godown v0.0.0-20200217152941-afc959f6a561 h1:0YGo77enc6tJpXQxUeQWs9bPIQPTH1lbOmc5tgRuq4o=
github.com/mattn/godown v0.0.0-20200217152941-afc959f6a561/go.mod h1:/ivCKurgV/bx6yqtP/Jtc2Xmrv3beCYBvlfAUl4X5g4=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/minio/minio-go/v6 v6.0.55/go.mod h1:KQMM+/44DSlSGSQWSfRrAZ12FVMmpWNuX37i2AX0jfI=
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
github.com/missdeer/golib v1.0.3 h1:+kz/tn1lXlPS8i+gjHHVAZC8YcgrmfiMTqELyvOwI4g=
github.com/missdeer/golib v1.0.3/go.mod h1:Cys1ITPPZxIk2eTcQcKT3jDsBdhICAfrrw+ki/eRXxA=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.2.3 h1:f/MjBEBDLttYCGfRaKBbKSRVF5aV2O6fnBpzknuE3jU=
github.com/mitchellh/mapstructure v1.2.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/monaco-io/request v1.0.3 h1:FsiIwXCCbHEyWx9A7lgg6JBTMHhHlEEsADsgAOvZ9HA=
github.com/monaco-io/request v1.0.3/go.mod h1:EmggwHktBsbJmCgwZXqy7o0H1NNsAstQBWZrFVd3xtQ=
@@ -221,58 +426,140 @@ github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474 h1:oKIteT
github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8=
github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff h1:HLGD5/9UxxfEuO9DtP8gnTmNtMxbPyhYltfxsITel8g=
github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff/go.mod h1:B8jLfIIPn2sKyWr0D7cL2v7tnrDD5z291s2Zypdu89E=
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
github.com/muesli/smartcrop v0.2.1-0.20181030220600-548bbf0c0965/go.mod h1:i2fCI/UorTfgEpPPLWiFBv4pye+YAG78RwcQLUkocpI=
github.com/muesli/smartcrop v0.3.0/go.mod h1:i2fCI/UorTfgEpPPLWiFBv4pye+YAG78RwcQLUkocpI=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/nelsonken/gomf v0.0.0-20180504123937-a9dd2f9deae9 h1:mp6tU1r0xLostUGLkTspf/9/AiHuVD7ptyXhySkDEsE=
github.com/nelsonken/gomf v0.0.0-20180504123937-a9dd2f9deae9/go.mod h1:A5SRAcpTemjGgIuBq6Kic2yHcoeUFWUinOAlMP/i9xo=
github.com/nicksnyder/go-i18n v1.4.0 h1:AgLl+Yq7kg5OYlzCgu9cKTZOyI4tD/NgukKqLqC8E+I=
github.com/nicksnyder/go-i18n v1.4.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
github.com/olivere/elastic v6.2.30+incompatible/go.mod h1:J+q1zQJTgAz9woqsbVRqGeB5G1iqDKVBWLNSYW8yfJ8=
github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.1 h1:PZSj/UFNaVp3KxrzHOcS7oyuWA7LoOY/77yCTEFu21U=
github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c h1:P6XGcuPTigoHf4TSu+3D/7QOQ1MbL6alNwrGhcW7sKw=
github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c/go.mod h1:YnNlZP7l4MhyGQ4CBRwv6ohZTPrUJJZtEv4ZgADkbs4=
github.com/pborman/uuid v0.0.0-20160216163710-c55201b03606 h1:/CPgDYrfeK2LMK6xcUhvI17yO9SlpAdDIJGkhDEgO8A=
github.com/pborman/uuid v0.0.0-20160216163710-c55201b03606/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.7.0 h1:7utD74fnzVc/cpcyy8sjrlFr5vYpypUixARcHIMIGuI=
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/peterbourgon/diskv v0.0.0-20171120014656-2973218375c3/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rickb777/date v1.12.4 h1:+6IzcCCS/1t17DrmnEvrznyq7nM8vPwir6/UhlyohKw=
github.com/rickb777/date v1.12.4/go.mod h1:xP0eo/I5qmUt97yRGClHZfyLZ3ikMw6v6SU5MOGZTE0=
github.com/rickb777/plural v1.2.0 h1:5tvEc7UBCZ7l8h/2UeybSkt/uu1DQsZFOFdNevmUhlE=
github.com/rickb777/plural v1.2.0/go.mod h1:UdpyWFCGbo3mvK3f/PfZOAOrkjzJlYN/sD46XNWJ+Es=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rudderlabs/analytics-go v3.2.1+incompatible/go.mod h1:LF8/ty9kUX4PTY3l5c97K3nZZaX5Hwsvt+NBaRL/f30=
github.com/russellhaering/goxmldsig v0.0.0-20180430223755-7acd5e4a6ef7/go.mod h1:Oz4y6ImuOQZxynhbSXk7btjEfNBtGlj2dcaOvXl2FSM=
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
github.com/satori/go.uuid v0.0.0-20180103174451-36e9d2ebbde5/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/segmentio/analytics-go v3.1.0+incompatible/go.mod h1:C7CYBtQWk4vRk2RyLu0qOcbHJ18E3F1HV2C/8JvKN48=
github.com/segmentio/backo-go v0.0.0-20200129164019-23eae7c10bd3/go.mod h1:9/Rh6yILuLysoQnZ2oNooD2g7aBnvM7r/fNVxRNWfBc=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shazow/rateio v0.0.0-20150116013248-e8e00881e5c1 h1:Lx3BlDGFElJt4u/zKc9A3BuGYbQAGlEFyPuUA3jeMD0=
github.com/shazow/rateio v0.0.0-20150116013248-e8e00881e5c1/go.mod h1:vt2jWY/3Qw1bIzle5thrJWucsLuuX9iUNnp20CqCciI=
github.com/shazow/ssh-chat v1.8.3-0.20200308224626-80ddf1f43a98 h1:sN07ff+PSRsUNhpSod4uGKAQ+Nc0FXsBPG9FmYMNg4w=
github.com/shazow/ssh-chat v1.8.3-0.20200308224626-80ddf1f43a98/go.mod h1:xkTgfD+WP+KR4HuG76oal25BBEeu5kJyi2EOsgiu/4Q=
github.com/shirou/gopsutil v2.20.4+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw=
github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI=
github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU=
github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag=
github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg=
github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw=
github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y=
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q=
github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ=
github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I=
github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0=
github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ=
github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk=
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9 h1:lpEzuenPuO1XNTeikEmvqYFcU37GVLl8SRNblzyvGBE=
@@ -281,22 +568,43 @@ github.com/slack-go/slack v0.6.5 h1:IkDKtJ2IROJNoe3d6mW870/NRKvq2fhLB/Q5XmzWk00=
github.com/slack-go/slack v0.6.5/go.mod h1:FGqNzJBmxIsZURAxh2a8D21AnOVvvXZvGligs4npPUM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8=
github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM=
github.com/steveyen/gtreap v0.1.0/go.mod h1:kl/5J7XbrOmlIbYIXdRHDDE5QxHqpk0cmkT7Z4dM9/Y=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@@ -304,45 +612,88 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8=
github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM=
github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog=
github.com/throttled/throttled v2.2.4+incompatible/go.mod h1:0BjlrEGQmvxps+HuXLsyRdqpSRvJpq0PNIsOtqP9Nos=
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/tylerb/graceful v1.2.15/go.mod h1:LPYTbOYmUTdabwRt0TGhLllQ0MUNbs0Y5q1WXJOI9II=
github.com/uber/jaeger-client-go v2.23.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
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/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4=
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
github.com/wiggin77/cfg v1.0.2/go.mod h1:b3gotba2e5bXTqTW48DwIFoLc+4lWKP7WPi/CdvZ4aE=
github.com/wiggin77/logr v1.0.4/go.mod h1:h98FF6GPfThhDrHCg063hZA1sIyOEzQ/P85wgqI0IqE=
github.com/wiggin77/merror v1.0.2/go.mod h1:uQTcIU0Z6jRK4OwqganPYerzQxSFJ4GSHM3aurxxQpg=
github.com/wiggin77/srslog v1.0.1/go.mod h1:fehkyYDq1QfuYn60TDPu9YdY2bB85VUW2mvN1WynEls=
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/writeas/go-strip-markdown v2.0.1+incompatible h1:IIqxTM5Jr7RzhigcL6FkrCNfXkvbR+Nbu1ls48pXYcw=
github.com/writeas/go-strip-markdown v2.0.1+incompatible/go.mod h1:Rsyu10ZhbEK9pXdk8V6MVnZmTzRG0alMNLMwa0J01fE=
github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg=
github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xlab/treeprint v1.0.0/go.mod h1:IoImgRak9i3zJyuxOKUP1v4UZd1tMoKkq/Cimt1uhCg=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63MEE3IF9l2/ebyx59GyGgPi+tICQdmM=
github.com/yaegashi/msgraph.go v0.1.3 h1:xeknrGbPGqUVvjjtXGuxvesHLNJ6jEfiOtqJToZe0qw=
github.com/yaegashi/msgraph.go v0.1.3/go.mod h1:dpty8G9hMEC1xBQeXp6Z2hCXKalqczk2BLvK9me/TUU=
github.com/yaegashi/wtz.go v0.0.2/go.mod h1:nOLA5QXsmdkRxBkP5tljhua13ADHCKirLBrzPf4PEJc=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/zfjagann/golang-ring v0.0.0-20190304061218-d34796e0a6c2 h1:UQwvu7FjUEdVYofx0U6bsc5odNE7wa5TSA0fl559GcA=
github.com/zfjagann/golang-ring v0.0.0-20190304061218-d34796e0a6c2/go.mod h1:0MsIttMJIF/8Y7x0XjonJP7K99t3sR6bjj4m5S4JmqU=
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
go.opencensus.io v0.19.1/go.mod h1:gug0GbSHa8Pafr0d2urOSgoXHZ6x/RUlaiT0d9pqb4A=
go.opencensus.io v0.19.2/go.mod h1:NO/8qkisMZLZ1FCsKNqtJPwc8/TaclWyY0B6wcYNg9M=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM=
go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ=
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
golang.org/x/build v0.0.0-20190314133821-5284462c4bec/go.mod h1:atTaCNAy0f16Ah5aV1gMSwgiKVHwu/JncqDpuRr7lS4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg=
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -350,46 +701,70 @@ golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200618115811-c13761719519 h1:1e2ufUJNM3lCHEY5jIgac/7UTjd6cgJNdatjPdFWf34=
golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5 h1:WQ8q63x+f/zpC8Ac1s9wLElVoHhm32p6tudrU72n1QA=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190319182350-c85d3e98c914/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -400,12 +775,19 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181218192612-074acd46bca6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -414,8 +796,15 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9 h1:YTzHMGlqJu67/uEo1lBv0n3wBXhXNeUbB1XfN2vmTm0=
@@ -424,45 +813,73 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181219222714-6e267b5cc78e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200428021058-7ae4988eb4d9/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200529172331-a64b76657301 h1:G6CNEgFU8/XwexSnuFw+Jq/WePjRitgy6ofBcPnAIPo=
golang.org/x/tools v0.0.0-20200529172331-a64b76657301/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gomod.garykim.dev/nc-talk v0.0.1 h1:6mgjcAf5/HMkV0CFGeXVfYHG7FAUCQcGR8eg9oM6fCc=
gomod.garykim.dev/nc-talk v0.0.1/go.mod h1:0/Ksg0osAYmnWKs1OcCG+gBQ4HU1xiF1699g9B6jWZw=
gomod.garykim.dev/nc-talk v0.0.2 h1:QagJzL1Ie/sJDachAC42fEXlIh2mK8IDk1/ue0u8IcI=
gomod.garykim.dev/nc-talk v0.0.2/go.mod h1:0/Ksg0osAYmnWKs1OcCG+gBQ4HU1xiF1699g9B6jWZw=
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.0.0-20181220000619-583d854617af/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
google.golang.org/api v0.2.0/go.mod h1:IfRCZScioGtypHNTlz3gFk67J8uePVW7uDTBzXuIkhU=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
google.golang.org/genproto v0.0.0-20181219182458-5a97ab628bfb/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190321212433-e79c0c59cdb5/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@@ -470,20 +887,48 @@ google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200424135956-bca184e23272/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.55.0 h1:E8yzL5unfpW3M6fz/eB7Cb5MQAYSZ7GKo4Qth+N2sgQ=
gopkg.in/ini.v1 v1.55.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/olivere/elastic.v6 v6.2.30/go.mod h1:2cTT8Z+/LcArSWpCgvZqBgt3VOqXiy7v00w12Lz8bd4=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
@@ -491,11 +936,22 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/goversion v1.2.0/go.mod h1:Eih9y/uIBS3ulggl7KNJ09xGSLcuNaLgmvvqa07sgfo=
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
willnorris.com/go/gifresize v1.0.0/go.mod h1:eBM8gogBGCcaH603vxSpnfjwXIpq6nmnj/jauBDKtAk=
willnorris.com/go/imageproxy v0.10.0/go.mod h1:2tWdKRneln3E9X/zwH1RINpQAQWPeUiNynZ7UQ9OROk=

View File

@@ -16,7 +16,7 @@ import (
)
var (
version = "1.18.0"
version = "1.18.2"
githash string
flagConfig = flag.String("conf", "matterbridge.toml", "config file")

View File

@@ -1625,7 +1625,7 @@ IgnoreFailureOnStart=false
#writing, or if the value is empty. Note that the log won't roll, so
#you might want to use logrotate(8) with this feature.
#OPTIONAL (default empty)
LogFile=/var/log/matterbridge.log
LogFile="/var/log/matterbridge.log"
###################################################################
#Tengo configuration

View File

@@ -4,7 +4,7 @@ import (
"errors"
"strings"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/v5/model"
)
// GetChannels returns all channels we're members off
@@ -167,7 +167,7 @@ func (m *MMClient) JoinChannel(channelId string) error { //nolint:golint
}
func (m *MMClient) UpdateChannelsTeam(teamID string) error {
mmchannels, resp := m.Client.GetChannelsForTeamForUser(teamID, m.User.Id, "")
mmchannels, resp := m.Client.GetChannelsForTeamForUser(teamID, m.User.Id, false, "")
if resp.Error != nil {
return errors.New(resp.Error.DetailedError)
}

View File

@@ -13,7 +13,7 @@ import (
"github.com/gorilla/websocket"
"github.com/jpillora/backoff"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/v5/model"
)
func (m *MMClient) doLogin(firstConnection bool, b *backoff.Backoff) error {
@@ -154,7 +154,7 @@ func (m *MMClient) initUser() error {
t := &Team{Team: team, Users: usermap, Id: team.Id}
mmchannels, resp := m.Client.GetChannelsForTeamForUser(team.Id, m.User.Id, "")
mmchannels, resp := m.Client.GetChannelsForTeamForUser(team.Id, m.User.Id, false, "")
if resp.Error != nil {
return resp.Error
}

View File

@@ -11,7 +11,7 @@ import (
lru "github.com/hashicorp/golang-lru"
"github.com/jpillora/backoff"
prefixed "github.com/matterbridge/logrus-prefixed-formatter"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/sirupsen/logrus"
)
@@ -69,6 +69,7 @@ type MMClient struct {
logger *logrus.Entry
rootLogger *logrus.Logger
lruCache *lru.Cache
allevents bool
}
// New will instantiate a new Matterclient with the specified login details without connecting.
@@ -119,6 +120,10 @@ func (m *MMClient) SetLogLevel(level string) {
}
}
func (m *MMClient) EnableAllEvents() {
m.allevents = true
}
// Login tries to connect the client with the loging details with which it was initialized.
func (m *MMClient) Login() error {
// check if this is a first connect or a reconnection
@@ -220,6 +225,10 @@ func (m *MMClient) WsReceiver() {
continue
}
}
if m.allevents {
m.MessageChan <- msg
continue
}
switch msg.Raw.Event {
case model.WEBSOCKET_EVENT_USER_ADDED,
model.WEBSOCKET_EVENT_USER_REMOVED,

View File

@@ -3,7 +3,7 @@ package matterclient
import (
"strings"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/v5/model"
)
func (m *MMClient) parseActionPost(rmsg *Message) {

View File

@@ -4,7 +4,7 @@ import (
"errors"
"time"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/v5/model"
)
func (m *MMClient) GetNickName(userId string) string { //nolint:golint

38
tgs.Dockerfile Normal file
View File

@@ -0,0 +1,38 @@
FROM alpine:edge AS builder
COPY . /go/src/github.com/42wim/matterbridge
RUN apk add \
go \
git \
gcc \
musl-dev \
&& cd /go/src/github.com/42wim/matterbridge \
&& export GOPATH=/go \
&& go get \
&& go build -x -ldflags "-X main.githash=$(git log --pretty=format:'%h' -n 1)" -o /bin/matterbridge
FROM alpine:edge
RUN apk --no-cache add \
ca-certificates \
cairo \
libjpeg-turbo \
mailcap \
py3-webencodings \
python3 \
&& apk --no-cache add --virtual .compile \
gcc \
libffi-dev \
libjpeg-turbo-dev \
musl-dev \
py3-pip \
py3-wheel \
python3-dev \
zlib-dev \
&& pip3 install --no-cache-dir lottie[PNG] \
&& apk --no-cache del .compile
COPY --from=builder /bin/matterbridge /bin/matterbridge
RUN mkdir /etc/matterbridge \
&& touch /etc/matterbridge/matterbridge.toml \
&& ln -sf /matterbridge.toml /etc/matterbridge/matterbridge.toml
ENTRYPOINT ["/bin/matterbridge", "-conf", "/etc/matterbridge/matterbridge.toml"]

View File

@@ -70,6 +70,10 @@ func (myHandler) HandleContactMessage(message whatsapp.ContactMessage) {
fmt.Println(message)
}
func (myHandler) HandleBatteryMessage(msg whatsapp.BatteryMessage) {
fmt.Println(message)
}
wac.AddHandler(myHandler{})
```
The message handlers are all optional, you don't need to implement anything but the error handler to implement the interface. The ImageMessage, VideoMessage, AudioMessage and DocumentMessage provide a Download function to get the media data.

View File

@@ -88,6 +88,8 @@ type Conn struct {
Store *Store
ServerLastSeen time.Time
timeTag string // last 3 digits obtained after a successful login takeover
longClientName string
shortClientName string
clientVersion string
@@ -156,8 +158,8 @@ func (wac *Conn) connect() (err error) {
}()
dialer := &websocket.Dialer{
ReadBufferSize: 25 * 1024 * 1024,
WriteBufferSize: 10 * 1024 * 1024,
ReadBufferSize: 0,
WriteBufferSize: 0,
HandshakeTimeout: wac.msgTimeout,
Proxy: wac.Proxy,
}
@@ -246,3 +248,11 @@ func (wac *Conn) keepAlive(minIntervalMs int, maxIntervalMs int) {
}
}
}
func (wac *Conn) GetConnected() bool {
return wac.connected
}
func (wac *Conn) GetLoggedIn() bool {
return wac.loggedIn
}

View File

@@ -2,6 +2,7 @@ package whatsapp
import (
"fmt"
"github.com/pkg/errors"
)
@@ -20,6 +21,7 @@ var (
ErrServerRespondedWith404 = errors.New("server responded with status 404")
ErrMediaDownloadFailedWith404 = errors.New("download failed with status code 404")
ErrMediaDownloadFailedWith410 = errors.New("download failed with status code 410")
ErrInvalidWebsocket = errors.New("invalid websocket")
)
type ErrConnectionFailed struct {

View File

@@ -133,6 +133,14 @@ type ChatListHandler interface {
HandleChatList(contacts []Chat)
}
/**
The BatteryMessageHandler interface needs to be implemented to receive percentage the device connected dispatched by the dispatcher.
*/
type BatteryMessageHandler interface {
Handler
HandleBatteryMessage(battery BatteryMessage)
}
/*
AddHandler adds an handler to the list of handler that receive dispatched messages.
The provided handler must at least implement the Handler interface. Additionally implemented
@@ -285,6 +293,17 @@ func (wac *Conn) handleWithCustomHandlers(message interface{}, handlers []Handle
}
}
}
case BatteryMessage:
for _, h := range handlers {
if x, ok := h.(BatteryMessageHandler); ok {
if wac.shouldCallSynchronously(h) {
x.HandleBatteryMessage(m)
} else {
go x.HandleBatteryMessage(m)
}
}
}
case *proto.WebMessageInfo:
for _, h := range handlers {
@@ -379,6 +398,10 @@ func (wac *Conn) dispatch(msg interface{}) {
wac.handle(ParseProtoMessage(v))
}
}
} else if con, ok := message.Content.([]binary.Node); ok {
for a := range con {
wac.handle(ParseNodeMessage(con[a]))
}
}
} else if message.Description == "response" && message.Attributes["type"] == "contacts" {
wac.updateContacts(message.Content)

View File

@@ -93,18 +93,21 @@ func downloadMedia(url string) (file []byte, mac []byte, err error) {
return data[:n-10], data[n-10 : n], nil
}
type MediaConn struct {
Status int `json:"status"`
MediaConn struct {
Auth string `json:"auth"`
TTL int `json:"ttl"`
Hosts []struct {
Hostname string `json:"hostname"`
IPs []string `json:"ips"`
} `json:"hosts"`
} `json:"media_conn"`
type MediaConn struct {
Status int `json:"status"`
MediaConn struct {
Auth string `json:"auth"`
TTL int `json:"ttl"`
Hosts []struct {
Hostname string `json:"hostname"`
IPs []interface{} `json:"ips"`
} `json:"hosts"`
} `json:"media_conn"`
}
func (wac *Conn) queryMediaConn() (hostname, auth string, ttl int, err error) {
queryReq := []interface{}{"query", "mediaConn"}
ch, err := wac.writeJson(queryReq)

View File

@@ -81,7 +81,7 @@ func (wac *Conn) Send(msg interface{}) (string, error) {
return "ERROR", fmt.Errorf("error decoding sending response: %v\n", err)
}
if int(resp["status"].(float64)) != 200 {
return "ERROR", fmt.Errorf("message sending responded with %d", resp["status"])
return "ERROR", fmt.Errorf("message sending responded with %v", resp["status"])
}
if int(resp["status"].(float64)) == 200 {
return getMessageInfo(msgProto).Id, nil
@@ -105,6 +105,105 @@ func (wac *Conn) sendProto(p *proto.WebMessageInfo) (<-chan string, error) {
return wac.writeBinary(n, message, ignore, p.Key.GetId())
}
// RevokeMessage revokes a message (marks as "message removed") for everyone
func (wac *Conn) RevokeMessage(remotejid, msgid string, fromme bool) (revokeid string, err error) {
// create a revocation ID (required)
rawrevocationID := make([]byte, 10)
rand.Read(rawrevocationID)
revocationID := strings.ToUpper(hex.EncodeToString(rawrevocationID))
//
ts := uint64(time.Now().Unix())
status := proto.WebMessageInfo_PENDING
mtype := proto.ProtocolMessage_REVOKE
revoker := &proto.WebMessageInfo{
Key: &proto.MessageKey{
FromMe: &fromme,
Id: &revocationID,
RemoteJid: &remotejid,
},
MessageTimestamp: &ts,
Message: &proto.Message{
ProtocolMessage: &proto.ProtocolMessage{
Type: &mtype,
Key: &proto.MessageKey{
FromMe: &fromme,
Id: &msgid,
RemoteJid: &remotejid,
},
},
},
Status: &status,
}
if _, err := wac.Send(revoker); err != nil {
return revocationID, err
}
return revocationID, nil
}
// DeleteMessage deletes a single message for the user (removes the msgbox). To
// delete the message for everyone, use RevokeMessage
func (wac *Conn) DeleteMessage(remotejid, msgid string, fromMe bool) error {
ch, err := wac.deleteChatProto(remotejid, msgid, fromMe)
if err != nil {
return fmt.Errorf("could not send proto: %v", err)
}
select {
case response := <-ch:
var resp map[string]interface{}
if err = json.Unmarshal([]byte(response), &resp); err != nil {
return fmt.Errorf("error decoding deletion response: %v", err)
}
if int(resp["status"].(float64)) != 200 {
return fmt.Errorf("message deletion responded with %v", resp["status"])
}
if int(resp["status"].(float64)) == 200 {
return nil
}
case <-time.After(wac.msgTimeout):
return fmt.Errorf("deleting message timed out")
}
return nil
}
func (wac *Conn) deleteChatProto(remotejid, msgid string, fromMe bool) (<-chan string, error) {
tag := fmt.Sprintf("%s.--%d", wac.timeTag, wac.msgCount)
owner := "true"
if !fromMe {
owner = "false"
}
n := binary.Node{
Description: "action",
Attributes: map[string]string{
"epoch": strconv.Itoa(wac.msgCount),
"type": "set",
},
Content: []interface{}{
binary.Node{
Description: "chat",
Attributes: map[string]string{
"type": "clear",
"jid": remotejid,
"media": "true",
},
Content: []binary.Node{
{
Description: "item",
Attributes: map[string]string{
"owner": owner,
"index": msgid,
},
},
},
},
},
}
return wac.writeBinary(n, chat, expires|skipOffline, tag)
}
func init() {
rand.Seed(time.Now().UTC().UnixNano())
}
@@ -744,3 +843,38 @@ func ParseProtoMessage(msg *proto.WebMessageInfo) interface{} {
return nil
}
/*
BatteryMessage represents a battery level and charging state.
*/
type BatteryMessage struct {
Plugged bool
Powersave bool
Percentage int
}
func getBatteryMessage(msg map[string]string) BatteryMessage {
plugged, _ := strconv.ParseBool(msg["live"])
powersave, _ := strconv.ParseBool(msg["powersave"])
percentage, _ := strconv.Atoi(msg["value"])
batteryMessage := BatteryMessage{
Plugged: plugged,
Powersave: powersave,
Percentage: percentage,
}
return batteryMessage
}
func ParseNodeMessage(msg binary.Node) interface{} {
switch msg.Description {
case "battery":
return getBatteryMessage(msg.Attributes)
default:
//cannot match message
}
return nil
}

View File

@@ -5,13 +5,14 @@ import (
"crypto/sha256"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"strings"
"github.com/Rhymen/go-whatsapp/binary"
"github.com/Rhymen/go-whatsapp/crypto/cbc"
"github.com/gorilla/websocket"
"github.com/pkg/errors"
"io"
"io/ioutil"
"strings"
)
func (wac *Conn) readPump() {
@@ -27,7 +28,9 @@ func (wac *Conn) readPump() {
for {
readerFound := make(chan struct{})
go func() {
msgType, reader, readErr = wac.ws.conn.NextReader()
if wac.ws != nil {
msgType, reader, readErr = wac.ws.conn.NextReader()
}
close(readerFound)
}()
select {

View File

@@ -18,7 +18,7 @@ import (
)
//represents the WhatsAppWeb client version
var waVersion = []int{0, 4, 2080}
var waVersion = []int{2, 2033, 7}
/*
Session contains session individual information. To be able to resume the connection without scanning the qr code
@@ -141,11 +141,11 @@ func CheckCurrentServerVersion() ([]int, error) {
SetClientName sets the long and short client names that are sent to WhatsApp when logging in and displayed in the
WhatsApp Web device list. As the values are only sent when logging in, changing them after logging in is not possible.
*/
func (wac *Conn) SetClientName(long, short, version string) error {
func (wac *Conn) SetClientName(long, short string) error {
if wac.session != nil && (wac.session.EncKey != nil || wac.session.MacKey != nil) {
return fmt.Errorf("cannot change client name after logging in")
}
wac.longClientName, wac.shortClientName, wac.clientVersion = long, short, version
wac.longClientName, wac.shortClientName = long, short
return nil
}
@@ -231,7 +231,12 @@ func (wac *Conn) Login(qrChan chan<- string) (Session, error) {
return session, fmt.Errorf("error decoding login resp: %v\n", err)
}
ref := resp["ref"].(string)
var ref string
if rref, ok := resp["ref"].(string); ok {
ref = rref
} else {
return session, fmt.Errorf("error decoding login resp: invalid resp['ref']\n")
}
priv, pub, err := curve25519.GenerateKey()
if err != nil {
@@ -390,9 +395,11 @@ func (wac *Conn) Restore() error {
}
if int(resp["status"].(float64)) != 200 {
wac.timeTag = ""
return fmt.Errorf("init responded with %d", resp["status"])
}
case <-time.After(wac.msgTimeout):
wac.timeTag = ""
return fmt.Errorf("restore session init timed out")
}
@@ -401,10 +408,11 @@ func (wac *Conn) Restore() error {
select {
case r1 := <-s1:
if err := json.Unmarshal([]byte(r1), &connResp); err != nil {
wac.timeTag = ""
return fmt.Errorf("error decoding s1 message: %v\n", err)
}
case <-time.After(wac.msgTimeout):
wac.timeTag = ""
//check for an error message
select {
case r := <-loginChan:
@@ -429,15 +437,18 @@ func (wac *Conn) Restore() error {
wac.listener.Unlock()
if err := wac.resolveChallenge(connResp[1].(map[string]interface{})["challenge"].(string)); err != nil {
wac.timeTag = ""
return fmt.Errorf("error resolving challenge: %v\n", err)
}
select {
case r := <-s2:
if err := json.Unmarshal([]byte(r), &connResp); err != nil {
wac.timeTag = ""
return fmt.Errorf("error decoding s2 message: %v\n", err)
}
case <-time.After(wac.msgTimeout):
wac.timeTag = ""
return fmt.Errorf("restore session challenge timed out")
}
}
@@ -447,13 +458,16 @@ func (wac *Conn) Restore() error {
case r := <-loginChan:
var resp map[string]interface{}
if err = json.Unmarshal([]byte(r), &resp); err != nil {
wac.timeTag = ""
return fmt.Errorf("error decoding login connResp: %v\n", err)
}
if int(resp["status"].(float64)) != 200 {
wac.timeTag = ""
return fmt.Errorf("admin login responded with %d", resp["status"])
}
case <-time.After(wac.msgTimeout):
wac.timeTag = ""
return fmt.Errorf("restore session login timed out")
}

View File

@@ -30,6 +30,11 @@ func (wac *Conn) writeJson(data []interface{}) (<-chan string, error) {
messageTag := fmt.Sprintf("%d.--%d", ts, wac.msgCount)
bytes := []byte(fmt.Sprintf("%s,%s", messageTag, d))
if wac.timeTag == "" {
tss := fmt.Sprintf("%d", ts)
wac.timeTag = tss[len(tss)-3:]
}
ch, err := wac.write(websocket.TextMessage, messageTag, bytes)
if err != nil {
return nil, err
@@ -127,6 +132,9 @@ func (wac *Conn) write(messageType int, answerMessageTag string, data []byte) (<
wac.listener.Unlock()
}
if wac == nil || wac.ws == nil {
return nil, ErrInvalidWebsocket
}
wac.ws.Lock()
err := wac.ws.conn.WriteMessage(messageType, data)
wac.ws.Unlock()

21
vendor/github.com/blang/semver/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,21 @@
language: go
matrix:
include:
- go: 1.4.3
- go: 1.5.4
- go: 1.6.3
- go: 1.7
- go: tip
allow_failures:
- go: tip
install:
- go get golang.org/x/tools/cmd/cover
- go get github.com/mattn/goveralls
script:
- echo "Test and track coverage" ; $HOME/gopath/bin/goveralls -package "." -service=travis-ci
-repotoken $COVERALLS_TOKEN
- echo "Build examples" ; cd examples && go build
- echo "Check if gofmt'd" ; diff -u <(echo -n) <(gofmt -d -s .)
env:
global:
secure: HroGEAUQpVq9zX1b1VIkraLiywhGbzvNnTZq2TMxgK7JHP8xqNplAeF1izrR2i4QLL9nsY+9WtYss4QuPvEtZcVHUobw6XnL6radF7jS1LgfYZ9Y7oF+zogZ2I5QUMRLGA7rcxQ05s7mKq3XZQfeqaNts4bms/eZRefWuaFZbkw=

22
vendor/github.com/blang/semver/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
The MIT License
Copyright (c) 2014 Benedikt Lang <github at benediktlang.de>
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.

194
vendor/github.com/blang/semver/README.md generated vendored Normal file
View File

@@ -0,0 +1,194 @@
semver for golang [![Build Status](https://travis-ci.org/blang/semver.svg?branch=master)](https://travis-ci.org/blang/semver) [![GoDoc](https://godoc.org/github.com/blang/semver?status.png)](https://godoc.org/github.com/blang/semver) [![Coverage Status](https://img.shields.io/coveralls/blang/semver.svg)](https://coveralls.io/r/blang/semver?branch=master)
======
semver is a [Semantic Versioning](http://semver.org/) library written in golang. It fully covers spec version `2.0.0`.
Usage
-----
```bash
$ go get github.com/blang/semver
```
Note: Always vendor your dependencies or fix on a specific version tag.
```go
import github.com/blang/semver
v1, err := semver.Make("1.0.0-beta")
v2, err := semver.Make("2.0.0-beta")
v1.Compare(v2)
```
Also check the [GoDocs](http://godoc.org/github.com/blang/semver).
Why should I use this lib?
-----
- Fully spec compatible
- No reflection
- No regex
- Fully tested (Coverage >99%)
- Readable parsing/validation errors
- Fast (See [Benchmarks](#benchmarks))
- Only Stdlib
- Uses values instead of pointers
- Many features, see below
Features
-----
- Parsing and validation at all levels
- Comparator-like comparisons
- Compare Helper Methods
- InPlace manipulation
- Ranges `>=1.0.0 <2.0.0 || >=3.0.0 !3.0.1-beta.1`
- Wildcards `>=1.x`, `<=2.5.x`
- Sortable (implements sort.Interface)
- database/sql compatible (sql.Scanner/Valuer)
- encoding/json compatible (json.Marshaler/Unmarshaler)
Ranges
------
A `Range` is a set of conditions which specify which versions satisfy the range.
A condition is composed of an operator and a version. The supported operators are:
- `<1.0.0` Less than `1.0.0`
- `<=1.0.0` Less than or equal to `1.0.0`
- `>1.0.0` Greater than `1.0.0`
- `>=1.0.0` Greater than or equal to `1.0.0`
- `1.0.0`, `=1.0.0`, `==1.0.0` Equal to `1.0.0`
- `!1.0.0`, `!=1.0.0` Not equal to `1.0.0`. Excludes version `1.0.0`.
Note that spaces between the operator and the version will be gracefully tolerated.
A `Range` can link multiple `Ranges` separated by space:
Ranges can be linked by logical AND:
- `>1.0.0 <2.0.0` would match between both ranges, so `1.1.1` and `1.8.7` but not `1.0.0` or `2.0.0`
- `>1.0.0 <3.0.0 !2.0.3-beta.2` would match every version between `1.0.0` and `3.0.0` except `2.0.3-beta.2`
Ranges can also be linked by logical OR:
- `<2.0.0 || >=3.0.0` would match `1.x.x` and `3.x.x` but not `2.x.x`
AND has a higher precedence than OR. It's not possible to use brackets.
Ranges can be combined by both AND and OR
- `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1`
Range usage:
```
v, err := semver.Parse("1.2.3")
range, err := semver.ParseRange(">1.0.0 <2.0.0 || >=3.0.0")
if range(v) {
//valid
}
```
Example
-----
Have a look at full examples in [examples/main.go](examples/main.go)
```go
import github.com/blang/semver
v, err := semver.Make("0.0.1-alpha.preview+123.github")
fmt.Printf("Major: %d\n", v.Major)
fmt.Printf("Minor: %d\n", v.Minor)
fmt.Printf("Patch: %d\n", v.Patch)
fmt.Printf("Pre: %s\n", v.Pre)
fmt.Printf("Build: %s\n", v.Build)
// Prerelease versions array
if len(v.Pre) > 0 {
fmt.Println("Prerelease versions:")
for i, pre := range v.Pre {
fmt.Printf("%d: %q\n", i, pre)
}
}
// Build meta data array
if len(v.Build) > 0 {
fmt.Println("Build meta data:")
for i, build := range v.Build {
fmt.Printf("%d: %q\n", i, build)
}
}
v001, err := semver.Make("0.0.1")
// Compare using helpers: v.GT(v2), v.LT, v.GTE, v.LTE
v001.GT(v) == true
v.LT(v001) == true
v.GTE(v) == true
v.LTE(v) == true
// Or use v.Compare(v2) for comparisons (-1, 0, 1):
v001.Compare(v) == 1
v.Compare(v001) == -1
v.Compare(v) == 0
// Manipulate Version in place:
v.Pre[0], err = semver.NewPRVersion("beta")
if err != nil {
fmt.Printf("Error parsing pre release version: %q", err)
}
fmt.Println("\nValidate versions:")
v.Build[0] = "?"
err = v.Validate()
if err != nil {
fmt.Printf("Validation failed: %s\n", err)
}
```
Benchmarks
-----
BenchmarkParseSimple-4 5000000 390 ns/op 48 B/op 1 allocs/op
BenchmarkParseComplex-4 1000000 1813 ns/op 256 B/op 7 allocs/op
BenchmarkParseAverage-4 1000000 1171 ns/op 163 B/op 4 allocs/op
BenchmarkStringSimple-4 20000000 119 ns/op 16 B/op 1 allocs/op
BenchmarkStringLarger-4 10000000 206 ns/op 32 B/op 2 allocs/op
BenchmarkStringComplex-4 5000000 324 ns/op 80 B/op 3 allocs/op
BenchmarkStringAverage-4 5000000 273 ns/op 53 B/op 2 allocs/op
BenchmarkValidateSimple-4 200000000 9.33 ns/op 0 B/op 0 allocs/op
BenchmarkValidateComplex-4 3000000 469 ns/op 0 B/op 0 allocs/op
BenchmarkValidateAverage-4 5000000 256 ns/op 0 B/op 0 allocs/op
BenchmarkCompareSimple-4 100000000 11.8 ns/op 0 B/op 0 allocs/op
BenchmarkCompareComplex-4 50000000 30.8 ns/op 0 B/op 0 allocs/op
BenchmarkCompareAverage-4 30000000 41.5 ns/op 0 B/op 0 allocs/op
BenchmarkSort-4 3000000 419 ns/op 256 B/op 2 allocs/op
BenchmarkRangeParseSimple-4 2000000 850 ns/op 192 B/op 5 allocs/op
BenchmarkRangeParseAverage-4 1000000 1677 ns/op 400 B/op 10 allocs/op
BenchmarkRangeParseComplex-4 300000 5214 ns/op 1440 B/op 30 allocs/op
BenchmarkRangeMatchSimple-4 50000000 25.6 ns/op 0 B/op 0 allocs/op
BenchmarkRangeMatchAverage-4 30000000 56.4 ns/op 0 B/op 0 allocs/op
BenchmarkRangeMatchComplex-4 10000000 153 ns/op 0 B/op 0 allocs/op
See benchmark cases at [semver_test.go](semver_test.go)
Motivation
-----
I simply couldn't find any lib supporting the full spec. Others were just wrong or used reflection and regex which i don't like.
Contribution
-----
Feel free to make a pull request. For bigger changes create a issue first to discuss about it.
License
-----
See [LICENSE](LICENSE) file.

23
vendor/github.com/blang/semver/json.go generated vendored Normal file
View File

@@ -0,0 +1,23 @@
package semver
import (
"encoding/json"
)
// MarshalJSON implements the encoding/json.Marshaler interface.
func (v Version) MarshalJSON() ([]byte, error) {
return json.Marshal(v.String())
}
// UnmarshalJSON implements the encoding/json.Unmarshaler interface.
func (v *Version) UnmarshalJSON(data []byte) (err error) {
var versionString string
if err = json.Unmarshal(data, &versionString); err != nil {
return
}
*v, err = Parse(versionString)
return
}

17
vendor/github.com/blang/semver/package.json generated vendored Normal file
View File

@@ -0,0 +1,17 @@
{
"author": "blang",
"bugs": {
"URL": "https://github.com/blang/semver/issues",
"url": "https://github.com/blang/semver/issues"
},
"gx": {
"dvcsimport": "github.com/blang/semver"
},
"gxVersion": "0.10.0",
"language": "go",
"license": "MIT",
"name": "semver",
"releaseCmd": "git commit -a -m \"gx publish $VERSION\"",
"version": "3.5.1"
}

416
vendor/github.com/blang/semver/range.go generated vendored Normal file
View File

@@ -0,0 +1,416 @@
package semver
import (
"fmt"
"strconv"
"strings"
"unicode"
)
type wildcardType int
const (
noneWildcard wildcardType = iota
majorWildcard wildcardType = 1
minorWildcard wildcardType = 2
patchWildcard wildcardType = 3
)
func wildcardTypefromInt(i int) wildcardType {
switch i {
case 1:
return majorWildcard
case 2:
return minorWildcard
case 3:
return patchWildcard
default:
return noneWildcard
}
}
type comparator func(Version, Version) bool
var (
compEQ comparator = func(v1 Version, v2 Version) bool {
return v1.Compare(v2) == 0
}
compNE = func(v1 Version, v2 Version) bool {
return v1.Compare(v2) != 0
}
compGT = func(v1 Version, v2 Version) bool {
return v1.Compare(v2) == 1
}
compGE = func(v1 Version, v2 Version) bool {
return v1.Compare(v2) >= 0
}
compLT = func(v1 Version, v2 Version) bool {
return v1.Compare(v2) == -1
}
compLE = func(v1 Version, v2 Version) bool {
return v1.Compare(v2) <= 0
}
)
type versionRange struct {
v Version
c comparator
}
// rangeFunc creates a Range from the given versionRange.
func (vr *versionRange) rangeFunc() Range {
return Range(func(v Version) bool {
return vr.c(v, vr.v)
})
}
// Range represents a range of versions.
// A Range can be used to check if a Version satisfies it:
//
// range, err := semver.ParseRange(">1.0.0 <2.0.0")
// range(semver.MustParse("1.1.1") // returns true
type Range func(Version) bool
// OR combines the existing Range with another Range using logical OR.
func (rf Range) OR(f Range) Range {
return Range(func(v Version) bool {
return rf(v) || f(v)
})
}
// AND combines the existing Range with another Range using logical AND.
func (rf Range) AND(f Range) Range {
return Range(func(v Version) bool {
return rf(v) && f(v)
})
}
// ParseRange parses a range and returns a Range.
// If the range could not be parsed an error is returned.
//
// Valid ranges are:
// - "<1.0.0"
// - "<=1.0.0"
// - ">1.0.0"
// - ">=1.0.0"
// - "1.0.0", "=1.0.0", "==1.0.0"
// - "!1.0.0", "!=1.0.0"
//
// A Range can consist of multiple ranges separated by space:
// Ranges can be linked by logical AND:
// - ">1.0.0 <2.0.0" would match between both ranges, so "1.1.1" and "1.8.7" but not "1.0.0" or "2.0.0"
// - ">1.0.0 <3.0.0 !2.0.3-beta.2" would match every version between 1.0.0 and 3.0.0 except 2.0.3-beta.2
//
// Ranges can also be linked by logical OR:
// - "<2.0.0 || >=3.0.0" would match "1.x.x" and "3.x.x" but not "2.x.x"
//
// AND has a higher precedence than OR. It's not possible to use brackets.
//
// Ranges can be combined by both AND and OR
//
// - `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1`
func ParseRange(s string) (Range, error) {
parts := splitAndTrim(s)
orParts, err := splitORParts(parts)
if err != nil {
return nil, err
}
expandedParts, err := expandWildcardVersion(orParts)
if err != nil {
return nil, err
}
var orFn Range
for _, p := range expandedParts {
var andFn Range
for _, ap := range p {
opStr, vStr, err := splitComparatorVersion(ap)
if err != nil {
return nil, err
}
vr, err := buildVersionRange(opStr, vStr)
if err != nil {
return nil, fmt.Errorf("Could not parse Range %q: %s", ap, err)
}
rf := vr.rangeFunc()
// Set function
if andFn == nil {
andFn = rf
} else { // Combine with existing function
andFn = andFn.AND(rf)
}
}
if orFn == nil {
orFn = andFn
} else {
orFn = orFn.OR(andFn)
}
}
return orFn, nil
}
// splitORParts splits the already cleaned parts by '||'.
// Checks for invalid positions of the operator and returns an
// error if found.
func splitORParts(parts []string) ([][]string, error) {
var ORparts [][]string
last := 0
for i, p := range parts {
if p == "||" {
if i == 0 {
return nil, fmt.Errorf("First element in range is '||'")
}
ORparts = append(ORparts, parts[last:i])
last = i + 1
}
}
if last == len(parts) {
return nil, fmt.Errorf("Last element in range is '||'")
}
ORparts = append(ORparts, parts[last:])
return ORparts, nil
}
// buildVersionRange takes a slice of 2: operator and version
// and builds a versionRange, otherwise an error.
func buildVersionRange(opStr, vStr string) (*versionRange, error) {
c := parseComparator(opStr)
if c == nil {
return nil, fmt.Errorf("Could not parse comparator %q in %q", opStr, strings.Join([]string{opStr, vStr}, ""))
}
v, err := Parse(vStr)
if err != nil {
return nil, fmt.Errorf("Could not parse version %q in %q: %s", vStr, strings.Join([]string{opStr, vStr}, ""), err)
}
return &versionRange{
v: v,
c: c,
}, nil
}
// inArray checks if a byte is contained in an array of bytes
func inArray(s byte, list []byte) bool {
for _, el := range list {
if el == s {
return true
}
}
return false
}
// splitAndTrim splits a range string by spaces and cleans whitespaces
func splitAndTrim(s string) (result []string) {
last := 0
var lastChar byte
excludeFromSplit := []byte{'>', '<', '='}
for i := 0; i < len(s); i++ {
if s[i] == ' ' && !inArray(lastChar, excludeFromSplit) {
if last < i-1 {
result = append(result, s[last:i])
}
last = i + 1
} else if s[i] != ' ' {
lastChar = s[i]
}
}
if last < len(s)-1 {
result = append(result, s[last:])
}
for i, v := range result {
result[i] = strings.Replace(v, " ", "", -1)
}
// parts := strings.Split(s, " ")
// for _, x := range parts {
// if s := strings.TrimSpace(x); len(s) != 0 {
// result = append(result, s)
// }
// }
return
}
// splitComparatorVersion splits the comparator from the version.
// Input must be free of leading or trailing spaces.
func splitComparatorVersion(s string) (string, string, error) {
i := strings.IndexFunc(s, unicode.IsDigit)
if i == -1 {
return "", "", fmt.Errorf("Could not get version from string: %q", s)
}
return strings.TrimSpace(s[0:i]), s[i:], nil
}
// getWildcardType will return the type of wildcard that the
// passed version contains
func getWildcardType(vStr string) wildcardType {
parts := strings.Split(vStr, ".")
nparts := len(parts)
wildcard := parts[nparts-1]
possibleWildcardType := wildcardTypefromInt(nparts)
if wildcard == "x" {
return possibleWildcardType
}
return noneWildcard
}
// createVersionFromWildcard will convert a wildcard version
// into a regular version, replacing 'x's with '0's, handling
// special cases like '1.x.x' and '1.x'
func createVersionFromWildcard(vStr string) string {
// handle 1.x.x
vStr2 := strings.Replace(vStr, ".x.x", ".x", 1)
vStr2 = strings.Replace(vStr2, ".x", ".0", 1)
parts := strings.Split(vStr2, ".")
// handle 1.x
if len(parts) == 2 {
return vStr2 + ".0"
}
return vStr2
}
// incrementMajorVersion will increment the major version
// of the passed version
func incrementMajorVersion(vStr string) (string, error) {
parts := strings.Split(vStr, ".")
i, err := strconv.Atoi(parts[0])
if err != nil {
return "", err
}
parts[0] = strconv.Itoa(i + 1)
return strings.Join(parts, "."), nil
}
// incrementMajorVersion will increment the minor version
// of the passed version
func incrementMinorVersion(vStr string) (string, error) {
parts := strings.Split(vStr, ".")
i, err := strconv.Atoi(parts[1])
if err != nil {
return "", err
}
parts[1] = strconv.Itoa(i + 1)
return strings.Join(parts, "."), nil
}
// expandWildcardVersion will expand wildcards inside versions
// following these rules:
//
// * when dealing with patch wildcards:
// >= 1.2.x will become >= 1.2.0
// <= 1.2.x will become < 1.3.0
// > 1.2.x will become >= 1.3.0
// < 1.2.x will become < 1.2.0
// != 1.2.x will become < 1.2.0 >= 1.3.0
//
// * when dealing with minor wildcards:
// >= 1.x will become >= 1.0.0
// <= 1.x will become < 2.0.0
// > 1.x will become >= 2.0.0
// < 1.0 will become < 1.0.0
// != 1.x will become < 1.0.0 >= 2.0.0
//
// * when dealing with wildcards without
// version operator:
// 1.2.x will become >= 1.2.0 < 1.3.0
// 1.x will become >= 1.0.0 < 2.0.0
func expandWildcardVersion(parts [][]string) ([][]string, error) {
var expandedParts [][]string
for _, p := range parts {
var newParts []string
for _, ap := range p {
if strings.Index(ap, "x") != -1 {
opStr, vStr, err := splitComparatorVersion(ap)
if err != nil {
return nil, err
}
versionWildcardType := getWildcardType(vStr)
flatVersion := createVersionFromWildcard(vStr)
var resultOperator string
var shouldIncrementVersion bool
switch opStr {
case ">":
resultOperator = ">="
shouldIncrementVersion = true
case ">=":
resultOperator = ">="
case "<":
resultOperator = "<"
case "<=":
resultOperator = "<"
shouldIncrementVersion = true
case "", "=", "==":
newParts = append(newParts, ">="+flatVersion)
resultOperator = "<"
shouldIncrementVersion = true
case "!=", "!":
newParts = append(newParts, "<"+flatVersion)
resultOperator = ">="
shouldIncrementVersion = true
}
var resultVersion string
if shouldIncrementVersion {
switch versionWildcardType {
case patchWildcard:
resultVersion, _ = incrementMinorVersion(flatVersion)
case minorWildcard:
resultVersion, _ = incrementMajorVersion(flatVersion)
}
} else {
resultVersion = flatVersion
}
ap = resultOperator + resultVersion
}
newParts = append(newParts, ap)
}
expandedParts = append(expandedParts, newParts)
}
return expandedParts, nil
}
func parseComparator(s string) comparator {
switch s {
case "==":
fallthrough
case "":
fallthrough
case "=":
return compEQ
case ">":
return compGT
case ">=":
return compGE
case "<":
return compLT
case "<=":
return compLE
case "!":
fallthrough
case "!=":
return compNE
}
return nil
}
// MustParseRange is like ParseRange but panics if the range cannot be parsed.
func MustParseRange(s string) Range {
r, err := ParseRange(s)
if err != nil {
panic(`semver: ParseRange(` + s + `): ` + err.Error())
}
return r
}

418
vendor/github.com/blang/semver/semver.go generated vendored Normal file
View File

@@ -0,0 +1,418 @@
package semver
import (
"errors"
"fmt"
"strconv"
"strings"
)
const (
numbers string = "0123456789"
alphas = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-"
alphanum = alphas + numbers
)
// SpecVersion is the latest fully supported spec version of semver
var SpecVersion = Version{
Major: 2,
Minor: 0,
Patch: 0,
}
// Version represents a semver compatible version
type Version struct {
Major uint64
Minor uint64
Patch uint64
Pre []PRVersion
Build []string //No Precendence
}
// Version to string
func (v Version) String() string {
b := make([]byte, 0, 5)
b = strconv.AppendUint(b, v.Major, 10)
b = append(b, '.')
b = strconv.AppendUint(b, v.Minor, 10)
b = append(b, '.')
b = strconv.AppendUint(b, v.Patch, 10)
if len(v.Pre) > 0 {
b = append(b, '-')
b = append(b, v.Pre[0].String()...)
for _, pre := range v.Pre[1:] {
b = append(b, '.')
b = append(b, pre.String()...)
}
}
if len(v.Build) > 0 {
b = append(b, '+')
b = append(b, v.Build[0]...)
for _, build := range v.Build[1:] {
b = append(b, '.')
b = append(b, build...)
}
}
return string(b)
}
// Equals checks if v is equal to o.
func (v Version) Equals(o Version) bool {
return (v.Compare(o) == 0)
}
// EQ checks if v is equal to o.
func (v Version) EQ(o Version) bool {
return (v.Compare(o) == 0)
}
// NE checks if v is not equal to o.
func (v Version) NE(o Version) bool {
return (v.Compare(o) != 0)
}
// GT checks if v is greater than o.
func (v Version) GT(o Version) bool {
return (v.Compare(o) == 1)
}
// GTE checks if v is greater than or equal to o.
func (v Version) GTE(o Version) bool {
return (v.Compare(o) >= 0)
}
// GE checks if v is greater than or equal to o.
func (v Version) GE(o Version) bool {
return (v.Compare(o) >= 0)
}
// LT checks if v is less than o.
func (v Version) LT(o Version) bool {
return (v.Compare(o) == -1)
}
// LTE checks if v is less than or equal to o.
func (v Version) LTE(o Version) bool {
return (v.Compare(o) <= 0)
}
// LE checks if v is less than or equal to o.
func (v Version) LE(o Version) bool {
return (v.Compare(o) <= 0)
}
// Compare compares Versions v to o:
// -1 == v is less than o
// 0 == v is equal to o
// 1 == v is greater than o
func (v Version) Compare(o Version) int {
if v.Major != o.Major {
if v.Major > o.Major {
return 1
}
return -1
}
if v.Minor != o.Minor {
if v.Minor > o.Minor {
return 1
}
return -1
}
if v.Patch != o.Patch {
if v.Patch > o.Patch {
return 1
}
return -1
}
// Quick comparison if a version has no prerelease versions
if len(v.Pre) == 0 && len(o.Pre) == 0 {
return 0
} else if len(v.Pre) == 0 && len(o.Pre) > 0 {
return 1
} else if len(v.Pre) > 0 && len(o.Pre) == 0 {
return -1
}
i := 0
for ; i < len(v.Pre) && i < len(o.Pre); i++ {
if comp := v.Pre[i].Compare(o.Pre[i]); comp == 0 {
continue
} else if comp == 1 {
return 1
} else {
return -1
}
}
// If all pr versions are the equal but one has further prversion, this one greater
if i == len(v.Pre) && i == len(o.Pre) {
return 0
} else if i == len(v.Pre) && i < len(o.Pre) {
return -1
} else {
return 1
}
}
// Validate validates v and returns error in case
func (v Version) Validate() error {
// Major, Minor, Patch already validated using uint64
for _, pre := range v.Pre {
if !pre.IsNum { //Numeric prerelease versions already uint64
if len(pre.VersionStr) == 0 {
return fmt.Errorf("Prerelease can not be empty %q", pre.VersionStr)
}
if !containsOnly(pre.VersionStr, alphanum) {
return fmt.Errorf("Invalid character(s) found in prerelease %q", pre.VersionStr)
}
}
}
for _, build := range v.Build {
if len(build) == 0 {
return fmt.Errorf("Build meta data can not be empty %q", build)
}
if !containsOnly(build, alphanum) {
return fmt.Errorf("Invalid character(s) found in build meta data %q", build)
}
}
return nil
}
// New is an alias for Parse and returns a pointer, parses version string and returns a validated Version or error
func New(s string) (vp *Version, err error) {
v, err := Parse(s)
vp = &v
return
}
// Make is an alias for Parse, parses version string and returns a validated Version or error
func Make(s string) (Version, error) {
return Parse(s)
}
// ParseTolerant allows for certain version specifications that do not strictly adhere to semver
// specs to be parsed by this library. It does so by normalizing versions before passing them to
// Parse(). It currently trims spaces, removes a "v" prefix, and adds a 0 patch number to versions
// with only major and minor components specified
func ParseTolerant(s string) (Version, error) {
s = strings.TrimSpace(s)
s = strings.TrimPrefix(s, "v")
// Split into major.minor.(patch+pr+meta)
parts := strings.SplitN(s, ".", 3)
if len(parts) < 3 {
if strings.ContainsAny(parts[len(parts)-1], "+-") {
return Version{}, errors.New("Short version cannot contain PreRelease/Build meta data")
}
for len(parts) < 3 {
parts = append(parts, "0")
}
s = strings.Join(parts, ".")
}
return Parse(s)
}
// Parse parses version string and returns a validated Version or error
func Parse(s string) (Version, error) {
if len(s) == 0 {
return Version{}, errors.New("Version string empty")
}
// Split into major.minor.(patch+pr+meta)
parts := strings.SplitN(s, ".", 3)
if len(parts) != 3 {
return Version{}, errors.New("No Major.Minor.Patch elements found")
}
// Major
if !containsOnly(parts[0], numbers) {
return Version{}, fmt.Errorf("Invalid character(s) found in major number %q", parts[0])
}
if hasLeadingZeroes(parts[0]) {
return Version{}, fmt.Errorf("Major number must not contain leading zeroes %q", parts[0])
}
major, err := strconv.ParseUint(parts[0], 10, 64)
if err != nil {
return Version{}, err
}
// Minor
if !containsOnly(parts[1], numbers) {
return Version{}, fmt.Errorf("Invalid character(s) found in minor number %q", parts[1])
}
if hasLeadingZeroes(parts[1]) {
return Version{}, fmt.Errorf("Minor number must not contain leading zeroes %q", parts[1])
}
minor, err := strconv.ParseUint(parts[1], 10, 64)
if err != nil {
return Version{}, err
}
v := Version{}
v.Major = major
v.Minor = minor
var build, prerelease []string
patchStr := parts[2]
if buildIndex := strings.IndexRune(patchStr, '+'); buildIndex != -1 {
build = strings.Split(patchStr[buildIndex+1:], ".")
patchStr = patchStr[:buildIndex]
}
if preIndex := strings.IndexRune(patchStr, '-'); preIndex != -1 {
prerelease = strings.Split(patchStr[preIndex+1:], ".")
patchStr = patchStr[:preIndex]
}
if !containsOnly(patchStr, numbers) {
return Version{}, fmt.Errorf("Invalid character(s) found in patch number %q", patchStr)
}
if hasLeadingZeroes(patchStr) {
return Version{}, fmt.Errorf("Patch number must not contain leading zeroes %q", patchStr)
}
patch, err := strconv.ParseUint(patchStr, 10, 64)
if err != nil {
return Version{}, err
}
v.Patch = patch
// Prerelease
for _, prstr := range prerelease {
parsedPR, err := NewPRVersion(prstr)
if err != nil {
return Version{}, err
}
v.Pre = append(v.Pre, parsedPR)
}
// Build meta data
for _, str := range build {
if len(str) == 0 {
return Version{}, errors.New("Build meta data is empty")
}
if !containsOnly(str, alphanum) {
return Version{}, fmt.Errorf("Invalid character(s) found in build meta data %q", str)
}
v.Build = append(v.Build, str)
}
return v, nil
}
// MustParse is like Parse but panics if the version cannot be parsed.
func MustParse(s string) Version {
v, err := Parse(s)
if err != nil {
panic(`semver: Parse(` + s + `): ` + err.Error())
}
return v
}
// PRVersion represents a PreRelease Version
type PRVersion struct {
VersionStr string
VersionNum uint64
IsNum bool
}
// NewPRVersion creates a new valid prerelease version
func NewPRVersion(s string) (PRVersion, error) {
if len(s) == 0 {
return PRVersion{}, errors.New("Prerelease is empty")
}
v := PRVersion{}
if containsOnly(s, numbers) {
if hasLeadingZeroes(s) {
return PRVersion{}, fmt.Errorf("Numeric PreRelease version must not contain leading zeroes %q", s)
}
num, err := strconv.ParseUint(s, 10, 64)
// Might never be hit, but just in case
if err != nil {
return PRVersion{}, err
}
v.VersionNum = num
v.IsNum = true
} else if containsOnly(s, alphanum) {
v.VersionStr = s
v.IsNum = false
} else {
return PRVersion{}, fmt.Errorf("Invalid character(s) found in prerelease %q", s)
}
return v, nil
}
// IsNumeric checks if prerelease-version is numeric
func (v PRVersion) IsNumeric() bool {
return v.IsNum
}
// Compare compares two PreRelease Versions v and o:
// -1 == v is less than o
// 0 == v is equal to o
// 1 == v is greater than o
func (v PRVersion) Compare(o PRVersion) int {
if v.IsNum && !o.IsNum {
return -1
} else if !v.IsNum && o.IsNum {
return 1
} else if v.IsNum && o.IsNum {
if v.VersionNum == o.VersionNum {
return 0
} else if v.VersionNum > o.VersionNum {
return 1
} else {
return -1
}
} else { // both are Alphas
if v.VersionStr == o.VersionStr {
return 0
} else if v.VersionStr > o.VersionStr {
return 1
} else {
return -1
}
}
}
// PreRelease version to string
func (v PRVersion) String() string {
if v.IsNum {
return strconv.FormatUint(v.VersionNum, 10)
}
return v.VersionStr
}
func containsOnly(s string, set string) bool {
return strings.IndexFunc(s, func(r rune) bool {
return !strings.ContainsRune(set, r)
}) == -1
}
func hasLeadingZeroes(s string) bool {
return len(s) > 1 && s[0] == '0'
}
// NewBuildVersion creates a new valid build version
func NewBuildVersion(s string) (string, error) {
if len(s) == 0 {
return "", errors.New("Buildversion is empty")
}
if !containsOnly(s, alphanum) {
return "", fmt.Errorf("Invalid character(s) found in build meta data %q", s)
}
return s, nil
}

28
vendor/github.com/blang/semver/sort.go generated vendored Normal file
View File

@@ -0,0 +1,28 @@
package semver
import (
"sort"
)
// Versions represents multiple versions.
type Versions []Version
// Len returns length of version collection
func (s Versions) Len() int {
return len(s)
}
// Swap swaps two versions inside the collection by its indices
func (s Versions) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
// Less checks if version at index i is less than version at index j
func (s Versions) Less(i, j int) bool {
return s[i].LT(s[j])
}
// Sort sorts a slice of versions
func Sort(versions []Version) {
sort.Sort(Versions(versions))
}

30
vendor/github.com/blang/semver/sql.go generated vendored Normal file
View File

@@ -0,0 +1,30 @@
package semver
import (
"database/sql/driver"
"fmt"
)
// Scan implements the database/sql.Scanner interface.
func (v *Version) Scan(src interface{}) (err error) {
var str string
switch src := src.(type) {
case string:
str = src
case []byte:
str = string(src)
default:
return fmt.Errorf("Version.Scan: cannot convert %T to string.", src)
}
if t, err := Parse(str); err == nil {
*v = t
}
return
}
// Value implements the database/sql/driver.Valuer interface.
func (v Version) Value() (driver.Value, error) {
return v.String(), nil
}

22
vendor/github.com/dyatlov/go-opengraph/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 Vitaly Dyatlov
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.

View File

@@ -0,0 +1,365 @@
package opengraph
import (
"encoding/json"
"io"
"strconv"
"time"
"golang.org/x/net/html"
"golang.org/x/net/html/atom"
)
// Image defines Open Graph Image type
type Image struct {
URL string `json:"url"`
SecureURL string `json:"secure_url"`
Type string `json:"type"`
Width uint64 `json:"width"`
Height uint64 `json:"height"`
draft bool `json:"-"`
}
// Video defines Open Graph Video type
type Video struct {
URL string `json:"url"`
SecureURL string `json:"secure_url"`
Type string `json:"type"`
Width uint64 `json:"width"`
Height uint64 `json:"height"`
draft bool `json:"-"`
}
// Audio defines Open Graph Audio Type
type Audio struct {
URL string `json:"url"`
SecureURL string `json:"secure_url"`
Type string `json:"type"`
draft bool `json:"-"`
}
// Article contain Open Graph Article structure
type Article struct {
PublishedTime *time.Time `json:"published_time"`
ModifiedTime *time.Time `json:"modified_time"`
ExpirationTime *time.Time `json:"expiration_time"`
Section string `json:"section"`
Tags []string `json:"tags"`
Authors []*Profile `json:"authors"`
}
// Profile contains Open Graph Profile structure
type Profile struct {
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Username string `json:"username"`
Gender string `json:"gender"`
}
// Book contains Open Graph Book structure
type Book struct {
ISBN string `json:"isbn"`
ReleaseDate *time.Time `json:"release_date"`
Tags []string `json:"tags"`
Authors []*Profile `json:"authors"`
}
// OpenGraph contains facebook og data
type OpenGraph struct {
isArticle bool
isBook bool
isProfile bool
Type string `json:"type"`
URL string `json:"url"`
Title string `json:"title"`
Description string `json:"description"`
Determiner string `json:"determiner"`
SiteName string `json:"site_name"`
Locale string `json:"locale"`
LocalesAlternate []string `json:"locales_alternate"`
Images []*Image `json:"images"`
Audios []*Audio `json:"audios"`
Videos []*Video `json:"videos"`
Article *Article `json:"article,omitempty"`
Book *Book `json:"book,omitempty"`
Profile *Profile `json:"profile,omitempty"`
}
// NewOpenGraph returns new instance of Open Graph structure
func NewOpenGraph() *OpenGraph {
return &OpenGraph{}
}
// ToJSON a simple wrapper around json.Marshal
func (og *OpenGraph) ToJSON() ([]byte, error) {
return json.Marshal(og)
}
// String return json representation of structure, or error string
func (og *OpenGraph) String() string {
data, err := og.ToJSON()
if err != nil {
return err.Error()
}
return string(data[:])
}
// ProcessHTML parses given html from Reader interface and fills up OpenGraph structure
func (og *OpenGraph) ProcessHTML(buffer io.Reader) error {
z := html.NewTokenizer(buffer)
for {
tt := z.Next()
switch tt {
case html.ErrorToken:
if z.Err() == io.EOF {
return nil
}
return z.Err()
case html.StartTagToken, html.SelfClosingTagToken, html.EndTagToken:
name, hasAttr := z.TagName()
if atom.Lookup(name) == atom.Body {
return nil // OpenGraph is only in head, so we don't need body
}
if atom.Lookup(name) != atom.Meta || !hasAttr {
continue
}
m := make(map[string]string)
var key, val []byte
for hasAttr {
key, val, hasAttr = z.TagAttr()
m[atom.String(key)] = string(val)
}
og.ProcessMeta(m)
}
}
}
func (og *OpenGraph) ensureHasVideo() {
if len(og.Videos) > 0 {
return
}
og.Videos = append(og.Videos, &Video{draft: true})
}
func (og *OpenGraph) ensureHasImage() {
if len(og.Images) > 0 {
return
}
og.Images = append(og.Images, &Image{draft: true})
}
func (og *OpenGraph) ensureHasAudio() {
if len(og.Audios) > 0 {
return
}
og.Audios = append(og.Audios, &Audio{draft: true})
}
// ProcessMeta processes meta attributes and adds them to Open Graph structure if they are suitable for that
func (og *OpenGraph) ProcessMeta(metaAttrs map[string]string) {
switch metaAttrs["property"] {
case "og:description":
og.Description = metaAttrs["content"]
case "og:type":
og.Type = metaAttrs["content"]
switch og.Type {
case "article":
og.isArticle = true
case "book":
og.isBook = true
case "profile":
og.isProfile = true
}
case "og:title":
og.Title = metaAttrs["content"]
case "og:url":
og.URL = metaAttrs["content"]
case "og:determiner":
og.Determiner = metaAttrs["content"]
case "og:site_name":
og.SiteName = metaAttrs["content"]
case "og:locale":
og.Locale = metaAttrs["content"]
case "og:locale:alternate":
og.LocalesAlternate = append(og.LocalesAlternate, metaAttrs["content"])
case "og:audio":
if len(og.Audios)>0 && og.Audios[len(og.Audios)-1].draft {
og.Audios[len(og.Audios)-1].URL = metaAttrs["content"]
og.Audios[len(og.Audios)-1].draft = false
} else {
og.Audios = append(og.Audios, &Audio{URL: metaAttrs["content"]})
}
case "og:audio:secure_url":
og.ensureHasAudio()
og.Audios[len(og.Audios)-1].SecureURL = metaAttrs["content"]
case "og:audio:type":
og.ensureHasAudio()
og.Audios[len(og.Audios)-1].Type = metaAttrs["content"]
case "og:image":
if len(og.Images)>0 && og.Images[len(og.Images)-1].draft {
og.Images[len(og.Images)-1].URL = metaAttrs["content"]
og.Images[len(og.Images)-1].draft = false
} else {
og.Images = append(og.Images, &Image{URL: metaAttrs["content"]})
}
case "og:image:url":
og.ensureHasImage()
og.Images[len(og.Images)-1].URL = metaAttrs["content"]
case "og:image:secure_url":
og.ensureHasImage()
og.Images[len(og.Images)-1].SecureURL = metaAttrs["content"]
case "og:image:type":
og.ensureHasImage()
og.Images[len(og.Images)-1].Type = metaAttrs["content"]
case "og:image:width":
w, err := strconv.ParseUint(metaAttrs["content"], 10, 64)
if err == nil {
og.ensureHasImage()
og.Images[len(og.Images)-1].Width = w
}
case "og:image:height":
h, err := strconv.ParseUint(metaAttrs["content"], 10, 64)
if err == nil {
og.ensureHasImage()
og.Images[len(og.Images)-1].Height = h
}
case "og:video":
if len(og.Videos)>0 && og.Videos[len(og.Videos)-1].draft {
og.Videos[len(og.Videos)-1].URL = metaAttrs["content"]
og.Videos[len(og.Videos)-1].draft = false
} else {
og.Videos = append(og.Videos, &Video{URL: metaAttrs["content"]})
}
case "og:video:url":
og.ensureHasVideo()
og.Videos[len(og.Videos)-1].URL = metaAttrs["content"]
case "og:video:secure_url":
og.ensureHasVideo()
og.Videos[len(og.Videos)-1].SecureURL = metaAttrs["content"]
case "og:video:type":
og.ensureHasVideo()
og.Videos[len(og.Videos)-1].Type = metaAttrs["content"]
case "og:video:width":
w, err := strconv.ParseUint(metaAttrs["content"], 10, 64)
if err == nil {
og.ensureHasVideo()
og.Videos[len(og.Videos)-1].Width = w
}
case "og:video:height":
h, err := strconv.ParseUint(metaAttrs["content"], 10, 64)
if err == nil {
og.ensureHasVideo()
og.Videos[len(og.Videos)-1].Height = h
}
default:
if og.isArticle {
og.processArticleMeta(metaAttrs)
} else if og.isBook {
og.processBookMeta(metaAttrs)
} else if og.isProfile {
og.processProfileMeta(metaAttrs)
}
}
}
func (og *OpenGraph) processArticleMeta(metaAttrs map[string]string) {
if og.Article == nil {
og.Article = &Article{}
}
switch metaAttrs["property"] {
case "article:published_time":
t, err := time.Parse(time.RFC3339, metaAttrs["content"])
if err == nil {
og.Article.PublishedTime = &t
}
case "article:modified_time":
t, err := time.Parse(time.RFC3339, metaAttrs["content"])
if err == nil {
og.Article.ModifiedTime = &t
}
case "article:expiration_time":
t, err := time.Parse(time.RFC3339, metaAttrs["content"])
if err == nil {
og.Article.ExpirationTime = &t
}
case "article:section":
og.Article.Section = metaAttrs["content"]
case "article:tag":
og.Article.Tags = append(og.Article.Tags, metaAttrs["content"])
case "article:author:first_name":
if len(og.Article.Authors) == 0 {
og.Article.Authors = append(og.Article.Authors, &Profile{})
}
og.Article.Authors[len(og.Article.Authors)-1].FirstName = metaAttrs["content"]
case "article:author:last_name":
if len(og.Article.Authors) == 0 {
og.Article.Authors = append(og.Article.Authors, &Profile{})
}
og.Article.Authors[len(og.Article.Authors)-1].LastName = metaAttrs["content"]
case "article:author:username":
if len(og.Article.Authors) == 0 {
og.Article.Authors = append(og.Article.Authors, &Profile{})
}
og.Article.Authors[len(og.Article.Authors)-1].Username = metaAttrs["content"]
case "article:author:gender":
if len(og.Article.Authors) == 0 {
og.Article.Authors = append(og.Article.Authors, &Profile{})
}
og.Article.Authors[len(og.Article.Authors)-1].Gender = metaAttrs["content"]
}
}
func (og *OpenGraph) processBookMeta(metaAttrs map[string]string) {
if og.Book == nil {
og.Book = &Book{}
}
switch metaAttrs["property"] {
case "book:release_date":
t, err := time.Parse(time.RFC3339, metaAttrs["content"])
if err == nil {
og.Book.ReleaseDate = &t
}
case "book:isbn":
og.Book.ISBN = metaAttrs["content"]
case "book:tag":
og.Book.Tags = append(og.Book.Tags, metaAttrs["content"])
case "book:author:first_name":
if len(og.Book.Authors) == 0 {
og.Book.Authors = append(og.Book.Authors, &Profile{})
}
og.Book.Authors[len(og.Book.Authors)-1].FirstName = metaAttrs["content"]
case "book:author:last_name":
if len(og.Book.Authors) == 0 {
og.Book.Authors = append(og.Book.Authors, &Profile{})
}
og.Book.Authors[len(og.Book.Authors)-1].LastName = metaAttrs["content"]
case "book:author:username":
if len(og.Book.Authors) == 0 {
og.Book.Authors = append(og.Book.Authors, &Profile{})
}
og.Book.Authors[len(og.Book.Authors)-1].Username = metaAttrs["content"]
case "book:author:gender":
if len(og.Book.Authors) == 0 {
og.Book.Authors = append(og.Book.Authors, &Profile{})
}
og.Book.Authors[len(og.Book.Authors)-1].Gender = metaAttrs["content"]
}
}
func (og *OpenGraph) processProfileMeta(metaAttrs map[string]string) {
if og.Profile == nil {
og.Profile = &Profile{}
}
switch metaAttrs["property"] {
case "profile:first_name":
og.Profile.FirstName = metaAttrs["content"]
case "profile:last_name":
og.Profile.LastName = metaAttrs["content"]
case "profile:username":
og.Profile.Username = metaAttrs["content"]
case "profile:gender":
og.Profile.Gender = metaAttrs["content"]
}
}

5
vendor/github.com/francoispqt/gojay/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,5 @@
vendor
*.out
*.log
*.test
.vscode

15
vendor/github.com/francoispqt/gojay/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,15 @@
language: go
go:
- "1.10.x"
- "1.11.x"
- "1.12.x"
script:
- go get github.com/golang/dep/cmd/dep github.com/stretchr/testify
- dep ensure -v -vendor-only
- go test ./gojay/codegen/test/... -race
- go test -race -coverprofile=coverage.txt -covermode=atomic
after_success:
- bash <(curl -s https://codecov.io/bash)

163
vendor/github.com/francoispqt/gojay/Gopkg.lock generated vendored Normal file
View File

@@ -0,0 +1,163 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
digest = "1:1a37f9f2ae10d161d9688fb6008ffa14e1631e5068cc3e9698008b9e8d40d575"
name = "cloud.google.com/go"
packages = ["compute/metadata"]
pruneopts = ""
revision = "457ea5c15ccf3b87db582c450e80101989da35f7"
version = "v0.40.0"
[[projects]]
digest = "1:968d8903d598e3fae738325d3410f33f07ea6a2b9ee5591e9c262ee37df6845a"
name = "github.com/go-errors/errors"
packages = ["."]
pruneopts = ""
revision = "a6af135bd4e28680facf08a3d206b454abc877a4"
version = "v1.0.1"
[[projects]]
digest = "1:529d738b7976c3848cae5cf3a8036440166835e389c1f617af701eeb12a0518d"
name = "github.com/golang/protobuf"
packages = ["proto"]
pruneopts = ""
revision = "b5d812f8a3706043e23a9cd5babf2e5423744d30"
version = "v1.3.1"
[[projects]]
branch = "master"
digest = "1:cae59d7b8243c671c9f544965522ba35c0fec48ee80adb9f1400cd2f33abbbec"
name = "github.com/mailru/easyjson"
packages = [
".",
"buffer",
"jlexer",
"jwriter",
]
pruneopts = ""
revision = "1ea4449da9834f4d333f1cc461c374aea217d249"
[[projects]]
digest = "1:1d7e1867c49a6dd9856598ef7c3123604ea3daabf5b83f303ff457bcbc410b1d"
name = "github.com/pkg/errors"
packages = ["."]
pruneopts = ""
revision = "ba968bfe8b2f7e042a574c888954fccecfa385b4"
version = "v0.8.1"
[[projects]]
digest = "1:8d4bbd8ab012efc77ab6b97286f2aff262bcdeac9803bb57d75cf7d0a5e6a877"
name = "github.com/viant/assertly"
packages = ["."]
pruneopts = ""
revision = "04f45e0aeb6f3455884877b047a97bcc95dc9493"
version = "v0.4.8"
[[projects]]
digest = "1:5913451bc2d274673c0716efe226a137625740cd9380641f4d8300ff4f2d82a0"
name = "github.com/viant/toolbox"
packages = [
".",
"cred",
"data",
"storage",
"url",
]
pruneopts = ""
revision = "1be8e4d172138324f40d55ea61a2aeab0c5ce864"
version = "v0.24.0"
[[projects]]
branch = "master"
digest = "1:9d150270ca2c3356f2224a0878daa1652e4d0b25b345f18b4f6e156cc4b8ec5e"
name = "golang.org/x/crypto"
packages = [
"blowfish",
"curve25519",
"ed25519",
"ed25519/internal/edwards25519",
"internal/chacha20",
"internal/subtle",
"poly1305",
"ssh",
]
pruneopts = ""
revision = "f99c8df09eb5bff426315721bfa5f16a99cad32c"
[[projects]]
branch = "master"
digest = "1:5a56f211e7c12a65c5585c629457a2fb91d8719844ee8fab92727ea8adb5721c"
name = "golang.org/x/net"
packages = [
"context",
"context/ctxhttp",
"websocket",
]
pruneopts = ""
revision = "461777fb6f67e8cb9d70cda16573678d085a74cf"
[[projects]]
branch = "master"
digest = "1:01bdbbc604dcd5afb6f66a717f69ad45e9643c72d5bc11678d44ffa5c50f9e42"
name = "golang.org/x/oauth2"
packages = [
".",
"google",
"internal",
"jws",
"jwt",
]
pruneopts = ""
revision = "0f29369cfe4552d0e4bcddc57cc75f4d7e672a33"
[[projects]]
branch = "master"
digest = "1:8ddb956f67d4c176abbbc42b7514aaeaf9ea30daa24e27d2cf30ad82f9334a2c"
name = "golang.org/x/sys"
packages = ["cpu"]
pruneopts = ""
revision = "1e42afee0f762ed3d76e6dd942e4181855fd1849"
[[projects]]
digest = "1:47f391ee443f578f01168347818cb234ed819521e49e4d2c8dd2fb80d48ee41a"
name = "google.golang.org/appengine"
packages = [
".",
"internal",
"internal/app_identity",
"internal/base",
"internal/datastore",
"internal/log",
"internal/modules",
"internal/remote_api",
"internal/urlfetch",
"urlfetch",
]
pruneopts = ""
revision = "b2f4a3cf3c67576a2ee09e1fe62656a5086ce880"
version = "v1.6.1"
[[projects]]
digest = "1:cedccf16b71e86db87a24f8d4c70b0a855872eb967cb906a66b95de56aefbd0d"
name = "gopkg.in/yaml.v2"
packages = ["."]
pruneopts = ""
revision = "51d6538a90f86fe93ac480b35f37b2be17fef232"
version = "v2.2.2"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
input-imports = [
"github.com/go-errors/errors",
"github.com/mailru/easyjson",
"github.com/mailru/easyjson/jlexer",
"github.com/mailru/easyjson/jwriter",
"github.com/viant/assertly",
"github.com/viant/toolbox",
"github.com/viant/toolbox/url",
"golang.org/x/net/websocket",
]
solver-name = "gps-cdcl"
solver-version = 1

23
vendor/github.com/francoispqt/gojay/Gopkg.toml generated vendored Normal file
View File

@@ -0,0 +1,23 @@
# 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/francoispqt/benchmarks*","github.com/stretchr/testify*","github.com/stretchr/testify","github.com/json-iterator/go","github.com/buger/jsonparser"]

21
vendor/github.com/francoispqt/gojay/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2016 gojay
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.

11
vendor/github.com/francoispqt/gojay/Makefile generated vendored Normal file
View File

@@ -0,0 +1,11 @@
.PHONY: test
test:
go test -race -run=^Test -v
.PHONY: cover
cover:
go test -coverprofile=coverage.out -covermode=atomic
.PHONY: coverhtml
coverhtml:
go tool cover -html=coverage.out

855
vendor/github.com/francoispqt/gojay/README.md generated vendored Normal file
View File

@@ -0,0 +1,855 @@
[![Build Status](https://travis-ci.org/francoispqt/gojay.svg?branch=master)](https://travis-ci.org/francoispqt/gojay)
[![codecov](https://codecov.io/gh/francoispqt/gojay/branch/master/graph/badge.svg)](https://codecov.io/gh/francoispqt/gojay)
[![Go Report Card](https://goreportcard.com/badge/github.com/francoispqt/gojay)](https://goreportcard.com/report/github.com/francoispqt/gojay)
[![Go doc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square
)](https://godoc.org/github.com/francoispqt/gojay)
![MIT License](https://img.shields.io/badge/license-mit-blue.svg?style=flat-square)
[![Sourcegraph](https://sourcegraph.com/github.com/francoispqt/gojay/-/badge.svg)](https://sourcegraph.com/github.com/francoispqt/gojay)
![stability-stable](https://img.shields.io/badge/stability-stable-green.svg)
# GoJay
<img src="https://github.com/francoispqt/gojay/raw/master/gojay.png" width="200px">
GoJay is a performant JSON encoder/decoder for Golang (currently the most performant, [see benchmarks](#benchmark-results)).
It has a simple API and doesn't use reflection. It relies on small interfaces to decode/encode structures and slices.
Gojay also comes with powerful stream decoding features and an even faster [Unsafe](#unsafe-api) API.
There is also a [code generation tool](https://github.com/francoispqt/gojay/tree/master/gojay) to make usage easier and faster.
# Why another JSON parser?
I looked at other fast decoder/encoder and realised it was mostly hardly readable static code generation or a lot of reflection, poor streaming features, and not so fast in the end.
Also, I wanted to build a decoder that could consume an io.Reader of line or comma delimited JSON, in a JIT way. To consume a flow of JSON objects from a TCP connection for example or from a standard output. Same way I wanted to build an encoder that could encode a flow of data to a io.Writer.
This is how GoJay aims to be a very fast, JIT stream parser with 0 reflection, low allocation with a friendly API.
# Get started
```bash
go get github.com/francoispqt/gojay
```
* [Encoder](#encoding)
* [Decoder](#decoding)
* [Stream API](#stream-api)
* [Code Generation](https://github.com/francoispqt/gojay/tree/master/gojay)
## Decoding
Decoding is done through two different API similar to standard `encoding/json`:
* [Unmarshal](#unmarshal-api)
* [Decode](#decode-api)
Example of basic stucture decoding with Unmarshal:
```go
import "github.com/francoispqt/gojay"
type user struct {
id int
name string
email string
}
// implement gojay.UnmarshalerJSONObject
func (u *user) UnmarshalJSONObject(dec *gojay.Decoder, key string) error {
switch key {
case "id":
return dec.Int(&u.id)
case "name":
return dec.String(&u.name)
case "email":
return dec.String(&u.email)
}
return nil
}
func (u *user) NKeys() int {
return 3
}
func main() {
u := &user{}
d := []byte(`{"id":1,"name":"gojay","email":"gojay@email.com"}`)
err := gojay.UnmarshalJSONObject(d, u)
if err != nil {
log.Fatal(err)
}
}
```
with Decode:
```go
func main() {
u := &user{}
dec := gojay.NewDecoder(bytes.NewReader([]byte(`{"id":1,"name":"gojay","email":"gojay@email.com"}`)))
err := dec.DecodeObject(d, u)
if err != nil {
log.Fatal(err)
}
}
```
### Unmarshal API
Unmarshal API decodes a `[]byte` to a given pointer with a single function.
Behind the doors, Unmarshal API borrows a `*gojay.Decoder` resets its settings and decodes the data to the given pointer and releases the `*gojay.Decoder` to the pool when it finishes, whether it encounters an error or not.
If it cannot find the right Decoding strategy for the type of the given pointer, it returns an `InvalidUnmarshalError`. You can test the error returned by doing `if ok := err.(InvalidUnmarshalError); ok {}`.
Unmarshal API comes with three functions:
* Unmarshal
```go
func Unmarshal(data []byte, v interface{}) error
```
* UnmarshalJSONObject
```go
func UnmarshalJSONObject(data []byte, v gojay.UnmarshalerJSONObject) error
```
* UnmarshalJSONArray
```go
func UnmarshalJSONArray(data []byte, v gojay.UnmarshalerJSONArray) error
```
### Decode API
Decode API decodes a `[]byte` to a given pointer by creating or borrowing a `*gojay.Decoder` with an `io.Reader` and calling `Decode` methods.
__Getting a *gojay.Decoder or Borrowing__
You can either get a fresh `*gojay.Decoder` calling `dec := gojay.NewDecoder(io.Reader)` or borrow one from the pool by calling `dec := gojay.BorrowDecoder(io.Reader)`.
After using a decoder, you can release it by calling `dec.Release()`. Beware, if you reuse the decoder after releasing it, it will panic with an error of type `InvalidUsagePooledDecoderError`. If you want to fully benefit from the pooling, you must release your decoders after using.
Example getting a fresh an releasing:
```go
str := ""
dec := gojay.NewDecoder(strings.NewReader(`"test"`))
defer dec.Release()
if err := dec.Decode(&str); err != nil {
log.Fatal(err)
}
```
Example borrowing a decoder and releasing:
```go
str := ""
dec := gojay.BorrowDecoder(strings.NewReader(`"test"`))
defer dec.Release()
if err := dec.Decode(&str); err != nil {
log.Fatal(err)
}
```
`*gojay.Decoder` has multiple methods to decode to specific types:
* Decode
```go
func (dec *gojay.Decoder) Decode(v interface{}) error
```
* DecodeObject
```go
func (dec *gojay.Decoder) DecodeObject(v gojay.UnmarshalerJSONObject) error
```
* DecodeArray
```go
func (dec *gojay.Decoder) DecodeArray(v gojay.UnmarshalerJSONArray) error
```
* DecodeInt
```go
func (dec *gojay.Decoder) DecodeInt(v *int) error
```
* DecodeBool
```go
func (dec *gojay.Decoder) DecodeBool(v *bool) error
```
* DecodeString
```go
func (dec *gojay.Decoder) DecodeString(v *string) error
```
All DecodeXxx methods are used to decode top level JSON values. If you are decoding keys or items of a JSON object or array, don't use the Decode methods.
Example:
```go
reader := strings.NewReader(`"John Doe"`)
dec := NewDecoder(reader)
var str string
err := dec.DecodeString(&str)
if err != nil {
log.Fatal(err)
}
fmt.Println(str) // John Doe
```
### Structs and Maps
#### UnmarshalerJSONObject Interface
To unmarshal a JSON object to a structure, the structure must implement the `UnmarshalerJSONObject` interface:
```go
type UnmarshalerJSONObject interface {
UnmarshalJSONObject(*gojay.Decoder, string) error
NKeys() int
}
```
`UnmarshalJSONObject` method takes two arguments, the first one is a pointer to the Decoder (*gojay.Decoder) and the second one is the string value of the current key being parsed. If the JSON data is not an object, the UnmarshalJSONObject method will never be called.
`NKeys` method must return the number of keys to Unmarshal in the JSON object or 0. If zero is returned, all keys will be parsed.
Example of implementation for a struct:
```go
type user struct {
id int
name string
email string
}
// implement UnmarshalerJSONObject
func (u *user) UnmarshalJSONObject(dec *gojay.Decoder, key string) error {
switch key {
case "id":
return dec.Int(&u.id)
case "name":
return dec.String(&u.name)
case "email":
return dec.String(&u.email)
}
return nil
}
func (u *user) NKeys() int {
return 3
}
```
Example of implementation for a `map[string]string`:
```go
// define our custom map type implementing UnmarshalerJSONObject
type message map[string]string
// Implementing Unmarshaler
func (m message) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
str := ""
err := dec.String(&str)
if err != nil {
return err
}
m[k] = str
return nil
}
// we return 0, it tells the Decoder to decode all keys
func (m message) NKeys() int {
return 0
}
```
### Arrays, Slices and Channels
To unmarshal a JSON object to a slice an array or a channel, it must implement the UnmarshalerJSONArray interface:
```go
type UnmarshalerJSONArray interface {
UnmarshalJSONArray(*gojay.Decoder) error
}
```
UnmarshalJSONArray method takes one argument, a pointer to the Decoder (*gojay.Decoder). If the JSON data is not an array, the Unmarshal method will never be called.
Example of implementation with a slice:
```go
type testSlice []string
// implement UnmarshalerJSONArray
func (t *testSlice) UnmarshalJSONArray(dec *gojay.Decoder) error {
str := ""
if err := dec.String(&str); err != nil {
return err
}
*t = append(*t, str)
return nil
}
func main() {
dec := gojay.BorrowDecoder(strings.NewReader(`["Tom", "Jim"]`))
var slice testSlice
err := dec.DecodeArray(&slice)
if err != nil {
log.Fatal(err)
}
fmt.Println(slice) // [Tom Jim]
dec.Release()
}
```
Example of implementation with a channel:
```go
type testChannel chan string
// implement UnmarshalerJSONArray
func (c testChannel) UnmarshalJSONArray(dec *gojay.Decoder) error {
str := ""
if err := dec.String(&str); err != nil {
return err
}
c <- str
return nil
}
func main() {
dec := gojay.BorrowDecoder(strings.NewReader(`["Tom", "Jim"]`))
c := make(testChannel, 2)
err := dec.DecodeArray(c)
if err != nil {
log.Fatal(err)
}
for i := 0; i < 2; i++ {
fmt.Println(<-c)
}
close(c)
dec.Release()
}
```
Example of implementation with an array:
```go
type testArray [3]string
// implement UnmarshalerJSONArray
func (a *testArray) UnmarshalJSONArray(dec *Decoder) error {
var str string
if err := dec.String(&str); err != nil {
return err
}
a[dec.Index()] = str
return nil
}
func main() {
dec := gojay.BorrowDecoder(strings.NewReader(`["Tom", "Jim", "Bob"]`))
var a testArray
err := dec.DecodeArray(&a)
fmt.Println(a) // [Tom Jim Bob]
dec.Release()
}
```
### Other types
To decode other types (string, int, int32, int64, uint32, uint64, float, booleans), you don't need to implement any interface.
Example of encoding strings:
```go
func main() {
json := []byte(`"Jay"`)
var v string
err := gojay.Unmarshal(json, &v)
if err != nil {
log.Fatal(err)
}
fmt.Println(v) // Jay
}
```
### Decode values methods
When decoding a JSON object of a JSON array using `UnmarshalerJSONObject` or `UnmarshalerJSONArray` interface, the `gojay.Decoder` provides dozens of methods to Decode multiple types.
Non exhaustive list of methods available (to see all methods, check the godoc):
```go
dec.Int
dec.Int8
dec.Int16
dec.Int32
dec.Int64
dec.Uint8
dec.Uint16
dec.Uint32
dec.Uint64
dec.String
dec.Time
dec.Bool
dec.SQLNullString
dec.SQLNullInt64
```
## Encoding
Encoding is done through two different API similar to standard `encoding/json`:
* [Marshal](#marshal-api)
* [Encode](#encode-api)
Example of basic structure encoding with Marshal:
```go
import "github.com/francoispqt/gojay"
type user struct {
id int
name string
email string
}
// implement MarshalerJSONObject
func (u *user) MarshalJSONObject(enc *gojay.Encoder) {
enc.IntKey("id", u.id)
enc.StringKey("name", u.name)
enc.StringKey("email", u.email)
}
func (u *user) IsNil() bool {
return u == nil
}
func main() {
u := &user{1, "gojay", "gojay@email.com"}
b, err := gojay.MarshalJSONObject(u)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(b)) // {"id":1,"name":"gojay","email":"gojay@email.com"}
}
```
with Encode:
```go
func main() {
u := &user{1, "gojay", "gojay@email.com"}
b := strings.Builder{}
enc := gojay.NewEncoder(&b)
if err := enc.Encode(u); err != nil {
log.Fatal(err)
}
fmt.Println(b.String()) // {"id":1,"name":"gojay","email":"gojay@email.com"}
}
```
### Marshal API
Marshal API encodes a value to a JSON `[]byte` with a single function.
Behind the doors, Marshal API borrows a `*gojay.Encoder` resets its settings and encodes the data to an internal byte buffer and releases the `*gojay.Encoder` to the pool when it finishes, whether it encounters an error or not.
If it cannot find the right Encoding strategy for the type of the given value, it returns an `InvalidMarshalError`. You can test the error returned by doing `if ok := err.(InvalidMarshalError); ok {}`.
Marshal API comes with three functions:
* Marshal
```go
func Marshal(v interface{}) ([]byte, error)
```
* MarshalJSONObject
```go
func MarshalJSONObject(v gojay.MarshalerJSONObject) ([]byte, error)
```
* MarshalJSONArray
```go
func MarshalJSONArray(v gojay.MarshalerJSONArray) ([]byte, error)
```
### Encode API
Encode API decodes a value to JSON by creating or borrowing a `*gojay.Encoder` sending it to an `io.Writer` and calling `Encode` methods.
__Getting a *gojay.Encoder or Borrowing__
You can either get a fresh `*gojay.Encoder` calling `enc := gojay.NewEncoder(io.Writer)` or borrow one from the pool by calling `enc := gojay.BorrowEncoder(io.Writer)`.
After using an encoder, you can release it by calling `enc.Release()`. Beware, if you reuse the encoder after releasing it, it will panic with an error of type `InvalidUsagePooledEncoderError`. If you want to fully benefit from the pooling, you must release your encoders after using.
Example getting a fresh encoder an releasing:
```go
str := "test"
b := strings.Builder{}
enc := gojay.NewEncoder(&b)
defer enc.Release()
if err := enc.Encode(str); err != nil {
log.Fatal(err)
}
```
Example borrowing an encoder and releasing:
```go
str := "test"
b := strings.Builder{}
enc := gojay.BorrowEncoder(b)
defer enc.Release()
if err := enc.Encode(str); err != nil {
log.Fatal(err)
}
```
`*gojay.Encoder` has multiple methods to encoder specific types to JSON:
* Encode
```go
func (enc *gojay.Encoder) Encode(v interface{}) error
```
* EncodeObject
```go
func (enc *gojay.Encoder) EncodeObject(v gojay.MarshalerJSONObject) error
```
* EncodeArray
```go
func (enc *gojay.Encoder) EncodeArray(v gojay.MarshalerJSONArray) error
```
* EncodeInt
```go
func (enc *gojay.Encoder) EncodeInt(n int) error
```
* EncodeInt64
```go
func (enc *gojay.Encoder) EncodeInt64(n int64) error
```
* EncodeFloat
```go
func (enc *gojay.Encoder) EncodeFloat(n float64) error
```
* EncodeBool
```go
func (enc *gojay.Encoder) EncodeBool(v bool) error
```
* EncodeString
```go
func (enc *gojay.Encoder) EncodeString(s string) error
```
### Structs and Maps
To encode a structure, the structure must implement the MarshalerJSONObject interface:
```go
type MarshalerJSONObject interface {
MarshalJSONObject(enc *gojay.Encoder)
IsNil() bool
}
```
`MarshalJSONObject` method takes one argument, a pointer to the Encoder (*gojay.Encoder). The method must add all the keys in the JSON Object by calling Decoder's methods.
IsNil method returns a boolean indicating if the interface underlying value is nil or not. It is used to safely ensure that the underlying value is not nil without using Reflection.
Example of implementation for a struct:
```go
type user struct {
id int
name string
email string
}
// implement MarshalerJSONObject
func (u *user) MarshalJSONObject(enc *gojay.Encoder) {
enc.IntKey("id", u.id)
enc.StringKey("name", u.name)
enc.StringKey("email", u.email)
}
func (u *user) IsNil() bool {
return u == nil
}
```
Example of implementation for a `map[string]string`:
```go
// define our custom map type implementing MarshalerJSONObject
type message map[string]string
// Implementing Marshaler
func (m message) MarshalJSONObject(enc *gojay.Encoder) {
for k, v := range m {
enc.StringKey(k, v)
}
}
func (m message) IsNil() bool {
return m == nil
}
```
### Arrays and Slices
To encode an array or a slice, the slice/array must implement the MarshalerJSONArray interface:
```go
type MarshalerJSONArray interface {
MarshalJSONArray(enc *gojay.Encoder)
IsNil() bool
}
```
`MarshalJSONArray` method takes one argument, a pointer to the Encoder (*gojay.Encoder). The method must add all element in the JSON Array by calling Decoder's methods.
`IsNil` method returns a boolean indicating if the interface underlying value is nil(empty) or not. It is used to safely ensure that the underlying value is not nil without using Reflection and also to in `OmitEmpty` feature.
Example of implementation:
```go
type users []*user
// implement MarshalerJSONArray
func (u *users) MarshalJSONArray(enc *gojay.Encoder) {
for _, e := range u {
enc.Object(e)
}
}
func (u *users) IsNil() bool {
return len(u) == 0
}
```
### Other types
To encode other types (string, int, float, booleans), you don't need to implement any interface.
Example of encoding strings:
```go
func main() {
name := "Jay"
b, err := gojay.Marshal(name)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(b)) // "Jay"
}
```
# Stream API
### Stream Decoding
GoJay ships with a powerful stream decoder.
It allows to read continuously from an io.Reader stream and do JIT decoding writing unmarshalled JSON to a channel to allow async consuming.
When using the Stream API, the Decoder implements context.Context to provide graceful cancellation.
To decode a stream of JSON, you must call `gojay.Stream.DecodeStream` and pass it a `UnmarshalerStream` implementation.
```go
type UnmarshalerStream interface {
UnmarshalStream(*StreamDecoder) error
}
```
Example of implementation of stream reading from a WebSocket connection:
```go
// implement UnmarshalerStream
type ChannelStream chan *user
func (c ChannelStream) UnmarshalStream(dec *gojay.StreamDecoder) error {
u := &user{}
if err := dec.Object(u); err != nil {
return err
}
c <- u
return nil
}
func main() {
// get our websocket connection
origin := "http://localhost/"
url := "ws://localhost:12345/ws"
ws, err := websocket.Dial(url, "", origin)
if err != nil {
log.Fatal(err)
}
// create our channel which will receive our objects
streamChan := ChannelStream(make(chan *user))
// borrow a decoder
dec := gojay.Stream.BorrowDecoder(ws)
// start decoding, it will block until a JSON message is decoded from the WebSocket
// or until Done channel is closed
go dec.DecodeStream(streamChan)
for {
select {
case v := <-streamChan:
// Got something from my websocket!
log.Println(v)
case <-dec.Done():
log.Println("finished reading from WebSocket")
os.Exit(0)
}
}
}
```
### Stream Encoding
GoJay ships with a powerful stream encoder part of the Stream API.
It allows to write continuously to an io.Writer and do JIT encoding of data fed to a channel to allow async consuming. You can set multiple consumers on the channel to be as performant as possible. Consumers are non blocking and are scheduled individually in their own go routine.
When using the Stream API, the Encoder implements context.Context to provide graceful cancellation.
To encode a stream of data, you must call `EncodeStream` and pass it a `MarshalerStream` implementation.
```go
type MarshalerStream interface {
MarshalStream(enc *gojay.StreamEncoder)
}
```
Example of implementation of stream writing to a WebSocket:
```go
// Our structure which will be pushed to our stream
type user struct {
id int
name string
email string
}
func (u *user) MarshalJSONObject(enc *gojay.Encoder) {
enc.IntKey("id", u.id)
enc.StringKey("name", u.name)
enc.StringKey("email", u.email)
}
func (u *user) IsNil() bool {
return u == nil
}
// Our MarshalerStream implementation
type StreamChan chan *user
func (s StreamChan) MarshalStream(enc *gojay.StreamEncoder) {
select {
case <-enc.Done():
return
case o := <-s:
enc.Object(o)
}
}
// Our main function
func main() {
// get our websocket connection
origin := "http://localhost/"
url := "ws://localhost:12345/ws"
ws, err := websocket.Dial(url, "", origin)
if err != nil {
log.Fatal(err)
}
// we borrow an encoder set stdout as the writer,
// set the number of consumer to 10
// and tell the encoder to separate each encoded element
// added to the channel by a new line character
enc := gojay.Stream.BorrowEncoder(ws).NConsumer(10).LineDelimited()
// instantiate our MarshalerStream
s := StreamChan(make(chan *user))
// start the stream encoder
// will block its goroutine until enc.Cancel(error) is called
// or until something is written to the channel
go enc.EncodeStream(s)
// write to our MarshalerStream
for i := 0; i < 1000; i++ {
s <- &user{i, "username", "user@email.com"}
}
// Wait
<-enc.Done()
}
```
# Unsafe API
Unsafe API has the same functions than the regular API, it only has `Unmarshal API` for now. It is unsafe because it makes assumptions on the quality of the given JSON.
If you are not sure if your JSON is valid, don't use the Unsafe API.
Also, the `Unsafe` API does not copy the buffer when using Unmarshal API, which, in case of string decoding, can lead to data corruption if a byte buffer is reused. Using the `Decode` API makes `Unsafe` API safer as the io.Reader relies on `copy` builtin method and `Decoder` will have its own internal buffer :)
Access the `Unsafe` API this way:
```go
gojay.Unsafe.Unmarshal(b, v)
```
# Benchmarks
Benchmarks encode and decode three different data based on size (small, medium, large).
To run benchmark for decoder:
```bash
cd $GOPATH/src/github.com/francoispqt/gojay/benchmarks/decoder && make bench
```
To run benchmark for encoder:
```bash
cd $GOPATH/src/github.com/francoispqt/gojay/benchmarks/encoder && make bench
```
# Benchmark Results
## Decode
<img src="https://images2.imgbox.com/78/01/49OExcPh_o.png" width="500px">
### Small Payload
[benchmark code is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/decoder/decoder_bench_small_test.go)
[benchmark data is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/benchmarks_small.go)
| | ns/op | bytes/op | allocs/op |
|-----------------|-----------|--------------|-----------|
| Std Library | 2547 | 496 | 4 |
| JsonIter | 2046 | 312 | 12 |
| JsonParser | 1408 | 0 | 0 |
| EasyJson | 929 | 240 | 2 |
| **GoJay** | **807** | **256** | **2** |
| **GoJay-unsafe**| **712** | **112** | **1** |
### Medium Payload
[benchmark code is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/decoder/decoder_bench_medium_test.go)
[benchmark data is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/benchmarks_medium.go)
| | ns/op | bytes/op | allocs/op |
|-----------------|-----------|----------|-----------|
| Std Library | 30148 | 2152 | 496 |
| JsonIter | 16309 | 2976 | 80 |
| JsonParser | 7793 | 0 | 0 |
| EasyJson | 7957 | 232 | 6 |
| **GoJay** | **4984** | **2448** | **8** |
| **GoJay-unsafe**| **4809** | **144** | **7** |
### Large Payload
[benchmark code is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/decoder/decoder_bench_large_test.go)
[benchmark data is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/benchmarks_large.go)
| | ns/op | bytes/op | allocs/op |
|-----------------|-----------|-------------|-----------|
| JsonIter | 210078 | 41712 | 1136 |
| EasyJson | 106626 | 160 | 2 |
| JsonParser | 66813 | 0 | 0 |
| **GoJay** | **52153** | **31241** | **77** |
| **GoJay-unsafe**| **48277** | **2561** | **76** |
## Encode
<img src="https://images2.imgbox.com/e9/cc/pnM8c7Gf_o.png" width="500px">
### Small Struct
[benchmark code is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/encoder/encoder_bench_small_test.go)
[benchmark data is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/benchmarks_small.go)
| | ns/op | bytes/op | allocs/op |
|----------------|----------|--------------|-----------|
| Std Library | 1280 | 464 | 3 |
| EasyJson | 871 | 944 | 6 |
| JsonIter | 866 | 272 | 3 |
| **GoJay** | **543** | **112** | **1** |
| **GoJay-func** | **347** | **0** | **0** |
### Medium Struct
[benchmark code is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/encoder/encoder_bench_medium_test.go)
[benchmark data is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/benchmarks_medium.go)
| | ns/op | bytes/op | allocs/op |
|-------------|----------|--------------|-----------|
| Std Library | 5006 | 1496 | 25 |
| JsonIter | 2232 | 1544 | 20 |
| EasyJson | 1997 | 1544 | 19 |
| **GoJay** | **1522** | **312** | **14** |
### Large Struct
[benchmark code is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/encoder/encoder_bench_large_test.go)
[benchmark data is here](https://github.com/francoispqt/gojay/blob/master/benchmarks/benchmarks_large.go)
| | ns/op | bytes/op | allocs/op |
|-------------|-----------|--------------|-----------|
| Std Library | 66441 | 20576 | 332 |
| JsonIter | 35247 | 20255 | 328 |
| EasyJson | 32053 | 15474 | 327 |
| **GoJay** | **27847** | **9802** | **318** |
# Contributing
Contributions are welcome :)
If you encounter issues please report it in Github and/or send an email at [francois@parquet.ninja](mailto:francois@parquet.ninja)

386
vendor/github.com/francoispqt/gojay/decode.go generated vendored Normal file
View File

@@ -0,0 +1,386 @@
package gojay
import (
"fmt"
"io"
)
// UnmarshalJSONArray parses the JSON-encoded data and stores the result in the value pointed to by v.
//
// v must implement UnmarshalerJSONArray.
//
// If a JSON value is not appropriate for a given target type, or if a JSON number
// overflows the target type, UnmarshalJSONArray skips that field and completes the unmarshaling as best it can.
func UnmarshalJSONArray(data []byte, v UnmarshalerJSONArray) error {
dec := borrowDecoder(nil, 0)
defer dec.Release()
dec.data = make([]byte, len(data))
copy(dec.data, data)
dec.length = len(data)
_, err := dec.decodeArray(v)
if err != nil {
return err
}
if dec.err != nil {
return dec.err
}
return nil
}
// UnmarshalJSONObject parses the JSON-encoded data and stores the result in the value pointed to by v.
//
// v must implement UnmarshalerJSONObject.
//
// If a JSON value is not appropriate for a given target type, or if a JSON number
// overflows the target type, UnmarshalJSONObject skips that field and completes the unmarshaling as best it can.
func UnmarshalJSONObject(data []byte, v UnmarshalerJSONObject) error {
dec := borrowDecoder(nil, 0)
defer dec.Release()
dec.data = make([]byte, len(data))
copy(dec.data, data)
dec.length = len(data)
_, err := dec.decodeObject(v)
if err != nil {
return err
}
if dec.err != nil {
return dec.err
}
return nil
}
// Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v.
// If v is nil, not an implementation of UnmarshalerJSONObject or UnmarshalerJSONArray or not one of the following types:
// *string, **string, *int, **int, *int8, **int8, *int16, **int16, *int32, **int32, *int64, **int64, *uint8, **uint8, *uint16, **uint16,
// *uint32, **uint32, *uint64, **uint64, *float64, **float64, *float32, **float32, *bool, **bool
// Unmarshal returns an InvalidUnmarshalError.
//
//
// If a JSON value is not appropriate for a given target type, or if a JSON number
// overflows the target type, Unmarshal skips that field and completes the unmarshaling as best it can.
// If no more serious errors are encountered, Unmarshal returns an UnmarshalTypeError describing the earliest such error.
// In any case, it's not guaranteed that all the remaining fields following the problematic one will be unmarshaled into the target object.
func Unmarshal(data []byte, v interface{}) error {
var err error
var dec *Decoder
switch vt := v.(type) {
case *string:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeString(vt)
case **string:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeStringNull(vt)
case *int:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeInt(vt)
case **int:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeIntNull(vt)
case *int8:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeInt8(vt)
case **int8:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeInt8Null(vt)
case *int16:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeInt16(vt)
case **int16:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeInt16Null(vt)
case *int32:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeInt32(vt)
case **int32:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeInt32Null(vt)
case *int64:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeInt64(vt)
case **int64:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeInt64Null(vt)
case *uint8:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeUint8(vt)
case **uint8:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeUint8Null(vt)
case *uint16:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeUint16(vt)
case **uint16:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeUint16Null(vt)
case *uint32:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeUint32(vt)
case **uint32:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeUint32Null(vt)
case *uint64:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeUint64(vt)
case **uint64:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeUint64Null(vt)
case *float64:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeFloat64(vt)
case **float64:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeFloat64Null(vt)
case *float32:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeFloat32(vt)
case **float32:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeFloat32Null(vt)
case *bool:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeBool(vt)
case **bool:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeBoolNull(vt)
case UnmarshalerJSONObject:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = make([]byte, len(data))
copy(dec.data, data)
_, err = dec.decodeObject(vt)
case UnmarshalerJSONArray:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = make([]byte, len(data))
copy(dec.data, data)
_, err = dec.decodeArray(vt)
case *interface{}:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = make([]byte, len(data))
copy(dec.data, data)
err = dec.decodeInterface(vt)
default:
return InvalidUnmarshalError(fmt.Sprintf(invalidUnmarshalErrorMsg, vt))
}
defer dec.Release()
if err != nil {
return err
}
return dec.err
}
// UnmarshalerJSONObject is the interface to implement to decode a JSON Object.
type UnmarshalerJSONObject interface {
UnmarshalJSONObject(*Decoder, string) error
NKeys() int
}
// UnmarshalerJSONArray is the interface to implement to decode a JSON Array.
type UnmarshalerJSONArray interface {
UnmarshalJSONArray(*Decoder) error
}
// A Decoder reads and decodes JSON values from an input stream.
type Decoder struct {
r io.Reader
data []byte
err error
isPooled byte
called byte
child byte
cursor int
length int
keysDone int
arrayIndex int
}
// Decode reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the value pointed to by v.
//
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
// The differences between Decode and Unmarshal are:
// - Decode reads from an io.Reader in the Decoder, whereas Unmarshal reads from a []byte
// - Decode leaves to the user the option of borrowing and releasing a Decoder, whereas Unmarshal internally always borrows a Decoder and releases it when the unmarshaling is completed
func (dec *Decoder) Decode(v interface{}) error {
if dec.isPooled == 1 {
panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
var err error
switch vt := v.(type) {
case *string:
err = dec.decodeString(vt)
case **string:
err = dec.decodeStringNull(vt)
case *int:
err = dec.decodeInt(vt)
case **int:
err = dec.decodeIntNull(vt)
case *int8:
err = dec.decodeInt8(vt)
case **int8:
err = dec.decodeInt8Null(vt)
case *int16:
err = dec.decodeInt16(vt)
case **int16:
err = dec.decodeInt16Null(vt)
case *int32:
err = dec.decodeInt32(vt)
case **int32:
err = dec.decodeInt32Null(vt)
case *int64:
err = dec.decodeInt64(vt)
case **int64:
err = dec.decodeInt64Null(vt)
case *uint8:
err = dec.decodeUint8(vt)
case **uint8:
err = dec.decodeUint8Null(vt)
case *uint16:
err = dec.decodeUint16(vt)
case **uint16:
err = dec.decodeUint16Null(vt)
case *uint32:
err = dec.decodeUint32(vt)
case **uint32:
err = dec.decodeUint32Null(vt)
case *uint64:
err = dec.decodeUint64(vt)
case **uint64:
err = dec.decodeUint64Null(vt)
case *float64:
err = dec.decodeFloat64(vt)
case **float64:
err = dec.decodeFloat64Null(vt)
case *float32:
err = dec.decodeFloat32(vt)
case **float32:
err = dec.decodeFloat32Null(vt)
case *bool:
err = dec.decodeBool(vt)
case **bool:
err = dec.decodeBoolNull(vt)
case UnmarshalerJSONObject:
_, err = dec.decodeObject(vt)
case UnmarshalerJSONArray:
_, err = dec.decodeArray(vt)
case *EmbeddedJSON:
err = dec.decodeEmbeddedJSON(vt)
case *interface{}:
err = dec.decodeInterface(vt)
default:
return InvalidUnmarshalError(fmt.Sprintf(invalidUnmarshalErrorMsg, vt))
}
if err != nil {
return err
}
return dec.err
}
// Non exported
func isDigit(b byte) bool {
switch b {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return true
default:
return false
}
}
func (dec *Decoder) read() bool {
if dec.r != nil {
// if we reach the end, double the buffer to ensure there's always more space
if len(dec.data) == dec.length {
nLen := dec.length * 2
if nLen == 0 {
nLen = 512
}
Buf := make([]byte, nLen, nLen)
copy(Buf, dec.data)
dec.data = Buf
}
var n int
var err error
for n == 0 {
n, err = dec.r.Read(dec.data[dec.length:])
if err != nil {
if err != io.EOF {
dec.err = err
return false
}
if n == 0 {
return false
}
dec.length = dec.length + n
return true
}
}
dec.length = dec.length + n
return true
}
return false
}
func (dec *Decoder) nextChar() byte {
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch dec.data[dec.cursor] {
case ' ', '\n', '\t', '\r', ',':
continue
}
d := dec.data[dec.cursor]
return d
}
return 0
}

247
vendor/github.com/francoispqt/gojay/decode_array.go generated vendored Normal file
View File

@@ -0,0 +1,247 @@
package gojay
import "reflect"
// DecodeArray reads the next JSON-encoded value from the decoder's input (io.Reader)
// and stores it in the value pointed to by v.
//
// v must implement UnmarshalerJSONArray.
//
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *Decoder) DecodeArray(v UnmarshalerJSONArray) error {
if dec.isPooled == 1 {
panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
_, err := dec.decodeArray(v)
return err
}
func (dec *Decoder) decodeArray(arr UnmarshalerJSONArray) (int, error) {
// remember last array index in case of nested arrays
lastArrayIndex := dec.arrayIndex
dec.arrayIndex = 0
defer func() {
dec.arrayIndex = lastArrayIndex
}()
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch dec.data[dec.cursor] {
case ' ', '\n', '\t', '\r', ',':
continue
case '[':
dec.cursor = dec.cursor + 1
// array is open, char is not space start readings
for dec.nextChar() != 0 {
// closing array
if dec.data[dec.cursor] == ']' {
dec.cursor = dec.cursor + 1
return dec.cursor, nil
}
// calling unmarshall function for each element of the slice
err := arr.UnmarshalJSONArray(dec)
if err != nil {
return 0, err
}
dec.arrayIndex++
}
return 0, dec.raiseInvalidJSONErr(dec.cursor)
case 'n':
// is null
dec.cursor++
err := dec.assertNull()
if err != nil {
return 0, err
}
return dec.cursor, nil
case '{', '"', 'f', 't', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
// can't unmarshall to struct
// we skip array and set Error
dec.err = dec.makeInvalidUnmarshalErr(arr)
err := dec.skipData()
if err != nil {
return 0, err
}
return dec.cursor, nil
default:
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
}
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) decodeArrayNull(v interface{}) (int, error) {
// remember last array index in case of nested arrays
lastArrayIndex := dec.arrayIndex
dec.arrayIndex = 0
defer func() {
dec.arrayIndex = lastArrayIndex
}()
vv := reflect.ValueOf(v)
vvt := vv.Type()
if vvt.Kind() != reflect.Ptr || vvt.Elem().Kind() != reflect.Ptr {
dec.err = ErrUnmarshalPtrExpected
return 0, dec.err
}
// not an array not an error, but do not know what to do
// do not check syntax
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch dec.data[dec.cursor] {
case ' ', '\n', '\t', '\r', ',':
continue
case '[':
dec.cursor = dec.cursor + 1
// create our new type
elt := vv.Elem()
n := reflect.New(elt.Type().Elem())
var arr UnmarshalerJSONArray
var ok bool
if arr, ok = n.Interface().(UnmarshalerJSONArray); !ok {
dec.err = dec.makeInvalidUnmarshalErr((UnmarshalerJSONArray)(nil))
return 0, dec.err
}
// array is open, char is not space start readings
for dec.nextChar() != 0 {
// closing array
if dec.data[dec.cursor] == ']' {
elt.Set(n)
dec.cursor = dec.cursor + 1
return dec.cursor, nil
}
// calling unmarshall function for each element of the slice
err := arr.UnmarshalJSONArray(dec)
if err != nil {
return 0, err
}
dec.arrayIndex++
}
return 0, dec.raiseInvalidJSONErr(dec.cursor)
case 'n':
// is null
dec.cursor++
err := dec.assertNull()
if err != nil {
return 0, err
}
return dec.cursor, nil
case '{', '"', 'f', 't', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
// can't unmarshall to struct
// we skip array and set Error
dec.err = dec.makeInvalidUnmarshalErr((UnmarshalerJSONArray)(nil))
err := dec.skipData()
if err != nil {
return 0, err
}
return dec.cursor, nil
default:
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
}
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) skipArray() (int, error) {
var arraysOpen = 1
var arraysClosed = 0
// var stringOpen byte = 0
for j := dec.cursor; j < dec.length || dec.read(); j++ {
switch dec.data[j] {
case ']':
arraysClosed++
// everything is closed return
if arraysOpen == arraysClosed {
// add char to object data
return j + 1, nil
}
case '[':
arraysOpen++
case '"':
j++
var isInEscapeSeq bool
var isFirstQuote = true
for ; j < dec.length || dec.read(); j++ {
if dec.data[j] != '"' {
continue
}
if dec.data[j-1] != '\\' || (!isInEscapeSeq && !isFirstQuote) {
break
} else {
isInEscapeSeq = false
}
if isFirstQuote {
isFirstQuote = false
}
// loop backward and count how many anti slash found
// to see if string is effectively escaped
ct := 0
for i := j - 1; i > 0; i-- {
if dec.data[i] != '\\' {
break
}
ct++
}
// is pair number of slashes, quote is not escaped
if ct&1 == 0 {
break
}
isInEscapeSeq = true
}
default:
continue
}
}
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
// DecodeArrayFunc is a func type implementing UnmarshalerJSONArray.
// Use it to cast a `func(*Decoder) error` to Unmarshal an array on the fly.
type DecodeArrayFunc func(*Decoder) error
// UnmarshalJSONArray implements UnmarshalerJSONArray.
func (f DecodeArrayFunc) UnmarshalJSONArray(dec *Decoder) error {
return f(dec)
}
// IsNil implements UnmarshalerJSONArray.
func (f DecodeArrayFunc) IsNil() bool {
return f == nil
}
// Add Values functions
// AddArray decodes the JSON value within an object or an array to a UnmarshalerJSONArray.
func (dec *Decoder) AddArray(v UnmarshalerJSONArray) error {
return dec.Array(v)
}
// AddArrayNull decodes the JSON value within an object or an array to a UnmarshalerJSONArray.
func (dec *Decoder) AddArrayNull(v interface{}) error {
return dec.ArrayNull(v)
}
// Array decodes the JSON value within an object or an array to a UnmarshalerJSONArray.
func (dec *Decoder) Array(v UnmarshalerJSONArray) error {
newCursor, err := dec.decodeArray(v)
if err != nil {
return err
}
dec.cursor = newCursor
dec.called |= 1
return nil
}
// ArrayNull decodes the JSON value within an object or an array to a UnmarshalerJSONArray.
// v should be a pointer to an UnmarshalerJSONArray,
// if `null` value is encountered in JSON, it will leave the value v untouched,
// else it will create a new instance of the UnmarshalerJSONArray behind v.
func (dec *Decoder) ArrayNull(v interface{}) error {
newCursor, err := dec.decodeArrayNull(v)
if err != nil {
return err
}
dec.cursor = newCursor
dec.called |= 1
return nil
}
// Index returns the index of an array being decoded.
func (dec *Decoder) Index() int {
return dec.arrayIndex
}

241
vendor/github.com/francoispqt/gojay/decode_bool.go generated vendored Normal file
View File

@@ -0,0 +1,241 @@
package gojay
// DecodeBool reads the next JSON-encoded value from the decoder's input (io.Reader)
// and stores it in the boolean pointed to by v.
//
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *Decoder) DecodeBool(v *bool) error {
if dec.isPooled == 1 {
panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeBool(v)
}
func (dec *Decoder) decodeBool(v *bool) error {
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch dec.data[dec.cursor] {
case ' ', '\n', '\t', '\r', ',':
continue
case 't':
dec.cursor++
err := dec.assertTrue()
if err != nil {
return err
}
*v = true
return nil
case 'f':
dec.cursor++
err := dec.assertFalse()
if err != nil {
return err
}
*v = false
return nil
case 'n':
dec.cursor++
err := dec.assertNull()
if err != nil {
return err
}
*v = false
return nil
default:
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
}
}
return nil
}
func (dec *Decoder) decodeBoolNull(v **bool) error {
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch dec.data[dec.cursor] {
case ' ', '\n', '\t', '\r', ',':
continue
case 't':
dec.cursor++
err := dec.assertTrue()
if err != nil {
return err
}
if *v == nil {
*v = new(bool)
}
**v = true
return nil
case 'f':
dec.cursor++
err := dec.assertFalse()
if err != nil {
return err
}
if *v == nil {
*v = new(bool)
}
**v = false
return nil
case 'n':
dec.cursor++
err := dec.assertNull()
if err != nil {
return err
}
return nil
default:
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
}
}
return nil
}
func (dec *Decoder) assertTrue() error {
i := 0
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch i {
case 0:
if dec.data[dec.cursor] != 'r' {
return dec.raiseInvalidJSONErr(dec.cursor)
}
case 1:
if dec.data[dec.cursor] != 'u' {
return dec.raiseInvalidJSONErr(dec.cursor)
}
case 2:
if dec.data[dec.cursor] != 'e' {
return dec.raiseInvalidJSONErr(dec.cursor)
}
case 3:
switch dec.data[dec.cursor] {
case ' ', '\b', '\t', '\n', ',', ']', '}':
// dec.cursor--
return nil
default:
return dec.raiseInvalidJSONErr(dec.cursor)
}
}
i++
}
if i == 3 {
return nil
}
return dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) assertNull() error {
i := 0
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch i {
case 0:
if dec.data[dec.cursor] != 'u' {
return dec.raiseInvalidJSONErr(dec.cursor)
}
case 1:
if dec.data[dec.cursor] != 'l' {
return dec.raiseInvalidJSONErr(dec.cursor)
}
case 2:
if dec.data[dec.cursor] != 'l' {
return dec.raiseInvalidJSONErr(dec.cursor)
}
case 3:
switch dec.data[dec.cursor] {
case ' ', '\t', '\n', ',', ']', '}':
// dec.cursor--
return nil
default:
return dec.raiseInvalidJSONErr(dec.cursor)
}
}
i++
}
if i == 3 {
return nil
}
return dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) assertFalse() error {
i := 0
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch i {
case 0:
if dec.data[dec.cursor] != 'a' {
return dec.raiseInvalidJSONErr(dec.cursor)
}
case 1:
if dec.data[dec.cursor] != 'l' {
return dec.raiseInvalidJSONErr(dec.cursor)
}
case 2:
if dec.data[dec.cursor] != 's' {
return dec.raiseInvalidJSONErr(dec.cursor)
}
case 3:
if dec.data[dec.cursor] != 'e' {
return dec.raiseInvalidJSONErr(dec.cursor)
}
case 4:
switch dec.data[dec.cursor] {
case ' ', '\t', '\n', ',', ']', '}':
// dec.cursor--
return nil
default:
return dec.raiseInvalidJSONErr(dec.cursor)
}
}
i++
}
if i == 4 {
return nil
}
return dec.raiseInvalidJSONErr(dec.cursor)
}
// Add Values functions
// AddBool decodes the JSON value within an object or an array to a *bool.
// If next key is neither null nor a JSON boolean, an InvalidUnmarshalError will be returned.
// If next key is null, bool will be false.
func (dec *Decoder) AddBool(v *bool) error {
return dec.Bool(v)
}
// AddBoolNull decodes the JSON value within an object or an array to a *bool.
// If next key is neither null nor a JSON boolean, an InvalidUnmarshalError will be returned.
// If next key is null, bool will be false.
// If a `null` is encountered, gojay does not change the value of the pointer.
func (dec *Decoder) AddBoolNull(v **bool) error {
return dec.BoolNull(v)
}
// Bool decodes the JSON value within an object or an array to a *bool.
// If next key is neither null nor a JSON boolean, an InvalidUnmarshalError will be returned.
// If next key is null, bool will be false.
func (dec *Decoder) Bool(v *bool) error {
err := dec.decodeBool(v)
if err != nil {
return err
}
dec.called |= 1
return nil
}
// BoolNull decodes the JSON value within an object or an array to a *bool.
// If next key is neither null nor a JSON boolean, an InvalidUnmarshalError will be returned.
// If next key is null, bool will be false.
func (dec *Decoder) BoolNull(v **bool) error {
err := dec.decodeBoolNull(v)
if err != nil {
return err
}
dec.called |= 1
return nil
}

View File

@@ -0,0 +1,85 @@
package gojay
// EmbeddedJSON is a raw encoded JSON value.
// It can be used to delay JSON decoding or precompute a JSON encoding.
type EmbeddedJSON []byte
func (dec *Decoder) decodeEmbeddedJSON(ej *EmbeddedJSON) error {
var err error
if ej == nil {
return InvalidUnmarshalError("Invalid nil pointer given")
}
var beginOfEmbeddedJSON int
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch dec.data[dec.cursor] {
case ' ', '\n', '\t', '\r', ',':
continue
// is null
case 'n':
beginOfEmbeddedJSON = dec.cursor
dec.cursor++
err := dec.assertNull()
if err != nil {
return err
}
case 't':
beginOfEmbeddedJSON = dec.cursor
dec.cursor++
err := dec.assertTrue()
if err != nil {
return err
}
// is false
case 'f':
beginOfEmbeddedJSON = dec.cursor
dec.cursor++
err := dec.assertFalse()
if err != nil {
return err
}
// is an object
case '{':
beginOfEmbeddedJSON = dec.cursor
dec.cursor = dec.cursor + 1
dec.cursor, err = dec.skipObject()
// is string
case '"':
beginOfEmbeddedJSON = dec.cursor
dec.cursor = dec.cursor + 1
err = dec.skipString() // why no new dec.cursor in result?
// is array
case '[':
beginOfEmbeddedJSON = dec.cursor
dec.cursor = dec.cursor + 1
dec.cursor, err = dec.skipArray()
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-':
beginOfEmbeddedJSON = dec.cursor
dec.cursor, err = dec.skipNumber()
}
break
}
if err == nil {
if dec.cursor-1 >= beginOfEmbeddedJSON {
*ej = append(*ej, dec.data[beginOfEmbeddedJSON:dec.cursor]...)
}
dec.called |= 1
}
return err
}
// AddEmbeddedJSON adds an EmbeddedsJSON to the value pointed by v.
// It can be used to delay JSON decoding or precompute a JSON encoding.
func (dec *Decoder) AddEmbeddedJSON(v *EmbeddedJSON) error {
return dec.EmbeddedJSON(v)
}
// EmbeddedJSON adds an EmbeddedsJSON to the value pointed by v.
// It can be used to delay JSON decoding or precompute a JSON encoding.
func (dec *Decoder) EmbeddedJSON(v *EmbeddedJSON) error {
err := dec.decodeEmbeddedJSON(v)
if err != nil {
return err
}
dec.called |= 1
return nil
}

130
vendor/github.com/francoispqt/gojay/decode_interface.go generated vendored Normal file
View File

@@ -0,0 +1,130 @@
package gojay
// TODO @afiune for now we are using the standard json unmarshaling but in
// the future it would be great to implement one here inside this repo
import "encoding/json"
// DecodeInterface reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the value pointed to by i.
//
// i must be an interface poiter
func (dec *Decoder) DecodeInterface(i *interface{}) error {
if dec.isPooled == 1 {
panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
err := dec.decodeInterface(i)
return err
}
func (dec *Decoder) decodeInterface(i *interface{}) error {
start, end, err := dec.getObject()
if err != nil {
dec.cursor = start
return err
}
// if start & end are equal the object is a null, don't unmarshal
if start == end {
return nil
}
object := dec.data[start:end]
if err = json.Unmarshal(object, i); err != nil {
return err
}
dec.cursor = end
return nil
}
// @afiune Maybe return the type as well?
func (dec *Decoder) getObject() (start int, end int, err error) {
// start cursor
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch dec.data[dec.cursor] {
case ' ', '\n', '\t', '\r', ',':
continue
// is null
case 'n':
dec.cursor++
err = dec.assertNull()
if err != nil {
return
}
// Set start & end to the same cursor to indicate the object
// is a null and should not be unmarshal
start = dec.cursor
end = dec.cursor
return
case 't':
start = dec.cursor
dec.cursor++
err = dec.assertTrue()
if err != nil {
return
}
end = dec.cursor
dec.cursor++
return
// is false
case 'f':
start = dec.cursor
dec.cursor++
err = dec.assertFalse()
if err != nil {
return
}
end = dec.cursor
dec.cursor++
return
// is an object
case '{':
start = dec.cursor
dec.cursor++
end, err = dec.skipObject()
dec.cursor = end
return
// is string
case '"':
start = dec.cursor
dec.cursor++
start, end, err = dec.getString()
start--
dec.cursor = end
return
// is array
case '[':
start = dec.cursor
dec.cursor++
end, err = dec.skipArray()
dec.cursor = end
return
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-':
start = dec.cursor
end, err = dec.skipNumber()
dec.cursor = end
return
default:
err = dec.raiseInvalidJSONErr(dec.cursor)
return
}
}
err = dec.raiseInvalidJSONErr(dec.cursor)
return
}
// Add Values functions
// AddInterface decodes the JSON value within an object or an array to a interface{}.
func (dec *Decoder) AddInterface(v *interface{}) error {
return dec.Interface(v)
}
// Interface decodes the JSON value within an object or an array to an interface{}.
func (dec *Decoder) Interface(value *interface{}) error {
err := dec.decodeInterface(value)
if err != nil {
return err
}
dec.called |= 1
return nil
}

118
vendor/github.com/francoispqt/gojay/decode_number.go generated vendored Normal file
View File

@@ -0,0 +1,118 @@
package gojay
import (
"math"
)
var digits []int8
const maxInt64toMultiply = math.MaxInt64 / 10
const maxInt32toMultiply = math.MaxInt32 / 10
const maxInt16toMultiply = math.MaxInt16 / 10
const maxInt8toMultiply = math.MaxInt8 / 10
const maxUint8toMultiply = math.MaxUint8 / 10
const maxUint16toMultiply = math.MaxUint16 / 10
const maxUint32toMultiply = math.MaxUint32 / 10
const maxUint64toMultiply = math.MaxUint64 / 10
const maxUint32Length = 10
const maxUint64Length = 20
const maxUint16Length = 5
const maxUint8Length = 3
const maxInt32Length = 10
const maxInt64Length = 19
const maxInt16Length = 5
const maxInt8Length = 3
const invalidNumber = int8(-1)
var pow10uint64 = [21]uint64{
0,
1,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000,
10000000000,
100000000000,
1000000000000,
10000000000000,
100000000000000,
1000000000000000,
10000000000000000,
100000000000000000,
1000000000000000000,
10000000000000000000,
}
var skipNumberEndCursorIncrement [256]int
func init() {
digits = make([]int8, 256)
for i := 0; i < len(digits); i++ {
digits[i] = invalidNumber
}
for i := int8('0'); i <= int8('9'); i++ {
digits[i] = i - int8('0')
}
for i := 0; i < 256; i++ {
switch i {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', 'e', 'E', '+', '-':
skipNumberEndCursorIncrement[i] = 1
}
}
}
func (dec *Decoder) skipNumber() (int, error) {
end := dec.cursor + 1
// look for following numbers
for j := dec.cursor + 1; j < dec.length || dec.read(); j++ {
end += skipNumberEndCursorIncrement[dec.data[j]]
switch dec.data[j] {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', 'e', 'E', '+', '-', ' ', '\n', '\t', '\r':
continue
case ',', '}', ']':
return end, nil
default:
// invalid json we expect numbers, dot (single one), comma, or spaces
return end, dec.raiseInvalidJSONErr(dec.cursor)
}
}
return end, nil
}
func (dec *Decoder) getExponent() (int64, error) {
start := dec.cursor
end := dec.cursor
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch dec.data[dec.cursor] { // is positive
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
end = dec.cursor + 1
case '-':
dec.cursor++
exp, err := dec.getExponent()
return -exp, err
case '+':
dec.cursor++
return dec.getExponent()
default:
// if nothing return 0
// could raise error
if start == end {
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
return dec.atoi64(start, end-1), nil
}
}
if start == end {
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
return dec.atoi64(start, end-1), nil
}

View File

@@ -0,0 +1,516 @@
package gojay
// DecodeFloat64 reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the float64 pointed to by v.
//
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *Decoder) DecodeFloat64(v *float64) error {
if dec.isPooled == 1 {
panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeFloat64(v)
}
func (dec *Decoder) decodeFloat64(v *float64) error {
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch c := dec.data[dec.cursor]; c {
case ' ', '\n', '\t', '\r', ',':
continue
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
val, err := dec.getFloat()
if err != nil {
return err
}
*v = val
return nil
case '-':
dec.cursor = dec.cursor + 1
val, err := dec.getFloatNegative()
if err != nil {
return err
}
*v = -val
return nil
case 'n':
dec.cursor++
err := dec.assertNull()
if err != nil {
return err
}
return nil
default:
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
}
}
return dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) decodeFloat64Null(v **float64) error {
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch c := dec.data[dec.cursor]; c {
case ' ', '\n', '\t', '\r', ',':
continue
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
val, err := dec.getFloat()
if err != nil {
return err
}
if *v == nil {
*v = new(float64)
}
**v = val
return nil
case '-':
dec.cursor = dec.cursor + 1
val, err := dec.getFloatNegative()
if err != nil {
return err
}
if *v == nil {
*v = new(float64)
}
**v = -val
return nil
case 'n':
dec.cursor++
err := dec.assertNull()
if err != nil {
return err
}
return nil
default:
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
}
}
return dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) getFloatNegative() (float64, error) {
// look for following numbers
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch dec.data[dec.cursor] {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return dec.getFloat()
default:
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
}
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) getFloat() (float64, error) {
var end = dec.cursor
var start = dec.cursor
// look for following numbers
for j := dec.cursor + 1; j < dec.length || dec.read(); j++ {
switch dec.data[j] {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
end = j
continue
case '.':
// we get part before decimal as integer
beforeDecimal := dec.atoi64(start, end)
// then we get part after decimal as integer
start = j + 1
// get number after the decimal point
for i := j + 1; i < dec.length || dec.read(); i++ {
c := dec.data[i]
if isDigit(c) {
end = i
// multiply the before decimal point portion by 10 using bitwise
// make sure it doesn't overflow
if end-start < 18 {
beforeDecimal = (beforeDecimal << 3) + (beforeDecimal << 1)
}
continue
} else if (c == 'e' || c == 'E') && j < i-1 {
// we have an exponent, convert first the value we got before the exponent
var afterDecimal int64
expI := end - start + 2
// if exp is too long, it means number is too long, just truncate the number
if expI >= len(pow10uint64) || expI < 0 {
expI = len(pow10uint64) - 2
afterDecimal = dec.atoi64(start, start+expI-2)
} else {
// then we add both integers
// then we divide the number by the power found
afterDecimal = dec.atoi64(start, end)
}
dec.cursor = i + 1
pow := pow10uint64[expI]
floatVal := float64(beforeDecimal+afterDecimal) / float64(pow)
exp, err := dec.getExponent()
if err != nil {
return 0, err
}
pExp := (exp + (exp >> 31)) ^ (exp >> 31) + 1 // absolute exponent
if pExp >= int64(len(pow10uint64)) || pExp < 0 {
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
// if exponent is negative
if exp < 0 {
return float64(floatVal) * (1 / float64(pow10uint64[pExp])), nil
}
return float64(floatVal) * float64(pow10uint64[pExp]), nil
}
dec.cursor = i
break
}
if end >= dec.length || end < start {
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
var afterDecimal int64
expI := end - start + 2
// if exp is too long, it means number is too long, just truncate the number
if expI >= len(pow10uint64) || expI < 0 {
expI = 19
afterDecimal = dec.atoi64(start, start+expI-2)
} else {
afterDecimal = dec.atoi64(start, end)
}
pow := pow10uint64[expI]
// then we add both integers
// then we divide the number by the power found
return float64(beforeDecimal+afterDecimal) / float64(pow), nil
case 'e', 'E':
dec.cursor = j + 1
// we get part before decimal as integer
beforeDecimal := uint64(dec.atoi64(start, end))
// get exponent
exp, err := dec.getExponent()
if err != nil {
return 0, err
}
pExp := (exp + (exp >> 31)) ^ (exp >> 31) + 1 // abs
if pExp >= int64(len(pow10uint64)) || pExp < 0 {
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
// if exponent is negative
if exp < 0 {
return float64(beforeDecimal) * (1 / float64(pow10uint64[pExp])), nil
}
return float64(beforeDecimal) * float64(pow10uint64[pExp]), nil
case ' ', '\n', '\t', '\r', ',', '}', ']': // does not have decimal
dec.cursor = j
return float64(dec.atoi64(start, end)), nil
}
// invalid json we expect numbers, dot (single one), comma, or spaces
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
return float64(dec.atoi64(start, end)), nil
}
// DecodeFloat32 reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the float32 pointed to by v.
//
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *Decoder) DecodeFloat32(v *float32) error {
if dec.isPooled == 1 {
panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeFloat32(v)
}
func (dec *Decoder) decodeFloat32(v *float32) error {
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch c := dec.data[dec.cursor]; c {
case ' ', '\n', '\t', '\r', ',':
continue
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
val, err := dec.getFloat32()
if err != nil {
return err
}
*v = val
return nil
case '-':
dec.cursor = dec.cursor + 1
val, err := dec.getFloat32Negative()
if err != nil {
return err
}
*v = -val
return nil
case 'n':
dec.cursor++
err := dec.assertNull()
if err != nil {
return err
}
return nil
default:
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
}
}
return dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) decodeFloat32Null(v **float32) error {
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch c := dec.data[dec.cursor]; c {
case ' ', '\n', '\t', '\r', ',':
continue
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
val, err := dec.getFloat32()
if err != nil {
return err
}
if *v == nil {
*v = new(float32)
}
**v = val
return nil
case '-':
dec.cursor = dec.cursor + 1
val, err := dec.getFloat32Negative()
if err != nil {
return err
}
if *v == nil {
*v = new(float32)
}
**v = -val
return nil
case 'n':
dec.cursor++
err := dec.assertNull()
if err != nil {
return err
}
return nil
default:
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
}
}
return dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) getFloat32Negative() (float32, error) {
// look for following numbers
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch dec.data[dec.cursor] {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return dec.getFloat32()
default:
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
}
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) getFloat32() (float32, error) {
var end = dec.cursor
var start = dec.cursor
// look for following numbers
for j := dec.cursor + 1; j < dec.length || dec.read(); j++ {
switch dec.data[j] {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
end = j
continue
case '.':
// we get part before decimal as integer
beforeDecimal := dec.atoi64(start, end)
// then we get part after decimal as integer
start = j + 1
// get number after the decimal point
// multiple the before decimal point portion by 10 using bitwise
for i := j + 1; i < dec.length || dec.read(); i++ {
c := dec.data[i]
if isDigit(c) {
end = i
// multiply the before decimal point portion by 10 using bitwise
// make sure it desn't overflow
if end-start < 9 {
beforeDecimal = (beforeDecimal << 3) + (beforeDecimal << 1)
}
continue
} else if (c == 'e' || c == 'E') && j < i-1 {
// we get the number before decimal
var afterDecimal int64
expI := end - start + 2
// if exp is too long, it means number is too long, just truncate the number
if expI >= 12 || expI < 0 {
expI = 10
afterDecimal = dec.atoi64(start, start+expI-2)
} else {
afterDecimal = dec.atoi64(start, end)
}
dec.cursor = i + 1
pow := pow10uint64[expI]
// then we add both integers
// then we divide the number by the power found
floatVal := float32(beforeDecimal+afterDecimal) / float32(pow)
exp, err := dec.getExponent()
if err != nil {
return 0, err
}
pExp := (exp + (exp >> 31)) ^ (exp >> 31) + 1 // abs
if pExp >= int64(len(pow10uint64)) || pExp < 0 {
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
// if exponent is negative
if exp < 0 {
return float32(floatVal) * (1 / float32(pow10uint64[pExp])), nil
}
return float32(floatVal) * float32(pow10uint64[pExp]), nil
}
dec.cursor = i
break
}
if end >= dec.length || end < start {
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
// then we add both integers
// then we divide the number by the power found
var afterDecimal int64
expI := end - start + 2
// if exp is too long, it means number is too long, just truncate the number
if expI >= 12 || expI < 0 {
expI = 10
afterDecimal = dec.atoi64(start, start+expI-2)
} else {
// then we add both integers
// then we divide the number by the power found
afterDecimal = dec.atoi64(start, end)
}
pow := pow10uint64[expI]
return float32(beforeDecimal+afterDecimal) / float32(pow), nil
case 'e', 'E':
dec.cursor = j + 1
// we get part before decimal as integer
beforeDecimal := dec.atoi64(start, end)
// get exponent
exp, err := dec.getExponent()
if err != nil {
return 0, err
}
pExp := (exp + (exp >> 31)) ^ (exp >> 31) + 1
if pExp >= int64(len(pow10uint64)) || pExp < 0 {
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
// if exponent is negative
if exp < 0 {
return float32(beforeDecimal) * (1 / float32(pow10uint64[pExp])), nil
}
return float32(beforeDecimal) * float32(pow10uint64[pExp]), nil
case ' ', '\n', '\t', '\r', ',', '}', ']': // does not have decimal
dec.cursor = j
return float32(dec.atoi64(start, end)), nil
}
// invalid json we expect numbers, dot (single one), comma, or spaces
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
return float32(dec.atoi64(start, end)), nil
}
// Add Values functions
// AddFloat decodes the JSON value within an object or an array to a *float64.
// If next key value overflows float64, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) AddFloat(v *float64) error {
return dec.Float64(v)
}
// AddFloatNull decodes the JSON value within an object or an array to a *float64.
// If next key value overflows float64, an InvalidUnmarshalError error will be returned.
// If a `null` is encountered, gojay does not change the value of the pointer.
func (dec *Decoder) AddFloatNull(v **float64) error {
return dec.Float64Null(v)
}
// AddFloat64 decodes the JSON value within an object or an array to a *float64.
// If next key value overflows float64, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) AddFloat64(v *float64) error {
return dec.Float64(v)
}
// AddFloat64Null decodes the JSON value within an object or an array to a *float64.
// If next key value overflows float64, an InvalidUnmarshalError error will be returned.
// If a `null` is encountered, gojay does not change the value of the pointer.
func (dec *Decoder) AddFloat64Null(v **float64) error {
return dec.Float64Null(v)
}
// AddFloat32 decodes the JSON value within an object or an array to a *float64.
// If next key value overflows float64, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) AddFloat32(v *float32) error {
return dec.Float32(v)
}
// AddFloat32Null decodes the JSON value within an object or an array to a *float64.
// If next key value overflows float64, an InvalidUnmarshalError error will be returned.
// If a `null` is encountered, gojay does not change the value of the pointer.
func (dec *Decoder) AddFloat32Null(v **float32) error {
return dec.Float32Null(v)
}
// Float decodes the JSON value within an object or an array to a *float64.
// If next key value overflows float64, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) Float(v *float64) error {
return dec.Float64(v)
}
// FloatNull decodes the JSON value within an object or an array to a *float64.
// If next key value overflows float64, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) FloatNull(v **float64) error {
return dec.Float64Null(v)
}
// Float64 decodes the JSON value within an object or an array to a *float64.
// If next key value overflows float64, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) Float64(v *float64) error {
err := dec.decodeFloat64(v)
if err != nil {
return err
}
dec.called |= 1
return nil
}
// Float64Null decodes the JSON value within an object or an array to a *float64.
// If next key value overflows float64, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) Float64Null(v **float64) error {
err := dec.decodeFloat64Null(v)
if err != nil {
return err
}
dec.called |= 1
return nil
}
// Float32 decodes the JSON value within an object or an array to a *float64.
// If next key value overflows float64, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) Float32(v *float32) error {
err := dec.decodeFloat32(v)
if err != nil {
return err
}
dec.called |= 1
return nil
}
// Float32Null decodes the JSON value within an object or an array to a *float64.
// If next key value overflows float64, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) Float32Null(v **float32) error {
err := dec.decodeFloat32Null(v)
if err != nil {
return err
}
dec.called |= 1
return nil
}

1338
vendor/github.com/francoispqt/gojay/decode_number_int.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,715 @@
package gojay
import (
"math"
)
// DecodeUint8 reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the uint8 pointed to by v.
//
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *Decoder) DecodeUint8(v *uint8) error {
if dec.isPooled == 1 {
panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeUint8(v)
}
func (dec *Decoder) decodeUint8(v *uint8) error {
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch c := dec.data[dec.cursor]; c {
case ' ', '\n', '\t', '\r', ',':
continue
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
val, err := dec.getUint8()
if err != nil {
return err
}
*v = val
return nil
case '-': // if negative, we just set it to 0 and set error
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
case 'n':
dec.cursor++
err := dec.assertNull()
if err != nil {
return err
}
return nil
default:
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
}
}
return dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) decodeUint8Null(v **uint8) error {
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch c := dec.data[dec.cursor]; c {
case ' ', '\n', '\t', '\r', ',':
continue
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
val, err := dec.getUint8()
if err != nil {
return err
}
if *v == nil {
*v = new(uint8)
}
**v = val
return nil
case '-': // if negative, we just set it to 0 and set error
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
if *v == nil {
*v = new(uint8)
}
return nil
case 'n':
dec.cursor++
err := dec.assertNull()
if err != nil {
return err
}
return nil
default:
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
}
}
return dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) getUint8() (uint8, error) {
var end = dec.cursor
var start = dec.cursor
// look for following numbers
for j := dec.cursor + 1; j < dec.length || dec.read(); j++ {
switch dec.data[j] {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
end = j
continue
case ' ', '\n', '\t', '\r':
continue
case '.', ',', '}', ']':
dec.cursor = j
return dec.atoui8(start, end), nil
}
// invalid json we expect numbers, dot (single one), comma, or spaces
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
return dec.atoui8(start, end), nil
}
// DecodeUint16 reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the uint16 pointed to by v.
//
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *Decoder) DecodeUint16(v *uint16) error {
if dec.isPooled == 1 {
panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeUint16(v)
}
func (dec *Decoder) decodeUint16(v *uint16) error {
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch c := dec.data[dec.cursor]; c {
case ' ', '\n', '\t', '\r', ',':
continue
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
val, err := dec.getUint16()
if err != nil {
return err
}
*v = val
return nil
case '-':
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
case 'n':
dec.cursor++
err := dec.assertNull()
if err != nil {
return err
}
return nil
default:
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
}
}
return dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) decodeUint16Null(v **uint16) error {
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch c := dec.data[dec.cursor]; c {
case ' ', '\n', '\t', '\r', ',':
continue
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
val, err := dec.getUint16()
if err != nil {
return err
}
if *v == nil {
*v = new(uint16)
}
**v = val
return nil
case '-':
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
if *v == nil {
*v = new(uint16)
}
return nil
case 'n':
dec.cursor++
err := dec.assertNull()
if err != nil {
return err
}
return nil
default:
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
}
}
return dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) getUint16() (uint16, error) {
var end = dec.cursor
var start = dec.cursor
// look for following numbers
for j := dec.cursor + 1; j < dec.length || dec.read(); j++ {
switch dec.data[j] {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
end = j
continue
case ' ', '\n', '\t', '\r':
continue
case '.', ',', '}', ']':
dec.cursor = j
return dec.atoui16(start, end), nil
}
// invalid json we expect numbers, dot (single one), comma, or spaces
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
return dec.atoui16(start, end), nil
}
// DecodeUint32 reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the uint32 pointed to by v.
//
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *Decoder) DecodeUint32(v *uint32) error {
if dec.isPooled == 1 {
panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeUint32(v)
}
func (dec *Decoder) decodeUint32(v *uint32) error {
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch c := dec.data[dec.cursor]; c {
case ' ', '\n', '\t', '\r', ',':
continue
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
val, err := dec.getUint32()
if err != nil {
return err
}
*v = val
return nil
case '-':
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
case 'n':
dec.cursor++
err := dec.assertNull()
if err != nil {
return err
}
return nil
default:
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
}
}
return dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) decodeUint32Null(v **uint32) error {
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch c := dec.data[dec.cursor]; c {
case ' ', '\n', '\t', '\r', ',':
continue
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
val, err := dec.getUint32()
if err != nil {
return err
}
if *v == nil {
*v = new(uint32)
}
**v = val
return nil
case '-':
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
if *v == nil {
*v = new(uint32)
}
return nil
case 'n':
dec.cursor++
err := dec.assertNull()
if err != nil {
return err
}
return nil
default:
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
}
}
return dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) getUint32() (uint32, error) {
var end = dec.cursor
var start = dec.cursor
// look for following numbers
for j := dec.cursor + 1; j < dec.length || dec.read(); j++ {
switch dec.data[j] {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
end = j
continue
case ' ', '\n', '\t', '\r':
continue
case '.', ',', '}', ']':
dec.cursor = j
return dec.atoui32(start, end), nil
}
// invalid json we expect numbers, dot (single one), comma, or spaces
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
return dec.atoui32(start, end), nil
}
// DecodeUint64 reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the uint64 pointed to by v.
//
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *Decoder) DecodeUint64(v *uint64) error {
if dec.isPooled == 1 {
panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeUint64(v)
}
func (dec *Decoder) decodeUint64(v *uint64) error {
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch c := dec.data[dec.cursor]; c {
case ' ', '\n', '\t', '\r', ',':
continue
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
val, err := dec.getUint64()
if err != nil {
return err
}
*v = val
return nil
case '-':
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
case 'n':
dec.cursor++
err := dec.assertNull()
if err != nil {
return err
}
return nil
default:
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
}
}
return dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) decodeUint64Null(v **uint64) error {
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch c := dec.data[dec.cursor]; c {
case ' ', '\n', '\t', '\r', ',':
continue
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
val, err := dec.getUint64()
if err != nil {
return err
}
if *v == nil {
*v = new(uint64)
}
**v = val
return nil
case '-':
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
if *v == nil {
*v = new(uint64)
}
return nil
case 'n':
dec.cursor++
err := dec.assertNull()
if err != nil {
return err
}
return nil
default:
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
}
}
return dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) getUint64() (uint64, error) {
var end = dec.cursor
var start = dec.cursor
// look for following numbers
for j := dec.cursor + 1; j < dec.length || dec.read(); j++ {
switch dec.data[j] {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
end = j
continue
case ' ', '\n', '\t', '\r', '.', ',', '}', ']':
dec.cursor = j
return dec.atoui64(start, end), nil
}
// invalid json we expect numbers, dot (single one), comma, or spaces
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
return dec.atoui64(start, end), nil
}
func (dec *Decoder) atoui64(start, end int) uint64 {
var ll = end + 1 - start
var val = uint64(digits[dec.data[start]])
end = end + 1
if ll < maxUint64Length {
for i := start + 1; i < end; i++ {
uintv := uint64(digits[dec.data[i]])
val = (val << 3) + (val << 1) + uintv
}
} else if ll == maxUint64Length {
for i := start + 1; i < end; i++ {
uintv := uint64(digits[dec.data[i]])
if val > maxUint64toMultiply {
dec.err = dec.makeInvalidUnmarshalErr(val)
return 0
}
val = (val << 3) + (val << 1)
if math.MaxUint64-val < uintv {
dec.err = dec.makeInvalidUnmarshalErr(val)
return 0
}
val += uintv
}
} else {
dec.err = dec.makeInvalidUnmarshalErr(val)
return 0
}
return val
}
func (dec *Decoder) atoui32(start, end int) uint32 {
var ll = end + 1 - start
var val uint32
val = uint32(digits[dec.data[start]])
end = end + 1
if ll < maxUint32Length {
for i := start + 1; i < end; i++ {
uintv := uint32(digits[dec.data[i]])
val = (val << 3) + (val << 1) + uintv
}
} else if ll == maxUint32Length {
for i := start + 1; i < end; i++ {
uintv := uint32(digits[dec.data[i]])
if val > maxUint32toMultiply {
dec.err = dec.makeInvalidUnmarshalErr(val)
return 0
}
val = (val << 3) + (val << 1)
if math.MaxUint32-val < uintv {
dec.err = dec.makeInvalidUnmarshalErr(val)
return 0
}
val += uintv
}
} else if ll > maxUint32Length {
dec.err = dec.makeInvalidUnmarshalErr(val)
val = 0
}
return val
}
func (dec *Decoder) atoui16(start, end int) uint16 {
var ll = end + 1 - start
var val uint16
val = uint16(digits[dec.data[start]])
end = end + 1
if ll < maxUint16Length {
for i := start + 1; i < end; i++ {
uintv := uint16(digits[dec.data[i]])
val = (val << 3) + (val << 1) + uintv
}
} else if ll == maxUint16Length {
for i := start + 1; i < end; i++ {
uintv := uint16(digits[dec.data[i]])
if val > maxUint16toMultiply {
dec.err = dec.makeInvalidUnmarshalErr(val)
return 0
}
val = (val << 3) + (val << 1)
if math.MaxUint16-val < uintv {
dec.err = dec.makeInvalidUnmarshalErr(val)
return 0
}
val += uintv
}
} else if ll > maxUint16Length {
dec.err = dec.makeInvalidUnmarshalErr(val)
val = 0
}
return val
}
func (dec *Decoder) atoui8(start, end int) uint8 {
var ll = end + 1 - start
var val uint8
val = uint8(digits[dec.data[start]])
end = end + 1
if ll < maxUint8Length {
for i := start + 1; i < end; i++ {
uintv := uint8(digits[dec.data[i]])
val = (val << 3) + (val << 1) + uintv
}
} else if ll == maxUint8Length {
for i := start + 1; i < end; i++ {
uintv := uint8(digits[dec.data[i]])
if val > maxUint8toMultiply {
dec.err = dec.makeInvalidUnmarshalErr(val)
return 0
}
val = (val << 3) + (val << 1)
if math.MaxUint8-val < uintv {
dec.err = dec.makeInvalidUnmarshalErr(val)
return 0
}
val += uintv
}
} else if ll > maxUint8Length {
dec.err = dec.makeInvalidUnmarshalErr(val)
val = 0
}
return val
}
// Add Values functions
// AddUint8 decodes the JSON value within an object or an array to an *int.
// If next key value overflows uint8, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) AddUint8(v *uint8) error {
return dec.Uint8(v)
}
// AddUint8Null decodes the JSON value within an object or an array to an *int.
// If next key value overflows uint8, an InvalidUnmarshalError error will be returned.
// If a `null` is encountered, gojay does not change the value of the pointer.
func (dec *Decoder) AddUint8Null(v **uint8) error {
return dec.Uint8Null(v)
}
// AddUint16 decodes the JSON value within an object or an array to an *int.
// If next key value overflows uint16, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) AddUint16(v *uint16) error {
return dec.Uint16(v)
}
// AddUint16Null decodes the JSON value within an object or an array to an *int.
// If next key value overflows uint16, an InvalidUnmarshalError error will be returned.
// If a `null` is encountered, gojay does not change the value of the pointer.
func (dec *Decoder) AddUint16Null(v **uint16) error {
return dec.Uint16Null(v)
}
// AddUint32 decodes the JSON value within an object or an array to an *int.
// If next key value overflows uint32, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) AddUint32(v *uint32) error {
return dec.Uint32(v)
}
// AddUint32Null decodes the JSON value within an object or an array to an *int.
// If next key value overflows uint32, an InvalidUnmarshalError error will be returned.
// If a `null` is encountered, gojay does not change the value of the pointer.
func (dec *Decoder) AddUint32Null(v **uint32) error {
return dec.Uint32Null(v)
}
// AddUint64 decodes the JSON value within an object or an array to an *int.
// If next key value overflows uint64, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) AddUint64(v *uint64) error {
return dec.Uint64(v)
}
// AddUint64Null decodes the JSON value within an object or an array to an *int.
// If next key value overflows uint64, an InvalidUnmarshalError error will be returned.
// If a `null` is encountered, gojay does not change the value of the pointer.
func (dec *Decoder) AddUint64Null(v **uint64) error {
return dec.Uint64Null(v)
}
// Uint8 decodes the JSON value within an object or an array to an *int.
// If next key value overflows uint8, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) Uint8(v *uint8) error {
err := dec.decodeUint8(v)
if err != nil {
return err
}
dec.called |= 1
return nil
}
// Uint8Null decodes the JSON value within an object or an array to an *int.
// If next key value overflows uint8, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) Uint8Null(v **uint8) error {
err := dec.decodeUint8Null(v)
if err != nil {
return err
}
dec.called |= 1
return nil
}
// Uint16 decodes the JSON value within an object or an array to an *int.
// If next key value overflows uint16, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) Uint16(v *uint16) error {
err := dec.decodeUint16(v)
if err != nil {
return err
}
dec.called |= 1
return nil
}
// Uint16Null decodes the JSON value within an object or an array to an *int.
// If next key value overflows uint16, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) Uint16Null(v **uint16) error {
err := dec.decodeUint16Null(v)
if err != nil {
return err
}
dec.called |= 1
return nil
}
// Uint32 decodes the JSON value within an object or an array to an *int.
// If next key value overflows uint32, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) Uint32(v *uint32) error {
err := dec.decodeUint32(v)
if err != nil {
return err
}
dec.called |= 1
return nil
}
// Uint32Null decodes the JSON value within an object or an array to an *int.
// If next key value overflows uint32, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) Uint32Null(v **uint32) error {
err := dec.decodeUint32Null(v)
if err != nil {
return err
}
dec.called |= 1
return nil
}
// Uint64 decodes the JSON value within an object or an array to an *int.
// If next key value overflows uint64, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) Uint64(v *uint64) error {
err := dec.decodeUint64(v)
if err != nil {
return err
}
dec.called |= 1
return nil
}
// Uint64Null decodes the JSON value within an object or an array to an *int.
// If next key value overflows uint64, an InvalidUnmarshalError error will be returned.
func (dec *Decoder) Uint64Null(v **uint64) error {
err := dec.decodeUint64Null(v)
if err != nil {
return err
}
dec.called |= 1
return nil
}

407
vendor/github.com/francoispqt/gojay/decode_object.go generated vendored Normal file
View File

@@ -0,0 +1,407 @@
package gojay
import (
"reflect"
"unsafe"
)
// DecodeObject reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the value pointed to by v.
//
// v must implement UnmarshalerJSONObject.
//
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *Decoder) DecodeObject(j UnmarshalerJSONObject) error {
if dec.isPooled == 1 {
panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
_, err := dec.decodeObject(j)
return err
}
func (dec *Decoder) decodeObject(j UnmarshalerJSONObject) (int, error) {
keys := j.NKeys()
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch dec.data[dec.cursor] {
case ' ', '\n', '\t', '\r', ',':
case '{':
dec.cursor = dec.cursor + 1
// if keys is zero we will parse all keys
// we run two loops for micro optimization
if keys == 0 {
for dec.cursor < dec.length || dec.read() {
k, done, err := dec.nextKey()
if err != nil {
return 0, err
} else if done {
return dec.cursor, nil
}
err = j.UnmarshalJSONObject(dec, k)
if err != nil {
dec.err = err
return 0, err
} else if dec.called&1 == 0 {
err := dec.skipData()
if err != nil {
return 0, err
}
} else {
dec.keysDone++
}
dec.called &= 0
}
} else {
for (dec.cursor < dec.length || dec.read()) && dec.keysDone < keys {
k, done, err := dec.nextKey()
if err != nil {
return 0, err
} else if done {
return dec.cursor, nil
}
err = j.UnmarshalJSONObject(dec, k)
if err != nil {
dec.err = err
return 0, err
} else if dec.called&1 == 0 {
err := dec.skipData()
if err != nil {
return 0, err
}
} else {
dec.keysDone++
}
dec.called &= 0
}
}
// will get to that point when keysDone is not lower than keys anymore
// in that case, we make sure cursor goes to the end of object, but we skip
// unmarshalling
if dec.child&1 != 0 {
end, err := dec.skipObject()
dec.cursor = end
return dec.cursor, err
}
return dec.cursor, nil
case 'n':
dec.cursor++
err := dec.assertNull()
if err != nil {
return 0, err
}
return dec.cursor, nil
default:
// can't unmarshal to struct
dec.err = dec.makeInvalidUnmarshalErr(j)
err := dec.skipData()
if err != nil {
return 0, err
}
return dec.cursor, nil
}
}
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) decodeObjectNull(v interface{}) (int, error) {
// make sure the value is a pointer
vv := reflect.ValueOf(v)
vvt := vv.Type()
if vvt.Kind() != reflect.Ptr || vvt.Elem().Kind() != reflect.Ptr {
dec.err = ErrUnmarshalPtrExpected
return 0, dec.err
}
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch dec.data[dec.cursor] {
case ' ', '\n', '\t', '\r', ',':
case '{':
elt := vv.Elem()
n := reflect.New(elt.Type().Elem())
elt.Set(n)
var j UnmarshalerJSONObject
var ok bool
if j, ok = n.Interface().(UnmarshalerJSONObject); !ok {
dec.err = dec.makeInvalidUnmarshalErr((UnmarshalerJSONObject)(nil))
return 0, dec.err
}
keys := j.NKeys()
dec.cursor = dec.cursor + 1
// if keys is zero we will parse all keys
// we run two loops for micro optimization
if keys == 0 {
for dec.cursor < dec.length || dec.read() {
k, done, err := dec.nextKey()
if err != nil {
return 0, err
} else if done {
return dec.cursor, nil
}
err = j.UnmarshalJSONObject(dec, k)
if err != nil {
dec.err = err
return 0, err
} else if dec.called&1 == 0 {
err := dec.skipData()
if err != nil {
return 0, err
}
} else {
dec.keysDone++
}
dec.called &= 0
}
} else {
for (dec.cursor < dec.length || dec.read()) && dec.keysDone < keys {
k, done, err := dec.nextKey()
if err != nil {
return 0, err
} else if done {
return dec.cursor, nil
}
err = j.UnmarshalJSONObject(dec, k)
if err != nil {
dec.err = err
return 0, err
} else if dec.called&1 == 0 {
err := dec.skipData()
if err != nil {
return 0, err
}
} else {
dec.keysDone++
}
dec.called &= 0
}
}
// will get to that point when keysDone is not lower than keys anymore
// in that case, we make sure cursor goes to the end of object, but we skip
// unmarshalling
if dec.child&1 != 0 {
end, err := dec.skipObject()
dec.cursor = end
return dec.cursor, err
}
return dec.cursor, nil
case 'n':
dec.cursor++
err := dec.assertNull()
if err != nil {
return 0, err
}
return dec.cursor, nil
default:
// can't unmarshal to struct
dec.err = dec.makeInvalidUnmarshalErr((UnmarshalerJSONObject)(nil))
err := dec.skipData()
if err != nil {
return 0, err
}
return dec.cursor, nil
}
}
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) skipObject() (int, error) {
var objectsOpen = 1
var objectsClosed = 0
for j := dec.cursor; j < dec.length || dec.read(); j++ {
switch dec.data[j] {
case '}':
objectsClosed++
// everything is closed return
if objectsOpen == objectsClosed {
// add char to object data
return j + 1, nil
}
case '{':
objectsOpen++
case '"':
j++
var isInEscapeSeq bool
var isFirstQuote = true
for ; j < dec.length || dec.read(); j++ {
if dec.data[j] != '"' {
continue
}
if dec.data[j-1] != '\\' || (!isInEscapeSeq && !isFirstQuote) {
break
} else {
isInEscapeSeq = false
}
if isFirstQuote {
isFirstQuote = false
}
// loop backward and count how many anti slash found
// to see if string is effectively escaped
ct := 0
for i := j - 1; i > 0; i-- {
if dec.data[i] != '\\' {
break
}
ct++
}
// is pair number of slashes, quote is not escaped
if ct&1 == 0 {
break
}
isInEscapeSeq = true
}
default:
continue
}
}
return 0, dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) nextKey() (string, bool, error) {
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch dec.data[dec.cursor] {
case ' ', '\n', '\t', '\r', ',':
continue
case '"':
dec.cursor = dec.cursor + 1
start, end, err := dec.getString()
if err != nil {
return "", false, err
}
var found byte
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
if dec.data[dec.cursor] == ':' {
found |= 1
break
}
}
if found&1 != 0 {
dec.cursor++
d := dec.data[start : end-1]
return *(*string)(unsafe.Pointer(&d)), false, nil
}
return "", false, dec.raiseInvalidJSONErr(dec.cursor)
case '}':
dec.cursor = dec.cursor + 1
return "", true, nil
default:
// can't unmarshall to struct
return "", false, dec.raiseInvalidJSONErr(dec.cursor)
}
}
return "", false, dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) skipData() error {
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch dec.data[dec.cursor] {
case ' ', '\n', '\t', '\r', ',':
continue
// is null
case 'n':
dec.cursor++
err := dec.assertNull()
if err != nil {
return err
}
return nil
case 't':
dec.cursor++
err := dec.assertTrue()
if err != nil {
return err
}
return nil
// is false
case 'f':
dec.cursor++
err := dec.assertFalse()
if err != nil {
return err
}
return nil
// is an object
case '{':
dec.cursor = dec.cursor + 1
end, err := dec.skipObject()
dec.cursor = end
return err
// is string
case '"':
dec.cursor = dec.cursor + 1
err := dec.skipString()
return err
// is array
case '[':
dec.cursor = dec.cursor + 1
end, err := dec.skipArray()
dec.cursor = end
return err
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-':
end, err := dec.skipNumber()
dec.cursor = end
return err
}
return dec.raiseInvalidJSONErr(dec.cursor)
}
return dec.raiseInvalidJSONErr(dec.cursor)
}
// DecodeObjectFunc is a func type implementing UnmarshalerJSONObject.
// Use it to cast a `func(*Decoder, k string) error` to Unmarshal an object on the fly.
type DecodeObjectFunc func(*Decoder, string) error
// UnmarshalJSONObject implements UnmarshalerJSONObject.
func (f DecodeObjectFunc) UnmarshalJSONObject(dec *Decoder, k string) error {
return f(dec, k)
}
// NKeys implements UnmarshalerJSONObject.
func (f DecodeObjectFunc) NKeys() int {
return 0
}
// Add Values functions
// AddObject decodes the JSON value within an object or an array to a UnmarshalerJSONObject.
func (dec *Decoder) AddObject(v UnmarshalerJSONObject) error {
return dec.Object(v)
}
// AddObjectNull decodes the JSON value within an object or an array to a UnmarshalerJSONObject.
func (dec *Decoder) AddObjectNull(v interface{}) error {
return dec.ObjectNull(v)
}
// Object decodes the JSON value within an object or an array to a UnmarshalerJSONObject.
func (dec *Decoder) Object(value UnmarshalerJSONObject) error {
initialKeysDone := dec.keysDone
initialChild := dec.child
dec.keysDone = 0
dec.called = 0
dec.child |= 1
newCursor, err := dec.decodeObject(value)
if err != nil {
return err
}
dec.cursor = newCursor
dec.keysDone = initialKeysDone
dec.child = initialChild
dec.called |= 1
return nil
}
// ObjectNull decodes the JSON value within an object or an array to a UnmarshalerJSONObject.
// v should be a pointer to an UnmarshalerJSONObject,
// if `null` value is encountered in JSON, it will leave the value v untouched,
// else it will create a new instance of the UnmarshalerJSONObject behind v.
func (dec *Decoder) ObjectNull(v interface{}) error {
initialKeysDone := dec.keysDone
initialChild := dec.child
dec.keysDone = 0
dec.called = 0
dec.child |= 1
newCursor, err := dec.decodeObjectNull(v)
if err != nil {
return err
}
dec.cursor = newCursor
dec.keysDone = initialKeysDone
dec.child = initialChild
dec.called |= 1
return nil
}

64
vendor/github.com/francoispqt/gojay/decode_pool.go generated vendored Normal file
View File

@@ -0,0 +1,64 @@
package gojay
import (
"io"
"sync"
)
var decPool = sync.Pool{
New: newDecoderPool,
}
func init() {
for i := 0; i < 32; i++ {
decPool.Put(NewDecoder(nil))
}
}
// NewDecoder returns a new decoder.
// It takes an io.Reader implementation as data input.
func NewDecoder(r io.Reader) *Decoder {
return &Decoder{
called: 0,
cursor: 0,
keysDone: 0,
err: nil,
r: r,
data: make([]byte, 512),
length: 0,
isPooled: 0,
}
}
func newDecoderPool() interface{} {
return NewDecoder(nil)
}
// BorrowDecoder borrows a Decoder from the pool.
// It takes an io.Reader implementation as data input.
//
// In order to benefit from the pool, a borrowed decoder must be released after usage.
func BorrowDecoder(r io.Reader) *Decoder {
return borrowDecoder(r, 512)
}
func borrowDecoder(r io.Reader, bufSize int) *Decoder {
dec := decPool.Get().(*Decoder)
dec.called = 0
dec.keysDone = 0
dec.cursor = 0
dec.err = nil
dec.r = r
dec.length = 0
dec.isPooled = 0
if bufSize > 0 {
dec.data = make([]byte, bufSize)
}
return dec
}
// Release sends back a Decoder to the pool.
// If a decoder is used after calling Release
// a panic will be raised with an InvalidUsagePooledDecoderError error.
func (dec *Decoder) Release() {
dec.isPooled = 1
decPool.Put(dec)
}

89
vendor/github.com/francoispqt/gojay/decode_slice.go generated vendored Normal file
View File

@@ -0,0 +1,89 @@
package gojay
// AddSliceString unmarshals the next JSON array of strings to the given *[]string s
func (dec *Decoder) AddSliceString(s *[]string) error {
return dec.SliceString(s)
}
// SliceString unmarshals the next JSON array of strings to the given *[]string s
func (dec *Decoder) SliceString(s *[]string) error {
err := dec.Array(DecodeArrayFunc(func(dec *Decoder) error {
var str string
if err := dec.String(&str); err != nil {
return err
}
*s = append(*s, str)
return nil
}))
if err != nil {
return err
}
return nil
}
// AddSliceInt unmarshals the next JSON array of integers to the given *[]int s
func (dec *Decoder) AddSliceInt(s *[]int) error {
return dec.SliceInt(s)
}
// SliceInt unmarshals the next JSON array of integers to the given *[]int s
func (dec *Decoder) SliceInt(s *[]int) error {
err := dec.Array(DecodeArrayFunc(func(dec *Decoder) error {
var i int
if err := dec.Int(&i); err != nil {
return err
}
*s = append(*s, i)
return nil
}))
if err != nil {
return err
}
return nil
}
// AddFloat64 unmarshals the next JSON array of floats to the given *[]float64 s
func (dec *Decoder) AddSliceFloat64(s *[]float64) error {
return dec.SliceFloat64(s)
}
// SliceFloat64 unmarshals the next JSON array of floats to the given *[]float64 s
func (dec *Decoder) SliceFloat64(s *[]float64) error {
err := dec.Array(DecodeArrayFunc(func(dec *Decoder) error {
var i float64
if err := dec.Float64(&i); err != nil {
return err
}
*s = append(*s, i)
return nil
}))
if err != nil {
return err
}
return nil
}
// AddBool unmarshals the next JSON array of boolegers to the given *[]bool s
func (dec *Decoder) AddSliceBool(s *[]bool) error {
return dec.SliceBool(s)
}
// SliceBool unmarshals the next JSON array of boolegers to the given *[]bool s
func (dec *Decoder) SliceBool(s *[]bool) error {
err := dec.Array(DecodeArrayFunc(func(dec *Decoder) error {
var b bool
if err := dec.Bool(&b); err != nil {
return err
}
*s = append(*s, b)
return nil
}))
if err != nil {
return err
}
return nil
}

157
vendor/github.com/francoispqt/gojay/decode_sqlnull.go generated vendored Normal file
View File

@@ -0,0 +1,157 @@
package gojay
import "database/sql"
// DecodeSQLNullString decodes a sql.NullString
func (dec *Decoder) DecodeSQLNullString(v *sql.NullString) error {
if dec.isPooled == 1 {
panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeSQLNullString(v)
}
func (dec *Decoder) decodeSQLNullString(v *sql.NullString) error {
var str string
if err := dec.decodeString(&str); err != nil {
return err
}
v.String = str
v.Valid = true
return nil
}
// DecodeSQLNullInt64 decodes a sql.NullInt64
func (dec *Decoder) DecodeSQLNullInt64(v *sql.NullInt64) error {
if dec.isPooled == 1 {
panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeSQLNullInt64(v)
}
func (dec *Decoder) decodeSQLNullInt64(v *sql.NullInt64) error {
var i int64
if err := dec.decodeInt64(&i); err != nil {
return err
}
v.Int64 = i
v.Valid = true
return nil
}
// DecodeSQLNullFloat64 decodes a sql.NullString with the given format
func (dec *Decoder) DecodeSQLNullFloat64(v *sql.NullFloat64) error {
if dec.isPooled == 1 {
panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeSQLNullFloat64(v)
}
func (dec *Decoder) decodeSQLNullFloat64(v *sql.NullFloat64) error {
var i float64
if err := dec.decodeFloat64(&i); err != nil {
return err
}
v.Float64 = i
v.Valid = true
return nil
}
// DecodeSQLNullBool decodes a sql.NullString with the given format
func (dec *Decoder) DecodeSQLNullBool(v *sql.NullBool) error {
if dec.isPooled == 1 {
panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeSQLNullBool(v)
}
func (dec *Decoder) decodeSQLNullBool(v *sql.NullBool) error {
var b bool
if err := dec.decodeBool(&b); err != nil {
return err
}
v.Bool = b
v.Valid = true
return nil
}
// Add Values functions
// AddSQLNullString decodes the JSON value within an object or an array to qn *sql.NullString
func (dec *Decoder) AddSQLNullString(v *sql.NullString) error {
return dec.SQLNullString(v)
}
// SQLNullString decodes the JSON value within an object or an array to an *sql.NullString
func (dec *Decoder) SQLNullString(v *sql.NullString) error {
var b *string
if err := dec.StringNull(&b); err != nil {
return err
}
if b == nil {
v.Valid = false
} else {
v.String = *b
v.Valid = true
}
return nil
}
// AddSQLNullInt64 decodes the JSON value within an object or an array to qn *sql.NullInt64
func (dec *Decoder) AddSQLNullInt64(v *sql.NullInt64) error {
return dec.SQLNullInt64(v)
}
// SQLNullInt64 decodes the JSON value within an object or an array to an *sql.NullInt64
func (dec *Decoder) SQLNullInt64(v *sql.NullInt64) error {
var b *int64
if err := dec.Int64Null(&b); err != nil {
return err
}
if b == nil {
v.Valid = false
} else {
v.Int64 = *b
v.Valid = true
}
return nil
}
// AddSQLNullFloat64 decodes the JSON value within an object or an array to qn *sql.NullFloat64
func (dec *Decoder) AddSQLNullFloat64(v *sql.NullFloat64) error {
return dec.SQLNullFloat64(v)
}
// SQLNullFloat64 decodes the JSON value within an object or an array to an *sql.NullFloat64
func (dec *Decoder) SQLNullFloat64(v *sql.NullFloat64) error {
var b *float64
if err := dec.Float64Null(&b); err != nil {
return err
}
if b == nil {
v.Valid = false
} else {
v.Float64 = *b
v.Valid = true
}
return nil
}
// AddSQLNullBool decodes the JSON value within an object or an array to an *sql.NullBool
func (dec *Decoder) AddSQLNullBool(v *sql.NullBool) error {
return dec.SQLNullBool(v)
}
// SQLNullBool decodes the JSON value within an object or an array to an *sql.NullBool
func (dec *Decoder) SQLNullBool(v *sql.NullBool) error {
var b *bool
if err := dec.BoolNull(&b); err != nil {
return err
}
if b == nil {
v.Valid = false
} else {
v.Bool = *b
v.Valid = true
}
return nil
}

115
vendor/github.com/francoispqt/gojay/decode_stream.go generated vendored Normal file
View File

@@ -0,0 +1,115 @@
package gojay
import (
"sync"
"time"
)
// UnmarshalerStream is the interface to implement for a slice, an array or a slice
// to decode a line delimited JSON to.
type UnmarshalerStream interface {
UnmarshalStream(*StreamDecoder) error
}
// Stream is a struct holding the Stream api
var Stream = stream{}
type stream struct{}
// A StreamDecoder reads and decodes JSON values from an input stream.
//
// It implements conext.Context and provide a channel to notify interruption.
type StreamDecoder struct {
mux sync.RWMutex
*Decoder
done chan struct{}
deadline *time.Time
}
// DecodeStream reads the next line delimited JSON-encoded value from the decoder's input (io.Reader) and stores it in the value pointed to by c.
//
// c must implement UnmarshalerStream. Ideally c is a channel. See example for implementation.
//
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *StreamDecoder) DecodeStream(c UnmarshalerStream) error {
if dec.isPooled == 1 {
panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
if dec.r == nil {
dec.err = NoReaderError("No reader given to decode stream")
close(dec.done)
return dec.err
}
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch dec.data[dec.cursor] {
case ' ', '\n', '\t', '\r', ',':
continue
default:
// char is not space start reading
for dec.nextChar() != 0 {
// calling unmarshal stream
err := c.UnmarshalStream(dec)
if err != nil {
dec.err = err
close(dec.done)
return err
}
// garbage collects buffer
// we don't want the buffer to grow extensively
dec.data = dec.data[dec.cursor:]
dec.length = dec.length - dec.cursor
dec.cursor = 0
}
// close the done channel to signal the end of the job
close(dec.done)
return nil
}
}
close(dec.done)
dec.mux.Lock()
err := dec.raiseInvalidJSONErr(dec.cursor)
dec.mux.Unlock()
return err
}
// context.Context implementation
// Done returns a channel that's closed when work is done.
// It implements context.Context
func (dec *StreamDecoder) Done() <-chan struct{} {
return dec.done
}
// Deadline returns the time when work done on behalf of this context
// should be canceled. Deadline returns ok==false when no deadline is
// set. Successive calls to Deadline return the same results.
func (dec *StreamDecoder) Deadline() (time.Time, bool) {
if dec.deadline != nil {
return *dec.deadline, true
}
return time.Time{}, false
}
// SetDeadline sets the deadline
func (dec *StreamDecoder) SetDeadline(t time.Time) {
dec.deadline = &t
}
// Err returns nil if Done is not yet closed.
// If Done is closed, Err returns a non-nil error explaining why.
// It implements context.Context
func (dec *StreamDecoder) Err() error {
select {
case <-dec.done:
dec.mux.RLock()
defer dec.mux.RUnlock()
return dec.err
default:
return nil
}
}
// Value implements context.Context
func (dec *StreamDecoder) Value(key interface{}) interface{} {
return nil
}

View File

@@ -0,0 +1,59 @@
package gojay
import (
"io"
"sync"
)
var streamDecPool = sync.Pool{
New: newStreamDecoderPool,
}
// NewDecoder returns a new StreamDecoder.
// It takes an io.Reader implementation as data input.
// It initiates the done channel returned by Done().
func (s stream) NewDecoder(r io.Reader) *StreamDecoder {
dec := NewDecoder(r)
streamDec := &StreamDecoder{
Decoder: dec,
done: make(chan struct{}, 1),
mux: sync.RWMutex{},
}
return streamDec
}
func newStreamDecoderPool() interface{} {
return Stream.NewDecoder(nil)
}
// BorrowDecoder borrows a StreamDecoder from the pool.
// It takes an io.Reader implementation as data input.
// It initiates the done channel returned by Done().
//
// If no StreamEncoder is available in the pool, it returns a fresh one
func (s stream) BorrowDecoder(r io.Reader) *StreamDecoder {
return s.borrowDecoder(r, 512)
}
func (s stream) borrowDecoder(r io.Reader, bufSize int) *StreamDecoder {
streamDec := streamDecPool.Get().(*StreamDecoder)
streamDec.called = 0
streamDec.keysDone = 0
streamDec.cursor = 0
streamDec.err = nil
streamDec.r = r
streamDec.length = 0
streamDec.isPooled = 0
streamDec.done = make(chan struct{}, 1)
if bufSize > 0 {
streamDec.data = make([]byte, bufSize)
}
return streamDec
}
// Release sends back a Decoder to the pool.
// If a decoder is used after calling Release
// a panic will be raised with an InvalidUsagePooledDecoderError error.
func (dec *StreamDecoder) Release() {
dec.isPooled = 1
streamDecPool.Put(dec)
}

260
vendor/github.com/francoispqt/gojay/decode_string.go generated vendored Normal file
View File

@@ -0,0 +1,260 @@
package gojay
import (
"unsafe"
)
// DecodeString reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the string pointed to by v.
//
// See the documentation for Unmarshal for details about the conversion of JSON into a Go value.
func (dec *Decoder) DecodeString(v *string) error {
if dec.isPooled == 1 {
panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeString(v)
}
func (dec *Decoder) decodeString(v *string) error {
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch dec.data[dec.cursor] {
case ' ', '\n', '\t', '\r', ',':
// is string
continue
case '"':
dec.cursor++
start, end, err := dec.getString()
if err != nil {
return err
}
// we do minus one to remove the last quote
d := dec.data[start : end-1]
*v = *(*string)(unsafe.Pointer(&d))
dec.cursor = end
return nil
// is nil
case 'n':
dec.cursor++
err := dec.assertNull()
if err != nil {
return err
}
return nil
default:
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
}
}
return nil
}
func (dec *Decoder) decodeStringNull(v **string) error {
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
switch dec.data[dec.cursor] {
case ' ', '\n', '\t', '\r', ',':
// is string
continue
case '"':
dec.cursor++
start, end, err := dec.getString()
if err != nil {
return err
}
if *v == nil {
*v = new(string)
}
// we do minus one to remove the last quote
d := dec.data[start : end-1]
**v = *(*string)(unsafe.Pointer(&d))
dec.cursor = end
return nil
// is nil
case 'n':
dec.cursor++
err := dec.assertNull()
if err != nil {
return err
}
return nil
default:
dec.err = dec.makeInvalidUnmarshalErr(v)
err := dec.skipData()
if err != nil {
return err
}
return nil
}
}
return nil
}
func (dec *Decoder) parseEscapedString() error {
if dec.cursor >= dec.length && !dec.read() {
return dec.raiseInvalidJSONErr(dec.cursor)
}
switch dec.data[dec.cursor] {
case '"':
dec.data[dec.cursor] = '"'
case '\\':
dec.data[dec.cursor] = '\\'
case '/':
dec.data[dec.cursor] = '/'
case 'b':
dec.data[dec.cursor] = '\b'
case 'f':
dec.data[dec.cursor] = '\f'
case 'n':
dec.data[dec.cursor] = '\n'
case 'r':
dec.data[dec.cursor] = '\r'
case 't':
dec.data[dec.cursor] = '\t'
case 'u':
start := dec.cursor
dec.cursor++
str, err := dec.parseUnicode()
if err != nil {
return err
}
diff := dec.cursor - start
dec.data = append(append(dec.data[:start-1], str...), dec.data[dec.cursor:]...)
dec.length = len(dec.data)
dec.cursor += len(str) - diff - 1
return nil
default:
return dec.raiseInvalidJSONErr(dec.cursor)
}
dec.data = append(dec.data[:dec.cursor-1], dec.data[dec.cursor:]...)
dec.length--
// Since we've lost a character, our dec.cursor offset is now
// 1 past the escaped character which is precisely where we
// want it.
return nil
}
func (dec *Decoder) getString() (int, int, error) {
// extract key
var keyStart = dec.cursor
// var str *Builder
for dec.cursor < dec.length || dec.read() {
switch dec.data[dec.cursor] {
// string found
case '"':
dec.cursor = dec.cursor + 1
return keyStart, dec.cursor, nil
// slash found
case '\\':
dec.cursor = dec.cursor + 1
err := dec.parseEscapedString()
if err != nil {
return 0, 0, err
}
default:
dec.cursor = dec.cursor + 1
continue
}
}
return 0, 0, dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) skipEscapedString() error {
start := dec.cursor
for ; dec.cursor < dec.length || dec.read(); dec.cursor++ {
if dec.data[dec.cursor] != '\\' {
d := dec.data[dec.cursor]
dec.cursor = dec.cursor + 1
nSlash := dec.cursor - start
switch d {
case '"':
// nSlash must be odd
if nSlash&1 != 1 {
return dec.raiseInvalidJSONErr(dec.cursor)
}
return nil
case 'u': // is unicode, we skip the following characters and place the cursor one one byte backward to avoid it breaking when returning to skipString
if err := dec.skipString(); err != nil {
return err
}
dec.cursor--
return nil
case 'n', 'r', 't', '/', 'f', 'b':
return nil
default:
// nSlash must be even
if nSlash&1 == 1 {
return dec.raiseInvalidJSONErr(dec.cursor)
}
return nil
}
}
}
return dec.raiseInvalidJSONErr(dec.cursor)
}
func (dec *Decoder) skipString() error {
for dec.cursor < dec.length || dec.read() {
switch dec.data[dec.cursor] {
// found the closing quote
// let's return
case '"':
dec.cursor = dec.cursor + 1
return nil
// solidus found start parsing an escaped string
case '\\':
dec.cursor = dec.cursor + 1
err := dec.skipEscapedString()
if err != nil {
return err
}
default:
dec.cursor = dec.cursor + 1
continue
}
}
return dec.raiseInvalidJSONErr(len(dec.data) - 1)
}
// Add Values functions
// AddString decodes the JSON value within an object or an array to a *string.
// If next key is not a JSON string nor null, InvalidUnmarshalError will be returned.
func (dec *Decoder) AddString(v *string) error {
return dec.String(v)
}
// AddStringNull decodes the JSON value within an object or an array to a *string.
// If next key is not a JSON string nor null, InvalidUnmarshalError will be returned.
// If a `null` is encountered, gojay does not change the value of the pointer.
func (dec *Decoder) AddStringNull(v **string) error {
return dec.StringNull(v)
}
// String decodes the JSON value within an object or an array to a *string.
// If next key is not a JSON string nor null, InvalidUnmarshalError will be returned.
func (dec *Decoder) String(v *string) error {
err := dec.decodeString(v)
if err != nil {
return err
}
dec.called |= 1
return nil
}
// StringNull decodes the JSON value within an object or an array to a **string.
// If next key is not a JSON string nor null, InvalidUnmarshalError will be returned.
// If a `null` is encountered, gojay does not change the value of the pointer.
func (dec *Decoder) StringNull(v **string) error {
err := dec.decodeStringNull(v)
if err != nil {
return err
}
dec.called |= 1
return nil
}

View File

@@ -0,0 +1,98 @@
package gojay
import (
"unicode/utf16"
"unicode/utf8"
)
func (dec *Decoder) getUnicode() (rune, error) {
i := 0
r := rune(0)
for ; (dec.cursor < dec.length || dec.read()) && i < 4; dec.cursor++ {
c := dec.data[dec.cursor]
if c >= '0' && c <= '9' {
r = r*16 + rune(c-'0')
} else if c >= 'a' && c <= 'f' {
r = r*16 + rune(c-'a'+10)
} else if c >= 'A' && c <= 'F' {
r = r*16 + rune(c-'A'+10)
} else {
return 0, InvalidJSONError("Invalid unicode code point")
}
i++
}
return r, nil
}
func (dec *Decoder) appendEscapeChar(str []byte, c byte) ([]byte, error) {
switch c {
case 't':
str = append(str, '\t')
case 'n':
str = append(str, '\n')
case 'r':
str = append(str, '\r')
case 'b':
str = append(str, '\b')
case 'f':
str = append(str, '\f')
case '\\':
str = append(str, '\\')
default:
return nil, InvalidJSONError("Invalid JSON")
}
return str, nil
}
func (dec *Decoder) parseUnicode() ([]byte, error) {
// get unicode after u
r, err := dec.getUnicode()
if err != nil {
return nil, err
}
// no error start making new string
str := make([]byte, 16, 16)
i := 0
// check if code can be a surrogate utf16
if utf16.IsSurrogate(r) {
if dec.cursor >= dec.length && !dec.read() {
return nil, dec.raiseInvalidJSONErr(dec.cursor)
}
c := dec.data[dec.cursor]
if c != '\\' {
i += utf8.EncodeRune(str, r)
return str[:i], nil
}
dec.cursor++
if dec.cursor >= dec.length && !dec.read() {
return nil, dec.raiseInvalidJSONErr(dec.cursor)
}
c = dec.data[dec.cursor]
if c != 'u' {
i += utf8.EncodeRune(str, r)
str, err = dec.appendEscapeChar(str[:i], c)
if err != nil {
dec.err = err
return nil, err
}
i++
dec.cursor++
return str[:i], nil
}
dec.cursor++
r2, err := dec.getUnicode()
if err != nil {
return nil, err
}
combined := utf16.DecodeRune(r, r2)
if combined == '\uFFFD' {
i += utf8.EncodeRune(str, r)
i += utf8.EncodeRune(str, r2)
} else {
i += utf8.EncodeRune(str, combined)
}
return str[:i], nil
}
i += utf8.EncodeRune(str, r)
return str[:i], nil
}

53
vendor/github.com/francoispqt/gojay/decode_time.go generated vendored Normal file
View File

@@ -0,0 +1,53 @@
package gojay
import (
"time"
)
// DecodeTime decodes time with the given format
func (dec *Decoder) DecodeTime(v *time.Time, format string) error {
if dec.isPooled == 1 {
panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
}
return dec.decodeTime(v, format)
}
func (dec *Decoder) decodeTime(v *time.Time, format string) error {
if format == time.RFC3339 {
var ej = make(EmbeddedJSON, 0, 20)
if err := dec.decodeEmbeddedJSON(&ej); err != nil {
return err
}
if err := v.UnmarshalJSON(ej); err != nil {
return err
}
return nil
}
var str string
if err := dec.decodeString(&str); err != nil {
return err
}
tt, err := time.Parse(format, str)
if err != nil {
return err
}
*v = tt
return nil
}
// Add Values functions
// AddTime decodes the JSON value within an object or an array to a *time.Time with the given format
func (dec *Decoder) AddTime(v *time.Time, format string) error {
return dec.Time(v, format)
}
// Time decodes the JSON value within an object or an array to a *time.Time with the given format
func (dec *Decoder) Time(v *time.Time, format string) error {
err := dec.decodeTime(v, format)
if err != nil {
return err
}
dec.called |= 1
return nil
}

120
vendor/github.com/francoispqt/gojay/decode_unsafe.go generated vendored Normal file
View File

@@ -0,0 +1,120 @@
package gojay
import (
"fmt"
)
// Unsafe is the structure holding the unsafe version of the API.
// The difference between unsafe api and regular api is that the regular API
// copies the buffer passed to Unmarshal functions to a new internal buffer.
// Making it safer because internally GoJay uses unsafe.Pointer to transform slice of bytes into a string.
var Unsafe = decUnsafe{}
type decUnsafe struct{}
func (u decUnsafe) UnmarshalJSONArray(data []byte, v UnmarshalerJSONArray) error {
dec := borrowDecoder(nil, 0)
defer dec.Release()
dec.data = data
dec.length = len(data)
_, err := dec.decodeArray(v)
return err
}
func (u decUnsafe) UnmarshalJSONObject(data []byte, v UnmarshalerJSONObject) error {
dec := borrowDecoder(nil, 0)
defer dec.Release()
dec.data = data
dec.length = len(data)
_, err := dec.decodeObject(v)
return err
}
func (u decUnsafe) Unmarshal(data []byte, v interface{}) error {
var err error
var dec *Decoder
switch vt := v.(type) {
case *string:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeString(vt)
case *int:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeInt(vt)
case *int8:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeInt8(vt)
case *int16:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeInt16(vt)
case *int32:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeInt32(vt)
case *int64:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeInt64(vt)
case *uint8:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeUint8(vt)
case *uint16:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeUint16(vt)
case *uint32:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeUint32(vt)
case *uint64:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeUint64(vt)
case *float64:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeFloat64(vt)
case *float32:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeFloat32(vt)
case *bool:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
err = dec.decodeBool(vt)
case UnmarshalerJSONObject:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
_, err = dec.decodeObject(vt)
case UnmarshalerJSONArray:
dec = borrowDecoder(nil, 0)
dec.length = len(data)
dec.data = data
_, err = dec.decodeArray(vt)
default:
return InvalidUnmarshalError(fmt.Sprintf(invalidUnmarshalErrorMsg, vt))
}
defer dec.Release()
if err != nil {
return err
}
return dec.err
}

202
vendor/github.com/francoispqt/gojay/encode.go generated vendored Normal file
View File

@@ -0,0 +1,202 @@
package gojay
import (
"encoding/json"
"fmt"
"io"
)
var nullBytes = []byte("null")
// MarshalJSONArray returns the JSON encoding of v, an implementation of MarshalerJSONArray.
//
//
// Example:
// type TestSlice []*TestStruct
//
// func (t TestSlice) MarshalJSONArray(enc *Encoder) {
// for _, e := range t {
// enc.AddObject(e)
// }
// }
//
// func main() {
// test := &TestSlice{
// &TestStruct{123456},
// &TestStruct{7890},
// }
// b, _ := Marshal(test)
// fmt.Println(b) // [{"id":123456},{"id":7890}]
// }
func MarshalJSONArray(v MarshalerJSONArray) ([]byte, error) {
enc := BorrowEncoder(nil)
enc.grow(512)
enc.writeByte('[')
v.(MarshalerJSONArray).MarshalJSONArray(enc)
enc.writeByte(']')
defer func() {
enc.buf = make([]byte, 0, 512)
enc.Release()
}()
return enc.buf, nil
}
// MarshalJSONObject returns the JSON encoding of v, an implementation of MarshalerJSONObject.
//
// Example:
// type Object struct {
// id int
// }
// func (s *Object) MarshalJSONObject(enc *gojay.Encoder) {
// enc.IntKey("id", s.id)
// }
// func (s *Object) IsNil() bool {
// return s == nil
// }
//
// func main() {
// test := &Object{
// id: 123456,
// }
// b, _ := gojay.Marshal(test)
// fmt.Println(b) // {"id":123456}
// }
func MarshalJSONObject(v MarshalerJSONObject) ([]byte, error) {
enc := BorrowEncoder(nil)
enc.grow(512)
defer func() {
enc.buf = make([]byte, 0, 512)
enc.Release()
}()
return enc.encodeObject(v)
}
// Marshal returns the JSON encoding of v.
//
// If v is nil, not an implementation MarshalerJSONObject or MarshalerJSONArray or not one of the following types:
// string, int, int8, int16, int32, int64, uint8, uint16, uint32, uint64, float64, float32, bool
// Marshal returns an InvalidMarshalError.
func Marshal(v interface{}) ([]byte, error) {
return marshal(v, false)
}
// MarshalAny returns the JSON encoding of v.
//
// If v is nil, not an implementation MarshalerJSONObject or MarshalerJSONArray or not one of the following types:
// string, int, int8, int16, int32, int64, uint8, uint16, uint32, uint64, float64, float32, bool
// MarshalAny falls back to "json/encoding" package to marshal the value.
func MarshalAny(v interface{}) ([]byte, error) {
return marshal(v, true)
}
func marshal(v interface{}, any bool) ([]byte, error) {
var (
enc = BorrowEncoder(nil)
buf []byte
err error
)
defer func() {
enc.buf = make([]byte, 0, 512)
enc.Release()
}()
buf, err = func() ([]byte, error) {
switch vt := v.(type) {
case MarshalerJSONObject:
return enc.encodeObject(vt)
case MarshalerJSONArray:
return enc.encodeArray(vt)
case string:
return enc.encodeString(vt)
case bool:
return enc.encodeBool(vt)
case int:
return enc.encodeInt(vt)
case int64:
return enc.encodeInt64(vt)
case int32:
return enc.encodeInt(int(vt))
case int16:
return enc.encodeInt(int(vt))
case int8:
return enc.encodeInt(int(vt))
case uint64:
return enc.encodeInt(int(vt))
case uint32:
return enc.encodeInt(int(vt))
case uint16:
return enc.encodeInt(int(vt))
case uint8:
return enc.encodeInt(int(vt))
case float64:
return enc.encodeFloat(vt)
case float32:
return enc.encodeFloat32(vt)
case *EmbeddedJSON:
return enc.encodeEmbeddedJSON(vt)
default:
if any {
return json.Marshal(vt)
}
return nil, InvalidMarshalError(fmt.Sprintf(invalidMarshalErrorMsg, vt))
}
}()
return buf, err
}
// MarshalerJSONObject is the interface to implement for struct to be encoded
type MarshalerJSONObject interface {
MarshalJSONObject(enc *Encoder)
IsNil() bool
}
// MarshalerJSONArray is the interface to implement
// for a slice or an array to be encoded
type MarshalerJSONArray interface {
MarshalJSONArray(enc *Encoder)
IsNil() bool
}
// An Encoder writes JSON values to an output stream.
type Encoder struct {
buf []byte
isPooled byte
w io.Writer
err error
hasKeys bool
keys []string
}
// AppendBytes allows a modular usage by appending bytes manually to the current state of the buffer.
func (enc *Encoder) AppendBytes(b []byte) {
enc.writeBytes(b)
}
// AppendByte allows a modular usage by appending a single byte manually to the current state of the buffer.
func (enc *Encoder) AppendByte(b byte) {
enc.writeByte(b)
}
// Buf returns the Encoder's buffer.
func (enc *Encoder) Buf() []byte {
return enc.buf
}
// Write writes to the io.Writer and resets the buffer.
func (enc *Encoder) Write() (int, error) {
i, err := enc.w.Write(enc.buf)
enc.buf = enc.buf[:0]
return i, err
}
func (enc *Encoder) getPreviousRune() byte {
last := len(enc.buf) - 1
return enc.buf[last]
}

212
vendor/github.com/francoispqt/gojay/encode_array.go generated vendored Normal file
View File

@@ -0,0 +1,212 @@
package gojay
// EncodeArray encodes an implementation of MarshalerJSONArray to JSON
func (enc *Encoder) EncodeArray(v MarshalerJSONArray) error {
if enc.isPooled == 1 {
panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
}
_, _ = enc.encodeArray(v)
_, err := enc.Write()
if err != nil {
enc.err = err
return err
}
return nil
}
func (enc *Encoder) encodeArray(v MarshalerJSONArray) ([]byte, error) {
enc.grow(200)
enc.writeByte('[')
v.MarshalJSONArray(enc)
enc.writeByte(']')
return enc.buf, enc.err
}
// AddArray adds an implementation of MarshalerJSONArray to be encoded, must be used inside a slice or array encoding (does not encode a key)
// value must implement Marshaler
func (enc *Encoder) AddArray(v MarshalerJSONArray) {
enc.Array(v)
}
// AddArrayOmitEmpty adds an array or slice to be encoded, must be used inside a slice or array encoding (does not encode a key)
// value must implement MarshalerAddArrayOmitEmpty
func (enc *Encoder) AddArrayOmitEmpty(v MarshalerJSONArray) {
enc.ArrayOmitEmpty(v)
}
// AddArrayNullEmpty adds an array or slice to be encoded, must be used inside a slice or array encoding (does not encode a key)
// value must implement Marshaler, if v is empty, `null` will be encoded`
func (enc *Encoder) AddArrayNullEmpty(v MarshalerJSONArray) {
enc.ArrayNullEmpty(v)
}
// AddArrayKey adds an array or slice to be encoded, must be used inside an object as it will encode a key
// value must implement Marshaler
func (enc *Encoder) AddArrayKey(key string, v MarshalerJSONArray) {
enc.ArrayKey(key, v)
}
// AddArrayKeyOmitEmpty adds an array or slice to be encoded and skips it if it is nil.
// Must be called inside an object as it will encode a key.
func (enc *Encoder) AddArrayKeyOmitEmpty(key string, v MarshalerJSONArray) {
enc.ArrayKeyOmitEmpty(key, v)
}
// AddArrayKeyNullEmpty adds an array or slice to be encoded and skips it if it is nil.
// Must be called inside an object as it will encode a key. `null` will be encoded`
func (enc *Encoder) AddArrayKeyNullEmpty(key string, v MarshalerJSONArray) {
enc.ArrayKeyNullEmpty(key, v)
}
// Array adds an implementation of MarshalerJSONArray to be encoded, must be used inside a slice or array encoding (does not encode a key)
// value must implement Marshaler
func (enc *Encoder) Array(v MarshalerJSONArray) {
if v.IsNil() {
enc.grow(3)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.writeByte('[')
enc.writeByte(']')
return
}
enc.grow(100)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.writeByte('[')
v.MarshalJSONArray(enc)
enc.writeByte(']')
}
// ArrayOmitEmpty adds an array or slice to be encoded, must be used inside a slice or array encoding (does not encode a key)
// value must implement Marshaler
func (enc *Encoder) ArrayOmitEmpty(v MarshalerJSONArray) {
if v.IsNil() {
return
}
enc.grow(4)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.writeByte('[')
v.MarshalJSONArray(enc)
enc.writeByte(']')
}
// ArrayNullEmpty adds an array or slice to be encoded, must be used inside a slice or array encoding (does not encode a key)
// value must implement Marshaler
func (enc *Encoder) ArrayNullEmpty(v MarshalerJSONArray) {
enc.grow(4)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
if v.IsNil() {
enc.writeBytes(nullBytes)
return
}
enc.writeByte('[')
v.MarshalJSONArray(enc)
enc.writeByte(']')
}
// ArrayKey adds an array or slice to be encoded, must be used inside an object as it will encode a key
// value must implement Marshaler
func (enc *Encoder) ArrayKey(key string, v MarshalerJSONArray) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
if v.IsNil() {
enc.grow(2 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKeyArr)
enc.writeByte(']')
return
}
enc.grow(5 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKeyArr)
v.MarshalJSONArray(enc)
enc.writeByte(']')
}
// ArrayKeyOmitEmpty adds an array or slice to be encoded and skips if it is nil.
// Must be called inside an object as it will encode a key.
func (enc *Encoder) ArrayKeyOmitEmpty(key string, v MarshalerJSONArray) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
if v.IsNil() {
return
}
enc.grow(5 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKeyArr)
v.MarshalJSONArray(enc)
enc.writeByte(']')
}
// ArrayKeyNullEmpty adds an array or slice to be encoded and encodes `null`` if it is nil.
// Must be called inside an object as it will encode a key.
func (enc *Encoder) ArrayKeyNullEmpty(key string, v MarshalerJSONArray) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
enc.grow(5 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
if v.IsNil() {
enc.writeBytes(nullBytes)
return
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKeyArr)
v.MarshalJSONArray(enc)
enc.writeByte(']')
}
// EncodeArrayFunc is a custom func type implementing MarshaleArray.
// Use it to cast a func(*Encoder) to Marshal an object.
//
// enc := gojay.NewEncoder(io.Writer)
// enc.EncodeArray(gojay.EncodeArrayFunc(func(enc *gojay.Encoder) {
// enc.AddStringKey("hello", "world")
// }))
type EncodeArrayFunc func(*Encoder)
// MarshalJSONArray implements MarshalerJSONArray.
func (f EncodeArrayFunc) MarshalJSONArray(enc *Encoder) {
f(enc)
}
// IsNil implements MarshalerJSONArray.
func (f EncodeArrayFunc) IsNil() bool {
return f == nil
}

164
vendor/github.com/francoispqt/gojay/encode_bool.go generated vendored Normal file
View File

@@ -0,0 +1,164 @@
package gojay
import "strconv"
// EncodeBool encodes a bool to JSON
func (enc *Encoder) EncodeBool(v bool) error {
if enc.isPooled == 1 {
panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
}
_, _ = enc.encodeBool(v)
_, err := enc.Write()
if err != nil {
enc.err = err
return err
}
return nil
}
// encodeBool encodes a bool to JSON
func (enc *Encoder) encodeBool(v bool) ([]byte, error) {
enc.grow(5)
if v {
enc.writeString("true")
} else {
enc.writeString("false")
}
return enc.buf, enc.err
}
// AddBool adds a bool to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddBool(v bool) {
enc.Bool(v)
}
// AddBoolOmitEmpty adds a bool to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddBoolOmitEmpty(v bool) {
enc.BoolOmitEmpty(v)
}
// AddBoolNullEmpty adds a bool to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddBoolNullEmpty(v bool) {
enc.BoolNullEmpty(v)
}
// AddBoolKey adds a bool to be encoded, must be used inside an object as it will encode a key.
func (enc *Encoder) AddBoolKey(key string, v bool) {
enc.BoolKey(key, v)
}
// AddBoolKeyOmitEmpty adds a bool to be encoded and skips if it is zero value.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) AddBoolKeyOmitEmpty(key string, v bool) {
enc.BoolKeyOmitEmpty(key, v)
}
// AddBoolKeyNullEmpty adds a bool to be encoded and encodes `null` if it is zero value.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) AddBoolKeyNullEmpty(key string, v bool) {
enc.BoolKeyNullEmpty(key, v)
}
// Bool adds a bool to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) Bool(v bool) {
enc.grow(5)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
if v {
enc.writeString("true")
} else {
enc.writeString("false")
}
}
// BoolOmitEmpty adds a bool to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) BoolOmitEmpty(v bool) {
if v == false {
return
}
enc.grow(5)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.writeString("true")
}
// BoolNullEmpty adds a bool to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) BoolNullEmpty(v bool) {
enc.grow(5)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
if v == false {
enc.writeBytes(nullBytes)
return
}
enc.writeString("true")
}
// BoolKey adds a bool to be encoded, must be used inside an object as it will encode a key.
func (enc *Encoder) BoolKey(key string, value bool) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
enc.grow(5 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
enc.buf = strconv.AppendBool(enc.buf, value)
}
// BoolKeyOmitEmpty adds a bool to be encoded and skips it if it is zero value.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) BoolKeyOmitEmpty(key string, v bool) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
if v == false {
return
}
enc.grow(5 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
enc.buf = strconv.AppendBool(enc.buf, v)
}
// BoolKeyNullEmpty adds a bool to be encoded and skips it if it is zero value.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) BoolKeyNullEmpty(key string, v bool) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
enc.grow(5 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
if v == false {
enc.writeBytes(nullBytes)
return
}
enc.buf = strconv.AppendBool(enc.buf, v)
}

65
vendor/github.com/francoispqt/gojay/encode_builder.go generated vendored Normal file
View File

@@ -0,0 +1,65 @@
package gojay
const hex = "0123456789abcdef"
// grow grows b's capacity, if necessary, to guarantee space for
// another n bytes. After grow(n), at least n bytes can be written to b
// without another allocation. If n is negative, grow panics.
func (enc *Encoder) grow(n int) {
if cap(enc.buf)-len(enc.buf) < n {
Buf := make([]byte, len(enc.buf), 2*cap(enc.buf)+n)
copy(Buf, enc.buf)
enc.buf = Buf
}
}
// Write appends the contents of p to b's Buffer.
// Write always returns len(p), nil.
func (enc *Encoder) writeBytes(p []byte) {
enc.buf = append(enc.buf, p...)
}
func (enc *Encoder) writeTwoBytes(b1 byte, b2 byte) {
enc.buf = append(enc.buf, b1, b2)
}
// WriteByte appends the byte c to b's Buffer.
// The returned error is always nil.
func (enc *Encoder) writeByte(c byte) {
enc.buf = append(enc.buf, c)
}
// WriteString appends the contents of s to b's Buffer.
// It returns the length of s and a nil error.
func (enc *Encoder) writeString(s string) {
enc.buf = append(enc.buf, s...)
}
func (enc *Encoder) writeStringEscape(s string) {
l := len(s)
for i := 0; i < l; i++ {
c := s[i]
if c >= 0x20 && c != '\\' && c != '"' {
enc.writeByte(c)
continue
}
switch c {
case '\\', '"':
enc.writeTwoBytes('\\', c)
case '\n':
enc.writeTwoBytes('\\', 'n')
case '\f':
enc.writeTwoBytes('\\', 'f')
case '\b':
enc.writeTwoBytes('\\', 'b')
case '\r':
enc.writeTwoBytes('\\', 'r')
case '\t':
enc.writeTwoBytes('\\', 't')
default:
enc.writeString(`\u00`)
enc.writeTwoBytes(hex[c>>4], hex[c&0xF])
}
continue
}
}

View File

@@ -0,0 +1,93 @@
package gojay
// EncodeEmbeddedJSON encodes an embedded JSON.
// is basically sets the internal buf as the value pointed by v and calls the io.Writer.Write()
func (enc *Encoder) EncodeEmbeddedJSON(v *EmbeddedJSON) error {
if enc.isPooled == 1 {
panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
}
enc.buf = *v
_, err := enc.Write()
if err != nil {
return err
}
return nil
}
func (enc *Encoder) encodeEmbeddedJSON(v *EmbeddedJSON) ([]byte, error) {
enc.writeBytes(*v)
return enc.buf, nil
}
// AddEmbeddedJSON adds an EmbeddedJSON to be encoded.
//
// It basically blindly writes the bytes to the final buffer. Therefore,
// it expects the JSON to be of proper format.
func (enc *Encoder) AddEmbeddedJSON(v *EmbeddedJSON) {
enc.grow(len(*v) + 4)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.writeBytes(*v)
}
// AddEmbeddedJSONOmitEmpty adds an EmbeddedJSON to be encoded or skips it if nil pointer or empty.
//
// It basically blindly writes the bytes to the final buffer. Therefore,
// it expects the JSON to be of proper format.
func (enc *Encoder) AddEmbeddedJSONOmitEmpty(v *EmbeddedJSON) {
if v == nil || len(*v) == 0 {
return
}
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.writeBytes(*v)
}
// AddEmbeddedJSONKey adds an EmbeddedJSON and a key to be encoded.
//
// It basically blindly writes the bytes to the final buffer. Therefore,
// it expects the JSON to be of proper format.
func (enc *Encoder) AddEmbeddedJSONKey(key string, v *EmbeddedJSON) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
enc.grow(len(key) + len(*v) + 5)
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
enc.writeBytes(*v)
}
// AddEmbeddedJSONKeyOmitEmpty adds an EmbeddedJSON and a key to be encoded or skips it if nil pointer or empty.
//
// It basically blindly writes the bytes to the final buffer. Therefore,
// it expects the JSON to be of proper format.
func (enc *Encoder) AddEmbeddedJSONKeyOmitEmpty(key string, v *EmbeddedJSON) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
if v == nil || len(*v) == 0 {
return
}
enc.grow(len(key) + len(*v) + 5)
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
enc.writeBytes(*v)
}

173
vendor/github.com/francoispqt/gojay/encode_interface.go generated vendored Normal file
View File

@@ -0,0 +1,173 @@
package gojay
import (
"fmt"
)
// Encode encodes a value to JSON.
//
// If Encode cannot find a way to encode the type to JSON
// it will return an InvalidMarshalError.
func (enc *Encoder) Encode(v interface{}) error {
if enc.isPooled == 1 {
panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
}
switch vt := v.(type) {
case string:
return enc.EncodeString(vt)
case bool:
return enc.EncodeBool(vt)
case MarshalerJSONArray:
return enc.EncodeArray(vt)
case MarshalerJSONObject:
return enc.EncodeObject(vt)
case int:
return enc.EncodeInt(vt)
case int64:
return enc.EncodeInt64(vt)
case int32:
return enc.EncodeInt(int(vt))
case int8:
return enc.EncodeInt(int(vt))
case uint64:
return enc.EncodeUint64(vt)
case uint32:
return enc.EncodeInt(int(vt))
case uint16:
return enc.EncodeInt(int(vt))
case uint8:
return enc.EncodeInt(int(vt))
case float64:
return enc.EncodeFloat(vt)
case float32:
return enc.EncodeFloat32(vt)
case *EmbeddedJSON:
return enc.EncodeEmbeddedJSON(vt)
default:
return InvalidMarshalError(fmt.Sprintf(invalidMarshalErrorMsg, vt))
}
}
// AddInterface adds an interface{} to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddInterface(value interface{}) {
switch vt := value.(type) {
case string:
enc.AddString(vt)
case bool:
enc.AddBool(vt)
case MarshalerJSONArray:
enc.AddArray(vt)
case MarshalerJSONObject:
enc.AddObject(vt)
case int:
enc.AddInt(vt)
case int64:
enc.AddInt(int(vt))
case int32:
enc.AddInt(int(vt))
case int8:
enc.AddInt(int(vt))
case uint64:
enc.AddUint64(vt)
case uint32:
enc.AddInt(int(vt))
case uint16:
enc.AddInt(int(vt))
case uint8:
enc.AddInt(int(vt))
case float64:
enc.AddFloat(vt)
case float32:
enc.AddFloat32(vt)
default:
if vt != nil {
enc.err = InvalidMarshalError(fmt.Sprintf(invalidMarshalErrorMsg, vt))
return
}
return
}
}
// AddInterfaceKey adds an interface{} to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddInterfaceKey(key string, value interface{}) {
switch vt := value.(type) {
case string:
enc.AddStringKey(key, vt)
case bool:
enc.AddBoolKey(key, vt)
case MarshalerJSONArray:
enc.AddArrayKey(key, vt)
case MarshalerJSONObject:
enc.AddObjectKey(key, vt)
case int:
enc.AddIntKey(key, vt)
case int64:
enc.AddIntKey(key, int(vt))
case int32:
enc.AddIntKey(key, int(vt))
case int16:
enc.AddIntKey(key, int(vt))
case int8:
enc.AddIntKey(key, int(vt))
case uint64:
enc.AddIntKey(key, int(vt))
case uint32:
enc.AddIntKey(key, int(vt))
case uint16:
enc.AddIntKey(key, int(vt))
case uint8:
enc.AddIntKey(key, int(vt))
case float64:
enc.AddFloatKey(key, vt)
case float32:
enc.AddFloat32Key(key, vt)
default:
if vt != nil {
enc.err = InvalidMarshalError(fmt.Sprintf(invalidMarshalErrorMsg, vt))
return
}
return
}
}
// AddInterfaceKeyOmitEmpty adds an interface{} to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddInterfaceKeyOmitEmpty(key string, v interface{}) {
switch vt := v.(type) {
case string:
enc.AddStringKeyOmitEmpty(key, vt)
case bool:
enc.AddBoolKeyOmitEmpty(key, vt)
case MarshalerJSONArray:
enc.AddArrayKeyOmitEmpty(key, vt)
case MarshalerJSONObject:
enc.AddObjectKeyOmitEmpty(key, vt)
case int:
enc.AddIntKeyOmitEmpty(key, vt)
case int64:
enc.AddIntKeyOmitEmpty(key, int(vt))
case int32:
enc.AddIntKeyOmitEmpty(key, int(vt))
case int16:
enc.AddIntKeyOmitEmpty(key, int(vt))
case int8:
enc.AddIntKeyOmitEmpty(key, int(vt))
case uint64:
enc.AddIntKeyOmitEmpty(key, int(vt))
case uint32:
enc.AddIntKeyOmitEmpty(key, int(vt))
case uint16:
enc.AddIntKeyOmitEmpty(key, int(vt))
case uint8:
enc.AddIntKeyOmitEmpty(key, int(vt))
case float64:
enc.AddFloatKeyOmitEmpty(key, vt)
case float32:
enc.AddFloat32KeyOmitEmpty(key, vt)
default:
if vt != nil {
enc.err = InvalidMarshalError(fmt.Sprintf(invalidMarshalErrorMsg, vt))
return
}
return
}
}

39
vendor/github.com/francoispqt/gojay/encode_null.go generated vendored Normal file
View File

@@ -0,0 +1,39 @@
package gojay
// AddNull adds a `null` to be encoded. Must be used while encoding an array.`
func (enc *Encoder) AddNull() {
enc.Null()
}
// Null adds a `null` to be encoded. Must be used while encoding an array.`
func (enc *Encoder) Null() {
enc.grow(5)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.writeBytes(nullBytes)
}
// AddNullKey adds a `null` to be encoded. Must be used while encoding an array.`
func (enc *Encoder) AddNullKey(key string) {
enc.NullKey(key)
}
// NullKey adds a `null` to be encoded. Must be used while encoding an array.`
func (enc *Encoder) NullKey(key string) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
enc.grow(5 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
enc.writeBytes(nullBytes)
}

1
vendor/github.com/francoispqt/gojay/encode_number.go generated vendored Normal file
View File

@@ -0,0 +1 @@
package gojay

View File

@@ -0,0 +1,368 @@
package gojay
import "strconv"
// EncodeFloat encodes a float64 to JSON
func (enc *Encoder) EncodeFloat(n float64) error {
if enc.isPooled == 1 {
panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
}
_, _ = enc.encodeFloat(n)
_, err := enc.Write()
if err != nil {
return err
}
return nil
}
// encodeFloat encodes a float64 to JSON
func (enc *Encoder) encodeFloat(n float64) ([]byte, error) {
enc.buf = strconv.AppendFloat(enc.buf, n, 'f', -1, 64)
return enc.buf, nil
}
// EncodeFloat32 encodes a float32 to JSON
func (enc *Encoder) EncodeFloat32(n float32) error {
if enc.isPooled == 1 {
panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
}
_, _ = enc.encodeFloat32(n)
_, err := enc.Write()
if err != nil {
return err
}
return nil
}
func (enc *Encoder) encodeFloat32(n float32) ([]byte, error) {
enc.buf = strconv.AppendFloat(enc.buf, float64(n), 'f', -1, 32)
return enc.buf, nil
}
// AddFloat adds a float64 to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddFloat(v float64) {
enc.Float64(v)
}
// AddFloatOmitEmpty adds a float64 to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddFloatOmitEmpty(v float64) {
enc.Float64OmitEmpty(v)
}
// AddFloatNullEmpty adds a float64 to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddFloatNullEmpty(v float64) {
enc.Float64NullEmpty(v)
}
// Float adds a float64 to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) Float(v float64) {
enc.Float64(v)
}
// FloatOmitEmpty adds a float64 to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) FloatOmitEmpty(v float64) {
enc.Float64OmitEmpty(v)
}
// FloatNullEmpty adds a float64 to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) FloatNullEmpty(v float64) {
enc.Float64NullEmpty(v)
}
// AddFloatKey adds a float64 to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddFloatKey(key string, v float64) {
enc.Float64Key(key, v)
}
// AddFloatKeyOmitEmpty adds a float64 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key
func (enc *Encoder) AddFloatKeyOmitEmpty(key string, v float64) {
enc.Float64KeyOmitEmpty(key, v)
}
// AddFloatKeyNullEmpty adds a float64 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key
func (enc *Encoder) AddFloatKeyNullEmpty(key string, v float64) {
enc.Float64KeyNullEmpty(key, v)
}
// FloatKey adds a float64 to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) FloatKey(key string, v float64) {
enc.Float64Key(key, v)
}
// FloatKeyOmitEmpty adds a float64 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key
func (enc *Encoder) FloatKeyOmitEmpty(key string, v float64) {
enc.Float64KeyOmitEmpty(key, v)
}
// FloatKeyNullEmpty adds a float64 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key
func (enc *Encoder) FloatKeyNullEmpty(key string, v float64) {
enc.Float64KeyNullEmpty(key, v)
}
// AddFloat64 adds a float64 to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddFloat64(v float64) {
enc.Float(v)
}
// AddFloat64OmitEmpty adds a float64 to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddFloat64OmitEmpty(v float64) {
enc.FloatOmitEmpty(v)
}
// Float64 adds a float64 to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) Float64(v float64) {
enc.grow(10)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.buf = strconv.AppendFloat(enc.buf, v, 'f', -1, 64)
}
// Float64OmitEmpty adds a float64 to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Float64OmitEmpty(v float64) {
if v == 0 {
return
}
enc.grow(10)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.buf = strconv.AppendFloat(enc.buf, v, 'f', -1, 64)
}
// Float64NullEmpty adds a float64 to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Float64NullEmpty(v float64) {
enc.grow(10)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
if v == 0 {
enc.writeBytes(nullBytes)
return
}
enc.buf = strconv.AppendFloat(enc.buf, v, 'f', -1, 64)
}
// AddFloat64Key adds a float64 to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddFloat64Key(key string, v float64) {
enc.FloatKey(key, v)
}
// AddFloat64KeyOmitEmpty adds a float64 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key
func (enc *Encoder) AddFloat64KeyOmitEmpty(key string, v float64) {
enc.FloatKeyOmitEmpty(key, v)
}
// Float64Key adds a float64 to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) Float64Key(key string, value float64) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.grow(10)
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
enc.buf = strconv.AppendFloat(enc.buf, value, 'f', -1, 64)
}
// Float64KeyOmitEmpty adds a float64 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key
func (enc *Encoder) Float64KeyOmitEmpty(key string, v float64) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
if v == 0 {
return
}
enc.grow(10 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
enc.buf = strconv.AppendFloat(enc.buf, v, 'f', -1, 64)
}
// Float64KeyNullEmpty adds a float64 to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Float64KeyNullEmpty(key string, v float64) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
enc.grow(10 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
if v == 0 {
enc.writeBytes(nullBytes)
return
}
enc.buf = strconv.AppendFloat(enc.buf, v, 'f', -1, 64)
}
// AddFloat32 adds a float32 to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddFloat32(v float32) {
enc.Float32(v)
}
// AddFloat32OmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddFloat32OmitEmpty(v float32) {
enc.Float32OmitEmpty(v)
}
// AddFloat32NullEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddFloat32NullEmpty(v float32) {
enc.Float32NullEmpty(v)
}
// Float32 adds a float32 to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) Float32(v float32) {
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32)
}
// Float32OmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Float32OmitEmpty(v float32) {
if v == 0 {
return
}
enc.grow(10)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32)
}
// Float32NullEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Float32NullEmpty(v float32) {
enc.grow(10)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
if v == 0 {
enc.writeBytes(nullBytes)
return
}
enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32)
}
// AddFloat32Key adds a float32 to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddFloat32Key(key string, v float32) {
enc.Float32Key(key, v)
}
// AddFloat32KeyOmitEmpty adds a float64 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key
func (enc *Encoder) AddFloat32KeyOmitEmpty(key string, v float32) {
enc.Float32KeyOmitEmpty(key, v)
}
// AddFloat32KeyNullEmpty adds a float64 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key
func (enc *Encoder) AddFloat32KeyNullEmpty(key string, v float32) {
enc.Float32KeyNullEmpty(key, v)
}
// Float32Key adds a float32 to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) Float32Key(key string, v float32) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
enc.grow(10 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeByte('"')
enc.writeByte(':')
enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32)
}
// Float32KeyOmitEmpty adds a float64 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key
func (enc *Encoder) Float32KeyOmitEmpty(key string, v float32) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
if v == 0 {
return
}
enc.grow(10 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32)
}
// Float32KeyNullEmpty adds a float64 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key
func (enc *Encoder) Float32KeyNullEmpty(key string, v float32) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
enc.grow(10 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
if v == 0 {
enc.writeBytes(nullBytes)
return
}
enc.buf = strconv.AppendFloat(enc.buf, float64(v), 'f', -1, 32)
}

View File

@@ -0,0 +1,500 @@
package gojay
import "strconv"
// EncodeInt encodes an int to JSON
func (enc *Encoder) EncodeInt(n int) error {
if enc.isPooled == 1 {
panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
}
_, _ = enc.encodeInt(n)
_, err := enc.Write()
if err != nil {
return err
}
return nil
}
// encodeInt encodes an int to JSON
func (enc *Encoder) encodeInt(n int) ([]byte, error) {
enc.buf = strconv.AppendInt(enc.buf, int64(n), 10)
return enc.buf, nil
}
// EncodeInt64 encodes an int64 to JSON
func (enc *Encoder) EncodeInt64(n int64) error {
if enc.isPooled == 1 {
panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
}
_, _ = enc.encodeInt64(n)
_, err := enc.Write()
if err != nil {
return err
}
return nil
}
// encodeInt64 encodes an int to JSON
func (enc *Encoder) encodeInt64(n int64) ([]byte, error) {
enc.buf = strconv.AppendInt(enc.buf, n, 10)
return enc.buf, nil
}
// AddInt adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddInt(v int) {
enc.Int(v)
}
// AddIntOmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddIntOmitEmpty(v int) {
enc.IntOmitEmpty(v)
}
// AddIntNullEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddIntNullEmpty(v int) {
enc.IntNullEmpty(v)
}
// Int adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) Int(v int) {
enc.grow(10)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.buf = strconv.AppendInt(enc.buf, int64(v), 10)
}
// IntOmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) IntOmitEmpty(v int) {
if v == 0 {
return
}
enc.grow(10)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.buf = strconv.AppendInt(enc.buf, int64(v), 10)
}
// IntNullEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) IntNullEmpty(v int) {
enc.grow(10)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
if v == 0 {
enc.writeBytes(nullBytes)
return
}
enc.buf = strconv.AppendInt(enc.buf, int64(v), 10)
}
// AddIntKey adds an int to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddIntKey(key string, v int) {
enc.IntKey(key, v)
}
// AddIntKeyOmitEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) AddIntKeyOmitEmpty(key string, v int) {
enc.IntKeyOmitEmpty(key, v)
}
// AddIntKeyNullEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) AddIntKeyNullEmpty(key string, v int) {
enc.IntKeyNullEmpty(key, v)
}
// IntKey adds an int to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) IntKey(key string, v int) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
enc.grow(10 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
enc.buf = strconv.AppendInt(enc.buf, int64(v), 10)
}
// IntKeyOmitEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) IntKeyOmitEmpty(key string, v int) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
if v == 0 {
return
}
enc.grow(10 + len(key))
r := enc.getPreviousRune()
if r != '{' && r != '[' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
enc.buf = strconv.AppendInt(enc.buf, int64(v), 10)
}
// IntKeyNullEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) IntKeyNullEmpty(key string, v int) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
enc.grow(10 + len(key))
r := enc.getPreviousRune()
if r != '{' && r != '[' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
if v == 0 {
enc.writeBytes(nullBytes)
return
}
enc.buf = strconv.AppendInt(enc.buf, int64(v), 10)
}
// AddInt64 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddInt64(v int64) {
enc.Int64(v)
}
// AddInt64OmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddInt64OmitEmpty(v int64) {
enc.Int64OmitEmpty(v)
}
// AddInt64NullEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddInt64NullEmpty(v int64) {
enc.Int64NullEmpty(v)
}
// Int64 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) Int64(v int64) {
enc.grow(10)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.buf = strconv.AppendInt(enc.buf, v, 10)
}
// Int64OmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Int64OmitEmpty(v int64) {
if v == 0 {
return
}
enc.grow(10)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.buf = strconv.AppendInt(enc.buf, v, 10)
}
// Int64NullEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Int64NullEmpty(v int64) {
enc.grow(10)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
if v == 0 {
enc.writeBytes(nullBytes)
return
}
enc.buf = strconv.AppendInt(enc.buf, v, 10)
}
// AddInt64Key adds an int64 to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddInt64Key(key string, v int64) {
enc.Int64Key(key, v)
}
// AddInt64KeyOmitEmpty adds an int64 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) AddInt64KeyOmitEmpty(key string, v int64) {
enc.Int64KeyOmitEmpty(key, v)
}
// AddInt64KeyNullEmpty adds an int64 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) AddInt64KeyNullEmpty(key string, v int64) {
enc.Int64KeyNullEmpty(key, v)
}
// Int64Key adds an int64 to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) Int64Key(key string, v int64) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
enc.grow(10 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
enc.buf = strconv.AppendInt(enc.buf, v, 10)
}
// Int64KeyOmitEmpty adds an int64 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) Int64KeyOmitEmpty(key string, v int64) {
if v == 0 {
return
}
enc.grow(10 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
enc.buf = strconv.AppendInt(enc.buf, v, 10)
}
// Int64KeyNullEmpty adds an int64 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) Int64KeyNullEmpty(key string, v int64) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
enc.grow(10 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
if v == 0 {
enc.writeBytes(nullBytes)
return
}
enc.buf = strconv.AppendInt(enc.buf, v, 10)
}
// AddInt32 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddInt32(v int32) {
enc.Int64(int64(v))
}
// AddInt32OmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddInt32OmitEmpty(v int32) {
enc.Int64OmitEmpty(int64(v))
}
// AddInt32NullEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddInt32NullEmpty(v int32) {
enc.Int64NullEmpty(int64(v))
}
// Int32 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) Int32(v int32) {
enc.Int64(int64(v))
}
// Int32OmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Int32OmitEmpty(v int32) {
enc.Int64OmitEmpty(int64(v))
}
// Int32NullEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Int32NullEmpty(v int32) {
enc.Int64NullEmpty(int64(v))
}
// AddInt32Key adds an int32 to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddInt32Key(key string, v int32) {
enc.Int64Key(key, int64(v))
}
// AddInt32KeyOmitEmpty adds an int32 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) AddInt32KeyOmitEmpty(key string, v int32) {
enc.Int64KeyOmitEmpty(key, int64(v))
}
// Int32Key adds an int32 to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) Int32Key(key string, v int32) {
enc.Int64Key(key, int64(v))
}
// Int32KeyOmitEmpty adds an int32 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) Int32KeyOmitEmpty(key string, v int32) {
enc.Int64KeyOmitEmpty(key, int64(v))
}
// Int32KeyNullEmpty adds an int32 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) Int32KeyNullEmpty(key string, v int32) {
enc.Int64KeyNullEmpty(key, int64(v))
}
// AddInt16 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddInt16(v int16) {
enc.Int64(int64(v))
}
// AddInt16OmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddInt16OmitEmpty(v int16) {
enc.Int64OmitEmpty(int64(v))
}
// Int16 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) Int16(v int16) {
enc.Int64(int64(v))
}
// Int16OmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Int16OmitEmpty(v int16) {
enc.Int64OmitEmpty(int64(v))
}
// Int16NullEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Int16NullEmpty(v int16) {
enc.Int64NullEmpty(int64(v))
}
// AddInt16Key adds an int16 to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddInt16Key(key string, v int16) {
enc.Int64Key(key, int64(v))
}
// AddInt16KeyOmitEmpty adds an int16 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) AddInt16KeyOmitEmpty(key string, v int16) {
enc.Int64KeyOmitEmpty(key, int64(v))
}
// AddInt16KeyNullEmpty adds an int16 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) AddInt16KeyNullEmpty(key string, v int16) {
enc.Int64KeyNullEmpty(key, int64(v))
}
// Int16Key adds an int16 to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) Int16Key(key string, v int16) {
enc.Int64Key(key, int64(v))
}
// Int16KeyOmitEmpty adds an int16 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) Int16KeyOmitEmpty(key string, v int16) {
enc.Int64KeyOmitEmpty(key, int64(v))
}
// Int16KeyNullEmpty adds an int16 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) Int16KeyNullEmpty(key string, v int16) {
enc.Int64KeyNullEmpty(key, int64(v))
}
// AddInt8 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddInt8(v int8) {
enc.Int64(int64(v))
}
// AddInt8OmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddInt8OmitEmpty(v int8) {
enc.Int64OmitEmpty(int64(v))
}
// AddInt8NullEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddInt8NullEmpty(v int8) {
enc.Int64NullEmpty(int64(v))
}
// Int8 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) Int8(v int8) {
enc.Int64(int64(v))
}
// Int8OmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Int8OmitEmpty(v int8) {
enc.Int64OmitEmpty(int64(v))
}
// Int8NullEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Int8NullEmpty(v int8) {
enc.Int64NullEmpty(int64(v))
}
// AddInt8Key adds an int8 to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddInt8Key(key string, v int8) {
enc.Int64Key(key, int64(v))
}
// AddInt8KeyOmitEmpty adds an int8 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) AddInt8KeyOmitEmpty(key string, v int8) {
enc.Int64KeyOmitEmpty(key, int64(v))
}
// AddInt8KeyNullEmpty adds an int8 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) AddInt8KeyNullEmpty(key string, v int8) {
enc.Int64KeyNullEmpty(key, int64(v))
}
// Int8Key adds an int8 to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) Int8Key(key string, v int8) {
enc.Int64Key(key, int64(v))
}
// Int8KeyOmitEmpty adds an int8 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) Int8KeyOmitEmpty(key string, v int8) {
enc.Int64KeyOmitEmpty(key, int64(v))
}
// Int8KeyNullEmpty adds an int8 to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) Int8KeyNullEmpty(key string, v int8) {
enc.Int64KeyNullEmpty(key, int64(v))
}

View File

@@ -0,0 +1,362 @@
package gojay
import "strconv"
// EncodeUint64 encodes an int64 to JSON
func (enc *Encoder) EncodeUint64(n uint64) error {
if enc.isPooled == 1 {
panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
}
_, _ = enc.encodeUint64(n)
_, err := enc.Write()
if err != nil {
return err
}
return nil
}
// encodeUint64 encodes an int to JSON
func (enc *Encoder) encodeUint64(n uint64) ([]byte, error) {
enc.buf = strconv.AppendUint(enc.buf, n, 10)
return enc.buf, nil
}
// AddUint64 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddUint64(v uint64) {
enc.Uint64(v)
}
// AddUint64OmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddUint64OmitEmpty(v uint64) {
enc.Uint64OmitEmpty(v)
}
// AddUint64NullEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddUint64NullEmpty(v uint64) {
enc.Uint64NullEmpty(v)
}
// Uint64 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) Uint64(v uint64) {
enc.grow(10)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.buf = strconv.AppendUint(enc.buf, v, 10)
}
// Uint64OmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Uint64OmitEmpty(v uint64) {
if v == 0 {
return
}
enc.grow(10)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.buf = strconv.AppendUint(enc.buf, v, 10)
}
// Uint64NullEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Uint64NullEmpty(v uint64) {
enc.grow(10)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
if v == 0 {
enc.writeBytes(nullBytes)
return
}
enc.buf = strconv.AppendUint(enc.buf, v, 10)
}
// AddUint64Key adds an int to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddUint64Key(key string, v uint64) {
enc.Uint64Key(key, v)
}
// AddUint64KeyOmitEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) AddUint64KeyOmitEmpty(key string, v uint64) {
enc.Uint64KeyOmitEmpty(key, v)
}
// AddUint64KeyNullEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) AddUint64KeyNullEmpty(key string, v uint64) {
enc.Uint64KeyNullEmpty(key, v)
}
// Uint64Key adds an int to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) Uint64Key(key string, v uint64) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
enc.grow(10 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
enc.buf = strconv.AppendUint(enc.buf, v, 10)
}
// Uint64KeyOmitEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) Uint64KeyOmitEmpty(key string, v uint64) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
if v == 0 {
return
}
enc.grow(10 + len(key))
r := enc.getPreviousRune()
if r != '{' && r != '[' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
enc.buf = strconv.AppendUint(enc.buf, v, 10)
}
// Uint64KeyNullEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) Uint64KeyNullEmpty(key string, v uint64) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
enc.grow(10 + len(key))
r := enc.getPreviousRune()
if r != '{' && r != '[' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
if v == 0 {
enc.writeBytes(nullBytes)
return
}
enc.buf = strconv.AppendUint(enc.buf, v, 10)
}
// AddUint32 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddUint32(v uint32) {
enc.Uint64(uint64(v))
}
// AddUint32OmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddUint32OmitEmpty(v uint32) {
enc.Uint64OmitEmpty(uint64(v))
}
// AddUint32NullEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddUint32NullEmpty(v uint32) {
enc.Uint64NullEmpty(uint64(v))
}
// Uint32 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) Uint32(v uint32) {
enc.Uint64(uint64(v))
}
// Uint32OmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Uint32OmitEmpty(v uint32) {
enc.Uint64OmitEmpty(uint64(v))
}
// Uint32NullEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Uint32NullEmpty(v uint32) {
enc.Uint64NullEmpty(uint64(v))
}
// AddUint32Key adds an int to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddUint32Key(key string, v uint32) {
enc.Uint64Key(key, uint64(v))
}
// AddUint32KeyOmitEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) AddUint32KeyOmitEmpty(key string, v uint32) {
enc.Uint64KeyOmitEmpty(key, uint64(v))
}
// AddUint32KeyNullEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) AddUint32KeyNullEmpty(key string, v uint32) {
enc.Uint64KeyNullEmpty(key, uint64(v))
}
// Uint32Key adds an int to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) Uint32Key(key string, v uint32) {
enc.Uint64Key(key, uint64(v))
}
// Uint32KeyOmitEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) Uint32KeyOmitEmpty(key string, v uint32) {
enc.Uint64KeyOmitEmpty(key, uint64(v))
}
// Uint32KeyNullEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) Uint32KeyNullEmpty(key string, v uint32) {
enc.Uint64KeyNullEmpty(key, uint64(v))
}
// AddUint16 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddUint16(v uint16) {
enc.Uint64(uint64(v))
}
// AddUint16OmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddUint16OmitEmpty(v uint16) {
enc.Uint64OmitEmpty(uint64(v))
}
// AddUint16NullEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddUint16NullEmpty(v uint16) {
enc.Uint64NullEmpty(uint64(v))
}
// Uint16 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) Uint16(v uint16) {
enc.Uint64(uint64(v))
}
// Uint16OmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Uint16OmitEmpty(v uint16) {
enc.Uint64OmitEmpty(uint64(v))
}
// Uint16NullEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Uint16NullEmpty(v uint16) {
enc.Uint64NullEmpty(uint64(v))
}
// AddUint16Key adds an int to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddUint16Key(key string, v uint16) {
enc.Uint64Key(key, uint64(v))
}
// AddUint16KeyOmitEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) AddUint16KeyOmitEmpty(key string, v uint16) {
enc.Uint64KeyOmitEmpty(key, uint64(v))
}
// AddUint16KeyNullEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) AddUint16KeyNullEmpty(key string, v uint16) {
enc.Uint64KeyNullEmpty(key, uint64(v))
}
// Uint16Key adds an int to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) Uint16Key(key string, v uint16) {
enc.Uint64Key(key, uint64(v))
}
// Uint16KeyOmitEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) Uint16KeyOmitEmpty(key string, v uint16) {
enc.Uint64KeyOmitEmpty(key, uint64(v))
}
// Uint16KeyNullEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) Uint16KeyNullEmpty(key string, v uint16) {
enc.Uint64KeyNullEmpty(key, uint64(v))
}
// AddUint8 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddUint8(v uint8) {
enc.Uint64(uint64(v))
}
// AddUint8OmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddUint8OmitEmpty(v uint8) {
enc.Uint64OmitEmpty(uint64(v))
}
// AddUint8NullEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) AddUint8NullEmpty(v uint8) {
enc.Uint64NullEmpty(uint64(v))
}
// Uint8 adds an int to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) Uint8(v uint8) {
enc.Uint64(uint64(v))
}
// Uint8OmitEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Uint8OmitEmpty(v uint8) {
enc.Uint64OmitEmpty(uint64(v))
}
// Uint8NullEmpty adds an int to be encoded and skips it if its value is 0,
// must be used inside a slice or array encoding (does not encode a key).
func (enc *Encoder) Uint8NullEmpty(v uint8) {
enc.Uint64NullEmpty(uint64(v))
}
// AddUint8Key adds an int to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddUint8Key(key string, v uint8) {
enc.Uint64Key(key, uint64(v))
}
// AddUint8KeyOmitEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) AddUint8KeyOmitEmpty(key string, v uint8) {
enc.Uint64KeyOmitEmpty(key, uint64(v))
}
// AddUint8KeyNullEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) AddUint8KeyNullEmpty(key string, v uint8) {
enc.Uint64KeyNullEmpty(key, uint64(v))
}
// Uint8Key adds an int to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) Uint8Key(key string, v uint8) {
enc.Uint64Key(key, uint64(v))
}
// Uint8KeyOmitEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) Uint8KeyOmitEmpty(key string, v uint8) {
enc.Uint64KeyOmitEmpty(key, uint64(v))
}
// Uint8KeyNullEmpty adds an int to be encoded and skips it if its value is 0.
// Must be used inside an object as it will encode a key.
func (enc *Encoder) Uint8KeyNullEmpty(key string, v uint8) {
enc.Uint64KeyNullEmpty(key, uint64(v))
}

400
vendor/github.com/francoispqt/gojay/encode_object.go generated vendored Normal file
View File

@@ -0,0 +1,400 @@
package gojay
var objKeyStr = []byte(`":"`)
var objKeyObj = []byte(`":{`)
var objKeyArr = []byte(`":[`)
var objKey = []byte(`":`)
// EncodeObject encodes an object to JSON
func (enc *Encoder) EncodeObject(v MarshalerJSONObject) error {
if enc.isPooled == 1 {
panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
}
_, err := enc.encodeObject(v)
if err != nil {
enc.err = err
return err
}
_, err = enc.Write()
if err != nil {
enc.err = err
return err
}
return nil
}
// EncodeObjectKeys encodes an object to JSON
func (enc *Encoder) EncodeObjectKeys(v MarshalerJSONObject, keys []string) error {
if enc.isPooled == 1 {
panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
}
enc.hasKeys = true
enc.keys = keys
_, err := enc.encodeObject(v)
if err != nil {
enc.err = err
return err
}
_, err = enc.Write()
if err != nil {
enc.err = err
return err
}
return nil
}
func (enc *Encoder) encodeObject(v MarshalerJSONObject) ([]byte, error) {
enc.grow(512)
enc.writeByte('{')
if !v.IsNil() {
v.MarshalJSONObject(enc)
}
if enc.hasKeys {
enc.hasKeys = false
enc.keys = nil
}
enc.writeByte('}')
return enc.buf, enc.err
}
// AddObject adds an object to be encoded, must be used inside a slice or array encoding (does not encode a key)
// value must implement MarshalerJSONObject
func (enc *Encoder) AddObject(v MarshalerJSONObject) {
enc.Object(v)
}
// AddObjectOmitEmpty adds an object to be encoded or skips it if IsNil returns true.
// Must be used inside a slice or array encoding (does not encode a key)
// value must implement MarshalerJSONObject
func (enc *Encoder) AddObjectOmitEmpty(v MarshalerJSONObject) {
enc.ObjectOmitEmpty(v)
}
// AddObjectNullEmpty adds an object to be encoded or skips it if IsNil returns true.
// Must be used inside a slice or array encoding (does not encode a key)
// value must implement MarshalerJSONObject
func (enc *Encoder) AddObjectNullEmpty(v MarshalerJSONObject) {
enc.ObjectNullEmpty(v)
}
// AddObjectKey adds a struct to be encoded, must be used inside an object as it will encode a key
// value must implement MarshalerJSONObject
func (enc *Encoder) AddObjectKey(key string, v MarshalerJSONObject) {
enc.ObjectKey(key, v)
}
// AddObjectKeyOmitEmpty adds an object to be encoded or skips it if IsNil returns true.
// Must be used inside a slice or array encoding (does not encode a key)
// value must implement MarshalerJSONObject
func (enc *Encoder) AddObjectKeyOmitEmpty(key string, v MarshalerJSONObject) {
enc.ObjectKeyOmitEmpty(key, v)
}
// AddObjectKeyNullEmpty adds an object to be encoded or skips it if IsNil returns true.
// Must be used inside a slice or array encoding (does not encode a key)
// value must implement MarshalerJSONObject
func (enc *Encoder) AddObjectKeyNullEmpty(key string, v MarshalerJSONObject) {
enc.ObjectKeyNullEmpty(key, v)
}
// Object adds an object to be encoded, must be used inside a slice or array encoding (does not encode a key)
// value must implement MarshalerJSONObject
func (enc *Encoder) Object(v MarshalerJSONObject) {
if v.IsNil() {
enc.grow(2)
r := enc.getPreviousRune()
if r != '{' && r != '[' {
enc.writeByte(',')
}
enc.writeByte('{')
enc.writeByte('}')
return
}
enc.grow(4)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.writeByte('{')
var origHasKeys = enc.hasKeys
var origKeys = enc.keys
enc.hasKeys = false
enc.keys = nil
v.MarshalJSONObject(enc)
enc.hasKeys = origHasKeys
enc.keys = origKeys
enc.writeByte('}')
}
// ObjectWithKeys adds an object to be encoded, must be used inside a slice or array encoding (does not encode a key)
// value must implement MarshalerJSONObject. It will only encode the keys in keys.
func (enc *Encoder) ObjectWithKeys(v MarshalerJSONObject, keys []string) {
if v.IsNil() {
enc.grow(2)
r := enc.getPreviousRune()
if r != '{' && r != '[' {
enc.writeByte(',')
}
enc.writeByte('{')
enc.writeByte('}')
return
}
enc.grow(4)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.writeByte('{')
var origKeys = enc.keys
var origHasKeys = enc.hasKeys
enc.hasKeys = true
enc.keys = keys
v.MarshalJSONObject(enc)
enc.hasKeys = origHasKeys
enc.keys = origKeys
enc.writeByte('}')
}
// ObjectOmitEmpty adds an object to be encoded or skips it if IsNil returns true.
// Must be used inside a slice or array encoding (does not encode a key)
// value must implement MarshalerJSONObject
func (enc *Encoder) ObjectOmitEmpty(v MarshalerJSONObject) {
if v.IsNil() {
return
}
enc.grow(2)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.writeByte('{')
var origHasKeys = enc.hasKeys
var origKeys = enc.keys
enc.hasKeys = false
enc.keys = nil
v.MarshalJSONObject(enc)
enc.hasKeys = origHasKeys
enc.keys = origKeys
enc.writeByte('}')
}
// ObjectNullEmpty adds an object to be encoded or skips it if IsNil returns true.
// Must be used inside a slice or array encoding (does not encode a key)
// value must implement MarshalerJSONObject
func (enc *Encoder) ObjectNullEmpty(v MarshalerJSONObject) {
enc.grow(2)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
if v.IsNil() {
enc.writeBytes(nullBytes)
return
}
enc.writeByte('{')
var origHasKeys = enc.hasKeys
var origKeys = enc.keys
enc.hasKeys = false
enc.keys = nil
v.MarshalJSONObject(enc)
enc.hasKeys = origHasKeys
enc.keys = origKeys
enc.writeByte('}')
}
// ObjectKey adds a struct to be encoded, must be used inside an object as it will encode a key
// value must implement MarshalerJSONObject
func (enc *Encoder) ObjectKey(key string, v MarshalerJSONObject) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
if v.IsNil() {
enc.grow(2 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKeyObj)
enc.writeByte('}')
return
}
enc.grow(5 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKeyObj)
var origHasKeys = enc.hasKeys
var origKeys = enc.keys
enc.hasKeys = false
enc.keys = nil
v.MarshalJSONObject(enc)
enc.hasKeys = origHasKeys
enc.keys = origKeys
enc.writeByte('}')
}
// ObjectKeyWithKeys adds a struct to be encoded, must be used inside an object as it will encode a key.
// Value must implement MarshalerJSONObject. It will only encode the keys in keys.
func (enc *Encoder) ObjectKeyWithKeys(key string, value MarshalerJSONObject, keys []string) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
if value.IsNil() {
enc.grow(2 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKeyObj)
enc.writeByte('}')
return
}
enc.grow(5 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKeyObj)
var origKeys = enc.keys
var origHasKeys = enc.hasKeys
enc.hasKeys = true
enc.keys = keys
value.MarshalJSONObject(enc)
enc.hasKeys = origHasKeys
enc.keys = origKeys
enc.writeByte('}')
}
// ObjectKeyOmitEmpty adds an object to be encoded or skips it if IsNil returns true.
// Must be used inside a slice or array encoding (does not encode a key)
// value must implement MarshalerJSONObject
func (enc *Encoder) ObjectKeyOmitEmpty(key string, v MarshalerJSONObject) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
if v.IsNil() {
return
}
enc.grow(5 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKeyObj)
var origHasKeys = enc.hasKeys
var origKeys = enc.keys
enc.hasKeys = false
enc.keys = nil
v.MarshalJSONObject(enc)
enc.hasKeys = origHasKeys
enc.keys = origKeys
enc.writeByte('}')
}
// ObjectKeyNullEmpty adds an object to be encoded or skips it if IsNil returns true.
// Must be used inside a slice or array encoding (does not encode a key)
// value must implement MarshalerJSONObject
func (enc *Encoder) ObjectKeyNullEmpty(key string, v MarshalerJSONObject) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
enc.grow(5 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.writeStringEscape(key)
enc.writeBytes(objKey)
if v.IsNil() {
enc.writeBytes(nullBytes)
return
}
enc.writeByte('{')
var origHasKeys = enc.hasKeys
var origKeys = enc.keys
enc.hasKeys = false
enc.keys = nil
v.MarshalJSONObject(enc)
enc.hasKeys = origHasKeys
enc.keys = origKeys
enc.writeByte('}')
}
// EncodeObjectFunc is a custom func type implementing MarshaleObject.
// Use it to cast a func(*Encoder) to Marshal an object.
//
// enc := gojay.NewEncoder(io.Writer)
// enc.EncodeObject(gojay.EncodeObjectFunc(func(enc *gojay.Encoder) {
// enc.AddStringKey("hello", "world")
// }))
type EncodeObjectFunc func(*Encoder)
// MarshalJSONObject implements MarshalerJSONObject.
func (f EncodeObjectFunc) MarshalJSONObject(enc *Encoder) {
f(enc)
}
// IsNil implements MarshalerJSONObject.
func (f EncodeObjectFunc) IsNil() bool {
return f == nil
}
func (enc *Encoder) keyExists(k string) bool {
if enc.keys == nil {
return false
}
for _, key := range enc.keys {
if key == k {
return true
}
}
return false
}

50
vendor/github.com/francoispqt/gojay/encode_pool.go generated vendored Normal file
View File

@@ -0,0 +1,50 @@
package gojay
import (
"io"
"sync"
)
var encPool = sync.Pool{
New: func() interface{} {
return NewEncoder(nil)
},
}
var streamEncPool = sync.Pool{
New: func() interface{} {
return Stream.NewEncoder(nil)
},
}
func init() {
for i := 0; i < 32; i++ {
encPool.Put(NewEncoder(nil))
}
for i := 0; i < 32; i++ {
streamEncPool.Put(Stream.NewEncoder(nil))
}
}
// NewEncoder returns a new encoder or borrows one from the pool
func NewEncoder(w io.Writer) *Encoder {
return &Encoder{w: w}
}
// BorrowEncoder borrows an Encoder from the pool.
func BorrowEncoder(w io.Writer) *Encoder {
enc := encPool.Get().(*Encoder)
enc.w = w
enc.buf = enc.buf[:0]
enc.isPooled = 0
enc.err = nil
enc.hasKeys = false
enc.keys = nil
return enc
}
// Release sends back a Encoder to the pool.
func (enc *Encoder) Release() {
enc.isPooled = 1
encPool.Put(enc)
}

113
vendor/github.com/francoispqt/gojay/encode_slice.go generated vendored Normal file
View File

@@ -0,0 +1,113 @@
package gojay
// AddSliceString marshals the given []string s
func (enc *Encoder) AddSliceString(s []string) {
enc.SliceString(s)
}
// SliceString marshals the given []string s
func (enc *Encoder) SliceString(s []string) {
enc.Array(EncodeArrayFunc(func(enc *Encoder) {
for _, str := range s {
enc.String(str)
}
}))
}
// AddSliceStringKey marshals the given []string s
func (enc *Encoder) AddSliceStringKey(k string, s []string) {
enc.SliceStringKey(k, s)
}
// SliceStringKey marshals the given []string s
func (enc *Encoder) SliceStringKey(k string, s []string) {
enc.ArrayKey(k, EncodeArrayFunc(func(enc *Encoder) {
for _, str := range s {
enc.String(str)
}
}))
}
// AddSliceInt marshals the given []int s
func (enc *Encoder) AddSliceInt(s []int) {
enc.SliceInt(s)
}
// SliceInt marshals the given []int s
func (enc *Encoder) SliceInt(s []int) {
enc.Array(EncodeArrayFunc(func(enc *Encoder) {
for _, i := range s {
enc.Int(i)
}
}))
}
// AddSliceIntKey marshals the given []int s
func (enc *Encoder) AddSliceIntKey(k string, s []int) {
enc.SliceIntKey(k, s)
}
// SliceIntKey marshals the given []int s
func (enc *Encoder) SliceIntKey(k string, s []int) {
enc.ArrayKey(k, EncodeArrayFunc(func(enc *Encoder) {
for _, i := range s {
enc.Int(i)
}
}))
}
// AddSliceFloat64 marshals the given []float64 s
func (enc *Encoder) AddSliceFloat64(s []float64) {
enc.SliceFloat64(s)
}
// SliceFloat64 marshals the given []float64 s
func (enc *Encoder) SliceFloat64(s []float64) {
enc.Array(EncodeArrayFunc(func(enc *Encoder) {
for _, i := range s {
enc.Float64(i)
}
}))
}
// AddSliceFloat64Key marshals the given []float64 s
func (enc *Encoder) AddSliceFloat64Key(k string, s []float64) {
enc.SliceFloat64Key(k, s)
}
// SliceFloat64Key marshals the given []float64 s
func (enc *Encoder) SliceFloat64Key(k string, s []float64) {
enc.ArrayKey(k, EncodeArrayFunc(func(enc *Encoder) {
for _, i := range s {
enc.Float64(i)
}
}))
}
// AddSliceBool marshals the given []bool s
func (enc *Encoder) AddSliceBool(s []bool) {
enc.SliceBool(s)
}
// SliceBool marshals the given []bool s
func (enc *Encoder) SliceBool(s []bool) {
enc.Array(EncodeArrayFunc(func(enc *Encoder) {
for _, i := range s {
enc.Bool(i)
}
}))
}
// AddSliceBoolKey marshals the given []bool s
func (enc *Encoder) AddSliceBoolKey(k string, s []bool) {
enc.SliceBoolKey(k, s)
}
// SliceBoolKey marshals the given []bool s
func (enc *Encoder) SliceBoolKey(k string, s []bool) {
enc.ArrayKey(k, EncodeArrayFunc(func(enc *Encoder) {
for _, i := range s {
enc.Bool(i)
}
}))
}

377
vendor/github.com/francoispqt/gojay/encode_sqlnull.go generated vendored Normal file
View File

@@ -0,0 +1,377 @@
package gojay
import "database/sql"
// EncodeSQLNullString encodes a string to
func (enc *Encoder) EncodeSQLNullString(v *sql.NullString) error {
if enc.isPooled == 1 {
panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
}
_, _ = enc.encodeString(v.String)
_, err := enc.Write()
if err != nil {
enc.err = err
return err
}
return nil
}
// AddSQLNullString adds a string to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddSQLNullString(v *sql.NullString) {
enc.String(v.String)
}
// AddSQLNullStringOmitEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddSQLNullStringOmitEmpty(v *sql.NullString) {
if v != nil && v.Valid && v.String != "" {
enc.StringOmitEmpty(v.String)
}
}
// AddSQLNullStringNullEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddSQLNullStringNullEmpty(v *sql.NullString) {
if v != nil && v.Valid {
enc.StringNullEmpty(v.String)
}
}
// AddSQLNullStringKey adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddSQLNullStringKey(key string, v *sql.NullString) {
enc.StringKey(key, v.String)
}
// AddSQLNullStringKeyOmitEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside an object as it will encode a key
func (enc *Encoder) AddSQLNullStringKeyOmitEmpty(key string, v *sql.NullString) {
if v != nil && v.Valid && v.String != "" {
enc.StringKeyOmitEmpty(key, v.String)
}
}
// SQLNullString adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullString(v *sql.NullString) {
enc.String(v.String)
}
// SQLNullStringOmitEmpty adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullStringOmitEmpty(v *sql.NullString) {
if v != nil && v.Valid && v.String != "" {
enc.String(v.String)
}
}
// SQLNullStringNullEmpty adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullStringNullEmpty(v *sql.NullString) {
if v != nil && v.Valid {
enc.StringNullEmpty(v.String)
}
}
// SQLNullStringKey adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullStringKey(key string, v *sql.NullString) {
enc.StringKey(key, v.String)
}
// SQLNullStringKeyOmitEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullStringKeyOmitEmpty(key string, v *sql.NullString) {
if v != nil && v.Valid && v.String != "" {
enc.StringKeyOmitEmpty(key, v.String)
}
}
// SQLNullStringKeyNullEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullStringKeyNullEmpty(key string, v *sql.NullString) {
if v != nil && v.Valid {
enc.StringKeyNullEmpty(key, v.String)
}
}
// NullInt64
// EncodeSQLNullInt64 encodes a string to
func (enc *Encoder) EncodeSQLNullInt64(v *sql.NullInt64) error {
if enc.isPooled == 1 {
panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
}
_, _ = enc.encodeInt64(v.Int64)
_, err := enc.Write()
if err != nil {
enc.err = err
return err
}
return nil
}
// AddSQLNullInt64 adds a string to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddSQLNullInt64(v *sql.NullInt64) {
enc.Int64(v.Int64)
}
// AddSQLNullInt64OmitEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddSQLNullInt64OmitEmpty(v *sql.NullInt64) {
if v != nil && v.Valid && v.Int64 != 0 {
enc.Int64OmitEmpty(v.Int64)
}
}
// AddSQLNullInt64NullEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddSQLNullInt64NullEmpty(v *sql.NullInt64) {
if v != nil && v.Valid {
enc.Int64NullEmpty(v.Int64)
}
}
// AddSQLNullInt64Key adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddSQLNullInt64Key(key string, v *sql.NullInt64) {
enc.Int64Key(key, v.Int64)
}
// AddSQLNullInt64KeyOmitEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside an object as it will encode a key
func (enc *Encoder) AddSQLNullInt64KeyOmitEmpty(key string, v *sql.NullInt64) {
if v != nil && v.Valid && v.Int64 != 0 {
enc.Int64KeyOmitEmpty(key, v.Int64)
}
}
// AddSQLNullInt64KeyNullEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside an object as it will encode a key
func (enc *Encoder) AddSQLNullInt64KeyNullEmpty(key string, v *sql.NullInt64) {
if v != nil && v.Valid {
enc.Int64KeyNullEmpty(key, v.Int64)
}
}
// SQLNullInt64 adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullInt64(v *sql.NullInt64) {
enc.Int64(v.Int64)
}
// SQLNullInt64OmitEmpty adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullInt64OmitEmpty(v *sql.NullInt64) {
if v != nil && v.Valid && v.Int64 != 0 {
enc.Int64(v.Int64)
}
}
// SQLNullInt64NullEmpty adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullInt64NullEmpty(v *sql.NullInt64) {
if v != nil && v.Valid {
enc.Int64NullEmpty(v.Int64)
}
}
// SQLNullInt64Key adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullInt64Key(key string, v *sql.NullInt64) {
enc.Int64Key(key, v.Int64)
}
// SQLNullInt64KeyOmitEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullInt64KeyOmitEmpty(key string, v *sql.NullInt64) {
if v != nil && v.Valid && v.Int64 != 0 {
enc.Int64KeyOmitEmpty(key, v.Int64)
}
}
// SQLNullInt64KeyNullEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullInt64KeyNullEmpty(key string, v *sql.NullInt64) {
if v != nil && v.Valid {
enc.Int64KeyNullEmpty(key, v.Int64)
}
}
// NullFloat64
// EncodeSQLNullFloat64 encodes a string to
func (enc *Encoder) EncodeSQLNullFloat64(v *sql.NullFloat64) error {
if enc.isPooled == 1 {
panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
}
_, _ = enc.encodeFloat(v.Float64)
_, err := enc.Write()
if err != nil {
enc.err = err
return err
}
return nil
}
// AddSQLNullFloat64 adds a string to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddSQLNullFloat64(v *sql.NullFloat64) {
enc.Float64(v.Float64)
}
// AddSQLNullFloat64OmitEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddSQLNullFloat64OmitEmpty(v *sql.NullFloat64) {
if v != nil && v.Valid && v.Float64 != 0 {
enc.Float64OmitEmpty(v.Float64)
}
}
// AddSQLNullFloat64NullEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddSQLNullFloat64NullEmpty(v *sql.NullFloat64) {
if v != nil && v.Valid {
enc.Float64NullEmpty(v.Float64)
}
}
// AddSQLNullFloat64Key adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddSQLNullFloat64Key(key string, v *sql.NullFloat64) {
enc.Float64Key(key, v.Float64)
}
// AddSQLNullFloat64KeyOmitEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside an object as it will encode a key
func (enc *Encoder) AddSQLNullFloat64KeyOmitEmpty(key string, v *sql.NullFloat64) {
if v != nil && v.Valid && v.Float64 != 0 {
enc.Float64KeyOmitEmpty(key, v.Float64)
}
}
// AddSQLNullFloat64KeyNullEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside an object as it will encode a key
func (enc *Encoder) AddSQLNullFloat64KeyNullEmpty(key string, v *sql.NullFloat64) {
if v != nil && v.Valid {
enc.Float64KeyNullEmpty(key, v.Float64)
}
}
// SQLNullFloat64 adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullFloat64(v *sql.NullFloat64) {
enc.Float64(v.Float64)
}
// SQLNullFloat64OmitEmpty adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullFloat64OmitEmpty(v *sql.NullFloat64) {
if v != nil && v.Valid && v.Float64 != 0 {
enc.Float64(v.Float64)
}
}
// SQLNullFloat64NullEmpty adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullFloat64NullEmpty(v *sql.NullFloat64) {
if v != nil && v.Valid {
enc.Float64NullEmpty(v.Float64)
}
}
// SQLNullFloat64Key adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullFloat64Key(key string, v *sql.NullFloat64) {
enc.Float64Key(key, v.Float64)
}
// SQLNullFloat64KeyOmitEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullFloat64KeyOmitEmpty(key string, v *sql.NullFloat64) {
if v != nil && v.Valid && v.Float64 != 0 {
enc.Float64KeyOmitEmpty(key, v.Float64)
}
}
// SQLNullFloat64KeyNullEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullFloat64KeyNullEmpty(key string, v *sql.NullFloat64) {
if v != nil && v.Valid {
enc.Float64KeyNullEmpty(key, v.Float64)
}
}
// NullBool
// EncodeSQLNullBool encodes a string to
func (enc *Encoder) EncodeSQLNullBool(v *sql.NullBool) error {
if enc.isPooled == 1 {
panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
}
_, _ = enc.encodeBool(v.Bool)
_, err := enc.Write()
if err != nil {
enc.err = err
return err
}
return nil
}
// AddSQLNullBool adds a string to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddSQLNullBool(v *sql.NullBool) {
enc.Bool(v.Bool)
}
// AddSQLNullBoolOmitEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddSQLNullBoolOmitEmpty(v *sql.NullBool) {
if v != nil && v.Valid && v.Bool != false {
enc.BoolOmitEmpty(v.Bool)
}
}
// AddSQLNullBoolKey adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddSQLNullBoolKey(key string, v *sql.NullBool) {
enc.BoolKey(key, v.Bool)
}
// AddSQLNullBoolKeyOmitEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside an object as it will encode a key
func (enc *Encoder) AddSQLNullBoolKeyOmitEmpty(key string, v *sql.NullBool) {
if v != nil && v.Valid && v.Bool != false {
enc.BoolKeyOmitEmpty(key, v.Bool)
}
}
// AddSQLNullBoolKeyNullEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside an object as it will encode a key
func (enc *Encoder) AddSQLNullBoolKeyNullEmpty(key string, v *sql.NullBool) {
if v != nil && v.Valid {
enc.BoolKeyNullEmpty(key, v.Bool)
}
}
// SQLNullBool adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullBool(v *sql.NullBool) {
enc.Bool(v.Bool)
}
// SQLNullBoolOmitEmpty adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullBoolOmitEmpty(v *sql.NullBool) {
if v != nil && v.Valid && v.Bool != false {
enc.Bool(v.Bool)
}
}
// SQLNullBoolNullEmpty adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullBoolNullEmpty(v *sql.NullBool) {
if v != nil && v.Valid {
enc.BoolNullEmpty(v.Bool)
}
}
// SQLNullBoolKey adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullBoolKey(key string, v *sql.NullBool) {
enc.BoolKey(key, v.Bool)
}
// SQLNullBoolKeyOmitEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullBoolKeyOmitEmpty(key string, v *sql.NullBool) {
if v != nil && v.Valid && v.Bool != false {
enc.BoolKeyOmitEmpty(key, v.Bool)
}
}
// SQLNullBoolKeyNullEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside an object as it will encode a key
func (enc *Encoder) SQLNullBoolKeyNullEmpty(key string, v *sql.NullBool) {
if v != nil && v.Valid {
enc.BoolKeyNullEmpty(key, v.Bool)
}
}

205
vendor/github.com/francoispqt/gojay/encode_stream.go generated vendored Normal file
View File

@@ -0,0 +1,205 @@
package gojay
import (
"strconv"
"sync"
"time"
)
// MarshalerStream is the interface to implement
// to continuously encode of stream of data.
type MarshalerStream interface {
MarshalStream(enc *StreamEncoder)
}
// A StreamEncoder reads and encodes values to JSON from an input stream.
//
// It implements conext.Context and provide a channel to notify interruption.
type StreamEncoder struct {
mux *sync.RWMutex
*Encoder
nConsumer int
delimiter byte
deadline *time.Time
done chan struct{}
}
// EncodeStream spins up a defined number of non blocking consumers of the MarshalerStream m.
//
// m must implement MarshalerStream. Ideally m is a channel. See example for implementation.
//
// See the documentation for Marshal for details about the conversion of Go value to JSON.
func (s *StreamEncoder) EncodeStream(m MarshalerStream) {
// if a single consumer, just use this encoder
if s.nConsumer == 1 {
go consume(s, s, m)
return
}
// else use this Encoder only for first consumer
// and use new encoders for other consumers
// this is to avoid concurrent writing to same buffer
// resulting in a weird JSON
go consume(s, s, m)
for i := 1; i < s.nConsumer; i++ {
s.mux.RLock()
select {
case <-s.done:
default:
ss := Stream.borrowEncoder(s.w)
ss.mux.Lock()
ss.done = s.done
ss.buf = make([]byte, 0, 512)
ss.delimiter = s.delimiter
go consume(s, ss, m)
ss.mux.Unlock()
}
s.mux.RUnlock()
}
return
}
// LineDelimited sets the delimiter to a new line character.
//
// It will add a new line after each JSON marshaled by the MarshalerStream
func (s *StreamEncoder) LineDelimited() *StreamEncoder {
s.delimiter = '\n'
return s
}
// CommaDelimited sets the delimiter to a comma.
//
// It will add a new line after each JSON marshaled by the MarshalerStream
func (s *StreamEncoder) CommaDelimited() *StreamEncoder {
s.delimiter = ','
return s
}
// NConsumer sets the number of non blocking go routine to consume the stream.
func (s *StreamEncoder) NConsumer(n int) *StreamEncoder {
s.nConsumer = n
return s
}
// Release sends back a Decoder to the pool.
// If a decoder is used after calling Release
// a panic will be raised with an InvalidUsagePooledDecoderError error.
func (s *StreamEncoder) Release() {
s.isPooled = 1
streamEncPool.Put(s)
}
// Done returns a channel that's closed when work is done.
// It implements context.Context
func (s *StreamEncoder) Done() <-chan struct{} {
return s.done
}
// Err returns nil if Done is not yet closed.
// If Done is closed, Err returns a non-nil error explaining why.
// It implements context.Context
func (s *StreamEncoder) Err() error {
return s.err
}
// Deadline returns the time when work done on behalf of this context
// should be canceled. Deadline returns ok==false when no deadline is
// set. Successive calls to Deadline return the same results.
func (s *StreamEncoder) Deadline() (time.Time, bool) {
if s.deadline != nil {
return *s.deadline, true
}
return time.Time{}, false
}
// SetDeadline sets the deadline
func (s *StreamEncoder) SetDeadline(t time.Time) {
s.deadline = &t
}
// Value implements context.Context
func (s *StreamEncoder) Value(key interface{}) interface{} {
return nil
}
// Cancel cancels the consumers of the stream, interrupting the stream encoding.
//
// After calling cancel, Done() will return a closed channel.
func (s *StreamEncoder) Cancel(err error) {
s.mux.Lock()
defer s.mux.Unlock()
select {
case <-s.done:
default:
s.err = err
close(s.done)
}
}
// AddObject adds an object to be encoded.
// value must implement MarshalerJSONObject.
func (s *StreamEncoder) AddObject(v MarshalerJSONObject) {
if v.IsNil() {
return
}
s.Encoder.writeByte('{')
v.MarshalJSONObject(s.Encoder)
s.Encoder.writeByte('}')
s.Encoder.writeByte(s.delimiter)
}
// AddString adds a string to be encoded.
func (s *StreamEncoder) AddString(v string) {
s.Encoder.writeByte('"')
s.Encoder.writeString(v)
s.Encoder.writeByte('"')
s.Encoder.writeByte(s.delimiter)
}
// AddArray adds an implementation of MarshalerJSONArray to be encoded.
func (s *StreamEncoder) AddArray(v MarshalerJSONArray) {
s.Encoder.writeByte('[')
v.MarshalJSONArray(s.Encoder)
s.Encoder.writeByte(']')
s.Encoder.writeByte(s.delimiter)
}
// AddInt adds an int to be encoded.
func (s *StreamEncoder) AddInt(value int) {
s.buf = strconv.AppendInt(s.buf, int64(value), 10)
s.Encoder.writeByte(s.delimiter)
}
// AddFloat64 adds a float64 to be encoded.
func (s *StreamEncoder) AddFloat64(value float64) {
s.buf = strconv.AppendFloat(s.buf, value, 'f', -1, 64)
s.Encoder.writeByte(s.delimiter)
}
// AddFloat adds a float64 to be encoded.
func (s *StreamEncoder) AddFloat(value float64) {
s.AddFloat64(value)
}
// Non exposed
func consume(init *StreamEncoder, s *StreamEncoder, m MarshalerStream) {
defer s.Release()
for {
select {
case <-init.Done():
return
default:
m.MarshalStream(s)
if s.Encoder.err != nil {
init.Cancel(s.Encoder.err)
return
}
i, err := s.Encoder.Write()
if err != nil || i == 0 {
init.Cancel(err)
return
}
}
}
}

View File

@@ -0,0 +1,38 @@
package gojay
import (
"io"
"sync"
)
// NewEncoder returns a new StreamEncoder.
// It takes an io.Writer implementation to output data.
// It initiates the done channel returned by Done().
func (s stream) NewEncoder(w io.Writer) *StreamEncoder {
enc := BorrowEncoder(w)
return &StreamEncoder{Encoder: enc, nConsumer: 1, done: make(chan struct{}, 1), mux: &sync.RWMutex{}}
}
// BorrowEncoder borrows a StreamEncoder from the pool.
// It takes an io.Writer implementation to output data.
// It initiates the done channel returned by Done().
//
// If no StreamEncoder is available in the pool, it returns a fresh one
func (s stream) BorrowEncoder(w io.Writer) *StreamEncoder {
streamEnc := streamEncPool.Get().(*StreamEncoder)
streamEnc.w = w
streamEnc.Encoder.err = nil
streamEnc.done = make(chan struct{}, 1)
streamEnc.Encoder.buf = streamEnc.buf[:0]
streamEnc.nConsumer = 1
streamEnc.isPooled = 0
return streamEnc
}
func (s stream) borrowEncoder(w io.Writer) *StreamEncoder {
streamEnc := streamEncPool.Get().(*StreamEncoder)
streamEnc.isPooled = 0
streamEnc.w = w
streamEnc.Encoder.err = nil
return streamEnc
}

186
vendor/github.com/francoispqt/gojay/encode_string.go generated vendored Normal file
View File

@@ -0,0 +1,186 @@
package gojay
// EncodeString encodes a string to
func (enc *Encoder) EncodeString(s string) error {
if enc.isPooled == 1 {
panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
}
_, _ = enc.encodeString(s)
_, err := enc.Write()
if err != nil {
enc.err = err
return err
}
return nil
}
// encodeString encodes a string to
func (enc *Encoder) encodeString(v string) ([]byte, error) {
enc.writeByte('"')
enc.writeStringEscape(v)
enc.writeByte('"')
return enc.buf, nil
}
// AppendString appends a string to the buffer
func (enc *Encoder) AppendString(v string) {
enc.grow(len(v) + 2)
enc.writeByte('"')
enc.writeStringEscape(v)
enc.writeByte('"')
}
// AddString adds a string to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddString(v string) {
enc.String(v)
}
// AddStringOmitEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddStringOmitEmpty(v string) {
enc.StringOmitEmpty(v)
}
// AddStringNullEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddStringNullEmpty(v string) {
enc.StringNullEmpty(v)
}
// AddStringKey adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) AddStringKey(key, v string) {
enc.StringKey(key, v)
}
// AddStringKeyOmitEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside an object as it will encode a key
func (enc *Encoder) AddStringKeyOmitEmpty(key, v string) {
enc.StringKeyOmitEmpty(key, v)
}
// AddStringKeyNullEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside an object as it will encode a key
func (enc *Encoder) AddStringKeyNullEmpty(key, v string) {
enc.StringKeyNullEmpty(key, v)
}
// String adds a string to be encoded, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) String(v string) {
enc.grow(len(v) + 4)
r := enc.getPreviousRune()
if r != '[' {
enc.writeTwoBytes(',', '"')
} else {
enc.writeByte('"')
}
enc.writeStringEscape(v)
enc.writeByte('"')
}
// StringOmitEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) StringOmitEmpty(v string) {
if v == "" {
return
}
r := enc.getPreviousRune()
if r != '[' {
enc.writeTwoBytes(',', '"')
} else {
enc.writeByte('"')
}
enc.writeStringEscape(v)
enc.writeByte('"')
}
// StringNullEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) StringNullEmpty(v string) {
r := enc.getPreviousRune()
if v == "" {
if r != '[' {
enc.writeByte(',')
enc.writeBytes(nullBytes)
} else {
enc.writeBytes(nullBytes)
}
return
}
if r != '[' {
enc.writeTwoBytes(',', '"')
} else {
enc.writeByte('"')
}
enc.writeStringEscape(v)
enc.writeByte('"')
}
// StringKey adds a string to be encoded, must be used inside an object as it will encode a key
func (enc *Encoder) StringKey(key, v string) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
enc.grow(len(key) + len(v) + 5)
r := enc.getPreviousRune()
if r != '{' {
enc.writeTwoBytes(',', '"')
} else {
enc.writeByte('"')
}
enc.writeStringEscape(key)
enc.writeBytes(objKeyStr)
enc.writeStringEscape(v)
enc.writeByte('"')
}
// StringKeyOmitEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside an object as it will encode a key
func (enc *Encoder) StringKeyOmitEmpty(key, v string) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
if v == "" {
return
}
enc.grow(len(key) + len(v) + 5)
r := enc.getPreviousRune()
if r != '{' {
enc.writeTwoBytes(',', '"')
} else {
enc.writeByte('"')
}
enc.writeStringEscape(key)
enc.writeBytes(objKeyStr)
enc.writeStringEscape(v)
enc.writeByte('"')
}
// StringKeyNullEmpty adds a string to be encoded or skips it if it is zero value.
// Must be used inside an object as it will encode a key
func (enc *Encoder) StringKeyNullEmpty(key, v string) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
enc.grow(len(key) + len(v) + 5)
r := enc.getPreviousRune()
if r != '{' {
enc.writeTwoBytes(',', '"')
} else {
enc.writeByte('"')
}
enc.writeStringEscape(key)
enc.writeBytes(objKey)
if v == "" {
enc.writeBytes(nullBytes)
return
}
enc.writeByte('"')
enc.writeStringEscape(v)
enc.writeByte('"')
}

68
vendor/github.com/francoispqt/gojay/encode_time.go generated vendored Normal file
View File

@@ -0,0 +1,68 @@
package gojay
import (
"time"
)
// EncodeTime encodes a *time.Time to JSON with the given format
func (enc *Encoder) EncodeTime(t *time.Time, format string) error {
if enc.isPooled == 1 {
panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
}
_, _ = enc.encodeTime(t, format)
_, err := enc.Write()
if err != nil {
return err
}
return nil
}
// encodeInt encodes an int to JSON
func (enc *Encoder) encodeTime(t *time.Time, format string) ([]byte, error) {
enc.writeByte('"')
enc.buf = t.AppendFormat(enc.buf, format)
enc.writeByte('"')
return enc.buf, nil
}
// AddTimeKey adds an *time.Time to be encoded with the given format, must be used inside an object as it will encode a key
func (enc *Encoder) AddTimeKey(key string, t *time.Time, format string) {
enc.TimeKey(key, t, format)
}
// TimeKey adds an *time.Time to be encoded with the given format, must be used inside an object as it will encode a key
func (enc *Encoder) TimeKey(key string, t *time.Time, format string) {
if enc.hasKeys {
if !enc.keyExists(key) {
return
}
}
enc.grow(10 + len(key))
r := enc.getPreviousRune()
if r != '{' {
enc.writeTwoBytes(',', '"')
} else {
enc.writeByte('"')
}
enc.writeStringEscape(key)
enc.writeBytes(objKeyStr)
enc.buf = t.AppendFormat(enc.buf, format)
enc.writeByte('"')
}
// AddTime adds an *time.Time to be encoded with the given format, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) AddTime(t *time.Time, format string) {
enc.Time(t, format)
}
// Time adds an *time.Time to be encoded with the given format, must be used inside a slice or array encoding (does not encode a key)
func (enc *Encoder) Time(t *time.Time, format string) {
enc.grow(10)
r := enc.getPreviousRune()
if r != '[' {
enc.writeByte(',')
}
enc.writeByte('"')
enc.buf = t.AppendFormat(enc.buf, format)
enc.writeByte('"')
}

88
vendor/github.com/francoispqt/gojay/errors.go generated vendored Normal file
View File

@@ -0,0 +1,88 @@
package gojay
import (
"errors"
"fmt"
)
const invalidJSONCharErrorMsg = "Invalid JSON, wrong char '%c' found at position %d"
// InvalidJSONError is a type representing an error returned when
// Decoding encounters invalid JSON.
type InvalidJSONError string
func (err InvalidJSONError) Error() string {
return string(err)
}
func (dec *Decoder) raiseInvalidJSONErr(pos int) error {
var c byte
if len(dec.data) > pos {
c = dec.data[pos]
}
dec.err = InvalidJSONError(
fmt.Sprintf(
invalidJSONCharErrorMsg,
c,
pos,
),
)
return dec.err
}
const invalidUnmarshalErrorMsg = "Cannot unmarshal JSON to type '%T'"
// InvalidUnmarshalError is a type representing an error returned when
// Decoding cannot unmarshal JSON to the receiver type for various reasons.
type InvalidUnmarshalError string
func (err InvalidUnmarshalError) Error() string {
return string(err)
}
func (dec *Decoder) makeInvalidUnmarshalErr(v interface{}) error {
return InvalidUnmarshalError(
fmt.Sprintf(
invalidUnmarshalErrorMsg,
v,
),
)
}
const invalidMarshalErrorMsg = "Invalid type %T provided to Marshal"
// InvalidMarshalError is a type representing an error returned when
// Encoding did not find the proper way to encode
type InvalidMarshalError string
func (err InvalidMarshalError) Error() string {
return string(err)
}
// NoReaderError is a type representing an error returned when
// decoding requires a reader and none was given
type NoReaderError string
func (err NoReaderError) Error() string {
return string(err)
}
// InvalidUsagePooledDecoderError is a type representing an error returned
// when decoding is called on a still pooled Decoder
type InvalidUsagePooledDecoderError string
func (err InvalidUsagePooledDecoderError) Error() string {
return string(err)
}
// InvalidUsagePooledEncoderError is a type representing an error returned
// when decoding is called on a still pooled Encoder
type InvalidUsagePooledEncoderError string
func (err InvalidUsagePooledEncoderError) Error() string {
return string(err)
}
// ErrUnmarshalPtrExpected is the error returned when unmarshal expects a pointer value,
// When using `dec.ObjectNull` or `dec.ArrayNull` for example.
var ErrUnmarshalPtrExpected = errors.New("Cannot unmarshal to given value, a pointer is expected")

24
vendor/github.com/francoispqt/gojay/go.mod generated vendored Normal file
View File

@@ -0,0 +1,24 @@
module github.com/francoispqt/gojay
go 1.12
require (
cloud.google.com/go v0.37.0 // indirect
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23
github.com/go-errors/errors v1.0.1
github.com/golang/protobuf v1.3.1 // indirect
github.com/json-iterator/go v1.1.6
github.com/lunixbochs/vtclean v1.0.0 // indirect
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/pkg/errors v0.8.1 // indirect
github.com/stretchr/testify v1.2.2
github.com/viant/assertly v0.4.8
github.com/viant/toolbox v0.24.0
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a // indirect
golang.org/x/net v0.0.0-20190313220215-9f648a60d977
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 // indirect
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f // indirect
gopkg.in/yaml.v2 v2.2.2 // indirect
)

182
vendor/github.com/francoispqt/gojay/go.sum generated vendored Normal file
View File

@@ -0,0 +1,182 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.37.0 h1:69FNAINiZfsEuwH3fKq8QrAAnHz+2m4XL4kVYi5BX0Q=
cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo=
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 h1:D21IyuvjDCshj1/qq+pCNd3VZOAEI9jy6Bi131YlXgI=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lunixbochs/vtclean v1.0.0 h1:xu2sLAri4lGiovBDQKxl5mrXyESr3gUr5m5SM5+LVb8=
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe h1:W/GaMY0y69G4cFlmsC6B9sbuo2fP8OFP1ABjt4kPz+w=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw=
github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI=
github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU=
github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag=
github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg=
github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw=
github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y=
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q=
github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ=
github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I=
github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0=
github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ=
github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk=
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
github.com/viant/assertly v0.4.8 h1:5x1GzBaRteIwTr5RAGFVG14uNeRFxVNbXPWrK2qAgpc=
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
github.com/viant/toolbox v0.24.0 h1:6TteTDQ68CjgcCe8wH3D3ZhUQQOJXMTbj/D9rkk2a1k=
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a h1:YX8ljsm6wXlHZO+aRz9Exqr0evNhKRNe5K/gi+zKh4U=
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190313220215-9f648a60d977 h1:actzWV6iWn3GLqN8dZjzsB+CLt+gaV2+wsxroxiQI8I=
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f h1:yCrMx/EeIue0+Qca57bWZS7VX6ymEoypmhWyPhz0NHM=
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=

10
vendor/github.com/francoispqt/gojay/gojay.go generated vendored Normal file
View File

@@ -0,0 +1,10 @@
// Package gojay implements encoding and decoding of JSON as defined in RFC 7159.
// The mapping between JSON and Go values is described
// in the documentation for the Marshal and Unmarshal functions.
//
// It aims at performance and usability by relying on simple interfaces
// to decode and encode structures, slices, arrays and even channels.
//
// On top of the simple interfaces to implement, gojay provides lots of helpers to decode and encode
// multiple of different types natively such as bit.Int, sql.NullString or time.Time
package gojay

BIN
vendor/github.com/francoispqt/gojay/gojay.png generated vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

38
vendor/github.com/go-asn1-ber/asn1-ber/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,38 @@
language: go
matrix:
include:
- go: 1.2.x
env: GOOS=linux GOARCH=amd64
- go: 1.2.x
env: GOOS=linux GOARCH=386
- go: 1.2.x
env: GOOS=windows GOARCH=amd64
- go: 1.2.x
env: GOOS=windows GOARCH=386
- go: 1.3.x
- go: 1.4.x
- go: 1.5.x
- go: 1.6.x
- go: 1.7.x
- go: 1.8.x
- go: 1.9.x
- go: 1.10.x
- go: 1.11.x
- go: 1.12.x
- go: 1.13.x
env: GOOS=linux GOARCH=amd64
- go: 1.13.x
env: GOOS=linux GOARCH=386
- go: 1.13.x
env: GOOS=windows GOARCH=amd64
- go: 1.13.x
env: GOOS=windows GOARCH=386
- go: tip
go_import_path: gopkg.in/asn-ber.v1
install:
- go list -f '{{range .Imports}}{{.}} {{end}}' ./... | xargs go get -v
- go list -f '{{range .TestImports}}{{.}} {{end}}' ./... | xargs go get -v
- go get code.google.com/p/go.tools/cmd/cover || go get golang.org/x/tools/cmd/cover
- go build -v ./...
script:
- go test -v -cover ./... || go test -v ./...

22
vendor/github.com/go-asn1-ber/asn1-ber/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2011-2015 Michael Mitton (mmitton@gmail.com)
Portions copyright (c) 2015-2016 go-asn1-ber Authors
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.

24
vendor/github.com/go-asn1-ber/asn1-ber/README.md generated vendored Normal file
View File

@@ -0,0 +1,24 @@
[![GoDoc](https://godoc.org/gopkg.in/asn1-ber.v1?status.svg)](https://godoc.org/gopkg.in/asn1-ber.v1) [![Build Status](https://travis-ci.org/go-asn1-ber/asn1-ber.svg)](https://travis-ci.org/go-asn1-ber/asn1-ber)
ASN1 BER Encoding / Decoding Library for the GO programming language.
---------------------------------------------------------------------
Required libraries:
None
Working:
Very basic encoding / decoding needed for LDAP protocol
Tests Implemented:
A few
TODO:
Fix all encoding / decoding to conform to ASN1 BER spec
Implement Tests / Benchmarks
---
The Go gopher was designed by Renee French. (http://reneefrench.blogspot.com/)
The design is licensed under the Creative Commons 3.0 Attributions license.
Read this article for more details: http://blog.golang.org/gopher

532
vendor/github.com/go-asn1-ber/asn1-ber/ber.go generated vendored Normal file
View File

@@ -0,0 +1,532 @@
package ber
import (
"bytes"
"errors"
"fmt"
"io"
"math"
"os"
"reflect"
)
// MaxPacketLengthBytes specifies the maximum allowed packet size when calling ReadPacket or DecodePacket. Set to 0 for
// no limit.
var MaxPacketLengthBytes int64 = math.MaxInt32
type Packet struct {
Identifier
Value interface{}
ByteValue []byte
Data *bytes.Buffer
Children []*Packet
Description string
}
type Identifier struct {
ClassType Class
TagType Type
Tag Tag
}
type Tag uint64
const (
TagEOC Tag = 0x00
TagBoolean Tag = 0x01
TagInteger Tag = 0x02
TagBitString Tag = 0x03
TagOctetString Tag = 0x04
TagNULL Tag = 0x05
TagObjectIdentifier Tag = 0x06
TagObjectDescriptor Tag = 0x07
TagExternal Tag = 0x08
TagRealFloat Tag = 0x09
TagEnumerated Tag = 0x0a
TagEmbeddedPDV Tag = 0x0b
TagUTF8String Tag = 0x0c
TagRelativeOID Tag = 0x0d
TagSequence Tag = 0x10
TagSet Tag = 0x11
TagNumericString Tag = 0x12
TagPrintableString Tag = 0x13
TagT61String Tag = 0x14
TagVideotexString Tag = 0x15
TagIA5String Tag = 0x16
TagUTCTime Tag = 0x17
TagGeneralizedTime Tag = 0x18
TagGraphicString Tag = 0x19
TagVisibleString Tag = 0x1a
TagGeneralString Tag = 0x1b
TagUniversalString Tag = 0x1c
TagCharacterString Tag = 0x1d
TagBMPString Tag = 0x1e
TagBitmask Tag = 0x1f // xxx11111b
// HighTag indicates the start of a high-tag byte sequence
HighTag Tag = 0x1f // xxx11111b
// HighTagContinueBitmask indicates the high-tag byte sequence should continue
HighTagContinueBitmask Tag = 0x80 // 10000000b
// HighTagValueBitmask obtains the tag value from a high-tag byte sequence byte
HighTagValueBitmask Tag = 0x7f // 01111111b
)
const (
// LengthLongFormBitmask is the mask to apply to the length byte to see if a long-form byte sequence is used
LengthLongFormBitmask = 0x80
// LengthValueBitmask is the mask to apply to the length byte to get the number of bytes in the long-form byte sequence
LengthValueBitmask = 0x7f
// LengthIndefinite is returned from readLength to indicate an indefinite length
LengthIndefinite = -1
)
var tagMap = map[Tag]string{
TagEOC: "EOC (End-of-Content)",
TagBoolean: "Boolean",
TagInteger: "Integer",
TagBitString: "Bit String",
TagOctetString: "Octet String",
TagNULL: "NULL",
TagObjectIdentifier: "Object Identifier",
TagObjectDescriptor: "Object Descriptor",
TagExternal: "External",
TagRealFloat: "Real (float)",
TagEnumerated: "Enumerated",
TagEmbeddedPDV: "Embedded PDV",
TagUTF8String: "UTF8 String",
TagRelativeOID: "Relative-OID",
TagSequence: "Sequence and Sequence of",
TagSet: "Set and Set OF",
TagNumericString: "Numeric String",
TagPrintableString: "Printable String",
TagT61String: "T61 String",
TagVideotexString: "Videotex String",
TagIA5String: "IA5 String",
TagUTCTime: "UTC Time",
TagGeneralizedTime: "Generalized Time",
TagGraphicString: "Graphic String",
TagVisibleString: "Visible String",
TagGeneralString: "General String",
TagUniversalString: "Universal String",
TagCharacterString: "Character String",
TagBMPString: "BMP String",
}
type Class uint8
const (
ClassUniversal Class = 0 // 00xxxxxxb
ClassApplication Class = 64 // 01xxxxxxb
ClassContext Class = 128 // 10xxxxxxb
ClassPrivate Class = 192 // 11xxxxxxb
ClassBitmask Class = 192 // 11xxxxxxb
)
var ClassMap = map[Class]string{
ClassUniversal: "Universal",
ClassApplication: "Application",
ClassContext: "Context",
ClassPrivate: "Private",
}
type Type uint8
const (
TypePrimitive Type = 0 // xx0xxxxxb
TypeConstructed Type = 32 // xx1xxxxxb
TypeBitmask Type = 32 // xx1xxxxxb
)
var TypeMap = map[Type]string{
TypePrimitive: "Primitive",
TypeConstructed: "Constructed",
}
var Debug bool = false
func PrintBytes(out io.Writer, buf []byte, indent string) {
data_lines := make([]string, (len(buf)/30)+1)
num_lines := make([]string, (len(buf)/30)+1)
for i, b := range buf {
data_lines[i/30] += fmt.Sprintf("%02x ", b)
num_lines[i/30] += fmt.Sprintf("%02d ", (i+1)%100)
}
for i := 0; i < len(data_lines); i++ {
out.Write([]byte(indent + data_lines[i] + "\n"))
out.Write([]byte(indent + num_lines[i] + "\n\n"))
}
}
func WritePacket(out io.Writer, p *Packet) {
printPacket(out, p, 0, false)
}
func PrintPacket(p *Packet) {
printPacket(os.Stdout, p, 0, false)
}
func printPacket(out io.Writer, p *Packet, indent int, printBytes bool) {
indent_str := ""
for len(indent_str) != indent {
indent_str += " "
}
class_str := ClassMap[p.ClassType]
tagtype_str := TypeMap[p.TagType]
tag_str := fmt.Sprintf("0x%02X", p.Tag)
if p.ClassType == ClassUniversal {
tag_str = tagMap[p.Tag]
}
value := fmt.Sprint(p.Value)
description := ""
if p.Description != "" {
description = p.Description + ": "
}
fmt.Fprintf(out, "%s%s(%s, %s, %s) Len=%d %q\n", indent_str, description, class_str, tagtype_str, tag_str, p.Data.Len(), value)
if printBytes {
PrintBytes(out, p.Bytes(), indent_str)
}
for _, child := range p.Children {
printPacket(out, child, indent+1, printBytes)
}
}
// ReadPacket reads a single Packet from the reader
func ReadPacket(reader io.Reader) (*Packet, error) {
p, _, err := readPacket(reader)
if err != nil {
return nil, err
}
return p, nil
}
func DecodeString(data []byte) string {
return string(data)
}
func ParseInt64(bytes []byte) (ret int64, err error) {
if len(bytes) > 8 {
// We'll overflow an int64 in this case.
err = fmt.Errorf("integer too large")
return
}
for bytesRead := 0; bytesRead < len(bytes); bytesRead++ {
ret <<= 8
ret |= int64(bytes[bytesRead])
}
// Shift up and down in order to sign extend the result.
ret <<= 64 - uint8(len(bytes))*8
ret >>= 64 - uint8(len(bytes))*8
return
}
func encodeInteger(i int64) []byte {
n := int64Length(i)
out := make([]byte, n)
var j int
for ; n > 0; n-- {
out[j] = (byte(i >> uint((n-1)*8)))
j++
}
return out
}
func int64Length(i int64) (numBytes int) {
numBytes = 1
for i > 127 {
numBytes++
i >>= 8
}
for i < -128 {
numBytes++
i >>= 8
}
return
}
// DecodePacket decodes the given bytes into a single Packet
// If a decode error is encountered, nil is returned.
func DecodePacket(data []byte) *Packet {
p, _, _ := readPacket(bytes.NewBuffer(data))
return p
}
// DecodePacketErr decodes the given bytes into a single Packet
// If a decode error is encountered, nil is returned
func DecodePacketErr(data []byte) (*Packet, error) {
p, _, err := readPacket(bytes.NewBuffer(data))
if err != nil {
return nil, err
}
return p, nil
}
// readPacket reads a single Packet from the reader, returning the number of bytes read
func readPacket(reader io.Reader) (*Packet, int, error) {
identifier, length, read, err := readHeader(reader)
if err != nil {
return nil, read, err
}
p := &Packet{
Identifier: identifier,
}
p.Data = new(bytes.Buffer)
p.Children = make([]*Packet, 0, 2)
p.Value = nil
if p.TagType == TypeConstructed {
// TODO: if universal, ensure tag type is allowed to be constructed
// Track how much content we've read
contentRead := 0
for {
if length != LengthIndefinite {
// End if we've read what we've been told to
if contentRead == length {
break
}
// Detect if a packet boundary didn't fall on the expected length
if contentRead > length {
return nil, read, fmt.Errorf("expected to read %d bytes, read %d", length, contentRead)
}
}
// Read the next packet
child, r, err := readPacket(reader)
if err != nil {
return nil, read, err
}
contentRead += r
read += r
// Test is this is the EOC marker for our packet
if isEOCPacket(child) {
if length == LengthIndefinite {
break
}
return nil, read, errors.New("eoc child not allowed with definite length")
}
// Append and continue
p.AppendChild(child)
}
return p, read, nil
}
if length == LengthIndefinite {
return nil, read, errors.New("indefinite length used with primitive type")
}
// Read definite-length content
if MaxPacketLengthBytes > 0 && int64(length) > MaxPacketLengthBytes {
return nil, read, fmt.Errorf("length %d greater than maximum %d", length, MaxPacketLengthBytes)
}
content := make([]byte, length, length)
if length > 0 {
_, err := io.ReadFull(reader, content)
if err != nil {
if err == io.EOF {
return nil, read, io.ErrUnexpectedEOF
}
return nil, read, err
}
read += length
}
if p.ClassType == ClassUniversal {
p.Data.Write(content)
p.ByteValue = content
switch p.Tag {
case TagEOC:
case TagBoolean:
val, _ := ParseInt64(content)
p.Value = val != 0
case TagInteger:
p.Value, _ = ParseInt64(content)
case TagBitString:
case TagOctetString:
// the actual string encoding is not known here
// (e.g. for LDAP content is already an UTF8-encoded
// string). Return the data without further processing
p.Value = DecodeString(content)
case TagNULL:
case TagObjectIdentifier:
case TagObjectDescriptor:
case TagExternal:
case TagRealFloat:
case TagEnumerated:
p.Value, _ = ParseInt64(content)
case TagEmbeddedPDV:
case TagUTF8String:
p.Value = DecodeString(content)
case TagRelativeOID:
case TagSequence:
case TagSet:
case TagNumericString:
case TagPrintableString:
p.Value = DecodeString(content)
case TagT61String:
case TagVideotexString:
case TagIA5String:
case TagUTCTime:
case TagGeneralizedTime:
case TagGraphicString:
case TagVisibleString:
case TagGeneralString:
case TagUniversalString:
case TagCharacterString:
case TagBMPString:
}
} else {
p.Data.Write(content)
}
return p, read, nil
}
func (p *Packet) Bytes() []byte {
var out bytes.Buffer
out.Write(encodeIdentifier(p.Identifier))
out.Write(encodeLength(p.Data.Len()))
out.Write(p.Data.Bytes())
return out.Bytes()
}
func (p *Packet) AppendChild(child *Packet) {
p.Data.Write(child.Bytes())
p.Children = append(p.Children, child)
}
func Encode(ClassType Class, TagType Type, Tag Tag, Value interface{}, Description string) *Packet {
p := new(Packet)
p.ClassType = ClassType
p.TagType = TagType
p.Tag = Tag
p.Data = new(bytes.Buffer)
p.Children = make([]*Packet, 0, 2)
p.Value = Value
p.Description = Description
if Value != nil {
v := reflect.ValueOf(Value)
if ClassType == ClassUniversal {
switch Tag {
case TagOctetString:
sv, ok := v.Interface().(string)
if ok {
p.Data.Write([]byte(sv))
}
}
}
}
return p
}
func NewSequence(Description string) *Packet {
return Encode(ClassUniversal, TypeConstructed, TagSequence, nil, Description)
}
func NewBoolean(ClassType Class, TagType Type, Tag Tag, Value bool, Description string) *Packet {
intValue := int64(0)
if Value {
intValue = 1
}
p := Encode(ClassType, TagType, Tag, nil, Description)
p.Value = Value
p.Data.Write(encodeInteger(intValue))
return p
}
// NewLDAPBoolean returns a RFC 4511-compliant Boolean packet
func NewLDAPBoolean(Value bool, Description string) *Packet {
intValue := int64(0)
if Value {
intValue = 255
}
p := Encode(ClassUniversal, TypePrimitive, TagBoolean, nil, Description)
p.Value = Value
p.Data.Write(encodeInteger(intValue))
return p
}
func NewInteger(ClassType Class, TagType Type, Tag Tag, Value interface{}, Description string) *Packet {
p := Encode(ClassType, TagType, Tag, nil, Description)
p.Value = Value
switch v := Value.(type) {
case int:
p.Data.Write(encodeInteger(int64(v)))
case uint:
p.Data.Write(encodeInteger(int64(v)))
case int64:
p.Data.Write(encodeInteger(v))
case uint64:
// TODO : check range or add encodeUInt...
p.Data.Write(encodeInteger(int64(v)))
case int32:
p.Data.Write(encodeInteger(int64(v)))
case uint32:
p.Data.Write(encodeInteger(int64(v)))
case int16:
p.Data.Write(encodeInteger(int64(v)))
case uint16:
p.Data.Write(encodeInteger(int64(v)))
case int8:
p.Data.Write(encodeInteger(int64(v)))
case uint8:
p.Data.Write(encodeInteger(int64(v)))
default:
// TODO : add support for big.Int ?
panic(fmt.Sprintf("Invalid type %T, expected {u|}int{64|32|16|8}", v))
}
return p
}
func NewString(ClassType Class, TagType Type, Tag Tag, Value, Description string) *Packet {
p := Encode(ClassType, TagType, Tag, nil, Description)
p.Value = Value
p.Data.Write([]byte(Value))
return p
}

25
vendor/github.com/go-asn1-ber/asn1-ber/content_int.go generated vendored Normal file
View File

@@ -0,0 +1,25 @@
package ber
func encodeUnsignedInteger(i uint64) []byte {
n := uint64Length(i)
out := make([]byte, n)
var j int
for ; n > 0; n-- {
out[j] = (byte(i >> uint((n-1)*8)))
j++
}
return out
}
func uint64Length(i uint64) (numBytes int) {
numBytes = 1
for i > 255 {
numBytes++
i >>= 8
}
return
}

3
vendor/github.com/go-asn1-ber/asn1-ber/go.mod generated vendored Normal file
View File

@@ -0,0 +1,3 @@
module github.com/go-asn1-ber/asn1-ber
go 1.13

Some files were not shown because too many files have changed in this diff Show More