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}