replacingwriter.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. // Copyright (C) 2014 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. package osutil
  7. import (
  8. "bytes"
  9. "io"
  10. "github.com/syncthing/syncthing/lib/build"
  11. )
  12. type ReplacingWriter struct {
  13. Writer io.Writer
  14. From byte
  15. To []byte
  16. }
  17. func (w ReplacingWriter) Write(bs []byte) (int, error) {
  18. var n, written int
  19. var err error
  20. newlineIdx := bytes.IndexByte(bs, w.From)
  21. for newlineIdx >= 0 {
  22. n, err = w.Writer.Write(bs[:newlineIdx])
  23. written += n
  24. if err != nil {
  25. break
  26. }
  27. if len(w.To) > 0 {
  28. n, err := w.Writer.Write(w.To)
  29. if n == len(w.To) {
  30. written++
  31. }
  32. if err != nil {
  33. break
  34. }
  35. }
  36. bs = bs[newlineIdx+1:]
  37. newlineIdx = bytes.IndexByte(bs, w.From)
  38. }
  39. n, err = w.Writer.Write(bs)
  40. written += n
  41. return written, err
  42. }
  43. // LineEndingsWriter returns a writer that writes platform-appropriate line
  44. // endings. (This is a no-op on non-Windows platforms.)
  45. func LineEndingsWriter(w io.Writer) io.Writer {
  46. if !build.IsWindows {
  47. return w
  48. }
  49. return &ReplacingWriter{
  50. Writer: w,
  51. From: '\n',
  52. To: []byte{'\r', '\n'},
  53. }
  54. }