aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/bytes
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2019-01-18 19:04:36 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-01-18 19:04:36 +0000
commit4f4a855d82a889cebcfca150a7a43909bcb6a346 (patch)
treef12bae0781920fa34669fe30b6f4615a86d9fb80 /libgo/go/bytes
parent225220d668dafb8262db7012bced688acbe63b33 (diff)
downloadgcc-4f4a855d82a889cebcfca150a7a43909bcb6a346.zip
gcc-4f4a855d82a889cebcfca150a7a43909bcb6a346.tar.gz
gcc-4f4a855d82a889cebcfca150a7a43909bcb6a346.tar.bz2
libgo: update to Go1.12beta2
Reviewed-on: https://go-review.googlesource.com/c/158019 gotools/: * Makefile.am (go_cmd_vet_files): Update for Go1.12beta2 release. (GOTOOLS_TEST_TIMEOUT): Increase to 600. (check-runtime): Export LD_LIBRARY_PATH before computing GOARCH and GOOS. (check-vet): Copy golang.org/x/tools into check-vet-dir. * Makefile.in: Regenerate. gcc/testsuite/: * go.go-torture/execute/names-1.go: Stop using debug/xcoff, which is no longer externally visible. From-SVN: r268084
Diffstat (limited to 'libgo/go/bytes')
-rw-r--r--libgo/go/bytes/buffer.go23
-rw-r--r--libgo/go/bytes/buffer_test.go2
-rw-r--r--libgo/go/bytes/bytes.go62
-rw-r--r--libgo/go/bytes/bytes_decl.go24
-rw-r--r--libgo/go/bytes/bytes_test.go6
-rw-r--r--libgo/go/bytes/compare_test.go13
-rw-r--r--libgo/go/bytes/example_test.go14
-rw-r--r--libgo/go/bytes/indexbyte.c73
-rw-r--r--libgo/go/bytes/reader.go6
-rw-r--r--libgo/go/bytes/reader_test.go42
10 files changed, 136 insertions, 129 deletions
diff --git a/libgo/go/bytes/buffer.go b/libgo/go/bytes/buffer.go
index a2eca2e..aff2db5 100644
--- a/libgo/go/bytes/buffer.go
+++ b/libgo/go/bytes/buffer.go
@@ -12,13 +12,15 @@ import (
"unicode/utf8"
)
+// smallBufferSize is an initial allocation minimal capacity.
+const smallBufferSize = 64
+
// A Buffer is a variable-sized buffer of bytes with Read and Write methods.
// The zero value for Buffer is an empty buffer ready to use.
type Buffer struct {
- buf []byte // contents are the bytes buf[off : len(buf)]
- off int // read at &buf[off], write at &buf[len(buf)]
- bootstrap [64]byte // memory to hold first slice; helps small buffers avoid allocation.
- lastRead readOp // last read operation, so that Unread* can work correctly.
+ buf []byte // contents are the bytes buf[off : len(buf)]
+ off int // read at &buf[off], write at &buf[len(buf)]
+ lastRead readOp // last read operation, so that Unread* can work correctly.
// FIXME: it would be advisable to align Buffer to cachelines to avoid false
// sharing.
@@ -66,7 +68,7 @@ func (b *Buffer) String() string {
return string(b.buf[b.off:])
}
-// empty returns whether the unread portion of the buffer is empty.
+// empty reports whether the unread portion of the buffer is empty.
func (b *Buffer) empty() bool { return len(b.buf) <= b.off }
// Len returns the number of bytes of the unread portion of the buffer;
@@ -125,9 +127,8 @@ func (b *Buffer) grow(n int) int {
if i, ok := b.tryGrowByReslice(n); ok {
return i
}
- // Check if we can make use of bootstrap array.
- if b.buf == nil && n <= len(b.bootstrap) {
- b.buf = b.bootstrap[:n]
+ if b.buf == nil && n <= smallBufferSize {
+ b.buf = make([]byte, n, smallBufferSize)
return 0
}
c := cap(b.buf)
@@ -441,9 +442,9 @@ func (b *Buffer) ReadString(delim byte) (line string, err error) {
// NewBuffer creates and initializes a new Buffer using buf as its
// initial contents. The new Buffer takes ownership of buf, and the
// caller should not use buf after this call. NewBuffer is intended to
-// prepare a Buffer to read existing data. It can also be used to size
-// the internal buffer for writing. To do that, buf should have the
-// desired capacity but a length of zero.
+// prepare a Buffer to read existing data. It can also be used to set
+// the initial size of the internal buffer for writing. To do that,
+// buf should have the desired capacity but a length of zero.
//
// In most cases, new(Buffer) (or just declaring a Buffer variable) is
// sufficient to initialize a Buffer.
diff --git a/libgo/go/bytes/buffer_test.go b/libgo/go/bytes/buffer_test.go
index acbe5ca..6e9d695 100644
--- a/libgo/go/bytes/buffer_test.go
+++ b/libgo/go/bytes/buffer_test.go
@@ -293,7 +293,7 @@ func TestReadFromPanicReader(t *testing.T) {
}
check(t, "TestReadFromPanicReader (1)", &buf, "")
- // Confirm that when Reader panics, the emtpy buffer remains empty
+ // Confirm that when Reader panics, the empty buffer remains empty
var buf2 Buffer
defer func() {
recover()
diff --git a/libgo/go/bytes/bytes.go b/libgo/go/bytes/bytes.go
index 437a6e1..daf4a32 100644
--- a/libgo/go/bytes/bytes.go
+++ b/libgo/go/bytes/bytes.go
@@ -12,6 +12,13 @@ import (
"unicode/utf8"
)
+// Equal returns a boolean reporting whether a and b
+// are the same length and contain the same bytes.
+// A nil argument is equivalent to an empty slice.
+func Equal(a, b []byte) bool {
+ return bytealg.Equal(a, b)
+}
+
func equalPortable(a, b []byte) bool {
if len(a) != len(b) {
return false
@@ -24,6 +31,13 @@ func equalPortable(a, b []byte) bool {
return true
}
+// Compare returns an integer comparing two byte slices lexicographically.
+// The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
+// A nil argument is equivalent to an empty slice.
+func Compare(a, b []byte) int {
+ return bytealg.Compare(a, b)
+}
+
// explode splits s into a slice of UTF-8 sequences, one per Unicode code point (still slices of bytes),
// up to a maximum of n byte slices. Invalid UTF-8 sequences are chopped into individual bytes.
func explode(s []byte, n int) [][]byte {
@@ -83,6 +97,11 @@ func ContainsRune(b []byte, r rune) bool {
return IndexRune(b, r) >= 0
}
+// IndexByte returns the index of the first instance of c in b, or -1 if c is not present in b.
+func IndexByte(b []byte, c byte) int {
+ return bytealg.IndexByte(b, c)
+}
+
func indexBytePortable(s []byte, c byte) int {
for i, b := range s {
if b == c {
@@ -489,19 +508,19 @@ func ToTitle(s []byte) []byte { return Map(unicode.ToTitle, s) }
// ToUpperSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
// upper case, giving priority to the special casing rules.
func ToUpperSpecial(c unicode.SpecialCase, s []byte) []byte {
- return Map(func(r rune) rune { return c.ToUpper(r) }, s)
+ return Map(c.ToUpper, s)
}
// ToLowerSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
// lower case, giving priority to the special casing rules.
func ToLowerSpecial(c unicode.SpecialCase, s []byte) []byte {
- return Map(func(r rune) rune { return c.ToLower(r) }, s)
+ return Map(c.ToLower, s)
}
// ToTitleSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
// title case, giving priority to the special casing rules.
func ToTitleSpecial(c unicode.SpecialCase, s []byte) []byte {
- return Map(func(r rune) rune { return c.ToTitle(r) }, s)
+ return Map(c.ToTitle, s)
}
// isSeparator reports whether the rune could mark a word boundary.
@@ -774,6 +793,15 @@ func Replace(s, old, new []byte, n int) []byte {
return t[0:w]
}
+// ReplaceAll returns a copy of the slice s with all
+// non-overlapping instances of old replaced by new.
+// If old is empty, it matches at the beginning of the slice
+// and after each UTF-8 sequence, yielding up to k+1 replacements
+// for a k-rune slice.
+func ReplaceAll(s, old, new []byte) []byte {
+ return Replace(s, old, new, -1)
+}
+
// EqualFold reports whether s and t, interpreted as UTF-8 strings,
// are equal under Unicode case-folding.
func EqualFold(s, t []byte) bool {
@@ -849,21 +877,22 @@ func Index(s, sep []byte) int {
if len(s) <= bytealg.MaxBruteForce {
return bytealg.Index(s, sep)
}
- c := sep[0]
+ c0 := sep[0]
+ c1 := sep[1]
i := 0
- t := s[:len(s)-n+1]
+ t := len(s) - n + 1
fails := 0
- for i < len(t) {
- if t[i] != c {
+ for i < t {
+ if s[i] != c0 {
// IndexByte is faster than bytealg.Index, so use it as long as
// we're not getting lots of false positives.
- o := IndexByte(t[i:], c)
+ o := IndexByte(s[i:t], c0)
if o < 0 {
return -1
}
i += o
}
- if Equal(s[i:i+n], sep) {
+ if s[i+1] == c1 && Equal(s[i:i+n], sep) {
return i
}
fails++
@@ -879,24 +908,25 @@ func Index(s, sep []byte) int {
}
return -1
}
- c := sep[0]
+ c0 := sep[0]
+ c1 := sep[1]
i := 0
fails := 0
- t := s[:len(s)-n+1]
- for i < len(t) {
- if t[i] != c {
- o := IndexByte(t[i:], c)
+ t := len(s) - n + 1
+ for i < t {
+ if s[i] != c0 {
+ o := IndexByte(s[i:t], c0)
if o < 0 {
break
}
i += o
}
- if Equal(s[i:i+n], sep) {
+ if s[i+1] == c1 && Equal(s[i:i+n], sep) {
return i
}
i++
fails++
- if fails >= 4+i>>4 && i < len(t) {
+ if fails >= 4+i>>4 && i < t {
// Give up on IndexByte, it isn't skipping ahead
// far enough to be better than Rabin-Karp.
// Experiments (using IndexPeriodic) suggest
diff --git a/libgo/go/bytes/bytes_decl.go b/libgo/go/bytes/bytes_decl.go
deleted file mode 100644
index af0f8b1..0000000
--- a/libgo/go/bytes/bytes_decl.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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 bytes
-
-//go:noescape
-
-// IndexByte returns the index of the first instance of c in b, or -1 if c is not present in b.
-func IndexByte(b []byte, c byte) int // in internal/bytealg
-
-//go:noescape
-
-// Equal returns a boolean reporting whether a and b
-// are the same length and contain the same bytes.
-// A nil argument is equivalent to an empty slice.
-func Equal(a, b []byte) bool // in internal/bytealg
-
-//go:noescape
-
-// Compare returns an integer comparing two byte slices lexicographically.
-// The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
-// A nil argument is equivalent to an empty slice.
-func Compare(a, b []byte) int // in internal/bytealg
diff --git a/libgo/go/bytes/bytes_test.go b/libgo/go/bytes/bytes_test.go
index 11c5ef9..ec4ecf3 100644
--- a/libgo/go/bytes/bytes_test.go
+++ b/libgo/go/bytes/bytes_test.go
@@ -1367,6 +1367,12 @@ func TestReplace(t *testing.T) {
if cap(in) == cap(out) && &in[:1][0] == &out[:1][0] {
t.Errorf("Replace(%q, %q, %q, %d) didn't copy", tt.in, tt.old, tt.new, tt.n)
}
+ if tt.n == -1 {
+ out := ReplaceAll(in, []byte(tt.old), []byte(tt.new))
+ if s := string(out); s != tt.out {
+ t.Errorf("ReplaceAll(%q, %q, %q) = %q, want %q", tt.in, tt.old, tt.new, s, tt.out)
+ }
+ }
}
}
diff --git a/libgo/go/bytes/compare_test.go b/libgo/go/bytes/compare_test.go
index 3e33c27..a321f2e 100644
--- a/libgo/go/bytes/compare_test.go
+++ b/libgo/go/bytes/compare_test.go
@@ -41,9 +41,16 @@ var compareTests = []struct {
func TestCompare(t *testing.T) {
for _, tt := range compareTests {
- cmp := Compare(tt.a, tt.b)
- if cmp != tt.i {
- t.Errorf(`Compare(%q, %q) = %v`, tt.a, tt.b, cmp)
+ numShifts := 16
+ buffer := make([]byte, len(tt.b)+numShifts)
+ // vary the input alignment of tt.b
+ for offset := 0; offset <= numShifts; offset++ {
+ shiftedB := buffer[offset : len(tt.b)+offset]
+ copy(shiftedB, tt.b)
+ cmp := Compare(tt.a, shiftedB)
+ if cmp != tt.i {
+ t.Errorf(`Compare(%q, %q), offset %d = %v; want %v`, tt.a, tt.b, offset, cmp, tt.i)
+ }
}
}
}
diff --git a/libgo/go/bytes/example_test.go b/libgo/go/bytes/example_test.go
index 5b7a460..6d32837 100644
--- a/libgo/go/bytes/example_test.go
+++ b/libgo/go/bytes/example_test.go
@@ -39,6 +39,14 @@ func ExampleBuffer_Grow() {
// Output: "64 bytes or fewer"
}
+func ExampleBuffer_Len() {
+ var b bytes.Buffer
+ b.Grow(64)
+ b.Write([]byte("abcde"))
+ fmt.Printf("%d", b.Len())
+ // Output: 5
+}
+
func ExampleCompare() {
// Interpret Compare's result by comparing it to zero.
var a, b []byte
@@ -290,6 +298,12 @@ func ExampleReplace() {
// moo moo moo
}
+func ExampleReplaceAll() {
+ fmt.Printf("%s\n", bytes.ReplaceAll([]byte("oink oink oink"), []byte("oink"), []byte("moo")))
+ // Output:
+ // moo moo moo
+}
+
func ExampleRunes() {
rs := bytes.Runes([]byte("go gopher"))
for _, r := range rs {
diff --git a/libgo/go/bytes/indexbyte.c b/libgo/go/bytes/indexbyte.c
deleted file mode 100644
index b248108..0000000
--- a/libgo/go/bytes/indexbyte.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* indexbyte.c -- implement bytes.IndexByte for Go.
-
- Copyright 2009 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 <stddef.h>
-
-#include "runtime.h"
-#include "array.h"
-
-/* This is in C so that the compiler can optimize it appropriately.
- We deliberately don't split the stack in case it does call the
- library function, which shouldn't need much stack space. */
-
-intgo IndexByte (struct __go_open_array, char)
- __asm__ (GOSYM_PREFIX "bytes.IndexByte")
- __attribute__ ((no_split_stack));
-
-intgo
-IndexByte (struct __go_open_array s, char b)
-{
- char *p;
-
- p = __builtin_memchr (s.__values, b, s.__count);
- if (p == NULL)
- return -1;
- return p - (char *) s.__values;
-}
-
-/* Comparison. */
-
-_Bool Equal (struct __go_open_array a, struct __go_open_array b)
- __asm__ (GOSYM_PREFIX "bytes.Equal")
- __attribute__ ((no_split_stack));
-
-_Bool
-Equal (struct __go_open_array a, struct __go_open_array b)
-{
- if (a.__count != b.__count)
- return 0;
- return __builtin_memcmp (a.__values, b.__values, a.__count) == 0;
-}
-
-intgo Compare (struct __go_open_array a, struct __go_open_array b)
- __asm__ (GOSYM_PREFIX "bytes.Compare")
- __attribute__ ((no_split_stack));
-
-intgo
-Compare (struct __go_open_array a, struct __go_open_array b)
-{
- intgo len;
-
- len = a.__count;
- if (len > b.__count)
- len = b.__count;
- if (len > 0)
- {
- intgo ret;
-
- ret = __builtin_memcmp (a.__values, b.__values, len);
- if (ret < 0)
- return -1;
- else if (ret > 0)
- return 1;
- }
- if (a.__count < b.__count)
- return -1;
- else if (a.__count > b.__count)
- return 1;
- else
- return 0;
-}
diff --git a/libgo/go/bytes/reader.go b/libgo/go/bytes/reader.go
index 08464c2..5946cf9 100644
--- a/libgo/go/bytes/reader.go
+++ b/libgo/go/bytes/reader.go
@@ -14,6 +14,7 @@ import (
// io.ByteScanner, and io.RuneScanner interfaces by reading from
// a byte slice.
// Unlike a Buffer, a Reader is read-only and supports seeking.
+// The zero value for Reader operates like a Reader of an empty slice.
type Reader struct {
s []byte
i int64 // current reading index
@@ -75,10 +76,10 @@ func (r *Reader) ReadByte() (byte, error) {
// UnreadByte complements ReadByte in implementing the io.ByteScanner interface.
func (r *Reader) UnreadByte() error {
- r.prevRune = -1
if r.i <= 0 {
return errors.New("bytes.Reader.UnreadByte: at beginning of slice")
}
+ r.prevRune = -1
r.i--
return nil
}
@@ -101,6 +102,9 @@ func (r *Reader) ReadRune() (ch rune, size int, err error) {
// UnreadRune complements ReadRune in implementing the io.RuneScanner interface.
func (r *Reader) UnreadRune() error {
+ if r.i <= 0 {
+ return errors.New("bytes.Reader.UnreadRune: at beginning of slice")
+ }
if r.prevRune < 0 {
return errors.New("bytes.Reader.UnreadRune: previous operation was not ReadRune")
}
diff --git a/libgo/go/bytes/reader_test.go b/libgo/go/bytes/reader_test.go
index 8806876..d799e03 100644
--- a/libgo/go/bytes/reader_test.go
+++ b/libgo/go/bytes/reader_test.go
@@ -276,3 +276,45 @@ func TestReaderReset(t *testing.T) {
t.Errorf("ReadAll: got %q, want %q", got, want)
}
}
+
+func TestReaderZero(t *testing.T) {
+ if l := (&Reader{}).Len(); l != 0 {
+ t.Errorf("Len: got %d, want 0", l)
+ }
+
+ if n, err := (&Reader{}).Read(nil); n != 0 || err != io.EOF {
+ t.Errorf("Read: got %d, %v; want 0, io.EOF", n, err)
+ }
+
+ if n, err := (&Reader{}).ReadAt(nil, 11); n != 0 || err != io.EOF {
+ t.Errorf("ReadAt: got %d, %v; want 0, io.EOF", n, err)
+ }
+
+ if b, err := (&Reader{}).ReadByte(); b != 0 || err != io.EOF {
+ t.Errorf("ReadByte: got %d, %v; want 0, io.EOF", b, err)
+ }
+
+ if ch, size, err := (&Reader{}).ReadRune(); ch != 0 || size != 0 || err != io.EOF {
+ t.Errorf("ReadRune: got %d, %d, %v; want 0, 0, io.EOF", ch, size, err)
+ }
+
+ if offset, err := (&Reader{}).Seek(11, io.SeekStart); offset != 11 || err != nil {
+ t.Errorf("Seek: got %d, %v; want 11, nil", offset, err)
+ }
+
+ if s := (&Reader{}).Size(); s != 0 {
+ t.Errorf("Size: got %d, want 0", s)
+ }
+
+ if (&Reader{}).UnreadByte() == nil {
+ t.Errorf("UnreadByte: got nil, want error")
+ }
+
+ if (&Reader{}).UnreadRune() == nil {
+ t.Errorf("UnreadRune: got nil, want error")
+ }
+
+ if n, err := (&Reader{}).WriteTo(ioutil.Discard); n != 0 || err != nil {
+ t.Errorf("WriteTo: got %d, %v; want 0, nil", n, err)
+ }
+}