code wiki / _hdl_build / nx_mobi_fixture_build.nx

nx_mobi_fixture_build.nx source

↩ module page · 298 lines · 20650 B

1// nx_mobi_fixture_build.nx -- build a DRM-free MOBI (Kindle) fixture sovereignly, so the MOBI reader rung can be 2// gated end-to-end against the REAL on-disk format (PDB container + PalmDOC-compressed text + EXTH metadata), 3// the way nx_epub_fixture_build gives the EPUB rungs a controlled real EPUB. Also writes a DRM-FLAGGED variant 4// (encryptionType=2) so the reader's "detect + DECLINE DRM" path is gated (we read DRM-FREE files; we never 5// circumvent DRM). Structure: 78-byte PDB header + 2 record-info entries + record0 (PalmDOC hdr + minimal MOBI 6// hdr + EXTH author/title) + record1 (PalmDOC-compressed XHTML). expect_exit: 0 license_tier: ORIGINAL 7import "nx_syscalls.nx" 8import "nx_palmdoc.nx" 9const K_MAGIC_262144: i64 = 262144 10const K_MAGIC_4096: i64 = 4096 11const K_MAGIC_65001: i64 = 65001 12const K_MAGIC_17480: i64 = 17480 13const K_MAGIC_1040: i64 = 1040 14const K_MAGIC_1296: i64 = 1296 15 16func mf_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 17func mf_p(s: *u8) -> i64 { sys_write(1, s, mf_slen(s)); return 0 } 18func mf_n(v: i64) -> i64 { let b: *u8=sys_mmap(24); var m: i64=v; if m<0{m=0-m}; let t: *u8=sys_mmap(24); 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{b[i]=t[k-1-i];i=i+1}; sys_write(1,b,k); return 0 } 19func ensure_dir(path: *u8) -> i64 { __syscall(258, 0-100, path, 0x1ed, 0, 0, 0); return 0 } 20 21func put16(m: *u8, o: i64, v: i64) -> i64 { m[o]=((v>>8)&0xff) as u8; m[o+1]=(v&0xff) as u8; return o+2 } 22func put32(m: *u8, o: i64, v: i64) -> i64 { m[o]=((v>>24)&0xff) as u8; m[o+1]=((v>>16)&0xff) as u8; m[o+2]=((v>>8)&0xff) as u8; m[o+3]=(v&0xff) as u8; return o+4 } 23func puts(m: *u8, o: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){ m[o+i]=s[i]; i=i+1 } return o+i } 24 25func main() -> i64 { 26 ensure_dir("knowledge/fixtures" as *u8) 27 let html: *u8 = "<html><head></head><body><h1>The Liberation of Alice</h1><p>Alice was beginning to get very tired of sitting by her sister on the bank. Alice was beginning to get very tired of sitting by her sister on the bank.</p><p>So she was considering in her own mind whether the pleasure of making a daisy chain would be worth the trouble of getting up and picking the daisies, when suddenly a White Rabbit ran close by her.</p></body></html>" as *u8 28 let htmln: i64 = mf_slen(html) 29 30 let m: *u8 = sys_mmap(K_MAGIC_262144) 31 // ---- PDB header (78 bytes); mmap is zero-filled so unset fields stay 0 ---- 32 puts(m, 0, "Liberation Fixture" as *u8) // database name (<=31 chars) 33 puts(m, 60, "BOOK" as *u8) // type 34 puts(m, 64, "MOBI" as *u8) // creator 35 put16(m, 76, 2) // numRecords = 2 36 let list0: i64 = 78 // record-info entry 0 (offset field, backpatched) 37 let list1: i64 = 86 // record-info entry 1 38 // 2-byte gap at 94; records start at 96 39 var o: i64 = 96 40 let rec0: i64 = o 41 42 // ---- record 0: PalmDOC header (16) ---- 43 o = put16(m, o, 2) // compression = 2 (PalmDOC) 44 o = put16(m, o, 0) // unused 45 o = put32(m, o, htmln) // textLength (uncompressed) 46 o = put16(m, o, 1) // text record count = 1 47 o = put16(m, o, K_MAGIC_4096) // record size 48 let enc_pos: i64 = o 49 o = put16(m, o, 0) // encryptionType = 0 (NO DRM) 50 o = put16(m, o, 0) // unused 51 // ---- minimal MOBI header ---- 52 o = puts(m, o, "MOBI" as *u8) 53 o = put32(m, o, 24) // header length 54 o = put32(m, o, 2) // mobi type = book 55 o = put32(m, o, K_MAGIC_65001) // text encoding = UTF-8 56 o = put32(m, o, 1) // unique id 57 o = put32(m, o, 6) // file version 58 // ---- EXTH block (author + title) ---- 59 let exth: i64 = o 60 o = puts(m, o, "EXTH" as *u8) 61 let exthlen_pos: i64 = o 62 o = put32(m, o, 0) // header length placeholder 63 o = put32(m, o, 2) // record count = 2 64 let auth: *u8 = "Lewis Carroll" as *u8; let authn: i64 = mf_slen(auth) 65 o = put32(m, o, 100); o = put32(m, o, 8 + authn); o = puts(m, o, auth) // EXTH 100 = author 66 let titl: *u8 = "The Liberation of Alice" as *u8; let titln: i64 = mf_slen(titl) 67 o = put32(m, o, 503); o = put32(m, o, 8 + titln); o = puts(m, o, titl) // EXTH 503 = title 68 var exthlen: i64 = o - exth 69 while (exthlen % 4) != 0 { m[o]=0 as u8; o=o+1; exthlen=exthlen+1 } 70 put32(m, exthlen_pos, exthlen) 71 while (o % 4) != 0 { m[o]=0 as u8; o=o+1 } // pad record 0 to 4-byte boundary 72 73 // ---- record 1: PalmDOC-compressed XHTML ---- 74 let rec1: i64 = o 75 let cn: i64 = palmdoc_compress(html, htmln, (m as i64 + o) as *u8, K_MAGIC_262144 - o) 76 o = o + cn 77 78 // backpatch the record-info offsets 79 put32(m, list0, rec0) 80 put32(m, list1, rec1) 81 82 let fd: i64 = sys_openat_wr("knowledge/fixtures/nishi_mobi_fixture.mobi" as *u8, 0x1a4) 83 if fd < 0 { mf_p("MOBI-FIXTURE-FAIL open\n" as *u8); sys_exit(1); return 1 } 84 sys_write(fd, m, o); sys_close(fd) 85 86 // DRM-flagged variant (encryptionType=2) for the reader's detect+decline gate 87 put16(m, enc_pos, 2) 88 let fd2: i64 = sys_openat_wr("knowledge/fixtures/nishi_mobi_drm.mobi" as *u8, 0x1a4) 89 if fd2 >= 0 { sys_write(fd2, m, o); sys_close(fd2) } 90 91 mf_p("MOBI-FIXTURE bytes=" as *u8); mf_n(o); mf_p(" htmln=" as *u8); mf_n(htmln); mf_p(" compressed_rec1=" as *u8); mf_n(cn) 92 mf_p(" -> knowledge/fixtures/nishi_mobi_fixture.mobi (+ _drm variant)\n" as *u8) 93 94 // ---- HUFF/CDIC variant: nishi_mobi_huff.mobi (compression 17480) ---- 95 // 4 PDB records: rec0=PalmDOC+MOBI hdr (Huffman Record Offset/Count at MOBI+0x70/0x74) + EXTH; 96 // rec1=HUFF stream (codelen-1: 256 dict1 entries all 0x181 -> bit'1'=>phrase0, bit'0'=>phrase1; 0x80 => 97 // phrase0 + phrase1*7); rec2=HUFF record; rec3=CDIC (phrase0/1 = HTML fragments). This is the MINIMAL Huffman 98 // case (all-terminal codelen-1) -- it gates the 17480 pipeline end-to-end; real multi-codelen Kindle HUFF 99 // needs a real DRM-free file (no open HUFF encoder exists -- Calibre/KindleUnpack only DECODE HUFF). 100 let h: *u8 = sys_mmap(K_MAGIC_262144) 101 let p0: *u8 = "<html><body><p>Alice was beginning to get very tired.</p>" as *u8; let p0n: i64 = mf_slen(p0) 102 let p1: *u8 = "<p>So a White Rabbit ran close by her.</p>" as *u8; let p1n: i64 = mf_slen(p1) 103 puts(h, 0, "Liberation HUFF" as *u8) 104 puts(h, 60, "BOOK" as *u8); puts(h, 64, "MOBI" as *u8) 105 put16(h, 76, 4) // numRecords = 4 106 let hrec0: i64 = 112 // 78 + 4*8 + 2-byte gap 107 var ho: i64 = hrec0 108 ho = put16(h, ho, K_MAGIC_17480) // compression = HUFF/CDIC 109 ho = put16(h, ho, 0) 110 ho = put32(h, ho, p0n + p1n*7) // uncompressed textLength 111 ho = put16(h, ho, 1) // text record count = 1 112 ho = put16(h, ho, K_MAGIC_4096) 113 let henc_pos: i64 = ho 114 ho = put16(h, ho, 0) // encryptionType = 0 (NO DRM) 115 ho = put16(h, ho, 0) 116 let mobistart: i64 = ho // == hrec0 + 16 117 puts(h, mobistart, "MOBI" as *u8) 118 put32(h, mobistart + 4, 232) // MOBI header length 119 put32(h, mobistart + 8, 2) // mobi type = book 120 put32(h, mobistart + 12, K_MAGIC_65001) // text encoding UTF-8 121 put32(h, mobistart + 16, 1) // unique id 122 put32(h, mobistart + 20, 6) // file version 123 put32(h, mobistart + 96, 2) // Huffman Record Offset (record-0 0x70 = MOBI-hdr +96) = PDB record 2 124 put32(h, mobistart + 100, 2) // Huffman Record Count (record-0 0x74 = MOBI-hdr +100) = 2 (HUFF + CDIC) 125 ho = mobistart + 232 126 let hexth: i64 = ho 127 ho = puts(h, ho, "EXTH" as *u8) 128 let hexthlen_pos: i64 = ho 129 ho = put32(h, ho, 0); ho = put32(h, ho, 2) // header-length placeholder + record count 130 ho = put32(h, ho, 100); ho = put32(h, ho, 8 + authn); ho = puts(h, ho, auth) 131 ho = put32(h, ho, 503); ho = put32(h, ho, 8 + titln); ho = puts(h, ho, titl) 132 var hexthlen: i64 = ho - hexth 133 while (hexthlen % 4) != 0 { h[ho]=0 as u8; ho=ho+1; hexthlen=hexthlen+1 } 134 put32(h, hexthlen_pos, hexthlen) 135 while (ho % 4) != 0 { h[ho]=0 as u8; ho=ho+1 } 136 let hrec1: i64 = ho // rec1: the HUFF-compressed text stream 137 h[ho] = 0x80 as u8; ho = ho + 1 138 while (ho % 4) != 0 { h[ho]=0 as u8; ho=ho+1 } 139 let hrec2: i64 = ho // rec2: HUFF record (magic + off1/off2 + dict1[256] + dict2[64]) 140 puts(h, ho, "HUFF" as *u8); h[ho+4]=0 as u8; h[ho+5]=0 as u8; h[ho+6]=0 as u8; h[ho+7]=0x18 as u8 141 put32(h, ho+8, 16); put32(h, ho+12, 16 + 256*4) 142 var di: i64 = 0; while di < 256 { put32(h, ho+16+di*4, 0x181); di=di+1 } // codelen1, term, maxcode-raw 1 143 di = 0; while di < 64 { put32(h, ho+K_MAGIC_1040+di*4, 0); di=di+1 } // dict2 zero (term path) 144 ho = ho + K_MAGIC_1296 145 let hrec3: i64 = ho // rec3: CDIC record (2 terminal phrases) 146 puts(h, ho, "CDIC" as *u8); h[ho+4]=0 as u8; h[ho+5]=0 as u8; h[ho+6]=0 as u8; h[ho+7]=0x10 as u8 147 put32(h, ho+8, 2); put32(h, ho+12, 1) // phrases=2, bits=1 148 put16(h, ho+16, 4) // off[0] = 4 (phrase0 header at cdic+20) 149 put16(h, ho+18, 6 + p0n) // off[1] = 6+p0n 150 put16(h, ho+20, 0x8000 + p0n); puts(h, ho+22, p0) // phrase0: terminal | len, bytes 151 put16(h, ho+22+p0n, 0x8000 + p1n); puts(h, ho+24+p0n, p1) // phrase1 152 ho = ho + 24 + p0n + p1n 153 put32(h, 78, hrec0); put32(h, 86, hrec1); put32(h, 94, hrec2); put32(h, 102, hrec3) 154 let fdh: i64 = sys_openat_wr("knowledge/fixtures/nishi_mobi_huff.mobi" as *u8, 0x1a4) 155 if fdh >= 0 { sys_write(fdh, h, ho); sys_close(fdh) } 156 mf_p("MOBI-HUFF-FIXTURE bytes=" as *u8); mf_n(ho); mf_p(" rec1@" as *u8); mf_n(hrec1); mf_p(" huff@" as *u8); mf_n(hrec2); mf_p(" cdic@" as *u8); mf_n(hrec3) 157 mf_p(" -> knowledge/fixtures/nishi_mobi_huff.mobi\n" as *u8) 158 159 // ---- COVER variant: nishi_mobi_cover.mobi (PalmDOC text + an EMBEDDED cover image record) ---- 160 // 3 PDB records: rec0=PalmDOC hdr + extended MOBI hdr (First Image index @ MOBI-hdr 0x6c=+92 -> PDB record 2) + 161 // EXTH (author/title + 201 coveroffset=0); rec1=PalmDOC text; rec2=a real 35-byte opaque GIF cover. This gates the 162 // reader EXTRACTING the cover out of the file ITSELF (offline, no download) -- how Calibre gets the cover. 163 let c: *u8 = sys_mmap(K_MAGIC_262144) 164 puts(c, 0, "Liberation Cover" as *u8) 165 puts(c, 60, "BOOK" as *u8); puts(c, 64, "MOBI" as *u8) 166 put16(c, 76, 3) // numRecords = 3 167 let crec0: i64 = 78 + 3*8 + 2 // record-info list (3*8) + 2-byte gap -> records start at 104 168 var co: i64 = crec0 169 co = put16(c, co, 2) // compression = PalmDOC 170 co = put16(c, co, 0) 171 co = put32(c, co, htmln) // textLength (uncompressed) 172 co = put16(c, co, 1) // text record count = 1 173 co = put16(c, co, K_MAGIC_4096) 174 co = put16(c, co, 0) // encryptionType = 0 (NO DRM) 175 co = put16(c, co, 0) 176 let cmobi: i64 = co // == crec0 + 16, MOBI header start 177 puts(c, cmobi, "MOBI" as *u8) 178 put32(c, cmobi + 4, 96) // MOBI header length = 96 (large enough to hold First Image index @ +92) 179 put32(c, cmobi + 8, 2) // mobi type = book 180 put32(c, cmobi + 12, K_MAGIC_65001) // text encoding UTF-8 181 put32(c, cmobi + 16, 1) // unique id 182 put32(c, cmobi + 20, 6) // file version 183 put32(c, cmobi + 92, 2) // First Image index (MOBI-hdr 0x6c = +92) = PDB record 2 (the cover) 184 co = cmobi + 96 185 let cexth: i64 = co 186 co = puts(c, co, "EXTH" as *u8) 187 let cexthlen_pos: i64 = co 188 co = put32(c, co, 0); co = put32(c, co, 6) // header-length placeholder + record count = 6 189 co = put32(c, co, 100); co = put32(c, co, 8 + authn); co = puts(c, co, auth) 190 co = put32(c, co, 503); co = put32(c, co, 8 + titln); co = puts(c, co, titl) 191 let pubr: *u8 = "Nishi Press" as *u8; let pubrn: i64 = mf_slen(pubr) 192 co = put32(c, co, 101); co = put32(c, co, 8 + pubrn); co = puts(c, co, pubr) // EXTH 101 publisher 193 let pdate: *u8 = "2026-06-23" as *u8; let pdaten: i64 = mf_slen(pdate) 194 co = put32(c, co, 106); co = put32(c, co, 8 + pdaten); co = puts(c, co, pdate) // EXTH 106 publishing date 195 let pdesc: *u8 = "<p>A <i>sample</i> liberation and cover demo.</p>" as *u8; let pdescn: i64 = mf_slen(pdesc) 196 co = put32(c, co, 103); co = put32(c, co, 8 + pdescn); co = puts(c, co, pdesc) // EXTH 103 description (HTML) 197 co = put32(c, co, 201); co = put32(c, co, 12); co = put32(c, co, 0) // EXTH 201 coveroffset = 0 -> cover at First Image index 198 var cexthlen: i64 = co - cexth 199 while (cexthlen % 4) != 0 { c[co]=0 as u8; co=co+1; cexthlen=cexthlen+1 } 200 put32(c, cexthlen_pos, cexthlen) 201 while (co % 4) != 0 { c[co]=0 as u8; co=co+1 } 202 let crec1: i64 = co // rec1: PalmDOC-compressed text 203 let ccn: i64 = palmdoc_compress(html, htmln, (c as i64 + co) as *u8, K_MAGIC_262144 - co) 204 co = co + ccn 205 while (co % 4) != 0 { c[co]=0 as u8; co=co+1 } 206 let crec2: i64 = co // rec2: the cover image (35-byte opaque 1x1 GIF, color 0 = navy 1a2238) 207 let g: *u8 = (c as i64 + co) as *u8 208 g[0]=0x47 as u8; g[1]=0x49 as u8; g[2]=0x46 as u8; g[3]=0x38 as u8; g[4]=0x39 as u8; g[5]=0x61 as u8 // "GIF89a" 209 g[6]=0x01 as u8; g[7]=0x00 as u8; g[8]=0x01 as u8; g[9]=0x00 as u8 // 1x1 210 g[10]=0x80 as u8; g[11]=0x00 as u8; g[12]=0x00 as u8 // GCT present (2 colors) 211 g[13]=0x1a as u8; g[14]=0x22 as u8; g[15]=0x38 as u8 // color 0 = navy 212 g[16]=0xff as u8; g[17]=0xff as u8; g[18]=0xff as u8 // color 1 = white 213 g[19]=0x2c as u8; g[20]=0x00 as u8; g[21]=0x00 as u8; g[22]=0x00 as u8; g[23]=0x00 as u8; g[24]=0x01 as u8; g[25]=0x00 as u8; g[26]=0x01 as u8; g[27]=0x00 as u8; g[28]=0x00 as u8 // image descriptor 1x1 214 g[29]=0x02 as u8; g[30]=0x02 as u8; g[31]=0x44 as u8; g[32]=0x01 as u8; g[33]=0x00 as u8 // LZW: min-code 2, one pixel (idx 0) 215 g[34]=0x3b as u8 // trailer 216 co = co + 35 217 put32(c, 78, crec0); put32(c, 86, crec1); put32(c, 94, crec2) 218 let fdc: i64 = sys_openat_wr("knowledge/fixtures/nishi_mobi_cover.mobi" as *u8, 0x1a4) 219 if fdc >= 0 { sys_write(fdc, c, co); sys_close(fdc) } 220 mf_p("MOBI-COVER-FIXTURE bytes=" as *u8); mf_n(co); mf_p(" rec2(cover)@" as *u8); mf_n(crec2); mf_p(" gif=35B -> knowledge/fixtures/nishi_mobi_cover.mobi\n" as *u8) 221 222 // ---- CHAPTERS variant: nishi_mobi_chapters.mobi (PalmDOC; 3 chapters via <mbp:pagebreak> -> real navigable TOC) ---- 223 let chtml: *u8 = "<html><body><h1>Chapter One</h1><p>In the beginning Alice fell down the rabbit hole and kept falling for a very long time indeed.</p><mbp:pagebreak/><h1>Chapter Two</h1><p>The White Rabbit checked his pocket watch nervously and hurried along the winding path.</p><mbp:pagebreak/><h1>Chapter Three</h1><p>At the tea party the Mad Hatter poured more tea and offered Alice a seat by the window.</p></body></html>" as *u8 224 let chtmln: i64 = mf_slen(chtml) 225 let ch: *u8 = sys_mmap(K_MAGIC_262144) 226 puts(ch, 0, "Chapters Fixture" as *u8) 227 puts(ch, 60, "BOOK" as *u8); puts(ch, 64, "MOBI" as *u8) 228 put16(ch, 76, 2) // numRecords = 2 229 var cho: i64 = 96 // 78 + 2*8 + 2-byte gap 230 let chrec0: i64 = cho 231 cho = put16(ch, cho, 2) // compression = PalmDOC 232 cho = put16(ch, cho, 0) 233 cho = put32(ch, cho, chtmln) // textLength 234 cho = put16(ch, cho, 1) // text record count = 1 235 cho = put16(ch, cho, K_MAGIC_4096) 236 cho = put16(ch, cho, 0) // encryptionType = 0 237 cho = put16(ch, cho, 0) 238 cho = puts(ch, cho, "MOBI" as *u8) 239 cho = put32(ch, cho, 24) // MOBI header length 240 cho = put32(ch, cho, 2) // mobi type = book 241 cho = put32(ch, cho, K_MAGIC_65001) // UTF-8 242 cho = put32(ch, cho, 1) // unique id 243 cho = put32(ch, cho, 6) // file version 244 let chexth: i64 = cho 245 cho = puts(ch, cho, "EXTH" as *u8) 246 let chexthlen_pos: i64 = cho 247 cho = put32(ch, cho, 0); cho = put32(ch, cho, 2) // hdr-len placeholder + record count = 2 248 cho = put32(ch, cho, 100); cho = put32(ch, cho, 8 + authn); cho = puts(ch, cho, auth) 249 let chtitl: *u8 = "Three-Chapter Demo" as *u8; let chtitln: i64 = mf_slen(chtitl) 250 cho = put32(ch, cho, 503); cho = put32(ch, cho, 8 + chtitln); cho = puts(ch, cho, chtitl) 251 var chexthlen: i64 = cho - chexth 252 while (chexthlen % 4) != 0 { ch[cho]=0 as u8; cho=cho+1; chexthlen=chexthlen+1 } 253 put32(ch, chexthlen_pos, chexthlen) 254 while (cho % 4) != 0 { ch[cho]=0 as u8; cho=cho+1 } 255 let chrec1: i64 = cho 256 let chcn: i64 = palmdoc_compress(chtml, chtmln, (ch as i64 + cho) as *u8, K_MAGIC_262144 - cho) 257 cho = cho + chcn 258 put32(ch, 78, chrec0); put32(ch, 86, chrec1) 259 let fdch: i64 = sys_openat_wr("knowledge/fixtures/nishi_mobi_chapters.mobi" as *u8, 0x1a4) 260 if fdch >= 0 { sys_write(fdch, ch, cho); sys_close(fdch) } 261 mf_p("MOBI-CHAPTERS-FIXTURE bytes=" as *u8); mf_n(cho); mf_p(" (3 chapters via pagebreak) -> knowledge/fixtures/nishi_mobi_chapters.mobi\n" as *u8) 262 263 // ---- HEADINGS variant: nishi_mobi_headings.mobi (PalmDOC; 3 <h1> chapters, NO pagebreaks -> heading-fallback TOC) ---- 264 let hhtml: *u8 = "<html><body><h1>Alpha</h1><p>The first chapter about the alpha wolves running through snow.</p><h1>Beta</h1><p>The second chapter where beta fish swim in clear water.</p><h1>Gamma</h1><p>The third chapter on gamma rays beaming from space.</p></body></html>" as *u8 265 let hhtmln: i64 = mf_slen(hhtml) 266 let hh: *u8 = sys_mmap(K_MAGIC_262144) 267 puts(hh, 0, "Headings Fixture" as *u8) 268 puts(hh, 60, "BOOK" as *u8); puts(hh, 64, "MOBI" as *u8) 269 put16(hh, 76, 2) // numRecords = 2 270 var hho: i64 = 96 271 let hhrec0: i64 = hho 272 hho = put16(hh, hho, 2); hho = put16(hh, hho, 0) // compression PalmDOC 273 hho = put32(hh, hho, hhtmln); hho = put16(hh, hho, 1); hho = put16(hh, hho, K_MAGIC_4096) 274 hho = put16(hh, hho, 0); hho = put16(hh, hho, 0) // enc=0 275 hho = puts(hh, hho, "MOBI" as *u8) 276 put32(hh, hho, 24); put32(hh, hho+4, 2); put32(hh, hho+8, K_MAGIC_65001); put32(hh, hho+12, 1); put32(hh, hho+16, 6); hho = hho + 20 277 let hhexth: i64 = hho 278 hho = puts(hh, hho, "EXTH" as *u8) 279 let hhexthlen_pos: i64 = hho 280 hho = put32(hh, hho, 0); hho = put32(hh, hho, 2) 281 hho = put32(hh, hho, 100); hho = put32(hh, hho, 8 + authn); hho = puts(hh, hho, auth) 282 let hhtitl: *u8 = "Heading Demo" as *u8; let hhtitln: i64 = mf_slen(hhtitl) 283 hho = put32(hh, hho, 503); hho = put32(hh, hho, 8 + hhtitln); hho = puts(hh, hho, hhtitl) 284 var hhexthlen: i64 = hho - hhexth 285 while (hhexthlen % 4) != 0 { hh[hho]=0 as u8; hho=hho+1; hhexthlen=hhexthlen+1 } 286 put32(hh, hhexthlen_pos, hhexthlen) 287 while (hho % 4) != 0 { hh[hho]=0 as u8; hho=hho+1 } 288 let hhrec1: i64 = hho 289 let hhcn: i64 = palmdoc_compress(hhtml, hhtmln, (hh as i64 + hho) as *u8, K_MAGIC_262144 - hho) 290 hho = hho + hhcn 291 put32(hh, 78, hhrec0); put32(hh, 86, hhrec1) 292 let fdhh: i64 = sys_openat_wr("knowledge/fixtures/nishi_mobi_headings.mobi" as *u8, 0x1a4) 293 if fdhh >= 0 { sys_write(fdhh, hh, hho); sys_close(fdhh) } 294 mf_p("MOBI-HEADINGS-FIXTURE bytes=" as *u8); mf_n(hho); mf_p(" (3 <h1> chapters, no pagebreak) -> knowledge/fixtures/nishi_mobi_headings.mobi\n" as *u8) 295 296 mf_p("MOBI-FIXTURE-OK\n" as *u8) 297 sys_exit(0); return 0 298}