fragmenting_writer.go
func (w *fragmentingWriter) Close() error {
	last := w.state == fragmentingWriteInLastArgument
	if w.err != nil {
		return w.err
	}

	if !w.state.isWritingArgument() {
		w.err = errNotWritingArgument
		return w.err
	}

	w.curChunk.finish()

	// There are three possibilities here:
	// 1. There are no more arguments
	//      flush with more_fragments=false, mark the stream as complete
	// 2. There are more arguments, but we can't fit more data into this fragment
	//      flush with more_fragments=true, start new fragment, write empty chunk to indicate
	//      the current argument is complete
	// 3. There are more arguments, and we can fit more data into this fragment
	//      update the chunk but leave the current fragment open
	if last {
		// No more arguments - flush this final fragment and mark ourselves complete
		w.state = fragmentingWriteComplete
		w.curFragment.finish(false)
		w.err = w.sender.flushFragment(w.curFragment)
		w.sender.doneSending()
		return w.err
	}

	w.state = fragmentingWriteWaitingForArgument
	if w.curFragment.contents.BytesRemaining() > chunkHeaderSize {
		// There's enough room in this fragment for the next argument's
		// initial chunk, so we're done here
		return nil
	}

	// This fragment is full - flush and prepare for another argument
	w.curFragment.finish(true)
	if w.err = w.sender.flushFragment(w.curFragment); w.err != nil {
		return w.err
	}

	if w.curFragment, w.err = w.sender.newFragment(false, w.checksum); w.err != nil {
		return w.err
	}

	// Write an empty chunk to indicate this argument has ended
	w.curFragment.contents.WriteUint16(0)
	return nil
}
func (w *fragmentingWriter) Close() error {
	last := w.state == fragmentingWriteInLastArgument
	if w.err != nil {
		return w.err
	}

	if !w.state.isWritingArgument() {
		w.err = errNotWritingArgument
		return w.err
	}

	w.curChunk.finish()

	// There are three possibilities here:
	// 1. There are no more arguments
	//      flush with more_fragments=false, mark the stream as complete
	// 2. There are more arguments, but we can't fit more data into this fragment
	//      flush with more_fragments=true, start new fragment, write empty chunk to indicate
	//      the current argument is complete
	// 3. There are more arguments, and we can fit more data into this fragment
	//      update the chunk but leave the current fragment open
	if last {
		// No more arguments - flush this final fragment and mark ourselves complete
		w.state = fragmentingWriteComplete
		w.curFragment.finish(false)
		w.err = w.sender.flushFragment(w.curFragment)
		w.sender.doneSending()
		return w.err
	}

	w.state = fragmentingWriteWaitingForArgument
	if w.curFragment.contents.BytesRemaining() > chunkHeaderSize {
		// There's enough room in this fragment for the next argument's
		// initial chunk, so we're done here
		return nil
	}

	// This fragment is full - flush and prepare for another argument
	w.curFragment.finish(true)
	if w.err = w.sender.flushFragment(w.curFragment); w.err != nil {
		return w.err
	}

	if w.curFragment, w.err = w.sender.newFragment(false, w.checksum); w.err != nil {
		return w.err
	}

	// Write an empty chunk to indicate this argument has ended
	w.curFragment.contents.WriteUint16(0)
	return nil
}
// Close ends the current argument.