code wiki / _hdl_build / nx_brand_assets.nx
nx_brand_assets.nx source
↩ module page · 77 lines · 3958 B
1// nx_brand_assets.nx -- brand ASSET SLOTS as DATA: `asset|<name>|<value>` (favicon / logo / og-image / og-title).
2// bas_emit_head writes the corresponding <head> tags (<link rel=icon>, apple-touch-icon, og:image, og:title) with
3// every value ATTRIBUTE-ESCAPED (no breakout) -- wired into wb_doc_open_branded. A brand with no asset tokens emits
4// nothing (backward-compatible). This is the asset-slot system (a full DAM is a separate arc). Library. 100% sovereign.
5// license_tier: ORIGINAL
6import "nx_syscalls.nx"
7
8func bas_app(out: *u8, pos: i64, cap: i64, s: *u8) -> i64 {
9 var p: i64 = pos; var i: i64 = 0
10 while s[i] != (0 as u8) { if p < cap { out[p] = s[i]; p = p + 1 } i = i + 1 }
11 return p
12}
13func bas_fw(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 }
14
15// escape an attribute value: " & < > -> entities (prevents attribute breakout). returns length.
16func bas_esc_attr(v: *u8, out: *u8, cap: i64) -> i64 {
17 var o: i64 = 0; var i: i64 = 0
18 while v[i] != (0 as u8) {
19 let c: i64 = v[i] as i64
20 if c == 34 { o = bas_app(out, o, cap, """ as *u8) }
21 else { if c == 38 { o = bas_app(out, o, cap, "&" as *u8) }
22 else { if c == 60 { o = bas_app(out, o, cap, "<" as *u8) }
23 else { if c == 62 { o = bas_app(out, o, cap, ">" as *u8) }
24 else { if o < cap - 1 { out[o] = v[i]; o = o + 1 } } } } }
25 i = i + 1
26 }
27 out[o] = 0 as u8
28 return o
29}
30// resolve "asset|<name>|<value>" -> value into out; return len or -1.
31func bas_lookup(text: *u8, n: i64, name: *u8, out: *u8, cap: i64) -> i64 {
32 var alen: i64 = 0; while name[alen] != (0 as u8) { alen = alen + 1 }
33 let pipes: *i64 = sys_mmap(64) as *i64
34 var i: i64 = 0
35 while i < n {
36 var le: i64 = i
37 while le < n { if text[le] == (10 as u8) { break } le = le + 1 }
38 var np: i64 = 0
39 var k: i64 = i
40 while k < le { if text[k] == (124 as u8) { if np < 2 { pipes[np] = k; np = np + 1 } } k = k + 1 }
41 if np == 2 {
42 var isa: i64 = 0
43 if pipes[0] - i == 5 { if text[i]==(97 as u8) { if text[i+1]==(115 as u8) { if text[i+2]==(115 as u8) { if text[i+3]==(101 as u8) { if text[i+4]==(116 as u8) { isa = 1 } } } } } } // "asset"
44 if isa == 1 {
45 let a0: i64 = pipes[0] + 1; let a1: i64 = pipes[1]
46 var ism: i64 = 0
47 if a1 - a0 == alen { ism = 1; var j: i64 = 0; while j < alen { if text[a0+j] != name[j] { ism = 0 } j = j + 1 } }
48 if ism == 1 {
49 var o: i64 = 0; var p: i64 = pipes[1] + 1
50 while p < le { if o < cap - 1 { out[o] = text[p]; o = o + 1 } p = p + 1 }
51 out[o] = 0 as u8
52 return o
53 }
54 }
55 }
56 i = le + 1
57 }
58 return 0 - 1
59}
60// emit one <head> tag for `asset` if present (escaped). returns 1 emitted, 0 absent.
61func bas_emit_one(brand: *u8, n: i64, asset: *u8, pre: *u8, post: *u8, fd: i64) -> i64 {
62 let v: *u8 = sys_mmap(512)
63 if bas_lookup(brand, n, asset, v, 512) < 0 { return 0 }
64 let ev: *u8 = sys_mmap(1024)
65 bas_esc_attr(v, ev, 1024)
66 bas_fw(fd, pre); bas_fw(fd, ev); bas_fw(fd, post)
67 return 1
68}
69// emit all known brand-asset <head> tags from the brand. returns count emitted (0 if the brand has no asset slots).
70func bas_emit_head(brand: *u8, n: i64, fd: i64) -> i64 {
71 var c: i64 = 0
72 c = c + bas_emit_one(brand, n, "favicon" as *u8, "<link rel=\"icon\" href=\"" as *u8, "\">\n" as *u8, fd)
73 c = c + bas_emit_one(brand, n, "logo" as *u8, "<link rel=\"apple-touch-icon\" href=\"" as *u8, "\">\n" as *u8, fd)
74 c = c + bas_emit_one(brand, n, "og-image" as *u8, "<meta property=\"og:image\" content=\"" as *u8, "\">\n" as *u8, fd)
75 c = c + bas_emit_one(brand, n, "og-title" as *u8, "<meta property=\"og:title\" content=\"" as *u8, "\">\n" as *u8, fd)
76 return c
77}