// TODO(prashant): Use a small buffer and then flush it when it's full. func writeHeaders(w io.Writer, headers map[string]string) error { // Calculate the size of the buffer that we need. size := 2 for k, v := range headers { size += 4 /* size of key/value lengths */ size += len(k) + len(v) } buf := make([]byte, size) writeBuffer := typed.NewWriteBuffer(buf) writeBuffer.WriteUint16(uint16(len(headers))) for k, v := range headers { writeBuffer.WriteLen16String(k) writeBuffer.WriteLen16String(v) } if err := writeBuffer.Err(); err != nil { return err } // Safety check to ensure the bytes written calculation is correct. if writeBuffer.BytesWritten() != size { return fmt.Errorf("writeHeaders size calculation wrong, expected to write %v bytes, only wrote %v bytes", size, writeBuffer.BytesWritten()) } _, err := writeBuffer.FlushTo(w) return err }
func (ch fragmentChannel) newFragment(initial bool, checksum Checksum) (*writableFragment, error) { wbuf := typed.NewWriteBuffer(make([]byte, testFragmentSize)) fragment := new(writableFragment) fragment.flagsRef = wbuf.DeferByte() wbuf.WriteSingleByte(byte(checksum.TypeCode())) fragment.checksumRef = wbuf.DeferBytes(checksum.Size()) fragment.checksum = checksum fragment.contents = wbuf return fragment, wbuf.Err() }
// newFragment creates a new fragment for marshaling into func (w *reqResWriter) newFragment(initial bool, checksum Checksum) (*writableFragment, error) { message := w.messageForFragment(initial) // Create the frame frame := w.conn.framePool.Get() frame.Header.ID = w.mex.msgID frame.Header.messageType = message.messageType() // Write the message into the fragment, reserving flags and checksum bytes wbuf := typed.NewWriteBuffer(frame.Payload[:]) fragment := new(writableFragment) fragment.frame = frame fragment.flagsRef = wbuf.DeferByte() if err := message.write(wbuf); err != nil { return nil, err } wbuf.WriteByte(byte(checksum.TypeCode())) fragment.checksumRef = wbuf.DeferBytes(checksum.Size()) fragment.checksum = checksum fragment.contents = wbuf return fragment, wbuf.Err() }