package syncio

import (
	
	

	
)

// WriterAt is synchronized io.WriterAt.
type WriterAt struct {
	w   io.WriterAt
	mux sync.Mutex
}

// NewWriterAt creates new WriterAt.
func ( io.WriterAt) *WriterAt {
	return &WriterAt{w: }
}

// WriteAt implements io.WriterAt.
func ( *WriterAt) ( []byte,  int64) ( int,  error) {
	.mux.Lock()
	,  = .w.WriteAt(, )
	.mux.Unlock()

	return
}

// BufWriterAt is synchronized buffer which implements io.WriterAt.
type BufWriterAt struct {
	buf []byte
	mux sync.RWMutex
}

// Bytes returns copy of data from buffer.
func ( *BufWriterAt) () ( []byte) {
	.mux.RLock()
	defer .mux.RUnlock()

	return append(make([]byte, 0, len(.buf)), .buf...)
}

// Len returns buffer available data size.
func ( *BufWriterAt) () int {
	.mux.RLock()
	defer .mux.RUnlock()

	return len(.buf)
}

// ReadAt implements io.ReaderAt.
func ( *BufWriterAt) ( []byte,  int64) ( int,  error) {
	if  < 0 {
		return 0, errors.Errorf("invalid offset %d", )
	}

	.mux.RLock()
	defer .mux.RUnlock()

	 := int64(len(.buf))
	switch {
	case  >= :
		return 0, nil
	case +int64(len()) >= :
		 := .buf[:]
		copy(, )
		return len(), nil
	}

	 := 
	 :=  + int64(len())
	copy(, .buf[:])
	return len(), nil
}

// WriteAt implements io.WriterAt.
func ( *BufWriterAt) ( []byte,  int64) ( int,  error) {
	if  < 0 {
		return 0, errors.Errorf("invalid offset %d", )
	}

	.mux.Lock()
	defer .mux.Unlock()

	 := len() + int()
	if len(.buf) <  {
		 := make([]byte, )
		copy(, .buf)
		.buf = 
	}

	 := 
	 :=  + int64(len())
	copy(.buf[:], )
	return len(), nil
}