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