|
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- package iconv
-
- import "io"
-
- type Writer struct {
- destination io.Writer
- converter *Converter
- buffer []byte
- readPos, writePos int
- err error
- }
-
- func NewWriter(destination io.Writer, fromEncoding string, toEncoding string) (*Writer, error) {
- // create a converter
- converter, err := NewConverter(fromEncoding, toEncoding)
-
- if err == nil {
- return NewWriterFromConverter(destination, converter), err
- }
-
- // return the error
- return nil, err
- }
-
- func NewWriterFromConverter(destination io.Writer, converter *Converter) (writer *Writer) {
- writer = new(Writer)
-
- // copy elements
- writer.destination = destination
- writer.converter = converter
-
- // create 8K buffers
- writer.buffer = make([]byte, 8*1024)
-
- return writer
- }
-
- func (this *Writer) emptyBuffer() {
- // write new data out of buffer
- bytesWritten, err := this.destination.Write(this.buffer[this.readPos:this.writePos])
-
- // update read position
- this.readPos += bytesWritten
-
- // slide existing data to beginning
- if this.readPos > 0 {
- // copy current bytes - is this guaranteed safe?
- copy(this.buffer, this.buffer[this.readPos:this.writePos])
-
- // adjust positions
- this.writePos -= this.readPos
- this.readPos = 0
- }
-
- // track any reader error / EOF
- if err != nil {
- this.err = err
- }
- }
-
- // implement the io.Writer interface
- func (this *Writer) Write(p []byte) (n int, err error) {
- // write data into our internal buffer
- bytesRead, bytesWritten, err := this.converter.Convert(p, this.buffer[this.writePos:])
-
- // update bytes written for return
- n += bytesRead
- this.writePos += bytesWritten
-
- // checks for when we have a full buffer
- for this.writePos > 0 {
- // if we have an error, just return it
- if this.err != nil {
- return
- }
-
- // else empty the buffer
- this.emptyBuffer()
- }
-
- return n, err
- }
|