Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
opt/
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
Expand Down
40 changes: 32 additions & 8 deletions converter/converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,19 +113,43 @@ func IntelHexToBin(inputFile string, outputFile string) error {
return fmt.Errorf("no data segments found in Intel HEX file")
}

// Find the lowest and highest addresses
minAddr := segments[0].Address
maxAddr := segments[0].Address + uint32(len(segments[0].Data))
for _, segment := range segments {
if segment.Address < minAddr {
minAddr = segment.Address
}
endAddr := segment.Address + uint32(len(segment.Data))
if endAddr > maxAddr {
maxAddr = endAddr
}
}

// Create a buffer filled with 0xFF
totalLen := maxAddr - minAddr
binData := make([]byte, totalLen)
for i := range binData {
binData[i] = 0xFF
}

// Copy each segment's data into the buffer
for _, segment := range segments {
start := segment.Address - minAddr
copy(binData[start:start+uint32(len(segment.Data))], segment.Data)
}

// Create output file
ofw, err := os.Create(outputFile)
of, err := os.Create(outputFile)
if err != nil {
return fmt.Errorf("error creating output file: %w", err)
}
defer ofw.Close()
defer of.Close()

// Write binary data in order of addresses
for _, segment := range segments {
_, err = ofw.Write(segment.Data)
if err != nil {
return fmt.Errorf("error writing binary data: %v", err)
}
// Write the buffer to the file
_, err = of.Write(binData)
if err != nil {
return fmt.Errorf("error writing binary data: %v", err)
}

return nil
Expand Down
Binary file added hex2bin
Binary file not shown.
25 changes: 20 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ var (
buildTime = "unknown"
)

// getOutputFileName determines the output file name based on input file and mode
func getOutputFileName(inputFile, mode string) (string, error) {
// GetOutputFileName determines the output file name based on input file and mode
func GetOutputFileName(inputFile, mode string) (string, error) {
ext := ""
switch mode {
case "bin2hex":
Expand All @@ -26,7 +26,22 @@ func getOutputFileName(inputFile, mode string) (string, error) {
return "", fmt.Errorf("cannot determine output file extension for mode '%s' (should be 'bin2hex' or 'hex2bin')", mode)
}
base := strings.TrimSuffix(inputFile, filepath.Ext(inputFile))
return base + ext, nil
output := base + ext

// Add suffix if file exists
if _, err := os.Stat(output); err == nil {
suffix := 1
for {
candidate := fmt.Sprintf("%s_%d%s", base, suffix, ext)
if _, err := os.Stat(candidate); os.IsNotExist(err) {
output = candidate
break
}
suffix++
}
}

return output, nil
}

// getModeFromInputExt tries to determine the mode from the input file extension
Expand Down Expand Up @@ -64,7 +79,7 @@ func main() {
if arg == "bin2hex" || arg == "hex2bin" {
mode = arg
var err error
outputFile, err = getOutputFileName(inputFile, mode)
outputFile, err = GetOutputFileName(inputFile, mode)
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
Expand All @@ -86,7 +101,7 @@ func main() {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}
outputFile, err = getOutputFileName(inputFile, mode)
outputFile, err = GetOutputFileName(inputFile, mode)
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
Expand Down
50 changes: 50 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package main

import (
"os"
"path/filepath"
"testing"
)

func TestGetOutputFileName_NoConflict(t *testing.T) {
dir := t.TempDir()
input := filepath.Join(dir, "file.hex")
os.WriteFile(input, []byte("dummy"), 0644)
name, err := GetOutputFileName(input, "hex2bin")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if filepath.Base(name) != "file.bin" {
t.Errorf("expected file.bin, got %s", filepath.Base(name))
}
}

func TestGetOutputFileName_OneConflict(t *testing.T) {
dir := t.TempDir()
input := filepath.Join(dir, "file.hex")
os.WriteFile(input, []byte("dummy"), 0644)
os.WriteFile(filepath.Join(dir, "file.bin"), []byte("bin"), 0644)
name, err := GetOutputFileName(input, "hex2bin")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if filepath.Base(name) != "file_1.bin" {
t.Errorf("expected file_1.bin, got %s", filepath.Base(name))
}
}

func TestGetOutputFileName_MultipleConflicts(t *testing.T) {
dir := t.TempDir()
input := filepath.Join(dir, "file.hex")
os.WriteFile(input, []byte("dummy"), 0644)
os.WriteFile(filepath.Join(dir, "file.bin"), []byte("bin"), 0644)
os.WriteFile(filepath.Join(dir, "file_1.bin"), []byte("bin1"), 0644)
os.WriteFile(filepath.Join(dir, "file_2.bin"), []byte("bin2"), 0644)
name, err := GetOutputFileName(input, "hex2bin")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if filepath.Base(name) != "file_3.bin" {
t.Errorf("expected file_3.bin, got %s", filepath.Base(name))
}
}