Skip to content

Implement lzss encoder #95

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jan 11, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update encoder
  • Loading branch information
polldo committed Jan 5, 2022
commit 909c6421a351fd75b578235f556dde23b850f6c3
72 changes: 8 additions & 64 deletions internal/ota/encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ import (
"encoding/binary"
"hash/crc32"
"io"
"io/ioutil"
"log"
"os"
"strconv"

"github.com/arduino/arduino-cloud-cli/internal/lzss"
Expand Down Expand Up @@ -86,10 +83,7 @@ func (e *encoder) Write(binaryData []byte) (int, error) {
}

// Compress the compiled binary
compressed, err := e.compress(&binaryData)
if err != nil {
return 0, err
}
compressed := lzss.Encode(binaryData)

// Prepend magic number and version field to payload
var binDataComplete []byte
Expand All @@ -98,12 +92,12 @@ func (e *encoder) Write(binaryData []byte) (int, error) {
binDataComplete = append(binDataComplete, compressed...)
//log.Println("binDataComplete is", len(binDataComplete), "bytes length")

headerSize, err := e.writeHeader(&binDataComplete)
headerSize, err := e.writeHeader(binDataComplete)
if err != nil {
return headerSize, err
}

payloadSize, err := e.writePayload(&binDataComplete)
payloadSize, err := e.writePayload(binDataComplete)
if err != nil {
return payloadSize, err
}
Expand All @@ -117,23 +111,19 @@ func (e *encoder) Close() error {
return e.w.Flush()
}

func (e *encoder) writeHeader(binDataComplete *[]byte) (int, error) {
func (e *encoder) writeHeader(binDataComplete []byte) (int, error) {

//
// Write the length of the content
//
lengthAsBytes := make([]byte, 4)
binary.LittleEndian.PutUint32(lengthAsBytes, uint32(len(*binDataComplete)))
binary.LittleEndian.PutUint32(lengthAsBytes, uint32(len(binDataComplete)))

n, err := e.w.Write(lengthAsBytes)
if err != nil {
return n, err
}

//
// Calculate the checksum for binDataComplete
//
crc := crc32.ChecksumIEEE(*binDataComplete)
crc := crc32.ChecksumIEEE(binDataComplete)

// encode the checksum uint32 value as 4 bytes
crcAsBytes := make([]byte, 4)
Expand All @@ -147,52 +137,6 @@ func (e *encoder) writeHeader(binDataComplete *[]byte) (int, error) {
return len(lengthAsBytes) + len(crcAsBytes), nil
}

func (e *encoder) writePayload(data *[]byte) (int, error) {

// write the payload
payloadSize, err := e.w.Write(*data)
if err != nil {
return payloadSize, err
}

return payloadSize, nil
}

func (e *encoder) compress(data *[]byte) ([]byte, error) {

// create a tmp file for input
inputFile, err := ioutil.TempFile("", "ota-lzss-input")
if err != nil {
log.Fatal(err)
return nil, err
}
defer os.Remove(inputFile.Name())

// create a tmp file for output
outputFile, err := ioutil.TempFile("", "ota-lzss-output")
if err != nil {
log.Fatal(err)
return nil, err
}
defer os.Remove(outputFile.Name())

// write data in the input file
ioutil.WriteFile(inputFile.Name(), *data, 644)
if err != nil {
log.Fatal(err)
return nil, err
}

// Compress the binary data using LZSS
lzss.Encode(inputFile.Name(), outputFile.Name())

// reads compressed data from output file and write it into
// the writer
compressed, err := ioutil.ReadFile(outputFile.Name())
if err != nil {
log.Fatal(err)
return nil, err
}

return compressed, nil
func (e *encoder) writePayload(data []byte) (int, error) {
return e.w.Write(data)
}