writer.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // Copyright (C) 2014 Jakob Borg and other contributors. All rights reserved.
  2. // Use of this source code is governed by an MIT-style license that can be
  3. // found in the LICENSE file.
  4. package xdr
  5. import (
  6. "io"
  7. "time"
  8. )
  9. func pad(l int) int {
  10. d := l % 4
  11. if d == 0 {
  12. return 0
  13. }
  14. return 4 - d
  15. }
  16. var padBytes = []byte{0, 0, 0}
  17. type Writer struct {
  18. w io.Writer
  19. tot int
  20. err error
  21. b [8]byte
  22. last time.Time
  23. }
  24. func NewWriter(w io.Writer) *Writer {
  25. return &Writer{
  26. w: w,
  27. }
  28. }
  29. func (w *Writer) WriteString(s string) (int, error) {
  30. return w.WriteBytes([]byte(s))
  31. }
  32. func (w *Writer) WriteBytes(bs []byte) (int, error) {
  33. if w.err != nil {
  34. return 0, w.err
  35. }
  36. w.last = time.Now()
  37. w.WriteUint32(uint32(len(bs)))
  38. if w.err != nil {
  39. return 0, w.err
  40. }
  41. if debug {
  42. if len(bs) > maxDebugBytes {
  43. dl.Debugf("wr bytes (%d): %x...", len(bs), bs[:maxDebugBytes])
  44. } else {
  45. dl.Debugf("wr bytes (%d): %x", len(bs), bs)
  46. }
  47. }
  48. var l, n int
  49. n, w.err = w.w.Write(bs)
  50. l += n
  51. if p := pad(len(bs)); w.err == nil && p > 0 {
  52. n, w.err = w.w.Write(padBytes[:p])
  53. l += n
  54. }
  55. w.tot += l
  56. return l, w.err
  57. }
  58. func (w *Writer) WriteUint16(v uint16) (int, error) {
  59. if w.err != nil {
  60. return 0, w.err
  61. }
  62. w.last = time.Now()
  63. if debug {
  64. dl.Debugf("wr uint16=%d", v)
  65. }
  66. w.b[0] = byte(v >> 8)
  67. w.b[1] = byte(v)
  68. w.b[2] = 0
  69. w.b[3] = 0
  70. var l int
  71. l, w.err = w.w.Write(w.b[:4])
  72. w.tot += l
  73. return l, w.err
  74. }
  75. func (w *Writer) WriteUint32(v uint32) (int, error) {
  76. if w.err != nil {
  77. return 0, w.err
  78. }
  79. w.last = time.Now()
  80. if debug {
  81. dl.Debugf("wr uint32=%d", v)
  82. }
  83. w.b[0] = byte(v >> 24)
  84. w.b[1] = byte(v >> 16)
  85. w.b[2] = byte(v >> 8)
  86. w.b[3] = byte(v)
  87. var l int
  88. l, w.err = w.w.Write(w.b[:4])
  89. w.tot += l
  90. return l, w.err
  91. }
  92. func (w *Writer) WriteUint64(v uint64) (int, error) {
  93. if w.err != nil {
  94. return 0, w.err
  95. }
  96. w.last = time.Now()
  97. if debug {
  98. dl.Debugf("wr uint64=%d", v)
  99. }
  100. w.b[0] = byte(v >> 56)
  101. w.b[1] = byte(v >> 48)
  102. w.b[2] = byte(v >> 40)
  103. w.b[3] = byte(v >> 32)
  104. w.b[4] = byte(v >> 24)
  105. w.b[5] = byte(v >> 16)
  106. w.b[6] = byte(v >> 8)
  107. w.b[7] = byte(v)
  108. var l int
  109. l, w.err = w.w.Write(w.b[:8])
  110. w.tot += l
  111. return l, w.err
  112. }
  113. func (w *Writer) Tot() int {
  114. return w.tot
  115. }
  116. func (w *Writer) Error() error {
  117. return w.err
  118. }
  119. func (w *Writer) LastWrite() time.Time {
  120. return w.last
  121. }