| 397 | } |
| 398 | |
| 399 | func (g *Grep) Reader(r io.Reader, name string) { |
| 400 | if g.buf == nil { |
| 401 | g.buf = make([]byte, 1<<20) |
| 402 | } |
| 403 | var ( |
| 404 | buf = g.buf[:0] |
| 405 | needLineno = g.N |
| 406 | lineno = 1 |
| 407 | count = 0 |
| 408 | prefix = "" |
| 409 | beginText = true |
| 410 | endText = false |
| 411 | ) |
| 412 | if !g.H { |
| 413 | prefix = name + ":" |
| 414 | } |
| 415 | for { |
| 416 | n, err := io.ReadFull(r, buf[len(buf):cap(buf)]) |
| 417 | buf = buf[:len(buf)+n] |
| 418 | end := len(buf) |
| 419 | if err == nil { |
| 420 | i := bytes.LastIndex(buf, nl) |
| 421 | if i >= 0 { |
| 422 | end = i + 1 |
| 423 | } |
| 424 | } else { |
| 425 | endText = true |
| 426 | } |
| 427 | chunkStart := 0 |
| 428 | for chunkStart < end { |
| 429 | m1 := g.Regexp.Match(buf[chunkStart:end], beginText, endText) + chunkStart |
| 430 | beginText = false |
| 431 | if m1 < chunkStart { |
| 432 | break |
| 433 | } |
| 434 | g.Match = true |
| 435 | if g.L { |
| 436 | fmt.Fprintf(g.Stdout, "%s\n", name) |
| 437 | return |
| 438 | } |
| 439 | lineStart := bytes.LastIndex(buf[chunkStart:m1], nl) + 1 + chunkStart |
| 440 | lineEnd := m1 + 1 |
| 441 | if lineEnd > end { |
| 442 | lineEnd = end |
| 443 | } |
| 444 | if needLineno { |
| 445 | lineno += countNL(buf[chunkStart:lineStart]) |
| 446 | } |
| 447 | line := buf[lineStart:lineEnd] |
| 448 | nl := "" |
| 449 | if len(line) == 0 || line[len(line)-1] != '\n' { |
| 450 | nl = "\n" |
| 451 | } |
| 452 | switch { |
| 453 | case g.C: |
| 454 | count++ |
| 455 | case g.N: |
| 456 | fmt.Fprintf(g.Stdout, "%s%d:%s%s", prefix, lineno, line, nl) |