gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

write.go (1082B)


      1 package bitio
      2 
      3 import (
      4 	"io"
      5 )
      6 
      7 type Writer interface {
      8 	io.Writer
      9 
     10 	// alignment:
     11 	//  |-1-byte-block-|--------------|--------------|--------------|
     12 	//  |<-offset->|<-------------------width---------------------->|
     13 	WriteBits(data []byte, width uint) error
     14 
     15 	WriteBit(bit bool) error
     16 }
     17 
     18 type writer struct {
     19 	writer io.Writer
     20 	octet  byte
     21 	width  uint
     22 }
     23 
     24 func NewWriter(w io.Writer) Writer {
     25 	return &writer{writer: w}
     26 }
     27 
     28 func (w *writer) Write(p []byte) (n int, err error) {
     29 	if w.width != 0 {
     30 		return 0, ErrInvalidAlignment
     31 	}
     32 	return w.writer.Write(p)
     33 }
     34 
     35 func (w *writer) WriteBits(data []byte, width uint) error {
     36 	length := uint(len(data)) * 8
     37 	offset := length - width
     38 	for i := offset; i < length; i++ {
     39 		oi := i / 8
     40 		if err := w.WriteBit((data[oi]>>(7-i%8))&0x01 != 0); err != nil {
     41 			return err
     42 		}
     43 	}
     44 	return nil
     45 }
     46 
     47 func (w *writer) WriteBit(bit bool) error {
     48 	if bit {
     49 		w.octet |= 0x1 << (7 - w.width)
     50 	}
     51 	w.width++
     52 
     53 	if w.width == 8 {
     54 		if _, err := w.writer.Write([]byte{w.octet}); err != nil {
     55 			return err
     56 		}
     57 		w.octet = 0x00
     58 		w.width = 0
     59 	}
     60 	return nil
     61 }