From 2cad3c275fcc5a7db44830ecaf9822dfdbb712ed Mon Sep 17 00:00:00 2001 From: Kevin Atkinson Date: Mon, 17 Sep 2018 21:50:24 -0400 Subject: [PATCH 01/10] Add '--filter' option to cid-fmt utility. --- cid-fmt/main.go | 94 +++++++++++++++++++++++++++++++++++-------------- format.go | 45 +++++++++++++++++++++++ 2 files changed, 112 insertions(+), 27 deletions(-) diff --git a/cid-fmt/main.go b/cid-fmt/main.go index 3aae3ee..8735658 100644 --- a/cid-fmt/main.go +++ b/cid-fmt/main.go @@ -1,7 +1,9 @@ package main import ( + "bufio" "fmt" + "io" "os" "strings" @@ -12,7 +14,9 @@ import ( ) func usage() { - fmt.Fprintf(os.Stderr, "usage: %s [-b multibase-code] [-v cid-version] ...\n\n", os.Args[0]) + fmt.Fprintf(os.Stderr, "usage: %s [-b multibase-code] [-v cid-version] [--filter] ...\n", os.Args[0]) + fmt.Fprintf(os.Stderr, "--filter will read from stdin and convert anything that looks like a \n") + fmt.Fprintf(os.Stderr, " -- including any non-cids that are valid Multihashes).\n") fmt.Fprintf(os.Stderr, " is either 'prefix' or a printf style format string:\n%s", cidutil.FormatRef) os.Exit(2) } @@ -24,8 +28,9 @@ func main() { newBase := mb.Encoding(-1) var verConv func(cid c.Cid) (c.Cid, error) args := os.Args[1:] + filter := false outer: - for { + for len(args) > 0 { switch args[0] { case "-b": if len(args) < 2 { @@ -52,11 +57,14 @@ outer: os.Exit(2) } args = args[2:] + case "--filter": + filter = true + args = args[1:] default: break outer } } - if len(args) < 2 { + if len(args) < 1 { usage() } fmtStr := args[0] @@ -69,41 +77,73 @@ outer: os.Exit(2) } } - for _, cidStr := range args[1:] { - cid, err := c.Decode(cidStr) - if err != nil { - fmt.Fprintf(os.Stdout, "!INVALID_CID!\n") - errorMsg("%s: %v", cidStr, err) - // Don't abort on a bad cid - continue - } + format := func(cid c.Cid, cidStr string) (string, error) { base := newBase - if newBase == -1 { + if base == -1 { base, _ = c.ExtractEncoding(cidStr) } + var err error if verConv != nil { cid, err = verConv(cid) if err != nil { - fmt.Fprintf(os.Stdout, "!ERROR!\n") - errorMsg("%s: %v", cidStr, err) - // Don't abort on a bad conversion - continue + return "", err + } + } + return cidutil.Format(fmtStr, base, cid) + } + if filter { + scanner := bufio.NewScanner(os.Stdin) + for scanner.Scan() { + buf := scanner.Bytes() + for { + i, j, cid, cidStr := cidutil.ScanForCid(buf) + os.Stdout.Write(buf[0:i]) + if i == len(buf) { + os.Stdout.Write([]byte{'\n'}) + break + } + str, err := format(cid, cidStr) + switch err.(type) { + case cidutil.FormatStringError: + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + os.Exit(2) + default: + // just use the orignal sting on non-fatal error + str = cidStr + case nil: + } + io.WriteString(os.Stdout, str) + buf = buf[j:] } } - str, err := cidutil.Format(fmtStr, base, cid) - switch err.(type) { - case cidutil.FormatStringError: + if err := scanner.Err(); err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(2) - default: - fmt.Fprintf(os.Stdout, "!ERROR!\n") - errorMsg("%s: %v", cidStr, err) - // Don't abort on cid specific errors - continue - case nil: - // no error } - fmt.Fprintf(os.Stdout, "%s\n", str) + } else { + for _, cidStr := range args[1:] { + cid, err := c.Decode(cidStr) + if err != nil { + fmt.Fprintf(os.Stdout, "!INVALID_CID!\n") + errorMsg("%s: %v", cidStr, err) + // Don't abort on a bad cid + continue + } + str, err := format(cid, cidStr) + switch err.(type) { + case cidutil.FormatStringError: + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + os.Exit(2) + default: + fmt.Fprintf(os.Stdout, "!ERROR!\n") + errorMsg("%s: %v", cidStr, err) + // Don't abort on cid specific errors + continue + case nil: + // no error + } + fmt.Fprintf(os.Stdout, "%s\n", str) + } } os.Exit(exitCode) } diff --git a/format.go b/format.go index 873d3ec..300277d 100644 --- a/format.go +++ b/format.go @@ -150,3 +150,48 @@ func encode(base mb.Encoder, data []byte, strip bool) string { } return str } + +// ScanForCid scans bytes for anything resembling a CId. If one is +// found `i` will point to the begging of the cid and `j` to to the end +// and the cid will be returned, otherwise `i` will point the end of the +// buffer and the cid will be `Undef`. +func ScanForCid(buf []byte) (i, j int, cid c.Cid, cidStr string) { + i = 0 + for { + i = j + for i < len(buf) && !asciiIsAlpha(buf[i]) { + i++ + } + j = i + if i == len(buf) { + return + } + for j < len(buf) && asciiIsAlpha(buf[j]) { + j++ + } + if j-i <= 1 || j-i > 128 || !supported[buf[i]] { + continue + } + var err error + cidStr = string(buf[i:j]) + cid, err = c.Decode(cidStr) + if err == nil { + return + } + } +} + +var supported = make([]bool, 256) + +func init() { + // for now base64 encoding are not supported as they contain non + // alhphanumeric characters + supportedPrefixes := []byte("QfFbBcCvVtThzZ") + for _, b := range supportedPrefixes { + supported[b] = true + } +} + +func asciiIsAlpha(b byte) bool { + return ('A' <= b && b <= 'Z') || ('a' <= b && b <= 'z') || ('0' <= b && b <= '9') +} From 345f0c7ce0d5c2f860467d26fe9dd333e56da70e Mon Sep 17 00:00:00 2001 From: Kevin Atkinson Date: Mon, 17 Sep 2018 22:35:22 -0400 Subject: [PATCH 02/10] Move TryOtherCidVersion from go-ipfs/thirdparty/cidv0v1. --- misc.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 misc.go diff --git a/misc.go b/misc.go new file mode 100644 index 0000000..9ea665e --- /dev/null +++ b/misc.go @@ -0,0 +1,20 @@ +package cidutil + +import ( + cid "github.com/ipfs/go-cid" + mh "github.com/multiformats/go-multihash" +) + +func TryOtherCidVersion(c cid.Cid) cid.Cid { + prefix := c.Prefix() + if prefix.Codec != cid.DagProtobuf || prefix.MhType != mh.SHA2_256 || prefix.MhLength != 32 { + return cid.Undef + } + var c1 cid.Cid + if prefix.Version == 0 { + c1 = cid.NewCidV1(cid.DagProtobuf, c.Hash()) + } else { + c1 = cid.NewCidV0(c.Hash()) + } + return c1 +} From 94ff1f02252350327ce1168866e5a8054754d08a Mon Sep 17 00:00:00 2001 From: Kevin Atkinson Date: Mon, 17 Sep 2018 22:35:49 -0400 Subject: [PATCH 03/10] Add apicid and cidenc packages. --- apicid/apicid.go | 62 ++++++++++++++++++++++++++++++++ cidenc/encoder.go | 91 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 6 ++++ 3 files changed, 159 insertions(+) create mode 100644 apicid/apicid.go create mode 100644 cidenc/encoder.go diff --git a/apicid/apicid.go b/apicid/apicid.go new file mode 100644 index 0000000..4ff6585 --- /dev/null +++ b/apicid/apicid.go @@ -0,0 +1,62 @@ +package apicid + +import ( + "encoding/json" + + cid "github.com/ipfs/go-cid" + "github.com/ipfs/go-cidutil/cidenc" + mbase "github.com/multiformats/go-multibase" +) + +// JSONBase is the base to use when Encoding into JSON. +var JSONBase mbase.Encoder = mbase.MustNewEncoder(mbase.Base58BTC) + +// apicid.Hash is a type to respesnt a CID in the API which marshals +// as a hash +type Hash struct { + str string // always in CidJSONBase +} + +// FromCid created an APICid from a Cid +func FromCid(c cid.Cid) Hash { + return Hash{c.Encode(JSONBase)} +} + +// Cid converts an APICid to a CID +func (c Hash) Cid() (cid.Cid, error) { + return cid.Decode(c.str) +} + +func (c Hash) String() string { + return c.Encode(cidenc.Default) +} + +func (c Hash) Encode(enc cidenc.Interface) string { + if c.str == "" { + return "" + } + str, err := enc.Recode(c.str) + if err != nil { + return c.str + } + return str +} + +func (c *Hash) UnmarshalJSON(b []byte) error { + return json.Unmarshal(b, &c.str) +} + +func (c Hash) MarshalJSON() ([]byte, error) { + return json.Marshal(c.str) +} + +// Cid is type to represent a normal CID in the API which marshals +// like a normal CID i.e. ({"/": }) but may uses cidenc.Default +// for the String() to optionally upgrade a version 0 CID to version 1 +type Cid struct { + cid.Cid +} + +func (c Cid) String() string { + return cidenc.Default.Encode(c.Cid) +} diff --git a/cidenc/encoder.go b/cidenc/encoder.go new file mode 100644 index 0000000..9c2b13a --- /dev/null +++ b/cidenc/encoder.go @@ -0,0 +1,91 @@ +package cidenc + +import ( + cid "github.com/ipfs/go-cid" + path "github.com/ipfs/go-path" + mbase "github.com/multiformats/go-multibase" +) + +// Encoder is a basic Encoder that will encode Cid's using +// a specifed base, optionally upgrading a Cid if is Version 0 +type Encoder struct { + Base mbase.Encoder + Upgrade bool +} + +// Interface is a generic interface to the Encoder functionally. +type Interface interface { + Encode(c cid.Cid) string + Recode(v string) (string, error) +} + +// Default is the +var Default = Encoder{ + Base: mbase.MustNewEncoder(mbase.Base58BTC), + Upgrade: false, +} + +func (enc Encoder) Encode(c cid.Cid) string { + if enc.Upgrade && c.Version() == 0 { + c = cid.NewCidV1(c.Type(), c.Hash()) + } + return c.Encode(enc.Base) +} + +func (enc Encoder) Recode(v string) (string, error) { + skip, err := enc.noopRecode(v) + if skip || err != nil { + return v, err + } + + c, err := cid.Decode(v) + if err != nil { + return v, err + } + + return enc.Encode(c), nil +} + +func (enc Encoder) noopRecode(v string) (bool, error) { + if len(v) < 2 { + return false, cid.ErrCidTooShort + } + ver := cidVer(v) + skip := ver == 0 && !enc.Upgrade || ver == 1 && v[0] == byte(enc.Base.Encoding()) + return skip, nil +} + +func cidVer(v string) int { + if len(v) == 46 && v[:2] == "Qm" { + return 0 + } else { + return 1 + } +} + +// FromPath creates a new encoder that is influenced from the encoded +// Cid in a Path. For CidV0 the multibase from the base encoder is +// used and automatic upgrades are disabled. For CidV1 the multibase +// from the CID is used and upgrades are eneabled. On error the base +// encoder is returned. If you don't care about the error condiation +// it is safe to ignore the error returned. +func FromPath(enc Encoder, p string) (Encoder, error) { + v := extractCidString(p) + if cidVer(v) == 0 { + return Encoder{enc.Base, false}, nil + } + e, err := mbase.NewEncoder(mbase.Encoding(v[0])) + if err != nil { + return enc, err + } + return Encoder{e, true}, nil +} + +func extractCidString(p string) string { + segs := path.FromString(p).Segments() + v := segs[0] + if v == "ipfs" && len(segs) > 0 { + v = segs[1] + } + return v +} diff --git a/package.json b/package.json index 1a6b20e..eac4d08 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,12 @@ "hash": "QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw", "name": "go-cid", "version": "0.9.1" + }, + { + "author": "why", + "hash": "QmRKuTyCzg7HFBcV1YUhzStroGtJSb8iWgyxfsDCwFhWTS", + "name": "go-path", + "version": "1.1.13" } ], "gxVersion": "0.12.1", From cec6117d848d91e998493643fd74d1fe66be8352 Mon Sep 17 00:00:00 2001 From: Kevin Atkinson Date: Wed, 19 Sep 2018 00:58:00 -0400 Subject: [PATCH 04/10] Add WithOverride to cidenc package. --- cidenc/encoder.go | 62 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/cidenc/encoder.go b/cidenc/encoder.go index 9c2b13a..cde3b87 100644 --- a/cidenc/encoder.go +++ b/cidenc/encoder.go @@ -1,6 +1,8 @@ package cidenc import ( + cidutil "github.com/ipfs/go-cidutil" + cid "github.com/ipfs/go-cid" path "github.com/ipfs/go-path" mbase "github.com/multiformats/go-multibase" @@ -19,7 +21,7 @@ type Interface interface { Recode(v string) (string, error) } -// Default is the +// Default is the default encoder var Default = Encoder{ Base: mbase.MustNewEncoder(mbase.Base58BTC), Upgrade: false, @@ -89,3 +91,61 @@ func extractCidString(p string) string { } return v } + +// WithOverride is like Encoder but also contains a override map to +// preserve the original encoding of select CIDs +type WithOverride struct { + base Encoder + override map[cid.Cid]string +} + +func (enc WithOverride) Encoder() Encoder { + return enc.base +} + +func (enc WithOverride) Map() map[cid.Cid]string { + return enc.override +} + +func NewOverride(enc Encoder) WithOverride { + return WithOverride{base: enc, override: map[cid.Cid]string{}} +} + +// Add adds a Cid to the override map if it will be encoded +// differently than the base encoder +func (enc WithOverride) Add(cids ...string) { + for _, p := range cids { + v := p + c, err := cid.Decode(v) + if err != nil { + continue + } + if enc.base.Encode(c) != v { + enc.override[c] = v + } + c2 := cidutil.TryOtherCidVersion(c) + if c2.Defined() && enc.base.Encode(c2) != v { + enc.override[c2] = v + } + } +} + +func (enc WithOverride) Encode(c cid.Cid) string { + v, ok := enc.override[c] + if ok { + return v + } + return enc.base.Encode(c) +} + +func (enc WithOverride) Recode(v string) (string, error) { + if len(enc.override) == 0 { + return enc.base.Recode(v) + } + c, err := cid.Decode(v) + if err != nil { + return v, err + } + + return enc.Encode(c), nil +} From 851475dc999285567bc3b8d77af14cf83fd21af7 Mon Sep 17 00:00:00 2001 From: Kevin Atkinson Date: Wed, 19 Sep 2018 01:34:19 -0400 Subject: [PATCH 05/10] Add support for storing an encoder in the current context. --- cidenc/encoder.go | 20 ++++++++++++++++++++ cidenc/encoder_test.go | 18 ++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 cidenc/encoder_test.go diff --git a/cidenc/encoder.go b/cidenc/encoder.go index cde3b87..bdffdb7 100644 --- a/cidenc/encoder.go +++ b/cidenc/encoder.go @@ -1,6 +1,8 @@ package cidenc import ( + "context" + cidutil "github.com/ipfs/go-cidutil" cid "github.com/ipfs/go-cid" @@ -149,3 +151,21 @@ func (enc WithOverride) Recode(v string) (string, error) { return enc.Encode(c), nil } + +type encoderKey struct{} + +// Enable "enables" the encoder in the context using WithValue +func Enable(ctx context.Context, enc Interface) context.Context { + return context.WithValue(ctx, encoderKey{}, enc) +} + +// Get gets an encoder from the context if it exists, otherwise the +// default context is called. +func Get(ctx context.Context) Interface { + enc, ok := ctx.Value(encoderKey{}).(Interface) + if !ok { + // FIXME: Warning? + enc = Default + } + return enc +} diff --git a/cidenc/encoder_test.go b/cidenc/encoder_test.go new file mode 100644 index 0000000..2a6829e --- /dev/null +++ b/cidenc/encoder_test.go @@ -0,0 +1,18 @@ +package cidenc + +import ( + "context" + "testing" + + mbase "github.com/multiformats/go-multibase" +) + +func TestContext(t *testing.T) { + enc := Encoder{Base: mbase.MustNewEncoder(mbase.Base64)} + ctx := context.Background() + ctx = Enable(ctx, enc) + e, ok := Get(ctx).(Encoder) + if !ok || e.Base.Encoding() != mbase.Base64 { + t.Fatal("Failed to retrive encoder from context") + } +} From 1917e044c9fc407fd4c843cf6e3fcab36876463d Mon Sep 17 00:00:00 2001 From: Kevin Atkinson Date: Wed, 26 Sep 2018 20:33:41 -0400 Subject: [PATCH 06/10] Doc. Enhancements. --- cidenc/encoder.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cidenc/encoder.go b/cidenc/encoder.go index bdffdb7..c1563cf 100644 --- a/cidenc/encoder.go +++ b/cidenc/encoder.go @@ -10,8 +10,8 @@ import ( mbase "github.com/multiformats/go-multibase" ) -// Encoder is a basic Encoder that will encode Cid's using -// a specifed base, optionally upgrading a Cid if is Version 0 +// Encoder is a basic Encoder that will encode Cid's using a specifed +// base and optionally upgrade a CidV0 to CidV1 type Encoder struct { Base mbase.Encoder Upgrade bool @@ -36,6 +36,8 @@ func (enc Encoder) Encode(c cid.Cid) string { return c.Encode(enc.Base) } +// Recode reencodes the cid string to match the paramaters of the +// encoder func (enc Encoder) Recode(v string) (string, error) { skip, err := enc.noopRecode(v) if skip || err != nil { From 9148d7fe73cd8a583f020dadf6d0f0ae90931e5d Mon Sep 17 00:00:00 2001 From: Kevin Atkinson Date: Wed, 26 Sep 2018 20:35:04 -0400 Subject: [PATCH 07/10] Use (Un)MarshalText instead of (Un)MarshalJSON for encoding. This is more to the point and will also allow the use of apicid.Hash as keys is JSON objects. --- apicid/apicid.go | 17 ++++++++------- apicid/apicid_test.go | 48 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 apicid/apicid_test.go diff --git a/apicid/apicid.go b/apicid/apicid.go index 4ff6585..22c4ea7 100644 --- a/apicid/apicid.go +++ b/apicid/apicid.go @@ -1,8 +1,6 @@ package apicid import ( - "encoding/json" - cid "github.com/ipfs/go-cid" "github.com/ipfs/go-cidutil/cidenc" mbase "github.com/multiformats/go-multibase" @@ -12,12 +10,12 @@ import ( var JSONBase mbase.Encoder = mbase.MustNewEncoder(mbase.Base58BTC) // apicid.Hash is a type to respesnt a CID in the API which marshals -// as a hash +// as a string type Hash struct { - str string // always in CidJSONBase + str string } -// FromCid created an APICid from a Cid +// FromCid creates an APICid from a Cid func FromCid(c cid.Cid) Hash { return Hash{c.Encode(JSONBase)} } @@ -42,12 +40,13 @@ func (c Hash) Encode(enc cidenc.Interface) string { return str } -func (c *Hash) UnmarshalJSON(b []byte) error { - return json.Unmarshal(b, &c.str) +func (c *Hash) UnmarshalText(b []byte) error { + c.str = string(b) + return nil } -func (c Hash) MarshalJSON() ([]byte, error) { - return json.Marshal(c.str) +func (c Hash) MarshalText() ([]byte, error) { + return []byte(c.str), nil } // Cid is type to represent a normal CID in the API which marshals diff --git a/apicid/apicid_test.go b/apicid/apicid_test.go new file mode 100644 index 0000000..b967f88 --- /dev/null +++ b/apicid/apicid_test.go @@ -0,0 +1,48 @@ +package apicid + +import ( + "encoding/json" + "testing" + + cid "github.com/ipfs/go-cid" +) + +func TestJson(t *testing.T) { + cid, _ := cid.Decode("zb2rhak9iRgDiik36KQBRr2qiCJHdyBH7YxFmw7FTdM6zo31m") + hash := FromCid(cid) + data, err := json.Marshal(hash) + if err != nil { + t.Fatal(err) + } + if string(data) != `"zb2rhak9iRgDiik36KQBRr2qiCJHdyBH7YxFmw7FTdM6zo31m"` { + t.Fatalf("json string incorrect: %s\n", data) + } + var hash2 Hash + err = json.Unmarshal(data, &hash2) + if err != nil { + t.Fatal(err) + } + if hash != hash2 { + t.Fatal("round trip failed") + } +} + +func TestJsonMap(t *testing.T) { + cid1, _ := cid.Decode("zb2rhak9iRgDiik36KQBRr2qiCJHdyBH7YxFmw7FTdM6zo31m") + cid2, _ := cid.Decode("QmRJggJREPCt7waGQKMXymrXRvrvsSiiPjgFbLK9isuM8K") + hash1 := FromCid(cid1) + hash2 := FromCid(cid2) + m := map[Hash]string{hash1: "a value", hash2: "something else"} + data, err := json.Marshal(m) + if err != nil { + t.Fatal(err) + } + m2 := map[Hash]string{} + err = json.Unmarshal(data, &m2) + if err != nil { + t.Fatal(err) + } + if len(m2) != 2 || m[hash1] != m2[hash1] || m[hash2] != m2[hash2] { + t.Fatal("round trip failed") + } +} From 329c831ccb320859ed5b456ebeb8169a6a8d84a1 Mon Sep 17 00:00:00 2001 From: Kevin Atkinson Date: Thu, 22 Nov 2018 15:02:06 -0500 Subject: [PATCH 08/10] gx publish 0.1.3 --- .gx/lastpubver | 2 +- package.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gx/lastpubver b/.gx/lastpubver index 38e7732..5474267 100644 --- a/.gx/lastpubver +++ b/.gx/lastpubver @@ -1 +1 @@ -0.1.2: QmbfKu17LbMWyGUxHEUns9Wf5Dkm8PT6be4uPhTkk4YvaV +0.1.3: QmVjZoEZg2oxXGFGjbD28x3gGN6ALHAW6BN2LKRUcaJ21i diff --git a/package.json b/package.json index eac4d08..f58dc30 100644 --- a/package.json +++ b/package.json @@ -25,9 +25,9 @@ }, { "author": "why", - "hash": "QmRKuTyCzg7HFBcV1YUhzStroGtJSb8iWgyxfsDCwFhWTS", + "hash": "QmVi2uUygezqaMTqs3Yzt5FcZFHJoYD4B7jQ2BELjj7ZuY", "name": "go-path", - "version": "1.1.13" + "version": "1.1.23" } ], "gxVersion": "0.12.1", @@ -35,6 +35,6 @@ "license": "", "name": "go-cidutil", "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", - "version": "0.1.2" + "version": "0.1.3" } From 07d0223ca81518f084b7e139292fe882e6584ece Mon Sep 17 00:00:00 2001 From: Kevin Atkinson Date: Sun, 25 Nov 2018 23:10:58 -0500 Subject: [PATCH 09/10] Remove code that depends on `go-path`. Also remove other now unused code. --- cidenc/encoder.go | 88 ----------------------------------------------- package.json | 6 ---- 2 files changed, 94 deletions(-) diff --git a/cidenc/encoder.go b/cidenc/encoder.go index c1563cf..1310821 100644 --- a/cidenc/encoder.go +++ b/cidenc/encoder.go @@ -3,10 +3,7 @@ package cidenc import ( "context" - cidutil "github.com/ipfs/go-cidutil" - cid "github.com/ipfs/go-cid" - path "github.com/ipfs/go-path" mbase "github.com/multiformats/go-multibase" ) @@ -69,91 +66,6 @@ func cidVer(v string) int { } } -// FromPath creates a new encoder that is influenced from the encoded -// Cid in a Path. For CidV0 the multibase from the base encoder is -// used and automatic upgrades are disabled. For CidV1 the multibase -// from the CID is used and upgrades are eneabled. On error the base -// encoder is returned. If you don't care about the error condiation -// it is safe to ignore the error returned. -func FromPath(enc Encoder, p string) (Encoder, error) { - v := extractCidString(p) - if cidVer(v) == 0 { - return Encoder{enc.Base, false}, nil - } - e, err := mbase.NewEncoder(mbase.Encoding(v[0])) - if err != nil { - return enc, err - } - return Encoder{e, true}, nil -} - -func extractCidString(p string) string { - segs := path.FromString(p).Segments() - v := segs[0] - if v == "ipfs" && len(segs) > 0 { - v = segs[1] - } - return v -} - -// WithOverride is like Encoder but also contains a override map to -// preserve the original encoding of select CIDs -type WithOverride struct { - base Encoder - override map[cid.Cid]string -} - -func (enc WithOverride) Encoder() Encoder { - return enc.base -} - -func (enc WithOverride) Map() map[cid.Cid]string { - return enc.override -} - -func NewOverride(enc Encoder) WithOverride { - return WithOverride{base: enc, override: map[cid.Cid]string{}} -} - -// Add adds a Cid to the override map if it will be encoded -// differently than the base encoder -func (enc WithOverride) Add(cids ...string) { - for _, p := range cids { - v := p - c, err := cid.Decode(v) - if err != nil { - continue - } - if enc.base.Encode(c) != v { - enc.override[c] = v - } - c2 := cidutil.TryOtherCidVersion(c) - if c2.Defined() && enc.base.Encode(c2) != v { - enc.override[c2] = v - } - } -} - -func (enc WithOverride) Encode(c cid.Cid) string { - v, ok := enc.override[c] - if ok { - return v - } - return enc.base.Encode(c) -} - -func (enc WithOverride) Recode(v string) (string, error) { - if len(enc.override) == 0 { - return enc.base.Recode(v) - } - c, err := cid.Decode(v) - if err != nil { - return v, err - } - - return enc.Encode(c), nil -} - type encoderKey struct{} // Enable "enables" the encoder in the context using WithValue diff --git a/package.json b/package.json index f58dc30..4ae8f88 100644 --- a/package.json +++ b/package.json @@ -22,12 +22,6 @@ "hash": "QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw", "name": "go-cid", "version": "0.9.1" - }, - { - "author": "why", - "hash": "QmVi2uUygezqaMTqs3Yzt5FcZFHJoYD4B7jQ2BELjj7ZuY", - "name": "go-path", - "version": "1.1.23" } ], "gxVersion": "0.12.1", From bfec35979f84518645b607d7177b2628d40ff9e9 Mon Sep 17 00:00:00 2001 From: Kevin Atkinson Date: Sun, 25 Nov 2018 23:51:56 -0500 Subject: [PATCH 10/10] gx publish 0.1.4 --- .gx/lastpubver | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gx/lastpubver b/.gx/lastpubver index 5474267..a19ded8 100644 --- a/.gx/lastpubver +++ b/.gx/lastpubver @@ -1 +1 @@ -0.1.3: QmVjZoEZg2oxXGFGjbD28x3gGN6ALHAW6BN2LKRUcaJ21i +0.1.4: QmckgkstbdXagMTQ4e1DW2SzxGcjjudbqEvA5H2Rb7uvAT diff --git a/package.json b/package.json index 4ae8f88..87ef6e4 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,6 @@ "license": "", "name": "go-cidutil", "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", - "version": "0.1.3" + "version": "0.1.4" }