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-codec-dagpb
Commits
e34a566d
Unverified
Commit
e34a566d
authored
Sep 28, 2020
by
Rod Vagg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
make it so
parents
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
581 additions
and
0 deletions
+581
-0
compat_test.go
compat_test.go
+291
-0
dagpb.go
dagpb.go
+14
-0
marshal.go
marshal.go
+109
-0
unmarshal.go
unmarshal.go
+167
-0
No files found.
compat_test.go
0 → 100644
View file @
e34a566d
package
dagpb
// mirrored in JavaScript @ https://github.com/ipld/js-dag-pb/blob/master/test/test-compat.js
import
(
"encoding/hex"
"encoding/json"
"testing"
)
var
dataZero
[]
byte
=
make
([]
byte
,
0
)
var
dataSome
[]
byte
=
[]
byte
{
0
,
1
,
2
,
3
,
4
}
var
cidBytes
[]
byte
=
[]
byte
{
1
,
85
,
0
,
5
,
0
,
1
,
2
,
3
,
4
}
var
zeroName
string
=
""
var
someName
string
=
"some name"
var
zeroTsize
uint64
=
0
var
someTsize
uint64
=
1010
var
largeTsize
uint64
=
9007199254740991
// JavaScript Number.MAX_SAFE_INTEGER
type
testCase
struct
{
name
string
node
*
PBNode
expectedBytes
string
expectedForm
string
}
var
testCases
=
[]
testCase
{
{
name
:
"empty"
,
node
:
&
PBNode
{},
expectedBytes
:
""
,
expectedForm
:
"{}"
,
},
{
name
:
"Data zero"
,
node
:
&
PBNode
{
Data
:
dataZero
},
expectedBytes
:
"0a00"
,
expectedForm
:
`{
"Data": ""
}`
,
},
{
name
:
"Data some"
,
node
:
&
PBNode
{
Data
:
dataSome
},
expectedBytes
:
"0a050001020304"
,
expectedForm
:
`{
"Data": "0001020304"
}`
,
},
{
name
:
"Links zero"
,
node
:
&
PBNode
{
Links
:
make
([]
*
PBLink
,
0
)},
expectedBytes
:
""
,
expectedForm
:
"{}"
,
},
{
name
:
"Data some Links zero"
,
node
:
&
PBNode
{
Data
:
dataSome
,
Links
:
make
([]
*
PBLink
,
0
)},
expectedBytes
:
"0a050001020304"
,
expectedForm
:
`{
"Data": "0001020304"
}`
,
},
{
name
:
"Links empty"
,
node
:
&
PBNode
{
Links
:
[]
*
PBLink
{{}}},
expectedBytes
:
"1200"
,
expectedForm
:
`{
"Links": [
{}
]
}`
,
},
{
name
:
"Data some Links empty"
,
node
:
&
PBNode
{
Data
:
dataSome
,
Links
:
[]
*
PBLink
{{}}},
expectedBytes
:
"12000a050001020304"
,
expectedForm
:
`{
"Data": "0001020304",
"Links": [
{}
]
}`
,
},
{
name
:
"Links Hash zero"
,
node
:
&
PBNode
{
Links
:
[]
*
PBLink
{{
Hash
:
dataZero
}}},
expectedBytes
:
"12020a00"
,
expectedForm
:
`{
"Links": [
{
"Hash": ""
}
]
}`
,
},
{
name
:
"Links Hash some"
,
node
:
&
PBNode
{
Links
:
[]
*
PBLink
{{
Hash
:
cidBytes
}}},
expectedBytes
:
"120b0a09015500050001020304"
,
expectedForm
:
`{
"Links": [
{
"Hash": "015500050001020304"
}
]
}`
,
},
{
name
:
"Links Name zero"
,
node
:
&
PBNode
{
Links
:
[]
*
PBLink
{{
Name
:
&
zeroName
}}},
expectedBytes
:
"12021200"
,
expectedForm
:
`{
"Links": [
{
"Name": ""
}
]
}`
,
},
{
name
:
"Links Hash some Name zero"
,
node
:
&
PBNode
{
Links
:
[]
*
PBLink
{{
Hash
:
cidBytes
,
Name
:
&
zeroName
}}},
expectedBytes
:
"120d0a090155000500010203041200"
,
expectedForm
:
`{
"Links": [
{
"Hash": "015500050001020304",
"Name": ""
}
]
}`
,
},
{
name
:
"Links Name some"
,
node
:
&
PBNode
{
Links
:
[]
*
PBLink
{{
Name
:
&
someName
}}},
expectedBytes
:
"120b1209736f6d65206e616d65"
,
expectedForm
:
`{
"Links": [
{
"Name": "some name"
}
]
}`
,
},
{
name
:
"Links Hash some Name some"
,
node
:
&
PBNode
{
Links
:
[]
*
PBLink
{{
Hash
:
cidBytes
,
Name
:
&
someName
}}},
expectedBytes
:
"12160a090155000500010203041209736f6d65206e616d65"
,
expectedForm
:
`{
"Links": [
{
"Hash": "015500050001020304",
"Name": "some name"
}
]
}`
,
},
{
name
:
"Links Tsize zero"
,
node
:
&
PBNode
{
Links
:
[]
*
PBLink
{{
Tsize
:
&
zeroTsize
}}},
expectedBytes
:
"12021800"
,
expectedForm
:
`{
"Links": [
{
"Tsize": 0
}
]
}`
,
},
{
name
:
"Links Hash some Tsize zero"
,
node
:
&
PBNode
{
Links
:
[]
*
PBLink
{{
Hash
:
cidBytes
,
Tsize
:
&
zeroTsize
}}},
expectedBytes
:
"120d0a090155000500010203041800"
,
expectedForm
:
`{
"Links": [
{
"Hash": "015500050001020304",
"Tsize": 0
}
]
}`
,
},
{
name
:
"Links Tsize some"
,
node
:
&
PBNode
{
Links
:
[]
*
PBLink
{{
Tsize
:
&
someTsize
}}},
expectedBytes
:
"120318f207"
,
expectedForm
:
`{
"Links": [
{
"Tsize": 1010
}
]
}`
,
},
{
name
:
"Links Hash some Tsize some"
,
node
:
&
PBNode
{
Links
:
[]
*
PBLink
{{
Hash
:
cidBytes
,
Tsize
:
&
largeTsize
}}},
expectedBytes
:
"12140a0901550005000102030418ffffffffffffff0f"
,
expectedForm
:
`{
"Links": [
{
"Hash": "015500050001020304",
"Tsize": 9007199254740991
}
]
}`
,
},
}
func
TestCompat
(
t
*
testing
.
T
)
{
for
_
,
tc
:=
range
testCases
{
t
.
Run
(
tc
.
name
,
func
(
t
*
testing
.
T
)
{
verifyRoundTrip
(
t
,
tc
)
})
}
}
func
verifyRoundTrip
(
t
*
testing
.
T
,
tc
testCase
)
{
actualBytes
,
actualForm
,
err
:=
nodeRoundTripToString
(
t
,
tc
.
node
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
actualBytes
!=
tc
.
expectedBytes
{
t
.
Logf
(
"Expected bytes: [%v]
\n
Got: [%v]
\n
"
,
tc
.
expectedBytes
,
actualBytes
)
t
.
Error
(
"Did not match"
)
}
if
actualForm
!=
tc
.
expectedForm
{
t
.
Logf
(
"Expected form: [%v]
\n
Got: [%v]
\n
"
,
tc
.
expectedForm
,
actualForm
)
t
.
Error
(
"Did not match"
)
}
}
func
nodeRoundTripToString
(
t
*
testing
.
T
,
n
*
PBNode
)
(
string
,
string
,
error
)
{
bytes
,
err
:=
n
.
Marshal
()
if
err
!=
nil
{
return
""
,
""
,
err
}
t
.
Logf
(
"[%v]
\n
"
,
hex
.
EncodeToString
(
bytes
))
rt
:=
new
(
PBNode
)
if
err
:=
rt
.
Unmarshal
(
bytes
);
err
!=
nil
{
return
""
,
""
,
err
}
str
,
err
:=
json
.
MarshalIndent
(
cleanPBNode
(
t
,
rt
),
""
,
"
\t
"
)
if
err
!=
nil
{
return
""
,
""
,
err
}
return
hex
.
EncodeToString
(
bytes
),
string
(
str
),
nil
}
// convert a PBLink into a map for clean JSON marshalling
func
cleanPBLink
(
t
*
testing
.
T
,
link
*
PBLink
)
map
[
string
]
interface
{}
{
if
link
==
nil
{
return
nil
}
nl
:=
make
(
map
[
string
]
interface
{})
if
link
.
Hash
!=
nil
{
nl
[
"Hash"
]
=
hex
.
EncodeToString
(
link
.
Hash
)
}
if
link
.
Name
!=
nil
{
nl
[
"Name"
]
=
link
.
Name
}
if
link
.
Tsize
!=
nil
{
nl
[
"Tsize"
]
=
link
.
Tsize
}
return
nl
}
// convert a PBNode into a map for clean JSON marshalling
func
cleanPBNode
(
t
*
testing
.
T
,
node
*
PBNode
)
map
[
string
]
interface
{}
{
nn
:=
make
(
map
[
string
]
interface
{})
if
node
.
Data
!=
nil
{
nn
[
"Data"
]
=
hex
.
EncodeToString
(
node
.
Data
)
}
if
node
.
Links
!=
nil
{
links
:=
make
([]
map
[
string
]
interface
{},
len
(
node
.
Links
))
for
i
,
l
:=
range
node
.
Links
{
links
[
i
]
=
cleanPBLink
(
t
,
l
)
}
nn
[
"Links"
]
=
links
}
return
nn
}
dagpb.go
0 → 100644
View file @
e34a566d
package
dagpb
// PBLink ...
type
PBLink
struct
{
Hash
[]
byte
Name
*
string
Tsize
*
uint64
}
// PBNode ...
type
PBNode
struct
{
Links
[]
*
PBLink
Data
[]
byte
}
marshal.go
0 → 100644
View file @
e34a566d
package
dagpb
// based on the original pb codegen
import
(
math_bits
"math/bits"
)
// Marshal TODO
func
(
m
*
PBNode
)
Marshal
()
(
data
[]
byte
,
err
error
)
{
size
:=
m
.
size
()
data
=
make
([]
byte
,
size
)
i
:=
len
(
data
)
if
m
.
Data
!=
nil
{
i
-=
len
(
m
.
Data
)
copy
(
data
[
i
:
],
m
.
Data
)
i
=
encodeVarint
(
data
,
i
,
uint64
(
len
(
m
.
Data
)))
-
1
data
[
i
]
=
0xa
}
if
len
(
m
.
Links
)
>
0
{
for
iNdEx
:=
len
(
m
.
Links
)
-
1
;
iNdEx
>=
0
;
iNdEx
--
{
size
,
err
:=
m
.
Links
[
iNdEx
]
.
marshal
(
data
[
:
i
])
if
err
!=
nil
{
return
nil
,
err
}
i
-=
size
i
=
encodeVarint
(
data
,
i
,
uint64
(
size
))
-
1
data
[
i
]
=
0x12
}
}
return
data
[
:
size
],
nil
}
func
(
m
*
PBLink
)
marshal
(
data
[]
byte
)
(
int
,
error
)
{
i
:=
len
(
data
)
if
m
.
Tsize
!=
nil
{
i
=
encodeVarint
(
data
,
i
,
uint64
(
*
m
.
Tsize
))
-
1
data
[
i
]
=
0x18
}
if
m
.
Name
!=
nil
{
i
-=
len
(
*
m
.
Name
)
copy
(
data
[
i
:
],
*
m
.
Name
)
i
=
encodeVarint
(
data
,
i
,
uint64
(
len
(
*
m
.
Name
)))
-
1
data
[
i
]
=
0x12
}
if
m
.
Hash
!=
nil
{
i
-=
len
(
m
.
Hash
)
copy
(
data
[
i
:
],
m
.
Hash
)
i
=
encodeVarint
(
data
,
i
,
uint64
(
len
(
m
.
Hash
)))
-
1
data
[
i
]
=
0xa
}
return
len
(
data
)
-
i
,
nil
}
func
(
m
*
PBLink
)
size
()
(
n
int
)
{
if
m
==
nil
{
return
0
}
var
l
int
_
=
l
if
m
.
Hash
!=
nil
{
l
=
len
(
m
.
Hash
)
n
+=
1
+
l
+
sizeOfVarint
(
uint64
(
l
))
}
if
m
.
Name
!=
nil
{
l
=
len
(
*
m
.
Name
)
n
+=
1
+
l
+
sizeOfVarint
(
uint64
(
l
))
}
if
m
.
Tsize
!=
nil
{
n
+=
1
+
sizeOfVarint
(
uint64
(
*
m
.
Tsize
))
}
return
n
}
func
(
m
*
PBNode
)
size
()
(
n
int
)
{
if
m
==
nil
{
return
0
}
var
l
int
_
=
l
if
m
.
Data
!=
nil
{
l
=
len
(
m
.
Data
)
n
+=
1
+
l
+
sizeOfVarint
(
uint64
(
l
))
}
if
len
(
m
.
Links
)
>
0
{
for
_
,
e
:=
range
m
.
Links
{
l
=
e
.
size
()
n
+=
1
+
l
+
sizeOfVarint
(
uint64
(
l
))
}
}
return
n
}
func
encodeVarint
(
data
[]
byte
,
offset
int
,
v
uint64
)
int
{
offset
-=
sizeOfVarint
(
v
)
base
:=
offset
for
v
>=
1
<<
7
{
data
[
offset
]
=
uint8
(
v
&
0x7f
|
0x80
)
v
>>=
7
offset
++
}
data
[
offset
]
=
uint8
(
v
)
return
base
}
func
sizeOfVarint
(
x
uint64
)
(
n
int
)
{
return
(
math_bits
.
Len64
(
x
|
1
)
+
6
)
/
7
}
unmarshal.go
0 → 100644
View file @
e34a566d
package
dagpb
import
(
"fmt"
"io"
)
// Unmarshal TODO
func
(
node
*
PBNode
)
Unmarshal
(
data
[]
byte
)
error
{
var
err
error
var
fieldNum
,
wireType
int
l
:=
len
(
data
)
index
:=
0
for
index
<
l
{
if
fieldNum
,
wireType
,
index
,
err
=
decodeKey
(
data
,
index
);
err
!=
nil
{
return
err
}
if
wireType
!=
2
{
return
fmt
.
Errorf
(
"protobuf: (PBNode) invalid wireType, expected 2, got %d"
,
wireType
)
}
if
fieldNum
==
1
{
if
node
.
Data
!=
nil
{
return
fmt
.
Errorf
(
"protobuf: (PBNode) duplicate Data section"
)
}
if
node
.
Data
,
index
,
err
=
decodeBytes
(
data
,
index
);
err
!=
nil
{
return
err
}
}
else
if
fieldNum
==
2
{
if
node
.
Data
!=
nil
{
return
fmt
.
Errorf
(
"protobuf: (PBNode) invalid order, found Data before Links content"
)
}
var
chunk
[]
byte
if
chunk
,
index
,
err
=
decodeBytes
(
data
,
index
);
err
!=
nil
{
return
err
}
node
.
Links
=
append
(
node
.
Links
,
&
PBLink
{})
if
err
:=
node
.
Links
[
len
(
node
.
Links
)
-
1
]
.
unmarshal
(
chunk
);
err
!=
nil
{
return
err
}
}
else
{
return
fmt
.
Errorf
(
"protobuf: (PBNode) invalid fieldNumber, expected 1 or 2, got %d"
,
fieldNum
)
}
}
if
index
>
l
{
return
io
.
ErrUnexpectedEOF
}
return
nil
}
func
(
link
*
PBLink
)
unmarshal
(
data
[]
byte
)
error
{
var
err
error
var
fieldNum
,
wireType
int
l
:=
len
(
data
)
index
:=
0
for
index
<
l
{
if
fieldNum
,
wireType
,
index
,
err
=
decodeKey
(
data
,
index
);
err
!=
nil
{
return
err
}
if
fieldNum
==
1
{
if
link
.
Hash
!=
nil
{
return
fmt
.
Errorf
(
"protobuf: (PBLink) duplicate Hash section"
)
}
if
link
.
Name
!=
nil
{
return
fmt
.
Errorf
(
"protobuf: (PBLink) invalid order, found Name before Hash"
)
}
if
link
.
Tsize
!=
nil
{
return
fmt
.
Errorf
(
"protobuf: (PBLink) invalid order, found Tsize before Hash"
)
}
if
wireType
!=
2
{
return
fmt
.
Errorf
(
"protobuf: (PBLink) wrong wireType (%d) for Hash"
,
wireType
)
}
if
link
.
Hash
,
index
,
err
=
decodeBytes
(
data
,
index
);
err
!=
nil
{
return
err
}
}
else
if
fieldNum
==
2
{
if
link
.
Name
!=
nil
{
return
fmt
.
Errorf
(
"protobuf: (PBLink) duplicate Name section"
)
}
if
link
.
Tsize
!=
nil
{
return
fmt
.
Errorf
(
"protobuf: (PBLink) invalid order, found Tsize before Name"
)
}
if
wireType
!=
2
{
return
fmt
.
Errorf
(
"protobuf: (PBLink) wrong wireType (%d) for Name"
,
wireType
)
}
var
chunk
[]
byte
if
chunk
,
index
,
err
=
decodeBytes
(
data
,
index
);
err
!=
nil
{
return
err
}
s
:=
string
(
chunk
)
link
.
Name
=
&
s
}
else
if
fieldNum
==
3
{
if
link
.
Tsize
!=
nil
{
return
fmt
.
Errorf
(
"protobuf: (PBLink) duplicate Tsize section"
)
}
if
wireType
!=
0
{
return
fmt
.
Errorf
(
"protobuf: (PBLink) wrong wireType (%d) for Tsize"
,
wireType
)
}
var
v
uint64
if
v
,
index
,
err
=
decodeVarint
(
data
,
index
);
err
!=
nil
{
return
err
}
link
.
Tsize
=
&
v
}
else
{
return
fmt
.
Errorf
(
"protobuf: (PBLink) invalid fieldNumber, expected 1, 2 or 3, got %d"
,
fieldNum
)
}
}
if
index
>
l
{
return
io
.
ErrUnexpectedEOF
}
return
nil
}
func
decodeKey
(
data
[]
byte
,
offset
int
)
(
int
,
int
,
int
,
error
)
{
var
wire
uint64
var
err
error
if
wire
,
offset
,
err
=
decodeVarint
(
data
,
offset
);
err
!=
nil
{
return
0
,
0
,
0
,
err
}
fieldNum
:=
int
(
wire
>>
3
)
wireType
:=
int
(
wire
&
0x7
)
return
fieldNum
,
wireType
,
offset
,
nil
}
func
decodeBytes
(
data
[]
byte
,
offset
int
)
([]
byte
,
int
,
error
)
{
var
bytesLen
uint64
var
err
error
if
bytesLen
,
offset
,
err
=
decodeVarint
(
data
,
offset
);
err
!=
nil
{
return
nil
,
0
,
err
}
postOffset
:=
offset
+
int
(
bytesLen
)
if
postOffset
>
len
(
data
)
{
return
nil
,
0
,
io
.
ErrUnexpectedEOF
}
return
data
[
offset
:
postOffset
],
postOffset
,
nil
}
func
decodeVarint
(
data
[]
byte
,
offset
int
)
(
uint64
,
int
,
error
)
{
var
v
uint64
l
:=
len
(
data
)
for
shift
:=
uint
(
0
);
;
shift
+=
7
{
if
shift
>=
64
{
return
0
,
0
,
ErrIntOverflow
}
if
offset
>=
l
{
return
0
,
0
,
io
.
ErrUnexpectedEOF
}
b
:=
data
[
offset
]
offset
++
v
|=
uint64
(
b
&
0x7F
)
<<
shift
if
b
<
0x80
{
break
}
}
return
v
,
offset
,
nil
}
// ErrIntOverflow TODO
var
ErrIntOverflow
=
fmt
.
Errorf
(
"protobuf: varint overflow"
)
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