idiomatic codec and rpc lib for msgpack, cbor, json, etc. msgpack.org[Go]

Sourcegraph Build Status codecov PkgGoDev rcard License

go-codec

This repository contains the go-codec library, the codecgen tool and benchmarks for comparing against other libraries.

This is a High Performance, Feature-Rich Idiomatic Go 1.4+ codec/encoding library for binary and text formats: binc, msgpack, cbor, json and simple.

It fully supports the legacy GOPATH and the new go modules modes.

Code Organization and Module Support

This repository consists of 4 modules:

  • github.com/ugorji/go (requires github.com/ugorji/go/codec)
  • github.com/ugorji/go/codec (requires github.com/ugorji/go) README
  • github.com/ugorji/go/codec/codecgen (requires github.com/ugorji/go/codec) README
  • github.com/ugorji/go/codec/bench (requires github.com/ugorji/go/codec) README

For encoding and decoding, the github.com/ugorji/go/codec module is sufficient.

To install:

go get github.com/ugorji/go/codec

The other modules exist for specific uses, and all require github.com/ugorji/go/codec

Owner
Comments
  • Fix module issues once and for all

    Fix module issues once and for all

    The use of modules in go-codec introduced more headaches than necessary.

    It has been a disaster, and I really wish I had waited until the dust settled before making this module aware, especially since so many people depended on this package and it has the atypical "package name differs from directory name" issue.

    I regret jumping on modules that early, and having to constantly try to correct my mistakes.

    It seems the dust has settled now and we have the tools to:

    • support the simulation of a multi-module repository

    We have 2 options:

    1. Make go/codec its own module using a tag: codec/vX.Y.Z
    2. Keep go as the only module, using a tag: vX.Y.Z
    3. Have both as modules using "same'ish" parallel tags (vX.Y.Z and codec/vX.Y.Z) and corresponding go.mod files

    I am not sure if 3. above is supported by go modules. I read that a module doesn't include modules within it.

    I will appreciate any thoughts on how best to resolve this. I am including references to places where I have seen folks have issues. I hope that you folks can respond and help me settle this once and for all with the best solution.

    https://github.com/golang/go/wiki/Modules#publishing-a-release https://golang.org/wiki/Modules#faqs--multi-module-repositories

    https://github.com/gin-gonic/gin/issues/1897

    @dmitshur @arizvisa @bvisness @HZ89 @bcmills @amarox @thepudds

  • Elements ignored when encoding struct embedding a Selfer

    Elements ignored when encoding struct embedding a Selfer

    Here's a simplified repro:

    package main
    
    import (
            "bytes"
            "fmt"
    
            "github.com/ugorji/go/codec"
    )
    
    // We have defined Selfers for a type (either with codecgen or manually)
    type Embedded struct {
            Embedded1 string
            Embedded2 string
    }
    
    func (e Embedded) CodecEncodeSelf(encoder *codec.Encoder) {
            // phon4y output, in a real example this would encode the struct properly
            encoder.Encode("['phony']")
    }
    
    func (e *Embedded) CodecDecodeSelf(decoder *codec.Decoder) {
    }
    
    // We use embedded in a different structure
    type Foo struct {
            Bar string
            Embedded
    }
    
    func main() {
            foo := Foo{
                    Bar: "bar",
                    Embedded: Embedded{
                            Embedded1: "embedded1",
                            Embedded2: "embedded2",
                    },
            }
    
            // The Decoder only encodes the Embedded struct
            // and ignores Bar!
            buffer := &bytes.Buffer{}
            codec.NewEncoder(buffer, &codec.JsonHandle{}).Encode(foo)
    
             fmt.Printf("Output: %s\n", buffer.String())
    }
    

    The program above outputs:

    Output: "['phony']"
    

    completely ignoring the Bar element.

    I would expect something in the lines of:

    Output: { Bar: "Bar", Embedded: "phony" }
    

    Or, with a properly defined selfer:

    Output: { Bar: "Bar", Embedded1: "embedded1", Embedded2: "embedded2"  }
    

    I guess that, since the embedded Selfer makes the full struct a Selfer too, the encoder is blindly applying (e Embedded) CodecEncodeSelf(), ignoring other fields. I think the Encoder must somehow distinguish between the case in which the struct embeds a Selfer and when the struct itself implements a Selfer directly.

    I haven't tried it yet it but, as a workaround, I guess one can define a Selfer for Foo.

    I haven't tested the decoding, but maybe that's broken too.

  • Change import path to github.com/ugorji/go-codec

    Change import path to github.com/ugorji/go-codec

    It would be nice if the import path mapped directly to a URL to the source code.

    Currently, it doesn't, and for no good reason. Initially, we used a repository name of go, with the hope of putting multiple packages into the same repository. However, in retrospect, that is not a good idea; one repository should only hold one package, with possible sub-packages which relate directly to that package.

    The plan of action is:

    • Use github to change repository name from go to go-codec
    • Move all files from the codec sub-directory of the repository to the top-level directory
    • Keep the codec subdirectory there, and create a codec/fail.go file

    The new codec/fail.go file will contain

    • package docs that tell users the new import path and where to find docs
    • init method that panics with an appropriate error message
    • possibly use the // import label to allow go get fail early

    We hope to do this soon, likely by the end of january.

  • Kubernetes: Failure when codecgen is run on anonymous type, but not on wrapping type.

    Kubernetes: Failure when codecgen is run on anonymous type, but not on wrapping type.

    To reproduce I'm using: https://github.com/kubernetes/kubernetes/compare/master...wojtek-t:use_ugorij#diff-22207499f9ab0d60831b9c388397f034R1

    Input data: https://github.com/kubernetes/kubernetes/compare/master...wojtek-t:use_ugorij#diff-29f2371dad30835b344a6ca05b473eaeR1

    I did NOT run codecgen for the file that contains definition of that jsons: https://github.com/kubernetes/kubernetes/blob/master/plugin/pkg/scheduler/api/types.go

    IIUC, this should result in falling back to encoding/json (which works fine). However this is not the case (i.e. the output is empty)

    @ugorji

  • Please tag releases

    Please tag releases

    Formal releases are useful to define dependency relationships. 3rd party developers would be able to bundle somewhat "stable" version of your software instead of just top of "master". Also it is helpful for downstream maintainers for numerous reasons.

    Please consider tagging. Thanks.

  • Slower than encoding/json

    Slower than encoding/json

    Here's my test:

    n := 5
    
    log.Print("encoding/json")
    for i := 0; i < n; i++ {
      t := time.Now()
      var v interface{}
      for j := 0; j < 20; j++ {
        if err = json.Unmarshal(b, &v); err != nil {
          panic(err)
        }
      }
      log.Print(time.Now().Sub(t))
    }
    
    log.Print("go-codec")
    for i := 0; i < n; i++ {
      t := time.Now()
      for j := 0; j < 20; j++ {
        var dec *codec.Decoder = codec.NewDecoderBytes(b, new(codec.JsonHandle))
        var v interface{}
        if err := dec.Decode(&v); err != nil {
          panic(err)
        }
      }
      log.Print(time.Now().Sub(t))
    }
    

    For a large, minified file with long keys (4.7MB), go-codec is ~ 31% slower than encoding/json:

    encoding/json
    1.617601942s
    1.576523967s
    1.610622356s
    1.608594081s
    1.647141938s
    go-codec
    2.129585437s
    2.166288614s
    2.1520013s
    2.061147463s
    2.102718168s
    

    For a file containing the same values, but with every key shortened to just 2 characters (970KB), it's 80% slower:

    encoding/json
    474.933239ms
    451.410297ms
    452.822768ms
    462.508272ms
    456.032676ms
    go-codec
    852.508337ms
    849.04073ms
    830.897711ms
    852.40816ms
    826.848954ms
    

    This is from byte arrays into interface{} values. Is there anything I can tweak to make go-codec be faster? Is this by design, somehow?

    Go 1.5.1 on OS X.

  • "reflect.Value.Addr of unaddressable value" error while marshaling

    When I was trying to use Ugorij for Kubernetes: https://github.com/kubernetes/kubernetes/blob/master/pkg/api/types.go I received the following error: "reflect.Value.Addr of unaddressable value"

    How to reproduce it:

    • I used the following code: https://github.com/kubernetes/kubernetes/compare/master...wojtek-t:use_ugorij#diff-a880abe356116a717967d2246a1ffc36R29

    • This diff also contains a file that was generated for our structures.

      Please let me know if you need more information on reproducing it

  • bug: MapValueReset has no effect

    bug: MapValueReset has no effect

    The sample code below doesn't seem to work as it should:

    package main
    
    import (
    	"bytes"
    	"fmt"
    
    	"github.com/ugorji/go/codec"
    )
    
    func main() {
    
    	h := &codec.JsonHandle{}
    	h.MapValueReset = true
    
    	d := bytes.NewBuffer([]byte(`{"map": {"a": 1}}`))
    	dec := codec.NewDecoder(d, h)
    
    	o := struct {
    		Map map[string]interface{} `json:"map"`
    	}{}
    
    	o.Map = map[string]interface{}{"b": 1}
    
    	if err := dec.Decode(&o); err != nil {
    		panic(err)
    	}
    
    	fmt.Println(o.Map)
    }
    

    This prints:

    map[a:1 b:1]
    

    Since I set MapValueReset = true, I would expect it to print:

    map[a:1]
    
  • mod: justify mod style

    mod: justify mod style

    In this way, we can get the right tag like v1.1.3, instead of pseudo-version

    A good example would be shown below

    https://github.com/stretchr/testify/blob/master/go.mod https://github.com/andrewstuart/go-robinhood/blob/master/go.mod#L8

    go-robinhood imports github.com/stretchr/testify/assert and got the right version

    github.com/stretchr/testify v1.2.2
    
  • register extension without custom en/decoding

    register extension without custom en/decoding

    As far as I've managed to dig into the docs, registering an extension (cbor tag) requires you to also manually en/decode the data yourself. Both the InterfaceExt and Ext interfaces assume you implement the en/decoding.

    I was wondering if there is a way to register a struct as an extension, and let the normal un/marshalling of the struct to take place for its payload.

    eg.

    type Something struct {
    	Foo string `json:"foo"`
    }
    

    I'd like for example to be able to register Foo as extension 123 and have the handler marshal the tag, followed by a map with a string element with key foo.

    Is there a way to do something simple like this in the current state of the lib that I am missing? If not, could point me to the right direction of what could be done to add it?

    Thank you for an amazing library.

  • Kubernetes: codecgen: produce consistent output on repeated runs

    Kubernetes: codecgen: produce consistent output on repeated runs

    This is usability issue (not correctness one). I observed that when I'm using codecgen, the output produced for a given file (I was using: https://github.com/kubernetes/kubernetes/blob/master/pkg/api/types.go is non deterministic. Few things that change:

    1. constants "codecSelferC*" has different names, e.g.:
    codecSelferC_UTF85477         = 1
    

    vs

     codecSelferC_UTF85165         = 1
    
    1. ordering of generated function (and thus the names of variables they are using, because IIUC, you're using consecutive integers for variable names)

    It would be very convenient if the output would be deterministic.

  • omitempty handling for arrays disagrees with the standard encoding/json

    omitempty handling for arrays disagrees with the standard encoding/json

    As of this commit: https://github.com/ugorji/go/commit/ebaaab4fb661237a0e4f376a751ae0eb26445b3d arrays with zero values ar treated as empty. Whether this is correct or not is up for debate (see https://github.com/golang/go/issues/29310), however it makes the current behaviour inconsistent with the standard json.Marshal() which makes it more difficult to use ugorji as a replacement.

    I personally would argue that array of zero values is not empty. It's true that for Go arrays there is no distinction (meaning a Go array cannot be empty), however when doing un-typed unmarshalling the difference is between an undefined/missing value and an array of zeros.

  • XML support

    XML support

    go-codec currently supports

    • Binary: Msgpack
    • Binary: CBOR
    • Text: JSON

    For completeness, it should support XML also.

    Though XML has fallen out-of-favor, it is still widely used. The encoding/xml in the standard library is not efficient, and does not conform to the simplicity used in encoding/json. We have a chance to add a performant XML encoder/decoder as just another format.

    We are attempting this due to perceived issues with encoding/xml:

    • Complicated. It tried to do too much, and is not as simple to use as json.
    • Due to over-engineering, reflection is over-used AND performance suffers: java is 6X faster:http://fabsk.eu/blog/category/informatique/dev/golang/ even PYTHON performs better: http://outgoing.typepad.com/outgoing/2014/07/exploring-golang.html

    codec framework will offer the following benefits

    • VASTLY improved performance (when using reflection-mode or codecgen)
    • simplicity and consistency: with the rest of the supported formats
    • all other benefits of codec framework (streaming, codegeneration, etc)

    go-codec is not a drop-in replacement for encoding/xml, as the tags and style will not transfer over. Having said that, it is a replacement, based on the simplicity and performance of codec.

    The goal is for this to be like JAXB for Go.

Related tags
msgpack.org[Go] MessagePack encoding for Golang

MessagePack encoding for Golang ❤️ Uptrace.dev - All-in-one tool to optimize performance and monitor errors & logs Join Discord to ask questions. Docu

Dec 28, 2022
Cap'n Proto library and parser for go. This is go-capnproto-1.0, and does not have rpc. See https://github.com/zombiezen/go-capnproto2 for 2.0 which has rpc and capabilities.

Version 1.0 vs 2.0 Update 2015 Sept 20: Big news! Version 2.0 of the go-bindings, authored by Ross Light, is now released and newly available! It feat

Nov 29, 2022
csvutil provides fast and idiomatic mapping between CSV and Go (golang) values.
csvutil provides fast and idiomatic mapping between CSV and Go (golang) values.

csvutil Package csvutil provides fast and idiomatic mapping between CSV and Go (golang) values. This package does not provide a CSV parser itself, it

Jan 6, 2023
Generate TypeScript interfaces from Go structs/interfaces - useful for JSON RPC

bel Generate TypeScript interfaces from Go structs/interfaces - useful for JSON RPC bel is used in production in https://gitpod.io. Getting started be

Oct 23, 2022
Go package for dealing with maps, slices, JSON and other data.

Objx Objx - Go package for dealing with maps, slices, JSON and other data. Get started: Install Objx with one line of code, or update it with another

Dec 27, 2022
A high-performance 100% compatible drop-in replacement of "encoding/json"
A high-performance 100% compatible drop-in replacement of

A high-performance 100% compatible drop-in replacement of "encoding/json" You can also use thrift like JSON using thrift-iterator Benchmark Source cod

Jan 7, 2023
Encode and decode binary message and file formats in Go

Encode and Decode Binary Formats in Go This module wraps the package encoding/binary of the Go standard library and provides the missing Marshal() and

Dec 22, 2022
Some Golang types based on builtin. Implements interfaces Value / Scan and MarshalJSON / UnmarshalJSON for simple working with database NULL-values and Base64 encoding / decoding.

gotypes Some simple types based on builtin Golang types that implement interfaces for working with DB (Scan / Value) and JSON (Marshal / Unmarshal). N

Feb 12, 2022
Asn.1 BER and DER encoding library for golang.

WARNING This repo has been archived! NO further developement will be made in the foreseen future. asn1 -- import "github.com/PromonLogicalis/asn1" Pac

Nov 14, 2022
Go library for decoding generic map values into native Go structures and vice versa.

mapstructure mapstructure is a Go library for decoding generic map values to structures and vice versa, while providing helpful error handling. This l

Jan 1, 2023
Easily and dynamically generate maps from Go static structures

structomap This package helps you to transform your struct into map easily. It provides a structomap.Serializer interface implemented by the structoma

Dec 9, 2022
Encode and decode Go (golang) struct types via protocol buffers.

protostructure protostructure is a Go library for encoding and decoding a struct type over the wire. This library is useful when you want to send arbi

Nov 15, 2022
Simple, specialised, and efficient binary marshaling

?? surge Documentation A library for fast binary (un)marshaling. Designed to be used in Byzantine networks, ?? surge never explicitly panics, protects

Oct 4, 2022
An optimal, byte-aligned, LZ+RLE hybrid encoder, designed to maximize decoding speed on NMOS 6502 and derived CPUs
An optimal, byte-aligned, LZ+RLE hybrid encoder, designed to maximize decoding speed on NMOS 6502 and derived CPUs

TSCrunch TSCrunch is an optimal, byte-aligned, LZ+RLE hybrid encoder, designed to maximize decoding speed on NMOS 6502 and derived CPUs, while keeping

Dec 21, 2022
CBOR RFC 7049 (Go/Golang) - safe & fast with standard API + toarray & keyasint, CBOR tags, float64/32/16, fuzz tested.
CBOR RFC 7049 (Go/Golang) - safe & fast with standard API + toarray & keyasint, CBOR tags, float64/32/16, fuzz tested.

CBOR library in Go fxamacker/cbor is a CBOR encoder & decoder in Go. It has a standard API, CBOR tags, options for duplicate map keys, float64→32→16,

Jan 6, 2023
msgpack.org[Go] MessagePack encoding for Golang

MessagePack encoding for Golang ❤️ Uptrace.dev - distributed traces, logs, and errors in one place Join Discord to ask questions. Documentation Refere

Dec 28, 2022
msgpack.org[Go] MessagePack encoding for Golang

MessagePack encoding for Golang ❤️ Uptrace.dev - All-in-one tool to optimize performance and monitor errors & logs Join Discord to ask questions. Docu

Dec 28, 2022
Goridge is high performance PHP-to-Golang codec library which works over native PHP sockets and Golang net/rpc package.
Goridge is high performance PHP-to-Golang codec library which works over native PHP sockets and Golang net/rpc package.

Goridge is high performance PHP-to-Golang codec library which works over native PHP sockets and Golang net/rpc package. The library allows you to call Go service methods from PHP with a minimal footprint, structures and []byte support.

Dec 28, 2022
An golang log lib, supports tracking and level, wrap by standard log lib

Logex An golang log lib, supports tracing and level, wrap by standard log lib How To Get shell go get gopkg.in/logex.v1 source code import "gopkg.in/

Nov 27, 2022
Github-org-diff - Simple CLI tool to check a diff between 2 branches of all org repos

github-org-diff Simple CLI tool to list org repos that have diff between dev and

Jan 25, 2022