A encdec.go => encdec.go +28 -0
@@ 0,0 1,28 @@
+package yenc
+
+import "unsafe"
+
+func yenc(input *[8]byte) []byte {
+ var mask [8]bool
+
+ // add 42 (0x2a) to every byte
+ *(*uint64)(unsafe.Pointer(&input)) += 0x2a2a2a2a2a2a2a2a
+
+ for i := 0; i < 8; i++ {
+ bte := (*(*[8]byte)(unsafe.Pointer(&input)))[i]
+
+ if bte == 0x00 || bte == 0x0A || bte == 0x0D || bte == 0x3D {
+ (*(*[8]byte)(unsafe.Pointer(&input)))[i] += uint8(64)
+ mask[i] = true
+ }
+ }
+
+ var result []byte
+ for i := 0; i < 8; i++ {
+ if mask[i] {
+ result = append(result, '=')
+ }
+ result = append(result, input[i])
+ }
+ return result
+}
A encoder.go => encoder.go +76 -0
@@ 0,0 1,76 @@
+package yenc
+
+import (
+ "bytes"
+ "fmt"
+ "hash"
+ "hash/crc32"
+ "io"
+ "sync"
+)
+
+type Encoder struct {
+ file io.Writer
+ buffer bytes.Buffer
+ writeMtx sync.Mutex
+
+ LineLength int
+ BlockSize int
+ CRC hash.Hash32
+}
+
+func NewEncoder(w io.Writer) *Encoder {
+ enc := &Encoder{
+ file: w,
+ LineLength: 128,
+ BlockSize: 0,
+ CRC: crc32.NewIEEE(),
+ }
+ return enc
+}
+
+func (e *Encoder) Write(slice []byte) (int, error) {
+ e.writeMtx.Lock()
+ defer e.writeMtx.Unlock()
+
+ var bytesWritten int
+ remainder := len(slice) % 8
+ parts := getParts(&slice)
+
+ maxindex := len(*parts) - 1
+
+ var err error
+ var n int
+ var encoded []byte
+
+ for i, p := range *parts {
+ encoded = yenc(&p)
+
+ if i == maxindex {
+ break
+ }
+
+ n, err = e.buffer.Write(encoded)
+ if err != nil {
+ return bytesWritten, fmt.Errorf("failed writing yenc to output-buffer: %v")
+ }
+ bytesWritten += n
+ }
+
+ n, err = e.buffer.Write(encoded[:len(encoded)-(8-remainder)])
+ if err != nil {
+ return bytesWritten, fmt.Errorf("failed writing yenc to output-buffer: %v")
+ }
+ bytesWritten += n
+
+ err = e.writeBlock(false)
+ if err != nil {
+ return n, err
+ }
+
+ return bytesWritten, nil
+}
+
+func (e *Encoder) writeBlock(closing bool) error {
+ return nil
+}
A splitting.go => splitting.go +28 -0
@@ 0,0 1,28 @@
+package yenc
+
+func getParts(in *[]byte) *[][8]byte {
+ var parts [][8]byte
+
+ var part [8]byte
+ var i int
+
+ for _, b := range *in {
+ part[i] = b
+ i++
+
+ if i == 8 {
+ parts = append(parts, part)
+ i = 0
+ }
+ }
+
+ if i != 0 {
+ for i < 8 {
+ part[i] = 0
+ i++
+ }
+ parts = append(parts, part)
+ }
+
+ return &parts
+}
D type.go => type.go +0 -12
@@ 1,12 0,0 @@
-package yenc
-
-type Encoder struct {
- LineLength int
- BlockSize int
-}
-
-func NewEncoder() Encoder {
- return Encoder{
- LineLength: 128,
- }
-}
D type_test.go => type_test.go +0 -12
@@ 1,12 0,0 @@
-package yenc
-
-import "testing"
-
-func TestNewEncoder(t *testing.T) {
- // Did I say GetLimit was useless? This one is even less useful… but I
- // absolutely hate red lines in the Coverage Report
- y := NewEncoder()
- if y.LineLength != 128 {
- t.Fail()
- }
-}