summaryrefslogtreecommitdiff
path: root/src/pkg/encoding
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-01-17 12:40:45 +0100
committerOndřej Surý <ondrej@sury.org>2011-01-17 12:40:45 +0100
commit3e45412327a2654a77944249962b3652e6142299 (patch)
treebc3bf69452afa055423cbe0c5cfa8ca357df6ccf /src/pkg/encoding
parentc533680039762cacbc37db8dc7eed074c3e497be (diff)
downloadgolang-upstream/2011.01.12.tar.gz
Imported Upstream version 2011.01.12upstream/2011.01.12
Diffstat (limited to 'src/pkg/encoding')
-rw-r--r--src/pkg/encoding/ascii85/Makefile2
-rw-r--r--src/pkg/encoding/ascii85/ascii85_test.go8
-rw-r--r--src/pkg/encoding/base64/Makefile2
-rw-r--r--src/pkg/encoding/base64/base64_test.go50
-rw-r--r--src/pkg/encoding/binary/Makefile2
-rw-r--r--src/pkg/encoding/binary/binary.go59
-rw-r--r--src/pkg/encoding/binary/binary_test.go82
-rw-r--r--src/pkg/encoding/git85/Makefile2
-rw-r--r--src/pkg/encoding/git85/git_test.go8
-rw-r--r--src/pkg/encoding/hex/Makefile2
-rw-r--r--src/pkg/encoding/hex/hex.go2
-rw-r--r--src/pkg/encoding/hex/hex_test.go112
-rw-r--r--src/pkg/encoding/line/Makefile11
-rw-r--r--src/pkg/encoding/line/line.go95
-rw-r--r--src/pkg/encoding/line/line_test.go89
-rw-r--r--src/pkg/encoding/pem/Makefile2
-rw-r--r--src/pkg/encoding/pem/pem.go13
-rw-r--r--src/pkg/encoding/pem/pem_test.go28
18 files changed, 424 insertions, 145 deletions
diff --git a/src/pkg/encoding/ascii85/Makefile b/src/pkg/encoding/ascii85/Makefile
index 7ec14bd1a..412383efd 100644
--- a/src/pkg/encoding/ascii85/Makefile
+++ b/src/pkg/encoding/ascii85/Makefile
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
-include ../../../Make.$(GOARCH)
+include ../../../Make.inc
TARG=encoding/ascii85
GOFILES=\
diff --git a/src/pkg/encoding/ascii85/ascii85_test.go b/src/pkg/encoding/ascii85/ascii85_test.go
index 738e1cc1b..fdfeb889f 100644
--- a/src/pkg/encoding/ascii85/ascii85_test.go
+++ b/src/pkg/encoding/ascii85/ascii85_test.go
@@ -17,7 +17,7 @@ type testpair struct {
var pairs = []testpair{
// Wikipedia example
- testpair{
+ {
"Man is distinguished, not only by his reason, but by this singular passion from " +
"other animals, which is a lust of the mind, that by a perseverance of delight in " +
"the continued and indefatigable generation of knowledge, exceeds the short " +
@@ -34,7 +34,7 @@ var bigtest = pairs[len(pairs)-1]
func testEqual(t *testing.T, msg string, args ...interface{}) bool {
if args[len(args)-2] != args[len(args)-1] {
- t.Errorf(msg, args)
+ t.Errorf(msg, args...)
return false
}
return true
@@ -138,8 +138,8 @@ func TestDecodeCorrupt(t *testing.T) {
p int
}
examples := []corrupt{
- corrupt{"v", 0},
- corrupt{"!z!!!!!!!!!", 1},
+ {"v", 0},
+ {"!z!!!!!!!!!", 1},
}
for _, e := range examples {
diff --git a/src/pkg/encoding/base64/Makefile b/src/pkg/encoding/base64/Makefile
index 8503b1663..2f54ed839 100644
--- a/src/pkg/encoding/base64/Makefile
+++ b/src/pkg/encoding/base64/Makefile
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
-include ../../../Make.$(GOARCH)
+include ../../../Make.inc
TARG=encoding/base64
GOFILES=\
diff --git a/src/pkg/encoding/base64/base64_test.go b/src/pkg/encoding/base64/base64_test.go
index c14785f1b..de41e704b 100644
--- a/src/pkg/encoding/base64/base64_test.go
+++ b/src/pkg/encoding/base64/base64_test.go
@@ -17,28 +17,28 @@ type testpair struct {
var pairs = []testpair{
// RFC 3548 examples
- testpair{"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l+"},
- testpair{"\x14\xfb\x9c\x03\xd9", "FPucA9k="},
- testpair{"\x14\xfb\x9c\x03", "FPucAw=="},
+ {"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l+"},
+ {"\x14\xfb\x9c\x03\xd9", "FPucA9k="},
+ {"\x14\xfb\x9c\x03", "FPucAw=="},
// RFC 4648 examples
- testpair{"", ""},
- testpair{"f", "Zg=="},
- testpair{"fo", "Zm8="},
- testpair{"foo", "Zm9v"},
- testpair{"foob", "Zm9vYg=="},
- testpair{"fooba", "Zm9vYmE="},
- testpair{"foobar", "Zm9vYmFy"},
+ {"", ""},
+ {"f", "Zg=="},
+ {"fo", "Zm8="},
+ {"foo", "Zm9v"},
+ {"foob", "Zm9vYg=="},
+ {"fooba", "Zm9vYmE="},
+ {"foobar", "Zm9vYmFy"},
// Wikipedia examples
- testpair{"sure.", "c3VyZS4="},
- testpair{"sure", "c3VyZQ=="},
- testpair{"sur", "c3Vy"},
- testpair{"su", "c3U="},
- testpair{"leasure.", "bGVhc3VyZS4="},
- testpair{"easure.", "ZWFzdXJlLg=="},
- testpair{"asure.", "YXN1cmUu"},
- testpair{"sure.", "c3VyZS4="},
+ {"sure.", "c3VyZS4="},
+ {"sure", "c3VyZQ=="},
+ {"sur", "c3Vy"},
+ {"su", "c3U="},
+ {"leasure.", "bGVhc3VyZS4="},
+ {"easure.", "ZWFzdXJlLg=="},
+ {"asure.", "YXN1cmUu"},
+ {"sure.", "c3VyZS4="},
}
var bigtest = testpair{
@@ -48,7 +48,7 @@ var bigtest = testpair{
func testEqual(t *testing.T, msg string, args ...interface{}) bool {
if args[len(args)-2] != args[len(args)-1] {
- t.Errorf(msg, args)
+ t.Errorf(msg, args...)
return false
}
return true
@@ -142,12 +142,12 @@ func TestDecodeCorrupt(t *testing.T) {
p int
}
examples := []corrupt{
- corrupt{"!!!!", 0},
- corrupt{"x===", 1},
- corrupt{"AA=A", 2},
- corrupt{"AAA=AAAA", 3},
- corrupt{"AAAAA", 4},
- corrupt{"AAAAAA", 4},
+ {"!!!!", 0},
+ {"x===", 1},
+ {"AA=A", 2},
+ {"AAA=AAAA", 3},
+ {"AAAAA", 4},
+ {"AAAAAA", 4},
}
for _, e := range examples {
diff --git a/src/pkg/encoding/binary/Makefile b/src/pkg/encoding/binary/Makefile
index 23d4d6d43..dc46abe90 100644
--- a/src/pkg/encoding/binary/Makefile
+++ b/src/pkg/encoding/binary/Makefile
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
-include ../../../Make.$(GOARCH)
+include ../../../Make.inc
TARG=encoding/binary
GOFILES=\
diff --git a/src/pkg/encoding/binary/binary.go b/src/pkg/encoding/binary/binary.go
index 5a92faa21..6bbe7eb89 100644
--- a/src/pkg/encoding/binary/binary.go
+++ b/src/pkg/encoding/binary/binary.go
@@ -29,8 +29,11 @@ type ByteOrder interface {
// allowing, e.g., order == binary.LittleEndian.
type unused byte
-var LittleEndian ByteOrder = littleEndian(0)
-var BigEndian ByteOrder = bigEndian(0)
+// LittleEndian is the little-endian implementation of ByteOrder.
+var LittleEndian littleEndian
+
+// BigEndian is the big-endian implementation of ByteOrder.
+var BigEndian bigEndian
type littleEndian unused
@@ -115,11 +118,11 @@ func (bigEndian) GoString() string { return "binary.BigEndian" }
// Read reads structured binary data from r into data.
// Data must be a pointer to a fixed-size value or a slice
// of fixed-size values.
-// A fixed-size value is either a fixed-size integer
-// (int8, uint8, int16, uint16, ...) or an array or struct
-// containing only fixed-size values. Bytes read from
-// r are decoded using the specified byte order and written
-// to successive fields of the data.
+// A fixed-size value is either a fixed-size arithmetic
+// type (int8, uint8, int16, float32, complex64, ...)
+// or an array or struct containing only fixed-size values.
+// Bytes read from r are decoded using the specified byte order
+// and written to successive fields of the data.
func Read(r io.Reader, order ByteOrder, data interface{}) os.Error {
var v reflect.Value
switch d := reflect.NewValue(data).(type) {
@@ -145,11 +148,11 @@ func Read(r io.Reader, order ByteOrder, data interface{}) os.Error {
// Write writes the binary representation of data into w.
// Data must be a fixed-size value or a pointer to
// a fixed-size value.
-// A fixed-size value is either a fixed-size integer
-// (int8, uint8, int16, uint16, ...) or an array or struct
-// containing only fixed-size values. Bytes written to
-// w are encoded using the specified byte order and read
-// from successive fields of the data.
+// A fixed-size value is either a fixed-size arithmetic
+// type (int8, uint8, int16, float32, complex64, ...)
+// or an array or struct containing only fixed-size values.
+// Bytes written to w are encoded using the specified byte order
+// and read from successive fields of the data.
func Write(w io.Writer, order ByteOrder, data interface{}) os.Error {
v := reflect.Indirect(reflect.NewValue(data))
size := TotalSize(v)
@@ -194,7 +197,11 @@ func sizeof(v reflect.Type) int {
}
return sum
- case *reflect.UintType, *reflect.IntType, *reflect.FloatType:
+ case *reflect.UintType, *reflect.IntType, *reflect.FloatType, *reflect.ComplexType:
+ switch t := t.Kind(); t {
+ case reflect.Int, reflect.Uint, reflect.Uintptr, reflect.Float, reflect.Complex:
+ return -1
+ }
return int(v.Size())
}
return -1
@@ -320,6 +327,20 @@ func (d *decoder) value(v reflect.Value) {
case reflect.Float64:
v.Set(math.Float64frombits(d.uint64()))
}
+
+ case *reflect.ComplexValue:
+ switch v.Type().Kind() {
+ case reflect.Complex64:
+ v.Set(cmplx(
+ float64(math.Float32frombits(d.uint32())),
+ float64(math.Float32frombits(d.uint32())),
+ ))
+ case reflect.Complex128:
+ v.Set(cmplx(
+ math.Float64frombits(d.uint64()),
+ math.Float64frombits(d.uint64()),
+ ))
+ }
}
}
@@ -372,5 +393,17 @@ func (e *encoder) value(v reflect.Value) {
case reflect.Float64:
e.uint64(math.Float64bits(v.Get()))
}
+
+ case *reflect.ComplexValue:
+ switch v.Type().Kind() {
+ case reflect.Complex64:
+ x := v.Get()
+ e.uint32(math.Float32bits(float32(real(x))))
+ e.uint32(math.Float32bits(float32(imag(x))))
+ case reflect.Complex128:
+ x := v.Get()
+ e.uint64(math.Float64bits(real(x)))
+ e.uint64(math.Float64bits(imag(x)))
+ }
}
}
diff --git a/src/pkg/encoding/binary/binary_test.go b/src/pkg/encoding/binary/binary_test.go
index 12d192d1e..c378413f1 100644
--- a/src/pkg/encoding/binary/binary_test.go
+++ b/src/pkg/encoding/binary/binary_test.go
@@ -13,16 +13,28 @@ import (
)
type Struct struct {
- Int8 int8
- Int16 int16
- Int32 int32
- Int64 int64
- Uint8 uint8
- Uint16 uint16
- Uint32 uint32
- Uint64 uint64
- Float64 float64
- Array [4]uint8
+ Int8 int8
+ Int16 int16
+ Int32 int32
+ Int64 int64
+ Uint8 uint8
+ Uint16 uint16
+ Uint32 uint32
+ Uint64 uint64
+ Float32 float32
+ Float64 float64
+ Complex64 complex64
+ Complex128 complex128
+ Array [4]uint8
+}
+
+type T struct {
+ Int int
+ Uint uint
+ Float float
+ Complex complex
+ Uintptr uintptr
+ Array [4]int
}
var s = Struct{
@@ -34,8 +46,19 @@ var s = Struct{
0x1112,
0x13141516,
0x1718191a1b1c1d1e,
- math.Float64frombits(0x1f20212223242526),
- [4]uint8{0x27, 0x28, 0x29, 0x2a},
+
+ math.Float32frombits(0x1f202122),
+ math.Float64frombits(0x232425262728292a),
+ cmplx(
+ math.Float32frombits(0x2b2c2d2e),
+ math.Float32frombits(0x2f303132),
+ ),
+ cmplx(
+ math.Float64frombits(0x333435363738393a),
+ math.Float64frombits(0x3b3c3d3e3f404142),
+ ),
+
+ [4]uint8{0x43, 0x44, 0x45, 0x46},
}
var big = []byte{
@@ -47,8 +70,13 @@ var big = []byte{
17, 18,
19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30,
- 31, 32, 33, 34, 35, 36, 37, 38,
- 39, 40, 41, 42,
+
+ 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+
+ 67, 68, 69, 70,
}
var little = []byte{
@@ -60,8 +88,13 @@ var little = []byte{
18, 17,
22, 21, 20, 19,
30, 29, 28, 27, 26, 25, 24, 23,
- 38, 37, 36, 35, 34, 33, 32, 31,
- 39, 40, 41, 42,
+
+ 34, 33, 32, 31,
+ 42, 41, 40, 39, 38, 37, 36, 35,
+ 46, 45, 44, 43, 50, 49, 48, 47,
+ 58, 57, 56, 55, 54, 53, 52, 51, 66, 65, 64, 63, 62, 61, 60, 59,
+
+ 67, 68, 69, 70,
}
var src = []byte{1, 2, 3, 4, 5, 6, 7, 8}
@@ -112,3 +145,20 @@ func TestWriteSlice(t *testing.T) {
err := Write(buf, BigEndian, res)
checkResult(t, "WriteSlice", BigEndian, err, buf.Bytes(), src)
}
+
+func TestWriteT(t *testing.T) {
+ buf := new(bytes.Buffer)
+ ts := T{}
+ err := Write(buf, BigEndian, ts)
+ if err == nil {
+ t.Errorf("WriteT: have nil, want non-nil")
+ }
+
+ tv := reflect.Indirect(reflect.NewValue(ts)).(*reflect.StructValue)
+ for i, n := 0, tv.NumField(); i < n; i++ {
+ err = Write(buf, BigEndian, tv.Field(i).Interface())
+ if err == nil {
+ t.Errorf("WriteT.%v: have nil, want non-nil", tv.Field(i).Type())
+ }
+ }
+}
diff --git a/src/pkg/encoding/git85/Makefile b/src/pkg/encoding/git85/Makefile
index 09dd96f32..fbd003454 100644
--- a/src/pkg/encoding/git85/Makefile
+++ b/src/pkg/encoding/git85/Makefile
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
-include ../../../Make.$(GOARCH)
+include ../../../Make.inc
TARG=encoding/git85
GOFILES=\
diff --git a/src/pkg/encoding/git85/git_test.go b/src/pkg/encoding/git85/git_test.go
index a31f14d3c..c76385c35 100644
--- a/src/pkg/encoding/git85/git_test.go
+++ b/src/pkg/encoding/git85/git_test.go
@@ -17,7 +17,7 @@ type testpair struct {
func testEqual(t *testing.T, msg string, args ...interface{}) bool {
if args[len(args)-2] != args[len(args)-1] {
- t.Errorf(msg, args)
+ t.Errorf(msg, args...)
return false
}
return true
@@ -40,7 +40,7 @@ func TestGitTable(t *testing.T) {
var gitPairs = []testpair{
// Wikipedia example, adapted.
- testpair{
+ {
"Man is distinguished, not only by his reason, but by this singular passion from " +
"other animals, which is a lust of the mind, that by a perseverance of delight in " +
"the continued and indefatigable generation of knowledge, exceeds the short " +
@@ -144,8 +144,8 @@ func TestDecodeCorrupt(t *testing.T) {
p int
}
examples := []corrupt{
- corrupt{"v", 0},
- corrupt{"!z!!!!!!!!!", 0},
+ {"v", 0},
+ {"!z!!!!!!!!!", 0},
}
for _, e := range examples {
diff --git a/src/pkg/encoding/hex/Makefile b/src/pkg/encoding/hex/Makefile
index d6849d9a5..22049f43b 100644
--- a/src/pkg/encoding/hex/Makefile
+++ b/src/pkg/encoding/hex/Makefile
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
-include ../../../Make.$(GOARCH)
+include ../../../Make.inc
TARG=encoding/hex
GOFILES=\
diff --git a/src/pkg/encoding/hex/hex.go b/src/pkg/encoding/hex/hex.go
index 1c52885e2..292d917eb 100644
--- a/src/pkg/encoding/hex/hex.go
+++ b/src/pkg/encoding/hex/hex.go
@@ -71,7 +71,7 @@ func Decode(dst, src []byte) (int, os.Error) {
// fromHexChar converts a hex character into its value and a success flag.
func fromHexChar(c byte) (byte, bool) {
switch {
- case 0 <= c && c <= '9':
+ case '0' <= c && c <= '9':
return c - '0', true
case 'a' <= c && c <= 'f':
return c - 'a' + 10, true
diff --git a/src/pkg/encoding/hex/hex_test.go b/src/pkg/encoding/hex/hex_test.go
index d741e595a..a14c9d4f4 100644
--- a/src/pkg/encoding/hex/hex_test.go
+++ b/src/pkg/encoding/hex/hex_test.go
@@ -14,26 +14,26 @@ type encodeTest struct {
}
var encodeTests = []encodeTest{
- encodeTest{[]byte{}, []byte{}},
- encodeTest{[]byte{0x01}, []byte{'0', '1'}},
- encodeTest{[]byte{0xff}, []byte{'f', 'f'}},
- encodeTest{[]byte{0xff, 00}, []byte{'f', 'f', '0', '0'}},
- encodeTest{[]byte{0}, []byte{'0', '0'}},
- encodeTest{[]byte{1}, []byte{'0', '1'}},
- encodeTest{[]byte{2}, []byte{'0', '2'}},
- encodeTest{[]byte{3}, []byte{'0', '3'}},
- encodeTest{[]byte{4}, []byte{'0', '4'}},
- encodeTest{[]byte{5}, []byte{'0', '5'}},
- encodeTest{[]byte{6}, []byte{'0', '6'}},
- encodeTest{[]byte{7}, []byte{'0', '7'}},
- encodeTest{[]byte{8}, []byte{'0', '8'}},
- encodeTest{[]byte{9}, []byte{'0', '9'}},
- encodeTest{[]byte{10}, []byte{'0', 'a'}},
- encodeTest{[]byte{11}, []byte{'0', 'b'}},
- encodeTest{[]byte{12}, []byte{'0', 'c'}},
- encodeTest{[]byte{13}, []byte{'0', 'd'}},
- encodeTest{[]byte{14}, []byte{'0', 'e'}},
- encodeTest{[]byte{15}, []byte{'0', 'f'}},
+ {[]byte{}, []byte{}},
+ {[]byte{0x01}, []byte{'0', '1'}},
+ {[]byte{0xff}, []byte{'f', 'f'}},
+ {[]byte{0xff, 00}, []byte{'f', 'f', '0', '0'}},
+ {[]byte{0}, []byte{'0', '0'}},
+ {[]byte{1}, []byte{'0', '1'}},
+ {[]byte{2}, []byte{'0', '2'}},
+ {[]byte{3}, []byte{'0', '3'}},
+ {[]byte{4}, []byte{'0', '4'}},
+ {[]byte{5}, []byte{'0', '5'}},
+ {[]byte{6}, []byte{'0', '6'}},
+ {[]byte{7}, []byte{'0', '7'}},
+ {[]byte{8}, []byte{'0', '8'}},
+ {[]byte{9}, []byte{'0', '9'}},
+ {[]byte{10}, []byte{'0', 'a'}},
+ {[]byte{11}, []byte{'0', 'b'}},
+ {[]byte{12}, []byte{'0', 'c'}},
+ {[]byte{13}, []byte{'0', 'd'}},
+ {[]byte{14}, []byte{'0', 'e'}},
+ {[]byte{15}, []byte{'0', 'f'}},
}
func TestEncode(t *testing.T) {
@@ -55,31 +55,32 @@ type decodeTest struct {
}
var decodeTests = []decodeTest{
- decodeTest{[]byte{}, []byte{}, true},
- decodeTest{[]byte{'0'}, []byte{}, false},
- decodeTest{[]byte{'0', 'g'}, []byte{}, false},
- decodeTest{[]byte{'0', '0'}, []byte{0}, true},
- decodeTest{[]byte{'0', '1'}, []byte{1}, true},
- decodeTest{[]byte{'0', '2'}, []byte{2}, true},
- decodeTest{[]byte{'0', '3'}, []byte{3}, true},
- decodeTest{[]byte{'0', '4'}, []byte{4}, true},
- decodeTest{[]byte{'0', '5'}, []byte{5}, true},
- decodeTest{[]byte{'0', '6'}, []byte{6}, true},
- decodeTest{[]byte{'0', '7'}, []byte{7}, true},
- decodeTest{[]byte{'0', '8'}, []byte{8}, true},
- decodeTest{[]byte{'0', '9'}, []byte{9}, true},
- decodeTest{[]byte{'0', 'a'}, []byte{10}, true},
- decodeTest{[]byte{'0', 'b'}, []byte{11}, true},
- decodeTest{[]byte{'0', 'c'}, []byte{12}, true},
- decodeTest{[]byte{'0', 'd'}, []byte{13}, true},
- decodeTest{[]byte{'0', 'e'}, []byte{14}, true},
- decodeTest{[]byte{'0', 'f'}, []byte{15}, true},
- decodeTest{[]byte{'0', 'A'}, []byte{10}, true},
- decodeTest{[]byte{'0', 'B'}, []byte{11}, true},
- decodeTest{[]byte{'0', 'C'}, []byte{12}, true},
- decodeTest{[]byte{'0', 'D'}, []byte{13}, true},
- decodeTest{[]byte{'0', 'E'}, []byte{14}, true},
- decodeTest{[]byte{'0', 'F'}, []byte{15}, true},
+ {[]byte{}, []byte{}, true},
+ {[]byte{'0'}, []byte{}, false},
+ {[]byte{'0', 'g'}, []byte{}, false},
+ {[]byte{'0', '\x01'}, []byte{}, false},
+ {[]byte{'0', '0'}, []byte{0}, true},
+ {[]byte{'0', '1'}, []byte{1}, true},
+ {[]byte{'0', '2'}, []byte{2}, true},
+ {[]byte{'0', '3'}, []byte{3}, true},
+ {[]byte{'0', '4'}, []byte{4}, true},
+ {[]byte{'0', '5'}, []byte{5}, true},
+ {[]byte{'0', '6'}, []byte{6}, true},
+ {[]byte{'0', '7'}, []byte{7}, true},
+ {[]byte{'0', '8'}, []byte{8}, true},
+ {[]byte{'0', '9'}, []byte{9}, true},
+ {[]byte{'0', 'a'}, []byte{10}, true},
+ {[]byte{'0', 'b'}, []byte{11}, true},
+ {[]byte{'0', 'c'}, []byte{12}, true},
+ {[]byte{'0', 'd'}, []byte{13}, true},
+ {[]byte{'0', 'e'}, []byte{14}, true},
+ {[]byte{'0', 'f'}, []byte{15}, true},
+ {[]byte{'0', 'A'}, []byte{10}, true},
+ {[]byte{'0', 'B'}, []byte{11}, true},
+ {[]byte{'0', 'C'}, []byte{12}, true},
+ {[]byte{'0', 'D'}, []byte{13}, true},
+ {[]byte{'0', 'E'}, []byte{14}, true},
+ {[]byte{'0', 'F'}, []byte{15}, true},
}
func TestDecode(t *testing.T) {
@@ -104,10 +105,10 @@ type encodeStringTest struct {
}
var encodeStringTests = []encodeStringTest{
- encodeStringTest{[]byte{}, ""},
- encodeStringTest{[]byte{0}, "00"},
- encodeStringTest{[]byte{0, 1}, "0001"},
- encodeStringTest{[]byte{0, 1, 255}, "0001ff"},
+ {[]byte{}, ""},
+ {[]byte{0}, "00"},
+ {[]byte{0, 1}, "0001"},
+ {[]byte{0, 1, 255}, "0001ff"},
}
func TestEncodeToString(t *testing.T) {
@@ -126,12 +127,13 @@ type decodeStringTest struct {
}
var decodeStringTests = []decodeStringTest{
- decodeStringTest{"", []byte{}, true},
- decodeStringTest{"0", []byte{}, false},
- decodeStringTest{"00", []byte{0}, true},
- decodeStringTest{"0g", []byte{}, false},
- decodeStringTest{"00ff00", []byte{0, 255, 0}, true},
- decodeStringTest{"0000ff", []byte{0, 0, 255}, true},
+ {"", []byte{}, true},
+ {"0", []byte{}, false},
+ {"00", []byte{0}, true},
+ {"0\x01", []byte{}, false},
+ {"0g", []byte{}, false},
+ {"00ff00", []byte{0, 255, 0}, true},
+ {"0000ff", []byte{0, 0, 255}, true},
}
func TestDecodeString(t *testing.T) {
diff --git a/src/pkg/encoding/line/Makefile b/src/pkg/encoding/line/Makefile
new file mode 100644
index 000000000..1af355c27
--- /dev/null
+++ b/src/pkg/encoding/line/Makefile
@@ -0,0 +1,11 @@
+# Copyright 2010 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+include ../../../Make.inc
+
+TARG=encoding/line
+GOFILES=\
+ line.go\
+
+include ../../../Make.pkg
diff --git a/src/pkg/encoding/line/line.go b/src/pkg/encoding/line/line.go
new file mode 100644
index 000000000..92dddcb99
--- /dev/null
+++ b/src/pkg/encoding/line/line.go
@@ -0,0 +1,95 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This package implements a Reader which handles reading \r and \r\n
+// deliminated lines.
+package line
+
+import (
+ "io"
+ "os"
+)
+
+// Reader reads lines from an io.Reader (which may use either '\n' or
+// '\r\n').
+type Reader struct {
+ buf []byte
+ consumed int
+ in io.Reader
+ err os.Error
+}
+
+func NewReader(in io.Reader, maxLineLength int) *Reader {
+ return &Reader{
+ buf: make([]byte, 0, maxLineLength),
+ consumed: 0,
+ in: in,
+ }
+}
+
+// ReadLine tries to return a single line, not including the end-of-line bytes.
+// If the line was found to be longer than the maximum length then isPrefix is
+// set and the beginning of the line is returned. The rest of the line will be
+// returned from future calls. isPrefix will be false when returning the last
+// fragment of the line. The returned buffer points into the internal state of
+// the Reader and is only valid until the next call to ReadLine. ReadLine
+// either returns a non-nil line or it returns an error, never both.
+func (l *Reader) ReadLine() (line []byte, isPrefix bool, err os.Error) {
+ if l.consumed > 0 {
+ n := copy(l.buf, l.buf[l.consumed:])
+ l.buf = l.buf[:n]
+ l.consumed = 0
+ }
+
+ if len(l.buf) == 0 && l.err != nil {
+ err = l.err
+ return
+ }
+
+ scannedTo := 0
+
+ for {
+ i := scannedTo
+ for ; i < len(l.buf); i++ {
+ if l.buf[i] == '\r' && len(l.buf) > i+1 && l.buf[i+1] == '\n' {
+ line = l.buf[:i]
+ l.consumed = i + 2
+ return
+ } else if l.buf[i] == '\n' {
+ line = l.buf[:i]
+ l.consumed = i + 1
+ return
+ }
+ }
+
+ if i == cap(l.buf) {
+ line = l.buf[:i]
+ l.consumed = i
+ isPrefix = true
+ return
+ }
+
+ if l.err != nil {
+ line = l.buf
+ l.consumed = i
+ return
+ }
+
+ // We don't want to rescan the input that we just scanned.
+ // However, we need to back up one byte because the last byte
+ // could have been a '\r' and we do need to rescan that.
+ scannedTo = i
+ if scannedTo > 0 {
+ scannedTo--
+ }
+ oldLen := len(l.buf)
+ l.buf = l.buf[:cap(l.buf)]
+ n, readErr := l.in.Read(l.buf[oldLen:])
+ l.buf = l.buf[:oldLen+n]
+ if readErr != nil {
+ l.err = readErr
+ }
+ }
+ panic("unreachable")
+}
diff --git a/src/pkg/encoding/line/line_test.go b/src/pkg/encoding/line/line_test.go
new file mode 100644
index 000000000..68d13b586
--- /dev/null
+++ b/src/pkg/encoding/line/line_test.go
@@ -0,0 +1,89 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package line
+
+import (
+ "bytes"
+ "os"
+ "testing"
+)
+
+var testOutput = []byte("0123456789abcdefghijklmnopqrstuvwxy")
+var testInput = []byte("012\n345\n678\n9ab\ncde\nfgh\nijk\nlmn\nopq\nrst\nuvw\nxy")
+var testInputrn = []byte("012\r\n345\r\n678\r\n9ab\r\ncde\r\nfgh\r\nijk\r\nlmn\r\nopq\r\nrst\r\nuvw\r\nxy\r\n\n\r\n")
+
+// TestReader wraps a []byte and returns reads of a specific length.
+type testReader struct {
+ data []byte
+ stride int
+}
+
+func (t *testReader) Read(buf []byte) (n int, err os.Error) {
+ n = t.stride
+ if n > len(t.data) {
+ n = len(t.data)
+ }
+ if n > len(buf) {
+ n = len(buf)
+ }
+ copy(buf, t.data)
+ t.data = t.data[n:]
+ if len(t.data) == 0 {
+ err = os.EOF
+ }
+ return
+}
+
+func testLineReader(t *testing.T, input []byte) {
+ for stride := 1; stride < len(input); stride++ {
+ done := 0
+ reader := testReader{input, stride}
+ l := NewReader(&reader, len(input)+1)
+ for {
+ line, isPrefix, err := l.ReadLine()
+ if len(line) > 0 && err != nil {
+ t.Errorf("ReadLine returned both data and error: %s", err)
+ }
+ if isPrefix {
+ t.Errorf("ReadLine returned prefix")
+ }
+ if err != nil {
+ if err != os.EOF {
+ t.Fatalf("Got unknown error: %s", err)
+ }
+ break
+ }
+ if want := testOutput[done : done+len(line)]; !bytes.Equal(want, line) {
+ t.Errorf("Bad line at stride %d: want: %x got: %x", stride, want, line)
+ }
+ done += len(line)
+ }
+ if done != len(testOutput) {
+ t.Error("ReadLine didn't return everything")
+ }
+ }
+}
+
+func TestReader(t *testing.T) {
+ testLineReader(t, testInput)
+ testLineReader(t, testInputrn)
+}
+
+func TestLineTooLong(t *testing.T) {
+ buf := bytes.NewBuffer([]byte("aaabbbcc\n"))
+ l := NewReader(buf, 3)
+ line, isPrefix, err := l.ReadLine()
+ if !isPrefix || !bytes.Equal(line, []byte("aaa")) || err != nil {
+ t.Errorf("bad result for first line: %x %s", line, err)
+ }
+ line, isPrefix, err = l.ReadLine()
+ if !isPrefix || !bytes.Equal(line, []byte("bbb")) || err != nil {
+ t.Errorf("bad result for second line: %x", line)
+ }
+ line, isPrefix, err = l.ReadLine()
+ if isPrefix || !bytes.Equal(line, []byte("cc")) || err != nil {
+ t.Errorf("bad result for third line: %x", line)
+ }
+}
diff --git a/src/pkg/encoding/pem/Makefile b/src/pkg/encoding/pem/Makefile
index 79490a57d..527670380 100644
--- a/src/pkg/encoding/pem/Makefile
+++ b/src/pkg/encoding/pem/Makefile
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
-include ../../../Make.$(GOARCH)
+include ../../../Make.inc
TARG=encoding/pem
GOFILES=\
diff --git a/src/pkg/encoding/pem/pem.go b/src/pkg/encoding/pem/pem.go
index f39540756..5653aeb77 100644
--- a/src/pkg/encoding/pem/pem.go
+++ b/src/pkg/encoding/pem/pem.go
@@ -218,14 +218,13 @@ func Encode(out io.Writer, b *Block) (err os.Error) {
return
}
- for k, v := range b.Headers {
- _, err = out.Write([]byte(k + ": " + v + "\n"))
- if err != nil {
- return
+ if len(b.Headers) > 0 {
+ for k, v := range b.Headers {
+ _, err = out.Write([]byte(k + ": " + v + "\n"))
+ if err != nil {
+ return
+ }
}
- }
-
- if len(b.Headers) > 1 {
_, err = out.Write([]byte{'\n'})
if err != nil {
return
diff --git a/src/pkg/encoding/pem/pem_test.go b/src/pkg/encoding/pem/pem_test.go
index 42bd573d7..11efe5544 100644
--- a/src/pkg/encoding/pem/pem_test.go
+++ b/src/pkg/encoding/pem/pem_test.go
@@ -15,14 +15,14 @@ type GetLineTest struct {
}
var getLineTests = []GetLineTest{
- GetLineTest{"abc", "abc", ""},
- GetLineTest{"abc\r", "abc\r", ""},
- GetLineTest{"abc\n", "abc", ""},
- GetLineTest{"abc\r\n", "abc", ""},
- GetLineTest{"abc\nd", "abc", "d"},
- GetLineTest{"abc\r\nd", "abc", "d"},
- GetLineTest{"\nabc", "", "abc"},
- GetLineTest{"\r\nabc", "", "abc"},
+ {"abc", "abc", ""},
+ {"abc\r", "abc\r", ""},
+ {"abc\n", "abc", ""},
+ {"abc\r\n", "abc", ""},
+ {"abc\nd", "abc", "d"},
+ {"abc\r\nd", "abc", "d"},
+ {"\nabc", "", "abc"},
+ {"\r\nabc", "", "abc"},
}
func TestGetLine(t *testing.T) {
@@ -63,12 +63,12 @@ type lineBreakerTest struct {
const sixtyFourCharString = "0123456789012345678901234567890123456789012345678901234567890123"
var lineBreakerTests = []lineBreakerTest{
- lineBreakerTest{"", ""},
- lineBreakerTest{"a", "a\n"},
- lineBreakerTest{"ab", "ab\n"},
- lineBreakerTest{sixtyFourCharString, sixtyFourCharString + "\n"},
- lineBreakerTest{sixtyFourCharString + "X", sixtyFourCharString + "\nX\n"},
- lineBreakerTest{sixtyFourCharString + sixtyFourCharString, sixtyFourCharString + "\n" + sixtyFourCharString + "\n"},
+ {"", ""},
+ {"a", "a\n"},
+ {"ab", "ab\n"},
+ {sixtyFourCharString, sixtyFourCharString + "\n"},
+ {sixtyFourCharString + "X", sixtyFourCharString + "\nX\n"},
+ {sixtyFourCharString + sixtyFourCharString, sixtyFourCharString + "\n" + sixtyFourCharString + "\n"},
}
func TestLineBreaker(t *testing.T) {