aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ber/base128.go14
-rw-r--r--ber/class.go37
-rw-r--r--ber/class_test.go7
-rw-r--r--ber/dump.go17
-rw-r--r--ber/len.go24
-rw-r--r--ber/len_test.go2
-rw-r--r--ber/packet.go19
7 files changed, 71 insertions, 49 deletions
diff --git a/ber/base128.go b/ber/base128.go
index 4777651..bf894bb 100644
--- a/ber/base128.go
+++ b/ber/base128.go
@@ -1,5 +1,7 @@
package ber
+import "io"
+
func base128(n int) (b []byte) {
if n == 0 {
return []byte{0}
@@ -29,3 +31,15 @@ func debase128(b []byte) (i, n int) {
}
return
}
+
+func Debase128(r io.ByteReader) (i int) {
+ for {
+ b, _ := r.ReadByte()
+ i <<= 7
+ i |= int(b & 0x7f)
+ if b&0x80 == 0 {
+ return
+ }
+ }
+ return
+}
diff --git a/ber/class.go b/ber/class.go
index b734964..ab455f1 100644
--- a/ber/class.go
+++ b/ber/class.go
@@ -1,5 +1,7 @@
package ber
+import "io"
+
type Class byte
const (
@@ -105,36 +107,15 @@ var tagNames = map[Tag]string{
func (t Tag) String() string { return tagNames[t] }
-func Ident(b []byte) (Class, Kind, Tag, int) {
- var d, n int
- c := Class(b[0]) & classMask
- k := Kind(b[0]) & kindMask
- t := Tag(b[0]) & tagMask
+func Ident(r io.ByteReader) (Class, Kind, Tag) {
+ b, _ := r.ReadByte()
+ c := Class(b) & classMask
+ k := Kind(b) & kindMask
+ t := Tag(b) & tagMask
if t == tagMask {
- d, n = debase128(b[1:])
- t = Tag(d)
+ t = Tag(Debase128(r))
}
- return c, k, t, n + 1
-}
-
-func Unversal(b []byte) (int, bool) {
- c, _, t, _ := Ident(b)
- return int(t), c == classUniversal
-}
-
-func Application(b []byte) (int, bool) {
- c, _, t, _ := Ident(b)
- return int(t), c == classApplication
-}
-
-func ContextSpecific(b []byte) (int, bool) {
- c, _, t, _ := Ident(b)
- return int(t), c == classContextSpecific
-}
-
-func Private(b []byte) (int, bool) {
- c, _, t, _ := Ident(b)
- return int(t), c == classPrivate
+ return c, k, t
}
func MarshalClass(c Class, k Kind, t Tag) []byte {
diff --git a/ber/class_test.go b/ber/class_test.go
index a0b2569..2eac220 100644
--- a/ber/class_test.go
+++ b/ber/class_test.go
@@ -1,6 +1,9 @@
package ber
-import "fmt"
+import (
+ "bytes"
+ "fmt"
+)
var berTestData = []byte{
0x02, 0x04, 0x0A, 0x30,
@@ -10,7 +13,7 @@ var berTestData = []byte{
func ExampleIdent() {
for _, test := range berTestData {
- c, k, t, _ := Ident([]byte{test})
+ c, k, t := Ident(bytes.NewBuffer([]byte{test}))
if c == classUniversal {
fmt.Printf("%#x: %v %v %v\n",
test, c, k, t)
diff --git a/ber/dump.go b/ber/dump.go
index 64a2672..da2c8bf 100644
--- a/ber/dump.go
+++ b/ber/dump.go
@@ -1,9 +1,12 @@
package ber
-import "fmt"
+import (
+ "bytes"
+ "fmt"
+)
func Dump(b []byte) string {
- return dump(b, 0)
+ return dump(bytes.NewBuffer(b), 0)
}
func short(b []byte) string {
@@ -13,8 +16,8 @@ func short(b []byte) string {
return fmt.Sprint(b)
}
-func dump(b []byte, indent int) (s string) {
- class, kind, tag, _, value, rest := Split(b)
+func dump(r *bytes.Buffer, indent int) (s string) {
+ class, kind, tag, _, value := Split(r)
s += fmt.Sprintf("%*s", indent*2, "")
@@ -39,11 +42,11 @@ func dump(b []byte, indent int) (s string) {
}
if len(value) > 0 && kind != kindPrimitive {
- s += dump(value, indent+1)
+ s += dump(bytes.NewBuffer(value), indent+1)
}
- if len(rest) > 0 {
- s += dump(rest, indent)
+ if r.Len() > 0 {
+ s += dump(r, indent)
}
return
}
diff --git a/ber/len.go b/ber/len.go
index 67aff34..2bccf59 100644
--- a/ber/len.go
+++ b/ber/len.go
@@ -1,12 +1,30 @@
package ber
-func UnmarshalLen(b []byte) (i, n int) {
+import (
+ "io"
+)
+
+func UnmarshalLen(r io.ByteReader) int {
+ b, _ := r.ReadByte()
+ if b&0x80 == 0 {
+ return int(b)
+ }
+ n := int(b & 0x7f)
+ var i int
+ for k := 0; k <= n; k++ {
+ b, _ := r.ReadByte()
+ i |= int(b) << uint(k*8)
+ }
+ return i
+}
+
+func unmarshalLen(b []byte) (i, n int) {
if b[0]&0x80 == 0 {
return int(b[0]), 1
}
n = int(b[0] & 0x7f)
- for k := n; k > 0; k-- {
- i += int(b[k]) << uint((k-1)*8)
+ for k := 0; k <= n; k++ {
+ i |= int(b[k]) << uint((k-1)*8)
}
return i, n + 1
}
diff --git a/ber/len_test.go b/ber/len_test.go
index ea40453..2db6453 100644
--- a/ber/len_test.go
+++ b/ber/len_test.go
@@ -24,7 +24,7 @@ func TestLen(t *testing.T) {
if !bytes.Equal(a, test.out) {
t.Error(test.in, "expected", test.out, "got", a)
}
- n, _ := UnmarshalLen(test.out)
+ n := UnmarshalLen(bytes.NewBuffer(test.out))
if n != test.in {
t.Error(test.out, "expected", test.in, "got", n)
}
diff --git a/ber/packet.go b/ber/packet.go
index f244c4e..ea90240 100644
--- a/ber/packet.go
+++ b/ber/packet.go
@@ -1,12 +1,15 @@
package ber
-func Split(b []byte) (c Class, k Kind, t Tag, l int, v []byte, r []byte) {
- var n int
- c, k, t, n = Ident(b)
- b = b[n:]
- l, n = UnmarshalLen(b)
- b = b[n:]
- v = b[:l]
- r = b[l:]
+import "io"
+
+func Split(r io.ByteReader) (c Class, k Kind, t Tag, l int, v []byte) {
+ c, k, t = Ident(r)
+ l = UnmarshalLen(r)
+ if l > 0 {
+ v = make([]byte, l)
+ for i := 0; i < l; i++ {
+ v[i], _ = r.ReadByte()
+ }
+ }
return
}