The test pair verify.py runs against is back in the repo, so a fresh clone can run the built-in checks. Conversion output (*-sab2sax-*) stays ignored, so converting inside testprogram/ still leaves the tree clean. claudeCodeChatLog.md records how this got built: what was asked for, the decisions worth remembering (plain paths in system.properties, the port source, Java float formatting, the f4-rounded manifest default, why a sab cannot return runtime props) and what is still untested. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
4.8 KiB
Claude Code session log
What was asked for, what was built, and the decisions behind it. Written 2026-08-13, covering the
work that produced ec4019e .. 2dcc170 (tags v0.0.0.001, v0.0.0.002).
Starting point: sab.py, a pure-Python .sax -> .sab encoder taking <app.sax> <sedona_home> <out.sab> on the command line, plus verify.py.
What was asked, in order
- Sedona home into
system.properties, with a folder chooser on first run, and a file chooser for the input. - Plain paths, not java-escaped, in that properties file.
- Timestamped output names —
[name]-sab2sax-20260728-140609. - The reverse direction,
.sab->.sax, direction chosen by the input's extension. - A version, shown in dialog titles.
testprogram/out of the repo — later reversed: the test pair is checked in again, while conversion output (*-sab2sax-*) stays gitignored.- A file chooser in
verify.pyand a round-trip check on whatever is chosen. - A window with a button per direction, showing the chosen file before converting and the output afterwards.
run.pyas the entry point; log labels in capitals, values on their own lines.
What exists now
run.py entry point: window with no arguments, CLI with them
gui.py the window: a button per direction
sab2sax.py the CLI: dispatches on the input extension
sab.py sax -> sab encoder
sax.py sab -> sax decoder
config.py system.properties, dialogs, NAME/VERSION
verify.py round trips + comparison against sedonac output
system.properties sedona.home
testprogram/ test apps verify.py runs against
sedona.home lives in system.properties. Missing or pointing somewhere without manifests/ and a
folder chooser opens, then the answer is written back. Output files are always written next to the
input as <stem>-sab2sax-<YYYYMMDD-HHMMSS>.<ext>, so a run never overwrites the previous one.
Decisions worth remembering
Plain paths in system.properties. Java's Properties (what sedonac reads it with) treats \
as an escape and doubles them up; we only read the file ourselves, so we write plain Windows paths.
The parser collapses \\ to \ and keeps every other backslash literal — both forms load, and
C:\niagara never becomes a newline.
The decoder is a port, not a guess. sax.py follows OfflineApp.decodeAppBinary +
encodeAppXml and OfflineComponent/OfflineLink from
sedonaSrcOrginal/sedona/src/sedona/offline/. The tree is rebuilt from the
firstChild/nextSibling id chain; the XML is written the way XWriter does it — two-space
indent, a <!-- /path --> comment above every <comp>, &#x..; escaping.
Java float formatting. Value.encodeString for a float is java.lang.Float.toString: shortest
digits that round-trip, always a decimal point, E form outside [1e-3, 1e7). sax.java_float
reproduces it. It matches modern Java rather than the old JDK's extra-digit quirk on subnormals
(1.4E-45 vs our 1.0E-45) — only reachable with denormal floats.
The manifest default is a 32-bit float too. A prop equal to its default is not written to the
.sax. Comparing a decoded float against a default parsed as a Python double makes 0.1 look
different from 0.1, and every minDelta="0.1" gets written where sedonac omits it. Rounding the
default to f4 first was the last diff between "close" and "identical".
A .sab cannot give back runtime props. Only config props are in the binary. sedonac has the
same hole. That is why a .sax round trip compares the two binaries, not the two texts.
Verification
test_normal.sax-> sab, byte-identical totest_normal_sedonac.sab(7852 bytes)test_normal_sedonac.sab-> sax, byte-identical totest_normal.sax(61294 bytes)- both round trips clean:
sab -> sax -> sab, andsax -> sab -> sax -> sab
A live sedonac.exe comparison was attempted and could not run here — it fails with Cannot load library: C:\Program Files\Zulu\zulu-21-jre\bin\server\jvm.dll. verify.check_encode(sax) /
check_decode(sab) with no reference argument still do that comparison on a machine with a JRE
sedonac will start under.
Malformed input fails with one line and exit 1, not a traceback: comp 0 app: missing child 254.
Where to pick up
- Untested paths are unchanged from before: action overrides,
Buf-typed props, non-ASCII strings, and apps whose ids exceed the 256-entry lookup table. verify.pyprintsSKIPand exits 0 whentestprogram/is empty rather than failing; the test pair is checked in, so it normally runs.- Version lives in
config.py(NAME,VERSION). The window title, every dialog title and the CLI banner all read from it.