code wiki / _hdl_build / nx_property_registry.nx
nx_property_registry.nx source
↩ module page · 68 lines · 2978 B
1// nx_property_registry.nx -- the hosting platform's PROPERTY REGISTRY: data-driven domain -> backend port.
2// One property per config line: "domain port tenancy group" (# = comment, blank lines ignored). MULTIPLE domains
3// pointing at the same port+group = ONE multi-domain business (e.g. West Industrial Direct's several sites all
4// roll up to its daemon). Rule 11/17: routing is DATA not hardcoded -- adding a property = adding a line, no
5// recompile. The SNI router loads this once at startup and looks up each connection's SNI. license_tier: ORIGINAL
6import "nx_syscalls.nx"
7
8// exact compare host[0..host_n] vs cfg[ds..ds+dl]
9func pr_eq(cfg: *u8, ds: i64, dl: i64, host: *u8, host_n: i64) -> i64 {
10 if dl != host_n { return 0 }
11 var i: i64=0
12 while i<dl { if cfg[ds+i] != host[i] { return 0 } i=i+1 }
13 return 1
14}
15// advance from p until cfg[p]==space or p==le (NishiLang has no && -- explicit go-flag scans)
16func pr_to_space(cfg: *u8, p: i64, le: i64) -> i64 {
17 var q: i64=p; var go: i64=1
18 while go==1 { if q>=le { go=0 } else { if cfg[q]==(32 as u8) { go=0 } else { q=q+1 } } }
19 return q
20}
21func pr_skip_sp(cfg: *u8, p: i64, le: i64) -> i64 {
22 var q: i64=p; var go: i64=1
23 while go==1 { if q>=le { go=0 } else { if cfg[q]==(32 as u8) { q=q+1 } else { go=0 } } }
24 return q
25}
26func pr_digits(cfg: *u8, p: i64, le: i64) -> i64 {
27 var q: i64=p; var v: i64=0; var go: i64=1
28 while go==1 {
29 if q>=le { go=0 } else {
30 let c: i64 = cfg[q] as i64
31 if c>=48 { if c<=57 { v=v*10+(c-48); q=q+1 } else { go=0 } } else { go=0 }
32 }
33 }
34 return v
35}
36
37// look up host -> backend port in the registry config buffer; default_port if no matching entry.
38func pr_lookup(cfg: *u8, cfg_n: i64, host: *u8, host_n: i64, default_port: i64) -> i64 {
39 var i: i64 = 0
40 while i < cfg_n {
41 var le: i64 = i; var fe: i64=1
42 while fe==1 { if le>=cfg_n { fe=0 } else { if cfg[le]==(10 as u8) { fe=0 } else { le=le+1 } } }
43 let p: i64 = pr_skip_sp(cfg, i, le)
44 if p < le {
45 if cfg[p] != (35 as u8) { // not a # comment
46 let ds: i64 = p
47 let de: i64 = pr_to_space(cfg, p, le)
48 let dl: i64 = de - ds
49 let pp: i64 = pr_skip_sp(cfg, de, le)
50 let port: i64 = pr_digits(cfg, pp, le)
51 if dl > 0 { if port > 0 { if pr_eq(cfg, ds, dl, host, host_n)==1 { return port } } }
52 }
53 }
54 i = le
55 if i < cfg_n { i = i + 1 }
56 }
57 return default_port
58}
59
60// load the registry file into buf; return bytes loaded (0 = missing/empty -> caller uses default routing).
61func pr_load(path: *u8, buf: *u8, cap: i64) -> i64 {
62 let lb: *i64 = (sys_mmap(8)) as *i64; lb[0]=0
63 let data: *u8 = sys_read_file(path, lb)
64 if (data as i64)==0 { return 0 }
65 var c: i64 = lb[0]; if c > cap { c = cap }
66 var i: i64=0; while i<c { buf[i]=data[i]; i=i+1 }
67 return c
68}