Write implements io.Writer.
(b []byte)
| 784 | |
| 785 | // Write implements io.Writer. |
| 786 | func (s *state) Write(b []byte) (n int, err error) { |
| 787 | if len(b) == 0 { |
| 788 | return 0, nil |
| 789 | } |
| 790 | k := 0 |
| 791 | |
| 792 | sep := detailSep |
| 793 | if !s.wantDetail { |
| 794 | sep = []byte("\n") |
| 795 | } |
| 796 | |
| 797 | for i, c := range b { |
| 798 | if c == '\n' { |
| 799 | //if s.needNewline > 0 { |
| 800 | // for i := 0; i < s.needNewline-1; i++ { |
| 801 | // s.buf.Write(detailSep[:len(sep)-1]) |
| 802 | // } |
| 803 | // s.needNewline = 0 |
| 804 | //} |
| 805 | // Flush all the bytes seen so far. |
| 806 | s.buf.Write(b[k:i]) |
| 807 | // Don't print the newline itself; instead, prepare the state so |
| 808 | // that the _next_ character encountered will pad with a newline. |
| 809 | // This algorithm avoids terminating error details with excess |
| 810 | // newline characters. |
| 811 | k = i + 1 |
| 812 | s.needNewline++ |
| 813 | s.needSpace = false |
| 814 | s.multiLine = true |
| 815 | if s.wantDetail { |
| 816 | s.switchOver() |
| 817 | } |
| 818 | } else { |
| 819 | if s.needNewline > 0 && s.notEmpty { |
| 820 | // If newline chars were pending, display them now. |
| 821 | for i := 0; i < s.needNewline-1; i++ { |
| 822 | s.buf.Write(detailSep[:len(sep)-1]) |
| 823 | } |
| 824 | s.buf.Write(sep) |
| 825 | s.needNewline = 0 |
| 826 | s.needSpace = false |
| 827 | } else if s.needSpace { |
| 828 | s.buf.WriteByte(' ') |
| 829 | s.needSpace = false |
| 830 | } |
| 831 | s.notEmpty = true |
| 832 | } |
| 833 | } |
| 834 | //if s.needNewline > 0 { |
| 835 | // for i := 0; i < s.needNewline-1; i++ { |
| 836 | // s.buf.Write(detailSep[:len(sep)-1]) |
| 837 | // } |
| 838 | //} |
| 839 | s.buf.Write(b[k:]) |
| 840 | return len(b), nil |
| 841 | } |
| 842 | |
| 843 | // printer wraps a state to implement an xerrors.Printer. |