diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Make.cmd | 2 | ||||
-rw-r--r-- | src/cmd/5a/lex.c | 53 | ||||
-rw-r--r-- | src/cmd/6a/lex.c | 53 | ||||
-rw-r--r-- | src/cmd/8a/lex.c | 53 | ||||
-rw-r--r-- | src/cmd/cc/lex.c | 58 | ||||
-rwxr-xr-x | src/cmd/prof/gopprof | 9 | ||||
-rw-r--r-- | src/pkg/compress/flate/deflate.go | 29 | ||||
-rw-r--r-- | src/pkg/http/pprof/pprof.go | 14 | ||||
-rw-r--r-- | src/pkg/http/transfer.go | 20 | ||||
-rw-r--r-- | src/pkg/image/image.go | 58 | ||||
-rw-r--r-- | src/pkg/image/jpeg/writer.go | 32 | ||||
-rw-r--r-- | src/pkg/image/jpeg/writer_test.go | 28 | ||||
-rw-r--r-- | src/pkg/image/png/reader.go | 22 | ||||
-rw-r--r-- | src/pkg/image/png/writer.go | 29 | ||||
-rw-r--r-- | src/pkg/image/png/writer_test.go | 40 | ||||
-rw-r--r-- | src/pkg/mime/multipart/multipart.go | 197 | ||||
-rw-r--r-- | src/pkg/mime/multipart/multipart_test.go | 125 | ||||
-rw-r--r-- | src/pkg/reflect/all_test.go | 22 | ||||
-rw-r--r-- | src/pkg/reflect/value.go | 9 | ||||
-rw-r--r-- | src/pkg/runtime/linux/arm/sys.s | 15 | ||||
-rw-r--r-- | src/pkg/sync/atomic/asm_linux_arm.s | 21 | ||||
-rw-r--r-- | src/pkg/xml/read.go | 9 | ||||
-rw-r--r-- | src/pkg/xml/xml_test.go | 81 |
23 files changed, 415 insertions, 564 deletions
diff --git a/src/Make.cmd b/src/Make.cmd index 26c3ca2fc..e769e3072 100644 --- a/src/Make.cmd +++ b/src/Make.cmd @@ -25,7 +25,7 @@ _go_.$O: $(GOFILES) $(PREREQ) install: $(TARGDIR)/$(TARG) $(TARGDIR)/$(TARG): $(TARG) - mkdir -p $(TARGDIR) && cp -f $(TARG) $(TARGDIR) + cp -f $(TARG) $(TARGDIR) CLEANFILES+=$(TARG) _test _testmain.go diff --git a/src/cmd/5a/lex.c b/src/cmd/5a/lex.c index a04cda220..dbee3657f 100644 --- a/src/cmd/5a/lex.c +++ b/src/cmd/5a/lex.c @@ -50,7 +50,7 @@ void main(int argc, char *argv[]) { char *p; - int c; + int nout, nproc, i, c; thechar = '5'; thestring = "arm"; @@ -94,10 +94,46 @@ main(int argc, char *argv[]) print("usage: %ca [-options] file.s\n", thechar); errorexit(); } - if(argc > 1){ - print("can't assemble multiple files\n"); + if(argc > 1 && systemtype(Windows)){ + print("can't assemble multiple files on windows\n"); errorexit(); } + if(argc > 1 && !systemtype(Windows)) { + nproc = 1; + if(p = getenv("NPROC")) + nproc = atol(p); /* */ + c = 0; + nout = 0; + for(;;) { + Waitmsg *w; + + while(nout < nproc && argc > 0) { + i = fork(); + if(i < 0) { + fprint(2, "fork: %r\n"); + errorexit(); + } + if(i == 0) { + print("%s:\n", *argv); + if(assemble(*argv)) + errorexit(); + exits(0); + } + nout++; + argc--; + argv++; + } + w = wait(); + if(w == nil) { + if(c) + errorexit(); + exits(0); + } + if(w->msg[0]) + c++; + nout--; + } + } if(assemble(argv[0])) errorexit(); exits(0); @@ -106,7 +142,7 @@ main(int argc, char *argv[]) int assemble(char *file) { - char *ofile, *p; + char *ofile, incfile[20], *p; int i, of; ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar) @@ -131,6 +167,15 @@ assemble(char *file) } else outfile = "/dev/null"; } + p = getenv("INCLUDE"); + if(p) { + setinclude(p); + } else { + if(systemtype(Plan9)) { + sprint(incfile,"/%s/include", thestring); + setinclude(strdup(incfile)); + } + } of = create(outfile, OWRITE, 0664); if(of < 0) { diff --git a/src/cmd/6a/lex.c b/src/cmd/6a/lex.c index b4c7d0c2c..37144c888 100644 --- a/src/cmd/6a/lex.c +++ b/src/cmd/6a/lex.c @@ -56,7 +56,7 @@ void main(int argc, char *argv[]) { char *p; - int c; + int nout, nproc, i, c; thechar = '6'; thestring = "amd64"; @@ -96,10 +96,46 @@ main(int argc, char *argv[]) print("usage: %ca [-options] file.s\n", thechar); errorexit(); } - if(argc > 1){ - print("can't assemble multiple files\n"); + if(argc > 1 && systemtype(Windows)){ + print("can't assemble multiple files on windows\n"); errorexit(); } + if(argc > 1 && !systemtype(Windows)) { + nproc = 1; + if(p = getenv("NPROC")) + nproc = atol(p); /* */ + c = 0; + nout = 0; + for(;;) { + Waitmsg *w; + + while(nout < nproc && argc > 0) { + i = fork(); + if(i < 0) { + fprint(2, "fork: %r\n"); + errorexit(); + } + if(i == 0) { + print("%s:\n", *argv); + if(assemble(*argv)) + errorexit(); + exits(0); + } + nout++; + argc--; + argv++; + } + w = wait(); + if(w == nil) { + if(c) + errorexit(); + exits(0); + } + if(w->msg[0]) + c++; + nout--; + } + } if(assemble(argv[0])) errorexit(); exits(0); @@ -108,7 +144,7 @@ main(int argc, char *argv[]) int assemble(char *file) { - char *ofile, *p; + char *ofile, incfile[20], *p; int i, of; ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar) @@ -133,6 +169,15 @@ assemble(char *file) } else outfile = "/dev/null"; } + p = getenv("INCLUDE"); + if(p) { + setinclude(p); + } else { + if(systemtype(Plan9)) { + sprint(incfile,"/%s/include", thestring); + setinclude(strdup(incfile)); + } + } of = create(outfile, OWRITE, 0664); if(of < 0) { diff --git a/src/cmd/8a/lex.c b/src/cmd/8a/lex.c index 078861877..ca18b69ce 100644 --- a/src/cmd/8a/lex.c +++ b/src/cmd/8a/lex.c @@ -56,7 +56,7 @@ void main(int argc, char *argv[]) { char *p; - int c; + int nout, nproc, i, c; thechar = '8'; thestring = "386"; @@ -96,10 +96,46 @@ main(int argc, char *argv[]) print("usage: %ca [-options] file.s\n", thechar); errorexit(); } - if(argc > 1){ - print("can't assemble multiple files\n"); + if(argc > 1 && systemtype(Windows)){ + print("can't assemble multiple files on windows\n"); errorexit(); } + if(argc > 1 && !systemtype(Windows)) { + nproc = 1; + if(p = getenv("NPROC")) + nproc = atol(p); /* */ + c = 0; + nout = 0; + for(;;) { + Waitmsg *w; + + while(nout < nproc && argc > 0) { + i = fork(); + if(i < 0) { + fprint(2, "fork: %r\n"); + errorexit(); + } + if(i == 0) { + print("%s:\n", *argv); + if(assemble(*argv)) + errorexit(); + exits(0); + } + nout++; + argc--; + argv++; + } + w = wait(); + if(w == nil) { + if(c) + errorexit(); + exits(0); + } + if(w->msg[0]) + c++; + nout--; + } + } if(assemble(argv[0])) errorexit(); exits(0); @@ -108,7 +144,7 @@ main(int argc, char *argv[]) int assemble(char *file) { - char *ofile, *p; + char *ofile, incfile[20], *p; int i, of; ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar) @@ -133,6 +169,15 @@ assemble(char *file) } else outfile = "/dev/null"; } + p = getenv("INCLUDE"); + if(p) { + setinclude(p); + } else { + if(systemtype(Plan9)) { + sprint(incfile,"/%s/include", thestring); + setinclude(strdup(incfile)); + } + } of = create(outfile, OWRITE, 0664); if(of < 0) { diff --git a/src/cmd/cc/lex.c b/src/cmd/cc/lex.c index 71cc89bf0..dba8ff634 100644 --- a/src/cmd/cc/lex.c +++ b/src/cmd/cc/lex.c @@ -88,7 +88,7 @@ void main(int argc, char *argv[]) { char **defs, *p; - int c, ndef; + int nproc, nout, i, c, ndef; ensuresymb(NSYMB); memset(debug, 0, sizeof(debug)); @@ -142,10 +142,51 @@ main(int argc, char *argv[]) print("usage: %cc [-options] files\n", thechar); errorexit(); } - if(argc > 1){ - print("can't compile multiple files\n"); + if(argc > 1 && systemtype(Windows)){ + print("can't compile multiple files on windows\n"); errorexit(); } + if(argc > 1 && !systemtype(Windows)) { + nproc = 1; + /* + * if we're writing acid to standard output, don't compile + * concurrently, to avoid interleaving output. + */ + if(((!debug['a'] && !debug['q'] && !debug['Q']) || debug['n']) && + (p = getenv("NPROC")) != nil) + nproc = atol(p); /* */ + c = 0; + nout = 0; + for(;;) { + Waitmsg *w; + + while(nout < nproc && argc > 0) { + i = fork(); + if(i < 0) { + print("cannot create a process\n"); + errorexit(); + } + if(i == 0) { + fprint(2, "%s:\n", *argv); + if (compile(*argv, defs, ndef)) + errorexit(); + exits(0); + } + nout++; + argc--; + argv++; + } + w = wait(); + if(w == nil) { + if(c) + errorexit(); + exits(0); + } + if(w->msg[0]) + c++; + nout--; + } + } if(argc == 0) c = compile("stdin", defs, ndef); @@ -160,7 +201,7 @@ main(int argc, char *argv[]) int compile(char *file, char **defs, int ndef) { - char *ofile; + char *ofile, incfile[20]; char *p, **av, opt[256]; int i, c, fd[2]; static int first = 1; @@ -195,6 +236,15 @@ compile(char *file, char **defs, int ndef) outfile = "/dev/null"; } + if(p = getenv("INCLUDE")) { + setinclude(p); + } else { + if(systemtype(Plan9)) { + sprint(incfile, "/%s/include", thestring); + setinclude(strdup(incfile)); + setinclude("/sys/include"); + } + } if (first) Binit(&diagbuf, 1, OWRITE); /* diff --git a/src/cmd/prof/gopprof b/src/cmd/prof/gopprof index 8863fc623..8fa00cbe8 100755 --- a/src/cmd/prof/gopprof +++ b/src/cmd/prof/gopprof @@ -2880,18 +2880,17 @@ sub FetchSymbols { my @toask = @pcs; while (@toask > 0) { my $n = @toask; - # NOTE(rsc): Limiting the number of PCs requested per round - # used to be necessary, but I think it was a bug in - # debug/pprof/symbol's implementation. Leaving here - # in case I am wrong. - # if ($n > 49) { $n = 49; } + if ($n > 49) { $n = 49; } my @thisround = @toask[0..$n]; +my $t = @toask; +print STDERR "$n $t\n"; @toask = @toask[($n+1)..(@toask-1)]; my $post_data = join("+", sort((map {"0x" . "$_"} @thisround))); open(POSTFILE, ">$main::tmpfile_sym"); print POSTFILE $post_data; close(POSTFILE); +print STDERR "SYMBL!\n"; my $url = SymbolPageURL(); $url = ResolveRedirectionForCurl($url); my $command_line = "$CURL -sd '\@$main::tmpfile_sym' '$url'"; diff --git a/src/pkg/compress/flate/deflate.go b/src/pkg/compress/flate/deflate.go index a02a5e8d9..e5b2beaef 100644 --- a/src/pkg/compress/flate/deflate.go +++ b/src/pkg/compress/flate/deflate.go @@ -143,18 +143,10 @@ func (d *compressor) fillWindow(index int) (int, os.Error) { d.blockStart = math.MaxInt32 } for i, h := range d.hashHead { - v := h - wSize - if v < -1 { - v = -1 - } - d.hashHead[i] = v + d.hashHead[i] = max(h-wSize, -1) } for i, h := range d.hashPrev { - v := -h - wSize - if v < -1 { - v = -1 - } - d.hashPrev[i] = v + d.hashPrev[i] = max(h-wSize, -1) } } count, err := d.r.Read(d.window[d.windowEnd:]) @@ -185,18 +177,10 @@ func (d *compressor) writeBlock(tokens []token, index int, eof bool) os.Error { // Try to find a match starting at index whose length is greater than prevSize. // We only look at chainCount possibilities before giving up. func (d *compressor) findMatch(pos int, prevHead int, prevLength int, lookahead int) (length, offset int, ok bool) { - minMatchLook := maxMatchLength - if lookahead < minMatchLook { - minMatchLook = lookahead - } - - win := d.window[0 : pos+minMatchLook] + win := d.window[0 : pos+min(maxMatchLength, lookahead)] // We quit when we get a match that's at least nice long - nice := len(win) - pos - if d.niceMatch < nice { - nice = d.niceMatch - } + nice := min(d.niceMatch, len(win)-pos) // If we've got a match that's good enough, only look in 1/4 the chain. tries := d.maxChainLength @@ -360,12 +344,9 @@ Loop: } prevLength := length prevOffset := offset + minIndex := max(index-maxOffset, 0) length = minMatchLength - 1 offset = 0 - minIndex := index - maxOffset - if minIndex < 0 { - minIndex = 0 - } if chainHead >= minIndex && (isFastDeflate && lookahead > minMatchLength-1 || diff --git a/src/pkg/http/pprof/pprof.go b/src/pkg/http/pprof/pprof.go index 917c7f877..bc79e2183 100644 --- a/src/pkg/http/pprof/pprof.go +++ b/src/pkg/http/pprof/pprof.go @@ -26,7 +26,6 @@ package pprof import ( "bufio" - "bytes" "fmt" "http" "os" @@ -89,14 +88,10 @@ func Profile(w http.ResponseWriter, r *http.Request) { func Symbol(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/plain; charset=utf-8") - // We have to read the whole POST body before - // writing any output. Buffer the output here. - var buf bytes.Buffer - // We don't know how many symbols we have, but we // do have symbol information. Pprof only cares whether // this number is 0 (no symbols available) or > 0. - fmt.Fprintf(&buf, "num_symbols: 1\n") + fmt.Fprintf(w, "num_symbols: 1\n") var b *bufio.Reader if r.Method == "POST" { @@ -114,19 +109,14 @@ func Symbol(w http.ResponseWriter, r *http.Request) { if pc != 0 { f := runtime.FuncForPC(uintptr(pc)) if f != nil { - fmt.Fprintf(&buf, "%#x %s\n", pc, f.Name()) + fmt.Fprintf(w, "%#x %s\n", pc, f.Name()) } } // Wait until here to check for err; the last // symbol will have an err because it doesn't end in +. if err != nil { - if err != os.EOF { - fmt.Fprintf(&buf, "reading request: %v\n", err) - } break } } - - w.Write(buf.Bytes()) } diff --git a/src/pkg/http/transfer.go b/src/pkg/http/transfer.go index 0fa8bed43..98c32bab6 100644 --- a/src/pkg/http/transfer.go +++ b/src/pkg/http/transfer.go @@ -439,29 +439,9 @@ type body struct { hdr interface{} // non-nil (Response or Request) value means read trailer r *bufio.Reader // underlying wire-format reader for the trailer closing bool // is the connection to be closed after reading body? - closed bool -} - -// ErrBodyReadAfterClose is returned when reading a Request Body after -// the body has been closed. This typically happens when the body is -// read after an HTTP Handler calls WriteHeader or Write on its -// ResponseWriter. -var ErrBodyReadAfterClose = os.NewError("http: invalid Read on closed request Body") - -func (b *body) Read(p []byte) (n int, err os.Error) { - if b.closed { - return 0, ErrBodyReadAfterClose - } - return b.Reader.Read(p) } func (b *body) Close() os.Error { - if b.closed { - return nil - } - defer func() { - b.closed = true - }() if b.hdr == nil && b.closing { // no trailer and closing the connection next. // no point in reading to EOF. diff --git a/src/pkg/image/image.go b/src/pkg/image/image.go index 222d21ade..5f398a304 100644 --- a/src/pkg/image/image.go +++ b/src/pkg/image/image.go @@ -51,13 +51,6 @@ func (p *RGBA) Set(x, y int, c Color) { p.Pix[y*p.Stride+x] = toRGBAColor(c).(RGBAColor) } -func (p *RGBA) SetRGBA(x, y int, c RGBAColor) { - if !p.Rect.Contains(Point{x, y}) { - return - } - p.Pix[y*p.Stride+x] = c -} - // Opaque scans the entire image and returns whether or not it is fully opaque. func (p *RGBA) Opaque() bool { if p.Rect.Empty() { @@ -110,13 +103,6 @@ func (p *RGBA64) Set(x, y int, c Color) { p.Pix[y*p.Stride+x] = toRGBA64Color(c).(RGBA64Color) } -func (p *RGBA64) SetRGBA64(x, y int, c RGBA64Color) { - if !p.Rect.Contains(Point{x, y}) { - return - } - p.Pix[y*p.Stride+x] = c -} - // Opaque scans the entire image and returns whether or not it is fully opaque. func (p *RGBA64) Opaque() bool { if p.Rect.Empty() { @@ -169,13 +155,6 @@ func (p *NRGBA) Set(x, y int, c Color) { p.Pix[y*p.Stride+x] = toNRGBAColor(c).(NRGBAColor) } -func (p *NRGBA) SetNRGBA(x, y int, c NRGBAColor) { - if !p.Rect.Contains(Point{x, y}) { - return - } - p.Pix[y*p.Stride+x] = c -} - // Opaque scans the entire image and returns whether or not it is fully opaque. func (p *NRGBA) Opaque() bool { if p.Rect.Empty() { @@ -228,13 +207,6 @@ func (p *NRGBA64) Set(x, y int, c Color) { p.Pix[y*p.Stride+x] = toNRGBA64Color(c).(NRGBA64Color) } -func (p *NRGBA64) SetNRGBA64(x, y int, c NRGBA64Color) { - if !p.Rect.Contains(Point{x, y}) { - return - } - p.Pix[y*p.Stride+x] = c -} - // Opaque scans the entire image and returns whether or not it is fully opaque. func (p *NRGBA64) Opaque() bool { if p.Rect.Empty() { @@ -280,20 +252,13 @@ func (p *Alpha) At(x, y int) Color { return p.Pix[y*p.Stride+x] } -func (p *Alpha) Set(x, y int, c AlphaColor) { +func (p *Alpha) Set(x, y int, c Color) { if !p.Rect.Contains(Point{x, y}) { return } p.Pix[y*p.Stride+x] = toAlphaColor(c).(AlphaColor) } -func (p *Alpha) SetAlpha(x, y int, c AlphaColor) { - if !p.Rect.Contains(Point{x, y}) { - return - } - p.Pix[y*p.Stride+x] = c -} - // Opaque scans the entire image and returns whether or not it is fully opaque. func (p *Alpha) Opaque() bool { if p.Rect.Empty() { @@ -346,13 +311,6 @@ func (p *Alpha16) Set(x, y int, c Color) { p.Pix[y*p.Stride+x] = toAlpha16Color(c).(Alpha16Color) } -func (p *Alpha16) SetAlpha16(x, y int, c Alpha16Color) { - if !p.Rect.Contains(Point{x, y}) { - return - } - p.Pix[y*p.Stride+x] = c -} - // Opaque scans the entire image and returns whether or not it is fully opaque. func (p *Alpha16) Opaque() bool { if p.Rect.Empty() { @@ -405,13 +363,6 @@ func (p *Gray) Set(x, y int, c Color) { p.Pix[y*p.Stride+x] = toGrayColor(c).(GrayColor) } -func (p *Gray) SetGray(x, y int, c GrayColor) { - if !p.Rect.Contains(Point{x, y}) { - return - } - p.Pix[y*p.Stride+x] = c -} - // Opaque scans the entire image and returns whether or not it is fully opaque. func (p *Gray) Opaque() bool { return true @@ -450,13 +401,6 @@ func (p *Gray16) Set(x, y int, c Color) { p.Pix[y*p.Stride+x] = toGray16Color(c).(Gray16Color) } -func (p *Gray16) SetGray16(x, y int, c Gray16Color) { - if !p.Rect.Contains(Point{x, y}) { - return - } - p.Pix[y*p.Stride+x] = c -} - // Opaque scans the entire image and returns whether or not it is fully opaque. func (p *Gray16) Opaque() bool { return true diff --git a/src/pkg/image/jpeg/writer.go b/src/pkg/image/jpeg/writer.go index 52b3dc4e2..505cce04f 100644 --- a/src/pkg/image/jpeg/writer.go +++ b/src/pkg/image/jpeg/writer.go @@ -391,31 +391,6 @@ func toYCbCr(m image.Image, p image.Point, yBlock, cbBlock, crBlock *block) { } } -// rgbaToYCbCr is a specialized version of toYCbCr for image.RGBA images. -func rgbaToYCbCr(m *image.RGBA, p image.Point, yBlock, cbBlock, crBlock *block) { - b := m.Bounds() - xmax := b.Max.X - 1 - ymax := b.Max.Y - 1 - for j := 0; j < 8; j++ { - sj := p.Y + j - if sj > ymax { - sj = ymax - } - yoff := sj * m.Stride - for i := 0; i < 8; i++ { - sx := p.X + i - if sx > xmax { - sx = xmax - } - col := &m.Pix[yoff+sx] - yy, cb, cr := ycbcr.RGBToYCbCr(col.R, col.G, col.B) - yBlock[8*j+i] = int(yy) - cbBlock[8*j+i] = int(cb) - crBlock[8*j+i] = int(cr) - } - } -} - // scale scales the 16x16 region represented by the 4 src blocks to the 8x8 // dst block. func scale(dst *block, src *[4]block) { @@ -456,18 +431,13 @@ func (e *encoder) writeSOS(m image.Image) { prevDCY, prevDCCb, prevDCCr int ) bounds := m.Bounds() - rgba, _ := m.(*image.RGBA) for y := bounds.Min.Y; y < bounds.Max.Y; y += 16 { for x := bounds.Min.X; x < bounds.Max.X; x += 16 { for i := 0; i < 4; i++ { xOff := (i & 1) * 8 yOff := (i & 2) * 4 p := image.Point{x + xOff, y + yOff} - if rgba != nil { - rgbaToYCbCr(rgba, p, &yBlock, &cbBlock[i], &crBlock[i]) - } else { - toYCbCr(m, p, &yBlock, &cbBlock[i], &crBlock[i]) - } + toYCbCr(m, p, &yBlock, &cbBlock[i], &crBlock[i]) prevDCY = e.writeBlock(&yBlock, 0, prevDCY) } scale(&cBlock, &cbBlock) diff --git a/src/pkg/image/jpeg/writer_test.go b/src/pkg/image/jpeg/writer_test.go index 7aec70f01..00922dd5c 100644 --- a/src/pkg/image/jpeg/writer_test.go +++ b/src/pkg/image/jpeg/writer_test.go @@ -8,8 +8,6 @@ import ( "bytes" "image" "image/png" - "io/ioutil" - "rand" "os" "testing" ) @@ -87,29 +85,3 @@ func TestWriter(t *testing.T) { } } } - -func BenchmarkEncodeRGBOpaque(b *testing.B) { - b.StopTimer() - img := image.NewRGBA(640, 480) - // Set all pixels to 0xFF alpha to force opaque mode. - bo := img.Bounds() - rnd := rand.New(rand.NewSource(123)) - for y := bo.Min.Y; y < bo.Max.Y; y++ { - for x := bo.Min.X; x < bo.Max.X; x++ { - img.Set(x, y, image.RGBAColor{ - uint8(rnd.Intn(256)), - uint8(rnd.Intn(256)), - uint8(rnd.Intn(256)), - 255}) - } - } - if !img.Opaque() { - panic("expected image to be opaque") - } - b.SetBytes(640 * 480 * 4) - b.StartTimer() - options := &Options{Quality: 90} - for i := 0; i < b.N; i++ { - Encode(ioutil.Discard, img, options) - } -} diff --git a/src/pkg/image/png/reader.go b/src/pkg/image/png/reader.go index 8c76afa72..b30a951c1 100644 --- a/src/pkg/image/png/reader.go +++ b/src/pkg/image/png/reader.go @@ -378,7 +378,7 @@ func (d *decoder) idatReader(idat io.Reader) (image.Image, os.Error) { for x := 0; x < d.width; x += 8 { b := cdat[x/8] for x2 := 0; x2 < 8 && x+x2 < d.width; x2++ { - gray.SetGray(x+x2, y, image.GrayColor{(b >> 7) * 0xff}) + gray.Set(x+x2, y, image.GrayColor{(b >> 7) * 0xff}) b <<= 1 } } @@ -386,7 +386,7 @@ func (d *decoder) idatReader(idat io.Reader) (image.Image, os.Error) { for x := 0; x < d.width; x += 4 { b := cdat[x/4] for x2 := 0; x2 < 4 && x+x2 < d.width; x2++ { - gray.SetGray(x+x2, y, image.GrayColor{(b >> 6) * 0x55}) + gray.Set(x+x2, y, image.GrayColor{(b >> 6) * 0x55}) b <<= 2 } } @@ -394,22 +394,22 @@ func (d *decoder) idatReader(idat io.Reader) (image.Image, os.Error) { for x := 0; x < d.width; x += 2 { b := cdat[x/2] for x2 := 0; x2 < 2 && x+x2 < d.width; x2++ { - gray.SetGray(x+x2, y, image.GrayColor{(b >> 4) * 0x11}) + gray.Set(x+x2, y, image.GrayColor{(b >> 4) * 0x11}) b <<= 4 } } case cbG8: for x := 0; x < d.width; x++ { - gray.SetGray(x, y, image.GrayColor{cdat[x]}) + gray.Set(x, y, image.GrayColor{cdat[x]}) } case cbGA8: for x := 0; x < d.width; x++ { ycol := cdat[2*x+0] - nrgba.SetNRGBA(x, y, image.NRGBAColor{ycol, ycol, ycol, cdat[2*x+1]}) + nrgba.Set(x, y, image.NRGBAColor{ycol, ycol, ycol, cdat[2*x+1]}) } case cbTC8: for x := 0; x < d.width; x++ { - rgba.SetRGBA(x, y, image.RGBAColor{cdat[3*x+0], cdat[3*x+1], cdat[3*x+2], 0xff}) + rgba.Set(x, y, image.RGBAColor{cdat[3*x+0], cdat[3*x+1], cdat[3*x+2], 0xff}) } case cbP1: for x := 0; x < d.width; x += 8 { @@ -456,25 +456,25 @@ func (d *decoder) idatReader(idat io.Reader) (image.Image, os.Error) { } case cbTCA8: for x := 0; x < d.width; x++ { - nrgba.SetNRGBA(x, y, image.NRGBAColor{cdat[4*x+0], cdat[4*x+1], cdat[4*x+2], cdat[4*x+3]}) + nrgba.Set(x, y, image.NRGBAColor{cdat[4*x+0], cdat[4*x+1], cdat[4*x+2], cdat[4*x+3]}) } case cbG16: for x := 0; x < d.width; x++ { ycol := uint16(cdat[2*x+0])<<8 | uint16(cdat[2*x+1]) - gray16.SetGray16(x, y, image.Gray16Color{ycol}) + gray16.Set(x, y, image.Gray16Color{ycol}) } case cbGA16: for x := 0; x < d.width; x++ { ycol := uint16(cdat[4*x+0])<<8 | uint16(cdat[4*x+1]) acol := uint16(cdat[4*x+2])<<8 | uint16(cdat[4*x+3]) - nrgba64.SetNRGBA64(x, y, image.NRGBA64Color{ycol, ycol, ycol, acol}) + nrgba64.Set(x, y, image.NRGBA64Color{ycol, ycol, ycol, acol}) } case cbTC16: for x := 0; x < d.width; x++ { rcol := uint16(cdat[6*x+0])<<8 | uint16(cdat[6*x+1]) gcol := uint16(cdat[6*x+2])<<8 | uint16(cdat[6*x+3]) bcol := uint16(cdat[6*x+4])<<8 | uint16(cdat[6*x+5]) - rgba64.SetRGBA64(x, y, image.RGBA64Color{rcol, gcol, bcol, 0xffff}) + rgba64.Set(x, y, image.RGBA64Color{rcol, gcol, bcol, 0xffff}) } case cbTCA16: for x := 0; x < d.width; x++ { @@ -482,7 +482,7 @@ func (d *decoder) idatReader(idat io.Reader) (image.Image, os.Error) { gcol := uint16(cdat[8*x+2])<<8 | uint16(cdat[8*x+3]) bcol := uint16(cdat[8*x+4])<<8 | uint16(cdat[8*x+5]) acol := uint16(cdat[8*x+6])<<8 | uint16(cdat[8*x+7]) - nrgba64.SetNRGBA64(x, y, image.NRGBA64Color{rcol, gcol, bcol, acol}) + nrgba64.Set(x, y, image.NRGBA64Color{rcol, gcol, bcol, acol}) } } diff --git a/src/pkg/image/png/writer.go b/src/pkg/image/png/writer.go index 2d593f6a7..081d06bf5 100644 --- a/src/pkg/image/png/writer.go +++ b/src/pkg/image/png/writer.go @@ -263,12 +263,7 @@ func writeImage(w io.Writer, m image.Image, cb int) os.Error { defer zw.Close() bpp := 0 // Bytes per pixel. - - // Used by fast paths for common image types var paletted *image.Paletted - var rgba *image.RGBA - rgba, _ = m.(*image.RGBA) - switch cb { case cbG8: bpp = 1 @@ -308,24 +303,12 @@ func writeImage(w io.Writer, m image.Image, cb int) os.Error { cr[0][x+1] = c.Y } case cbTC8: - // We have previously verified that the alpha value is fully opaque. - cr0 := cr[0] - if rgba != nil { - yoff := y * rgba.Stride - xoff := 3*b.Min.X + 1 - for _, color := range rgba.Pix[yoff+b.Min.X : yoff+b.Max.X] { - cr0[xoff] = color.R - cr0[xoff+1] = color.G - cr0[xoff+2] = color.B - xoff += 3 - } - } else { - for x := b.Min.X; x < b.Max.X; x++ { - r, g, b, _ := m.At(x, y).RGBA() - cr0[3*x+1] = uint8(r >> 8) - cr0[3*x+2] = uint8(g >> 8) - cr0[3*x+3] = uint8(b >> 8) - } + for x := b.Min.X; x < b.Max.X; x++ { + // We have previously verified that the alpha value is fully opaque. + r, g, b, _ := m.At(x, y).RGBA() + cr[0][3*x+1] = uint8(r >> 8) + cr[0][3*x+2] = uint8(g >> 8) + cr[0][3*x+3] = uint8(b >> 8) } case cbP8: rowOffset := y * paletted.Stride diff --git a/src/pkg/image/png/writer_test.go b/src/pkg/image/png/writer_test.go index 6b054aaa8..4d9929f31 100644 --- a/src/pkg/image/png/writer_test.go +++ b/src/pkg/image/png/writer_test.go @@ -5,10 +5,10 @@ package png import ( + "bytes" "fmt" "image" "io" - "io/ioutil" "os" "testing" ) @@ -81,42 +81,10 @@ func BenchmarkEncodePaletted(b *testing.B) { image.RGBAColor{0, 0, 0, 255}, image.RGBAColor{255, 255, 255, 255}, }) - b.SetBytes(640 * 480 * 1) b.StartTimer() + buffer := new(bytes.Buffer) for i := 0; i < b.N; i++ { - Encode(ioutil.Discard, img) - } -} - -func BenchmarkEncodeRGBOpaque(b *testing.B) { - b.StopTimer() - img := image.NewRGBA(640, 480) - // Set all pixels to 0xFF alpha to force opaque mode. - bo := img.Bounds() - for y := bo.Min.Y; y < bo.Max.Y; y++ { - for x := bo.Min.X; x < bo.Max.X; x++ { - img.Set(x, y, image.RGBAColor{0, 0, 0, 255}) - } - } - if !img.Opaque() { - panic("expected image to be opaque") - } - b.SetBytes(640 * 480 * 4) - b.StartTimer() - for i := 0; i < b.N; i++ { - Encode(ioutil.Discard, img) - } -} - -func BenchmarkEncodeRGBA(b *testing.B) { - b.StopTimer() - img := image.NewRGBA(640, 480) - if img.Opaque() { - panic("expected image to not be opaque") - } - b.SetBytes(640 * 480 * 4) - b.StartTimer() - for i := 0; i < b.N; i++ { - Encode(ioutil.Discard, img) + buffer.Reset() + Encode(buffer, img) } } diff --git a/src/pkg/mime/multipart/multipart.go b/src/pkg/mime/multipart/multipart.go index 60329fe17..e0b747c3f 100644 --- a/src/pkg/mime/multipart/multipart.go +++ b/src/pkg/mime/multipart/multipart.go @@ -15,13 +15,13 @@ package multipart import ( "bufio" "bytes" - "fmt" "io" "io/ioutil" "mime" "net/textproto" "os" "regexp" + "strings" ) var headerRegexp *regexp.Regexp = regexp.MustCompile("^([a-zA-Z0-9\\-]+): *([^\r\n]+)") @@ -79,28 +79,25 @@ func (p *Part) FormName() string { // NewReader creates a new multipart Reader reading from r using the // given MIME boundary. func NewReader(reader io.Reader, boundary string) Reader { - b := []byte("\r\n--" + boundary + "--") return &multiReader{ - bufReader: bufio.NewReader(reader), - - nlDashBoundary: b[:len(b)-2], - dashBoundaryDash: b[2:], - dashBoundary: b[2 : len(b)-2], + boundary: boundary, + dashBoundary: "--" + boundary, + endLine: "--" + boundary + "--", + bufReader: bufio.NewReader(reader), } } // Implementation .... -func newPart(mr *multiReader) (*Part, os.Error) { - bp := &Part{ - Header: make(map[string][]string), - mr: mr, - buffer: new(bytes.Buffer), - } - if err := bp.populateHeaders(); err != nil { - return nil, err +func newPart(mr *multiReader) (bp *Part, err os.Error) { + bp = new(Part) + bp.Header = make(map[string][]string) + bp.mr = mr + bp.buffer = new(bytes.Buffer) + if err = bp.populateHeaders(); err != nil { + bp = nil } - return bp, nil + return } func (bp *Part) populateHeaders() os.Error { @@ -125,49 +122,44 @@ func (bp *Part) populateHeaders() os.Error { // Read reads the body of a part, after its headers and before the // next part (if any) begins. func (bp *Part) Read(p []byte) (n int, err os.Error) { - if bp.buffer.Len() >= len(p) { - // Internal buffer of unconsumed data is large enough for - // the read request. No need to parse more at the moment. - return bp.buffer.Read(p) - } - peek, err := bp.mr.bufReader.Peek(4096) // TODO(bradfitz): add buffer size accessor - unexpectedEof := err == os.EOF - if err != nil && !unexpectedEof { - return 0, fmt.Errorf("multipart: Part Read: %v", err) - } - if peek == nil { - panic("nil peek buf") - } + for { + if bp.buffer.Len() >= len(p) { + // Internal buffer of unconsumed data is large enough for + // the read request. No need to parse more at the moment. + break + } + if !bp.mr.ensureBufferedLine() { + return 0, io.ErrUnexpectedEOF + } + if bp.mr.bufferedLineIsBoundary() { + // Don't consume this line + break + } - // Search the peek buffer for "\r\n--boundary". If found, - // consume everything up to the boundary. If not, consume only - // as much of the peek buffer as cannot hold the boundary - // string. - nCopy := 0 - foundBoundary := false - if idx := bytes.Index(peek, bp.mr.nlDashBoundary); idx != -1 { - nCopy = idx - foundBoundary = true - } else if safeCount := len(peek) - len(bp.mr.nlDashBoundary); safeCount > 0 { - nCopy = safeCount - } else if unexpectedEof { - // If we've run out of peek buffer and the boundary - // wasn't found (and can't possibly fit), we must have - // hit the end of the file unexpectedly. - return 0, io.ErrUnexpectedEOF - } - if nCopy > 0 { - if _, err := io.Copyn(bp.buffer, bp.mr.bufReader, int64(nCopy)); err != nil { - return 0, err + // Write all of this line, except the final CRLF + s := *bp.mr.bufferedLine + if strings.HasSuffix(s, "\r\n") { + bp.mr.consumeLine() + if !bp.mr.ensureBufferedLine() { + return 0, io.ErrUnexpectedEOF + } + if bp.mr.bufferedLineIsBoundary() { + // The final \r\n isn't ours. It logically belongs + // to the boundary line which follows. + bp.buffer.WriteString(s[0 : len(s)-2]) + } else { + bp.buffer.WriteString(s) + } + break } + if strings.HasSuffix(s, "\n") { + bp.buffer.WriteString(s) + bp.mr.consumeLine() + continue + } + return 0, os.NewError("multipart parse error during Read; unexpected line: " + s) } - n, err = bp.buffer.Read(p) - if err == os.EOF && !foundBoundary { - // If the boundary hasn't been reached there's more to - // read, so don't pass through an EOF from the buffer - err = nil - } - return + return bp.buffer.Read(p) } func (bp *Part) Close() os.Error { @@ -176,12 +168,46 @@ func (bp *Part) Close() os.Error { } type multiReader struct { - bufReader *bufio.Reader + boundary string + dashBoundary string // --boundary + endLine string // --boundary-- + bufferedLine *string + + bufReader *bufio.Reader currentPart *Part partsRead int +} - nlDashBoundary, dashBoundaryDash, dashBoundary []byte +func (mr *multiReader) eof() bool { + return mr.bufferedLine == nil && + !mr.readLine() +} + +func (mr *multiReader) readLine() bool { + lineBytes, err := mr.bufReader.ReadSlice('\n') + if err != nil { + // TODO: care about err being EOF or not? + return false + } + line := string(lineBytes) + mr.bufferedLine = &line + return true +} + +func (mr *multiReader) bufferedLineIsBoundary() bool { + return strings.HasPrefix(*mr.bufferedLine, mr.dashBoundary) +} + +func (mr *multiReader) ensureBufferedLine() bool { + if mr.bufferedLine == nil { + return mr.readLine() + } + return true +} + +func (mr *multiReader) consumeLine() { + mr.bufferedLine = nil } func (mr *multiReader) NextPart() (*Part, os.Error) { @@ -189,14 +215,13 @@ func (mr *multiReader) NextPart() (*Part, os.Error) { mr.currentPart.Close() } - expectNewPart := false for { - line, err := mr.bufReader.ReadSlice('\n') - if err != nil { - return nil, fmt.Errorf("multipart: NextPart: %v", err) + if mr.eof() { + return nil, io.ErrUnexpectedEOF } - if mr.isBoundaryDelimiterLine(line) { + if isBoundaryDelimiterLine(*mr.bufferedLine, mr.dashBoundary) { + mr.consumeLine() mr.partsRead++ bp, err := newPart(mr) if err != nil { @@ -206,67 +231,55 @@ func (mr *multiReader) NextPart() (*Part, os.Error) { return bp, nil } - if hasPrefixThenNewline(line, mr.dashBoundaryDash) { + if hasPrefixThenNewline(*mr.bufferedLine, mr.endLine) { + mr.consumeLine() // Expected EOF (no error) - // TODO(bradfitz): should return an os.EOF error here, not using nil for errors return nil, nil } - if expectNewPart { - return nil, fmt.Errorf("multipart: expecting a new Part; got line %q", string(line)) - } - if mr.partsRead == 0 { // skip line + mr.consumeLine() continue } - if bytes.Equal(line, []byte("\r\n")) { - // Consume the "\r\n" separator between the - // body of the previous part and the boundary - // line we now expect will follow. (either a - // new part or the end boundary) - expectNewPart = true - continue - } - - return nil, fmt.Errorf("multipart: unexpected line in Next(): %q", line) + return nil, os.NewError("Unexpected line in Next().") } panic("unreachable") } -func (mr *multiReader) isBoundaryDelimiterLine(line []byte) bool { +func isBoundaryDelimiterLine(line, dashPrefix string) bool { // http://tools.ietf.org/html/rfc2046#section-5.1 // The boundary delimiter line is then defined as a line // consisting entirely of two hyphen characters ("-", // decimal value 45) followed by the boundary parameter // value from the Content-Type header field, optional linear // whitespace, and a terminating CRLF. - if !bytes.HasPrefix(line, mr.dashBoundary) { + if !strings.HasPrefix(line, dashPrefix) { return false } - if bytes.HasSuffix(line, []byte("\r\n")) { - return onlyHorizontalWhitespace(line[len(mr.dashBoundary) : len(line)-2]) + if strings.HasSuffix(line, "\r\n") { + return onlyHorizontalWhitespace(line[len(dashPrefix) : len(line)-2]) } // Violate the spec and also support newlines without the // carriage return... - if bytes.HasSuffix(line, []byte("\n")) { - return onlyHorizontalWhitespace(line[len(mr.dashBoundary) : len(line)-1]) + if strings.HasSuffix(line, "\n") { + return onlyHorizontalWhitespace(line[len(dashPrefix) : len(line)-1]) } return false } -func onlyHorizontalWhitespace(s []byte) bool { - for _, b := range s { - if b != ' ' && b != '\t' { +func onlyHorizontalWhitespace(s string) bool { + for i := 0; i < len(s); i++ { + if s[i] != ' ' && s[i] != '\t' { return false } } return true } -func hasPrefixThenNewline(s, prefix []byte) bool { - return bytes.HasPrefix(s, prefix) && - (len(s) == len(prefix)+1 && s[len(s)-1] == '\n' || - len(s) == len(prefix)+2 && bytes.HasSuffix(s, []byte("\r\n"))) +func hasPrefixThenNewline(s, prefix string) bool { + return strings.HasPrefix(s, prefix) && + (len(s) == len(prefix)+1 && strings.HasSuffix(s, "\n") || + len(s) == len(prefix)+2 && strings.HasSuffix(s, "\r\n")) } diff --git a/src/pkg/mime/multipart/multipart_test.go b/src/pkg/mime/multipart/multipart_test.go index 16249146c..f8f10f3e1 100644 --- a/src/pkg/mime/multipart/multipart_test.go +++ b/src/pkg/mime/multipart/multipart_test.go @@ -8,37 +8,38 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "json" "os" + "regexp" "strings" "testing" ) func TestHorizontalWhitespace(t *testing.T) { - if !onlyHorizontalWhitespace([]byte(" \t")) { + if !onlyHorizontalWhitespace(" \t") { t.Error("expected pass") } - if onlyHorizontalWhitespace([]byte("foo bar")) { + if onlyHorizontalWhitespace("foo bar") { t.Error("expected failure") } } func TestBoundaryLine(t *testing.T) { - mr := NewReader(strings.NewReader(""), "myBoundary").(*multiReader) - if !mr.isBoundaryDelimiterLine([]byte("--myBoundary\r\n")) { + boundary := "myBoundary" + prefix := "--" + boundary + if !isBoundaryDelimiterLine("--myBoundary\r\n", prefix) { t.Error("expected") } - if !mr.isBoundaryDelimiterLine([]byte("--myBoundary \r\n")) { + if !isBoundaryDelimiterLine("--myBoundary \r\n", prefix) { t.Error("expected") } - if !mr.isBoundaryDelimiterLine([]byte("--myBoundary \n")) { + if !isBoundaryDelimiterLine("--myBoundary \n", prefix) { t.Error("expected") } - if mr.isBoundaryDelimiterLine([]byte("--myBoundary bogus \n")) { + if isBoundaryDelimiterLine("--myBoundary bogus \n", prefix) { t.Error("expected fail") } - if mr.isBoundaryDelimiterLine([]byte("--myBoundary bogus--")) { + if isBoundaryDelimiterLine("--myBoundary bogus--", prefix) { t.Error("expected fail") } } @@ -78,9 +79,7 @@ func TestFormName(t *testing.T) { } } -var longLine = strings.Repeat("\n\n\r\r\r\n\r\000", (1<<20)/8) - -func testMultipartBody() string { +func TestMultipart(t *testing.T) { testBody := ` This is a multi-part message. This line is ignored. --MyBoundary @@ -91,10 +90,6 @@ foo-bar: baz My value The end. --MyBoundary -name: bigsection - -[longline] ---MyBoundary Header1: value1b HEADER2: value2b foo-bar: bazb @@ -107,26 +102,11 @@ Line 3 ends in a newline, but just one. never read data --MyBoundary-- - - -useless trailer ` - testBody = strings.Replace(testBody, "\n", "\r\n", -1) - return strings.Replace(testBody, "[longline]", longLine, 1) -} - -func TestMultipart(t *testing.T) { - bodyReader := strings.NewReader(testMultipartBody()) - testMultipart(t, bodyReader) -} - -func TestMultipartSlowInput(t *testing.T) { - bodyReader := strings.NewReader(testMultipartBody()) - testMultipart(t, &slowReader{bodyReader}) -} + testBody = regexp.MustCompile("\n").ReplaceAllString(testBody, "\r\n") + bodyReader := strings.NewReader(testBody) -func testMultipart(t *testing.T, r io.Reader) { - reader := NewReader(r, "MyBoundary") + reader := NewReader(bodyReader, "MyBoundary") buf := new(bytes.Buffer) // Part1 @@ -145,64 +125,38 @@ func testMultipart(t *testing.T, r io.Reader) { t.Error("Expected Foo-Bar: baz") } buf.Reset() - if _, err := io.Copy(buf, part); err != nil { - t.Errorf("part 1 copy: %v", err) - } + io.Copy(buf, part) expectEq(t, "My value\r\nThe end.", buf.String(), "Value of first part") // Part2 part, err = reader.NextPart() - if err != nil { - t.Fatalf("Expected part2; got: %v", err) - return - } - if e, g := "bigsection", part.Header.Get("name"); e != g { - t.Errorf("part2's name header: expected %q, got %q", e, g) - } - buf.Reset() - if _, err := io.Copy(buf, part); err != nil { - t.Errorf("part 2 copy: %v", err) - } - s := buf.String() - if len(s) != len(longLine) { - t.Errorf("part2 body expected long line of length %d; got length %d", - len(longLine), len(s)) - } - if s != longLine { - t.Errorf("part2 long body didn't match") - } - - // Part3 - part, err = reader.NextPart() if part == nil || err != nil { - t.Error("Expected part3") + t.Error("Expected part2") return } if part.Header.Get("foo-bar") != "bazb" { t.Error("Expected foo-bar: bazb") } buf.Reset() - if _, err := io.Copy(buf, part); err != nil { - t.Errorf("part 3 copy: %v", err) - } + io.Copy(buf, part) expectEq(t, "Line 1\r\nLine 2\r\nLine 3 ends in a newline, but just one.\r\n", - buf.String(), "body of part 3") + buf.String(), "Value of second part") - // Part4 + // Part3 part, err = reader.NextPart() if part == nil || err != nil { - t.Error("Expected part 4 without errors") + t.Error("Expected part3 without errors") return } - // Non-existent part5 + // Non-existent part4 part, err = reader.NextPart() if part != nil { - t.Error("Didn't expect a fifth part.") + t.Error("Didn't expect a third part.") } if err != nil { - t.Errorf("Unexpected error getting fifth part: %v", err) + t.Errorf("Unexpected error getting third part: %v", err) } } @@ -283,36 +237,3 @@ func TestLineLimit(t *testing.T) { t.Errorf("expected to read < %d bytes; read %d", maxReadThreshold, mr.n) } } - -func TestMultipartTruncated(t *testing.T) { - testBody := ` -This is a multi-part message. This line is ignored. ---MyBoundary -foo-bar: baz - -Oh no, premature EOF! -` - body := strings.Replace(testBody, "\n", "\r\n", -1) - bodyReader := strings.NewReader(body) - r := NewReader(bodyReader, "MyBoundary") - - part, err := r.NextPart() - if err != nil { - t.Fatalf("didn't get a part") - } - _, err = io.Copy(ioutil.Discard, part) - if err != io.ErrUnexpectedEOF { - t.Fatalf("expected error io.ErrUnexpectedEOF; got %v", err) - } -} - -type slowReader struct { - r io.Reader -} - -func (s *slowReader) Read(p []byte) (int, os.Error) { - if len(p) == 0 { - return s.r.Read(p) - } - return s.r.Read(p[:1]) -} diff --git a/src/pkg/reflect/all_test.go b/src/pkg/reflect/all_test.go index dee3f4915..5bf65333c 100644 --- a/src/pkg/reflect/all_test.go +++ b/src/pkg/reflect/all_test.go @@ -182,9 +182,7 @@ var valueTests = []pair{ }), "struct { c chan *int32; d float32 }{chan *int32, 0}", }, - {new(struct { - c func(chan *integer, *int8) - }), + {new(struct{ c func(chan *integer, *int8) }), "struct { c func(chan *reflect_test.integer, *int8) }{func(chan *reflect_test.integer, *int8)(0)}", }, {new(struct { @@ -734,24 +732,6 @@ func TestDeepEqualComplexStructInequality(t *testing.T) { } } -type UnexpT struct { - m map[int]int -} - -func TestDeepEqualUnexportedMap(t *testing.T) { - // Check that DeepEqual can look at unexported fields. - x1 := UnexpT{map[int]int{1: 2}} - x2 := UnexpT{map[int]int{1: 2}} - if !DeepEqual(&x1, &x2) { - t.Error("DeepEqual(x1, x2) = false, want true") - } - - y1 := UnexpT{map[int]int{2: 3}} - if DeepEqual(&x1, &y1) { - t.Error("DeepEqual(x1, y1) = true, want false") - } -} - func check2ndField(x interface{}, offs uintptr, t *testing.T) { s := ValueOf(x) diff --git a/src/pkg/reflect/value.go b/src/pkg/reflect/value.go index 2c2158a3c..6dffb0783 100644 --- a/src/pkg/reflect/value.go +++ b/src/pkg/reflect/value.go @@ -958,19 +958,14 @@ func (v Value) MapIndex(key Value) Value { iv.mustBe(Map) typ := iv.typ.toType() - // Do not require ikey to be exported, so that DeepEqual - // and other programs can use all the keys returned by - // MapKeys as arguments to MapIndex. If either the map - // or the key is unexported, though, the result will be - // considered unexported. - ikey := key.internal() + ikey.mustBeExported() ikey = convertForAssignment("reflect.Value.MapIndex", nil, typ.Key(), ikey) if iv.word == 0 { return Value{} } - flag := (iv.flag | ikey.flag) & flagRO + flag := iv.flag & flagRO elemType := typ.Elem() elemWord, ok := mapaccess(iv.word, ikey.word) if !ok { diff --git a/src/pkg/runtime/linux/arm/sys.s b/src/pkg/runtime/linux/arm/sys.s index 2b5365bd8..d866b0e22 100644 --- a/src/pkg/runtime/linux/arm/sys.s +++ b/src/pkg/runtime/linux/arm/sys.s @@ -258,23 +258,12 @@ TEXT cas<>(SB),7,$0 TEXT runtime·cas(SB),7,$0 MOVW valptr+0(FP), R2 MOVW old+4(FP), R0 -casagain: MOVW new+8(FP), R1 BL cas<>(SB) - BCC cascheck - MOVW $1, R0 - RET -cascheck: - // Kernel lies; double-check. - MOVW valptr+0(FP), R2 - MOVW old+4(FP), R0 - MOVW 0(R2), R3 - CMP R0, R3 - BEQ casagain - MOVW $0, R0 + MOVW $0, R0 + MOVW.CS $1, R0 RET - TEXT runtime·casp(SB),7,$0 B runtime·cas(SB) diff --git a/src/pkg/sync/atomic/asm_linux_arm.s b/src/pkg/sync/atomic/asm_linux_arm.s index 72f8d746b..5e7aea292 100644 --- a/src/pkg/sync/atomic/asm_linux_arm.s +++ b/src/pkg/sync/atomic/asm_linux_arm.s @@ -13,12 +13,6 @@ // LR = return address // The function returns with CS true if the swap happened. // http://lxr.linux.no/linux+v2.6.37.2/arch/arm/kernel/entry-armv.S#L850 -// On older kernels (before 2.6.24) the function can incorrectly -// report a conflict, so we have to double-check the compare ourselves -// and retry if necessary. -// -// http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b49c0f24cf6744a3f4fd09289fe7cade349dead5 -// TEXT cas<>(SB),7,$0 MOVW $0xffff0fc0, PC @@ -29,23 +23,12 @@ TEXT ·CompareAndSwapInt32(SB),7,$0 TEXT ·CompareAndSwapUint32(SB),7,$0 MOVW valptr+0(FP), R2 MOVW old+4(FP), R0 -casagain: MOVW new+8(FP), R1 BL cas<>(SB) - BCC cascheck - MOVW $1, R0 -casret: + MOVW $0, R0 + MOVW.CS $1, R0 MOVW R0, ret+12(FP) RET -cascheck: - // Kernel lies; double-check. - MOVW valptr+0(FP), R2 - MOVW old+4(FP), R0 - MOVW 0(R2), R3 - CMP R0, R3 - BEQ casagain - MOVW $0, R0 - B casret TEXT ·CompareAndSwapUintptr(SB),7,$0 B ·CompareAndSwapUint32(SB) diff --git a/src/pkg/xml/read.go b/src/pkg/xml/read.go index e2b349c3f..554b2a61b 100644 --- a/src/pkg/xml/read.go +++ b/src/pkg/xml/read.go @@ -220,10 +220,13 @@ func (p *Parser) unmarshal(val reflect.Value, start *StartElement) os.Error { } if pv := val; pv.Kind() == reflect.Ptr { - if pv.IsNil() { - pv.Set(reflect.New(pv.Type().Elem())) + if pv.Pointer() == 0 { + zv := reflect.Zero(pv.Type().Elem()) + pv.Set(zv.Addr()) + val = zv + } else { + val = pv.Elem() } - val = pv.Elem() } var ( diff --git a/src/pkg/xml/xml_test.go b/src/pkg/xml/xml_test.go index 4e51cd53a..a99c1919e 100644 --- a/src/pkg/xml/xml_test.go +++ b/src/pkg/xml/xml_test.go @@ -329,50 +329,46 @@ func TestSyntax(t *testing.T) { } type allScalars struct { - True1 bool - True2 bool - False1 bool - False2 bool - Int int - Int8 int8 - Int16 int16 - Int32 int32 - Int64 int64 - Uint int - Uint8 uint8 - Uint16 uint16 - Uint32 uint32 - Uint64 uint64 - Uintptr uintptr - Float32 float32 - Float64 float64 - String string - PtrString *string + True1 bool + True2 bool + False1 bool + False2 bool + Int int + Int8 int8 + Int16 int16 + Int32 int32 + Int64 int64 + Uint int + Uint8 uint8 + Uint16 uint16 + Uint32 uint32 + Uint64 uint64 + Uintptr uintptr + Float32 float32 + Float64 float64 + String string } var all = allScalars{ - True1: true, - True2: true, - False1: false, - False2: false, - Int: 1, - Int8: -2, - Int16: 3, - Int32: -4, - Int64: 5, - Uint: 6, - Uint8: 7, - Uint16: 8, - Uint32: 9, - Uint64: 10, - Uintptr: 11, - Float32: 13.0, - Float64: 14.0, - String: "15", - PtrString: &sixteen, -} - -var sixteen = "16" + True1: true, + True2: true, + False1: false, + False2: false, + Int: 1, + Int8: -2, + Int16: 3, + Int32: -4, + Int64: 5, + Uint: 6, + Uint8: 7, + Uint16: 8, + Uint32: 9, + Uint64: 10, + Uintptr: 11, + Float32: 13.0, + Float64: 14.0, + String: "15", +} const testScalarsInput = `<allscalars> <true1>true</true1> @@ -394,7 +390,6 @@ const testScalarsInput = `<allscalars> <float32>13.0</float32> <float64>14.0</float64> <string>15</string> - <ptrstring>16</ptrstring> </allscalars>` func TestAllScalars(t *testing.T) { @@ -406,7 +401,7 @@ func TestAllScalars(t *testing.T) { t.Fatal(err) } if !reflect.DeepEqual(a, all) { - t.Errorf("have %+v want %+v", a, all) + t.Errorf("expected %+v got %+v", all, a) } } |