code wiki / _hdl_build / nx_reader_zoomserve.nx
nx_reader_zoomserve.nx
buildroot/runtime/_hdl_build/nx_reader_zoomserve.nx
about
nx_reader_zoomserve.nx -- the reader daemon's INTELLIGENT-ZOOM prep endpoint (lib; the lib+gate split so
nx_reader_zoomserve_gate exercises the handler in-process, no socket). GET /api/zoomprep?slug=<slug>&
file=<pagefile>&rtl=<0|1> ensures the tile pyramid + panel map exist for ONE comic/scan page:
reader/<slug>/<file> --fork ./_offc/nx_reader_page_prep.elf--> reader/<slug>/zoom/<stem>/{dz.json,
panels.json, <level>/<col>_<row>.jpg}
The tiles are then served by the EXISTING allowlisted /api/book route (p=reader/<slug>/zoom/<stem>/...), so
serving needs ZERO new code -- this endpoint only ensures the artifacts exist (lazy, cache-first, idempotent).
FAIL-CLOSED: slug must be a single safe component (alnum/_/-), file a safe leaf (alnum/_/-/., no "..", no
leading dot, exactly path-component chars) -> 403; missing source page -> 404; prep failure -> 500 with the
exit code; SUCCESS is decided by dz.json EXISTING after the fork (never by exit code alone -- no fake green).
The daemon behind THE WALL calls zs_handle_zoomprep; CWD is the repo root (paths repo-relative, same contract
as ms_handle_book / ms_run_extractor). license_tier: ORIGINAL
dependencies 1 imports · 6 importers
imports: nx_syscalls.nx
imported by: nx_manga_add.nxnx_manga_search.nxnx_media_server.nxnx_reader_library.nxnx_reader_sync.nxnx_reader_zoomserve_gate.nx
structs
| none |
consts
| 15 | const ZS_ROOT: *u8 = "knowledge/staging/media/reader/" |
| 16 | const ZS_PREP_ELF: *u8 = "./_offc/nx_reader_page_prep.elf" |
| 17 | const ZS_TILESIZE: *u8 = "512" // argv literal as a const (inline "..." as *u8 as i64 in an argv[] once miscompiled -> EFAULT/127; see nx_hostctl HC_READER note) |
functions
| 19 | func zs_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 20 | func zs_apps(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 } return off + i } |
| 21 | func zs_dec(dst: *u8, off: i64, v: i64) -> i64 { let t: *u8 = sys_mmap(28); var m: i64 = v; var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } var i: i64 = 0; while i < k { dst[off + i] = t[k - 1 - i]; i = i + 1 } return off + k } |
| 24 | func zs_qval(p: *u8, plen: i64, key: *u8, out: *u8, outcap: i64) -> i64 |
| 51 | func zs_slug_safe(s: *u8) -> i64 |
| 71 | func zs_fname_safe(s: *u8) -> i64 |
| 94 | func zs_exists(path: *u8) -> i64 { let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 } sys_close(fd); return 1 } |
| 95 | func zs_mkdir(path: *u8) -> i64 { __syscall(258, 0 - 100, path as i64, 0x1ed, 0, 0, 0); return 0 } |
| 97 | func zs_emit(cfd: i64, status: *u8, body: *u8) -> i64 |
| 113 | func zs_prep_run(src: *u8, outdir: *u8, rtl: *u8) -> i64 |
| 131 | func zs_handle_zoomprep(cfd: i64, p: *u8, plen: i64) -> i64 |