Encode encodes content of buf and writes to w. Encode returns Digest header value (or MI header value in draft 02), and error if one exists.
(w io.Writer, buf []byte, recordSize int)
| 70 | // Encode encodes content of buf and writes to w. Encode returns Digest header |
| 71 | // value (or MI header value in draft 02), and error if one exists. |
| 72 | func (enc Encoding) Encode(w io.Writer, buf []byte, recordSize int) (string, error) { |
| 73 | |
| 74 | numRecords := (len(buf) + recordSize - 1) / recordSize |
| 75 | |
| 76 | switch enc { |
| 77 | case Draft02Encoding: |
| 78 | if len(buf) == 0 { |
| 79 | numRecords = 1 |
| 80 | } |
| 81 | |
| 82 | case Draft03Encoding: |
| 83 | if len(buf) == 0 { |
| 84 | // As a special case, the encoding of an empty payload is itself an |
| 85 | // empty message (i.e. it omits the initial record size), and its |
| 86 | // integrity proof is SHA-256("\0"). [spec text] |
| 87 | h := sha256.New() |
| 88 | h.Write([]byte{0}) |
| 89 | proof := h.Sum(nil) |
| 90 | return enc.FormatDigestHeader(proof), nil |
| 91 | } |
| 92 | |
| 93 | default: |
| 94 | panic("not reached") |
| 95 | } |
| 96 | |
| 97 | // Calculate proofs. This loop iterates from the tail of the content and creates |
| 98 | // the proof chain. |
| 99 | proofs := make([][]byte, numRecords) |
| 100 | for i := 0; i < numRecords; i++ { |
| 101 | rec := numRecords - i - 1 |
| 102 | h := sha256.New() |
| 103 | if i == 0 { |
| 104 | h.Write(buf[rec*recordSize:]) |
| 105 | h.Write([]byte{0}) |
| 106 | } else { |
| 107 | h.Write(buf[rec*recordSize : (rec+1)*recordSize]) |
| 108 | h.Write(proofs[rec+1]) |
| 109 | h.Write([]byte{1}) |
| 110 | } |
| 111 | proofs[rec] = h.Sum(nil) |
| 112 | } |
| 113 | |
| 114 | if err := binary.Write(w, binary.BigEndian, uint64(recordSize)); err != nil { |
| 115 | return "", err |
| 116 | } |
| 117 | for i, proof := range proofs { |
| 118 | if i != 0 { |
| 119 | if _, err := w.Write(proof); err != nil { |
| 120 | return "", err |
| 121 | } |
| 122 | } |
| 123 | high := (i + 1) * recordSize |
| 124 | if high > len(buf) { |
| 125 | high = len(buf) |
| 126 | } |
| 127 | if _, err := w.Write(buf[i*recordSize : high]); err != nil { |
| 128 | return "", err |
| 129 | } |