Skip to content

Commit

Permalink
Automatically detect format (csv or bin). (#30)
Browse files Browse the repository at this point in the history
Also add a way to print as CSV.
  • Loading branch information
floitsch authored Nov 5, 2024
1 parent 3594b09 commit 4a64a4a
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ on:
- "*/*"

env:
TOIT_VERSION: v2.0.0-alpha.144
TOIT_VERSION: v2.0.0-alpha.161
APP_NAME: partitions

jobs:
Expand Down
2 changes: 1 addition & 1 deletion package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ name: partition-table
description: Tools to manipulate the partition table of an ESP32.

environment:
sdk: ^2.0.0-alpha.144
sdk: ^2.0.0-alpha.161
56 changes: 55 additions & 1 deletion src/partition_table.toit
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,17 @@ class PartitionTable:
offset = max offset end
return offset

/**
Decodes a partition table.
The given $bytes can be either a binary partition table or a CSV table.
*/
static decode bytes/ByteArray -> PartitionTable:
if bytes.size > 2 and bytes[..2] == Partition.MAGIC-BYTES:
return decode-bin_ bytes
return decode-csv_ bytes

static decode-bin_ bytes/ByteArray -> PartitionTable:
table := PartitionTable
checksum := md5.Md5
cursor := 0
Expand All @@ -191,7 +201,7 @@ class PartitionTable:
cursor = next
throw "Malformed table - not terminated"

static decode-csv bytes/ByteArray -> PartitionTable:
static decode-csv_ bytes/ByteArray -> PartitionTable:
// Something like:
// # Name, Type, SubType, Offset, Size, Flags
// # bootloader,, , 0x001000, 0x007000
Expand Down Expand Up @@ -275,6 +285,14 @@ class PartitionTable:
result.replace cursor md5
return result

encode --csv/True -> string:
result := "# Name, Type, SubType, Offset, Size, Flags\n"
sorted := partitions_.sort: | a b |
a.offset.compare-to b.offset
sorted.do: | partition/Partition |
result += partition.encode --csv-line
return result

encode-md5-partition_ partitions/ByteArray -> ByteArray:
partition := ByteArray 32: 0xff
partition.replace 0 MAGIC-BYTES-MD5
Expand All @@ -287,6 +305,9 @@ class PartitionTable:
do [block]:
partitions_.do block

stringify -> string:
return encode --csv

class Partition:
static MAGIC-BYTES ::= #[0xaa, 0x50]

Expand Down Expand Up @@ -334,6 +355,39 @@ class Partition:
LITTLE-ENDIAN.put-uint32 result 28 flags
return result

encode --csv-line/True -> string:
name-string := "$name,".pad 12

type-string/string := ?
if type == TYPE-APP: type-string = "app"
else if type == TYPE-DATA: type-string = "data"
else: type-string = "0x$(%02x type)"
type-string = "$type-string,".pad 5

subtype-string/string? := null
reverse-map/Map := ?
if type == TYPE-APP: reverse-map = PartitionTable.PARTITION-SUBTYPES-APP
else if type == TYPE-DATA: reverse-map = PartitionTable.PARTITION-SUBTYPES-DATA
else: reverse-map = {:}
reverse-map.any: | name/string value/int |
if value == subtype:
subtype-string = name
true
else:
false
if not subtype-string: subtype-string = "0x$(%02x subtype)"
subtype-string = "$subtype-string,".pad 8

offset-string := "0x$(%06x offset),"
size-string := "0x$(%06x size),"

flag-entries := []
if (flags & PartitionTable.FLAG-ENCRYPTED) != 0: flag-entries.add "encrypted"
if (flags & PartitionTable.FLAG-READONLY) != 0: flag-entries.add "readonly"
flags-string := flag-entries.join ":"

return "$name-string $type-string $subtype-string $offset-string $size-string $flags-string\n"

static decode-name_ bytes/ByteArray -> string:
zero := bytes.index-of 0
if zero < 0: throw "Malformed entry - name"
Expand Down
33 changes: 23 additions & 10 deletions tests/cvs-test.toit
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,37 @@ main:
csv-contents := file.read-contents "$program-dir/cvs-test-partitions.cvs"

partition-table-bin := PartitionTable.decode bin-contents
partition-table-cvs := PartitionTable.decode-csv csv-contents
partition-table-cvs := PartitionTable.decode csv-contents

partitions-bin := partition-table-bin.partitions
partitions-cvs := partition-table-cvs.partitions
expect-equals partitions-bin.size partitions-cvs.size

for i := 0; i < partitions-bin.size; i++:
partition-bin/Partition := partitions-bin[i]
partition-cvs/Partition := partitions-cvs[i]
expect-equals partition-bin.name partition-cvs.name
expect-equals partition-bin.type partition-cvs.type
expect-equals partition-bin.subtype partition-cvs.subtype
expect-equals partition-bin.offset partition-cvs.offset
expect-equals partition-bin.size partition-cvs.size
expect-equals partition-bin.flags partition-cvs.flags
expect-equals-partition-tables partition-table-bin partition-table-cvs

encoded := partition-table-cvs.encode
if encoded.size > bin-contents.size:
bin-contents += ByteArray (encoded.size - bin-contents.size): 0xff

expect-equals bin-contents encoded

encoded-csv := partition-table-bin.encode --csv
decoded-cvs := PartitionTable.decode encoded-csv.to-byte-array
expect-equals-partition-tables partition-table-bin decoded-cvs

encoded-csv2 := partition-table-cvs.encode --csv
expect-equals encoded-csv encoded-csv2

print encoded-csv

expect-equals-partition-tables partition-table1/PartitionTable partition-table2/PartitionTable:
expect-equals partition-table1.partitions.size partition-table2.partitions.size
for i := 0; i < partition-table1.partitions.size; i++:
partition1/Partition := partition-table1.partitions[i]
partition2/Partition := partition-table2.partitions[i]
expect-equals partition1.name partition2.name
expect-equals partition1.type partition2.type
expect-equals partition1.subtype partition2.subtype
expect-equals partition1.offset partition2.offset
expect-equals partition1.size partition2.size
expect-equals partition1.flags partition2.flags

0 comments on commit 4a64a4a

Please sign in to comment.