Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
ld
go-ld-prime
Commits
8fcc6767
Commit
8fcc6767
authored
Mar 12, 2021
by
Eric Myhre
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Multicodec registry now guarded by functions.
parent
08f13e56
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
99 additions
and
32 deletions
+99
-32
codec/dagcbor/multicodec.go
codec/dagcbor/multicodec.go
+2
-2
codec/dagjson/multicodec.go
codec/dagjson/multicodec.go
+2
-2
linking/cid/linksystem.go
linking/cid/linksystem.go
+6
-6
multicodec/multicodec.go
multicodec/multicodec.go
+89
-22
No files found.
codec/dagcbor/multicodec.go
View file @
8fcc6767
...
...
@@ -15,8 +15,8 @@ var (
)
func
init
()
{
multicodec
.
EncoderRegistry
[
0x71
]
=
Encode
multicodec
.
DecoderRegistry
[
0x71
]
=
Decode
multicodec
.
RegisterEncoder
(
0x71
,
Encode
)
multicodec
.
RegisterDecoder
(
0x71
,
Decode
)
}
func
Decode
(
na
ipld
.
NodeAssembler
,
r
io
.
Reader
)
error
{
...
...
codec/dagjson/multicodec.go
View file @
8fcc6767
...
...
@@ -16,8 +16,8 @@ var (
)
func
init
()
{
multicodec
.
EncoderRegistry
[
0x0129
]
=
Encode
multicodec
.
DecoderRegistry
[
0x0129
]
=
Decode
multicodec
.
RegisterEncoder
(
0x0129
,
Encode
)
multicodec
.
RegisterDecoder
(
0x0129
,
Decode
)
}
func
Decode
(
na
ipld
.
NodeAssembler
,
r
io
.
Reader
)
error
{
...
...
linking/cid/linksystem.go
View file @
8fcc6767
...
...
@@ -15,9 +15,9 @@ func DefaultLinkSystem() ipld.LinkSystem {
EncoderChooser
:
func
(
lp
ipld
.
LinkPrototype
)
(
ipld
.
Encoder
,
error
)
{
switch
lp2
:=
lp
.
(
type
)
{
case
LinkPrototype
:
fn
,
ok
:=
multicodec
.
Encoder
Registry
[
lp2
.
GetCodec
()
]
if
!
ok
{
return
nil
,
fmt
.
Errorf
(
"no encoder registered for multicodec indicator 0x%x"
,
lp2
.
GetCodec
())
fn
,
err
:=
multicodec
.
Lookup
Encoder
(
lp2
.
GetCodec
()
)
if
err
!=
nil
{
return
nil
,
err
}
return
fn
,
nil
default
:
...
...
@@ -28,9 +28,9 @@ func DefaultLinkSystem() ipld.LinkSystem {
lp
:=
lnk
.
Prototype
()
switch
lp2
:=
lp
.
(
type
)
{
case
LinkPrototype
:
fn
,
ok
:=
multicodec
.
Decoder
Registry
[
lp2
.
GetCodec
()
]
if
!
ok
{
return
nil
,
fmt
.
Errorf
(
"no decoder registered for multicodec indicator 0x%x"
,
lp2
.
GetCodec
())
fn
,
err
:=
multicodec
.
Lookup
Decoder
(
lp2
.
GetCodec
()
)
if
err
!=
nil
{
return
nil
,
err
}
return
fn
,
nil
default
:
...
...
multicodec/multicodec.go
View file @
8fcc6767
package
multicodec
import
(
"fmt"
"github.com/ipld/go-ipld-prime"
)
// EncoderRegistry is a simple map which maps a multicodec indicator number
// to an ipld.Encoder function.
var
encoderRegistry
=
make
(
map
[
uint64
]
ipld
.
Encoder
)
var
decoderRegistry
=
make
(
map
[
uint64
]
ipld
.
Decoder
)
// RegisterEncoder updates a simple map of multicodec indicator number to ipld.Encoder function.
// The encoder functions registered can be subsequently looked up using LookupEncoder.
//
// Packages which implement an IPLD codec and have a multicodec number reserved in
// https://github.com/multiformats/multicodec/blob/master/table.csv
// are encouraged to register themselves in this map at package init time.
// (Doing this at package init time ensures this map can be accessed without race conditions.)
//
// The linking/cid.DefaultLinkSystem will use this map to find encoders
// to use when serializing data for linking and storage.
//
// This registry map is only used for default behaviors.
// If you don't want to rely on it, you can always construct your own LinkSystem.
// (For this reason, there's no special effort made to detect conflicting registrations in this map.
// If more than one package registers for the same multicodec indicator, and
// you somehow end up with both in your import tree, and yet care about which wins:
// then just don't use this registry anymore: make a LinkSystem that does what you need.)
var
EncoderRegistry
=
make
(
map
[
uint64
]
ipld
.
Encoder
)
// For example, linking/cid.DefaultLinkSystem will use LookupEncoder to access this registry map
// and select encoders to use when serializing data for linking and storage.
// LinkSystem itself is not hardcoded to use the global LookupEncoder feature;
// therefore, you don't want to rely on this mapping, you can always construct your own LinkSystem.
//
// No effort is made to detect conflicting registrations in this map.
// If your dependency tree is such that this becomes a problem,
// there are two ways to address this:
// If RegisterEncoder is called with the same indicator code more than once, the last call wins.
// In practice, this means that if an application has a strong opinion about what implementation for a certain codec,
// then this can be done by making a Register call with that effect at init time in the application's main package.
// This should have the desired effect because the root of the import tree has its init time effect last.
// Alternatively, one can just avoid use of this registry entirely:
// do this by making a LinkSystem that uses a custom EncoderChooser function.
func
RegisterEncoder
(
indicator
uint64
,
encodeFunc
ipld
.
Encoder
)
{
// This function could arguably be just a bare map access.
// We introduced a function primarily for the interest of potential future changes.
// E.g. one could introduce logging here to help detect unintended conflicting registrations.
// (We probably won't do this, but you can do it yourself as a printf debug hack. :))
if
encodeFunc
==
nil
{
panic
(
"not sensible to attempt to register a nil function"
)
}
encoderRegistry
[
indicator
]
=
encodeFunc
}
// LookupEncoder yields an ipld.Encoder function matching a multicodec indicator code number.
//
// Multicodec indicator numbers are specified in
// https://github.com/multiformats/multicodec/blob/master/table.csv
//
// To be available from this lookup function, an encoder must have been registered
// for this indicator number by an earlier call to the RegisterEncoder function.
func
LookupEncoder
(
indicator
uint64
)
(
ipld
.
Encoder
,
error
)
{
encodeFunc
,
exists
:=
encoderRegistry
[
indicator
]
if
!
exists
{
return
nil
,
fmt
.
Errorf
(
"no encoder registered for multicodec code %d (0x%x)"
,
indicator
,
indicator
)
}
return
encodeFunc
,
nil
}
//
DecoderRegistry i
s a simple map
which maps a
multicodec indicator number
//
to an ipld.D
ecoder function.
//
RegisterDecoder update
s a simple map
of
multicodec indicator number
to ipld.Decoder function.
//
The d
ecoder function
s registered can be subsequently looked up using LookupDecoder
.
//
// Packages which implement an IPLD codec and have a multicodec number reserved in
// https://github.com/multiformats/multicodec/blob/master/table.csv
// are encouraged to register themselves in this map at package init time.
// (Doing this at package init time ensures this map can be accessed without race conditions.)
//
// The linking/cid.DefaultLinkSystem will use this map to find decoders
// to use when deserializing data from storage.
//
// This registry map is only used for default behaviors.
// If you don't want to rely on it, you can always construct your own LinkSystem.
// (For this reason, there's no special effort made to detect conflicting registrations in this map.
// If more than one package registers for the same multicodec indicator, and
// you somehow end up with both in your import tree, and yet care about which wins:
// then just don't use this registry anymore: make a LinkSystem that does what you need.)
var
DecoderRegistry
=
make
(
map
[
uint64
]
ipld
.
Decoder
)
// For example, linking/cid.DefaultLinkSystem will use LookupDecoder to access this registry map
// and select decoders to use when serializing data for linking and storage.
// LinkSystem itself is not hardcoded to use the global LookupDecoder feature;
// therefore, you don't want to rely on this mapping, you can always construct your own LinkSystem.
//
// No effort is made to detect conflicting registrations in this map.
// If your dependency tree is such that this becomes a problem,
// there are two ways to address this:
// If RegisterDecoder is called with the same indicator code more than once, the last call wins.
// In practice, this means that if an application has a strong opinion about what implementation for a certain codec,
// then this can be done by making a Register call with that effect at init time in the application's main package.
// This should have the desired effect because the root of the import tree has its init time effect last.
// Alternatively, one can just avoid use of this registry entirely:
// do this by making a LinkSystem that uses a custom DecoderChooser function.
func
RegisterDecoder
(
indicator
uint64
,
decodeFunc
ipld
.
Decoder
)
{
// This function could arguably be just a bare map access.
// We introduced a function primarily for the interest of potential future changes.
// E.g. one could introduce logging here to help detect unintended conflicting registrations.
// (We probably won't do this, but you can do it yourself as a printf debug hack. :))
if
decodeFunc
==
nil
{
panic
(
"not sensible to attempt to register a nil function"
)
}
decoderRegistry
[
indicator
]
=
decodeFunc
}
// LookupDecoder yields an ipld.Decoder function matching a multicodec indicator code number.
//
// Multicodec indicator numbers are specified in
// https://github.com/multiformats/multicodec/blob/master/table.csv
//
// To be available from this lookup function, an decoder must have been registered
// for this indicator number by an earlier call to the RegisterDecoder function.
func
LookupDecoder
(
indicator
uint64
)
(
ipld
.
Decoder
,
error
)
{
decodeFunc
,
exists
:=
decoderRegistry
[
indicator
]
if
!
exists
{
return
nil
,
fmt
.
Errorf
(
"no decoder registered for multicodec code %d (0x%x)"
,
indicator
,
indicator
)
}
return
decodeFunc
,
nil
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment