diff options
author | Ondřej Surý <ondrej@sury.org> | 2011-01-17 12:40:45 +0100 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2011-01-17 12:40:45 +0100 |
commit | 3e45412327a2654a77944249962b3652e6142299 (patch) | |
tree | bc3bf69452afa055423cbe0c5cfa8ca357df6ccf /src/pkg/encoding | |
parent | c533680039762cacbc37db8dc7eed074c3e497be (diff) | |
download | golang-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/Makefile | 2 | ||||
-rw-r--r-- | src/pkg/encoding/ascii85/ascii85_test.go | 8 | ||||
-rw-r--r-- | src/pkg/encoding/base64/Makefile | 2 | ||||
-rw-r--r-- | src/pkg/encoding/base64/base64_test.go | 50 | ||||
-rw-r--r-- | src/pkg/encoding/binary/Makefile | 2 | ||||
-rw-r--r-- | src/pkg/encoding/binary/binary.go | 59 | ||||
-rw-r--r-- | src/pkg/encoding/binary/binary_test.go | 82 | ||||
-rw-r--r-- | src/pkg/encoding/git85/Makefile | 2 | ||||
-rw-r--r-- | src/pkg/encoding/git85/git_test.go | 8 | ||||
-rw-r--r-- | src/pkg/encoding/hex/Makefile | 2 | ||||
-rw-r--r-- | src/pkg/encoding/hex/hex.go | 2 | ||||
-rw-r--r-- | src/pkg/encoding/hex/hex_test.go | 112 | ||||
-rw-r--r-- | src/pkg/encoding/line/Makefile | 11 | ||||
-rw-r--r-- | src/pkg/encoding/line/line.go | 95 | ||||
-rw-r--r-- | src/pkg/encoding/line/line_test.go | 89 | ||||
-rw-r--r-- | src/pkg/encoding/pem/Makefile | 2 | ||||
-rw-r--r-- | src/pkg/encoding/pem/pem.go | 13 | ||||
-rw-r--r-- | src/pkg/encoding/pem/pem_test.go | 28 |
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) { |