nx_lib_serve.nx source
↩ module page · 114 lines · 4268 B
1// nx_lib_serve.nx -- sovereign QUERY/SERVE layer for the nishi-library, on
2// nx_lib_store. This is the MIGRATION rung: the program's read path moves to
3// .nx, reading the sovereign catalog store and emitting the JSON an API
4// returns -- REPLACING serve.py's SQLite _read_work path. No shell, no python,
5// no 3rd-party. Built + run by the WOMB.
6// license_tier: ORIGINAL | genealogy_id: nishi_library_sovereign_serve_2026_06_30
7import "nx_syscalls.nx"
8import "nx_lib_store.nx"
9const K_MAGIC_1048576: i64 = 1048576
10
11// append NUL-terminated s to out at off; return new off.
12func lsv_cat(out: *u8, off: i64, s: *u8) -> i64 {
13 var i: i64 = 0
14 while s[i] != (0 as u8) { out[off + i] = s[i]; i = i + 1 }
15 return off + i
16}
17
18// locate the Nth (0-based) TAB-delimited field of rec[0..reclen): set
19// outp[0]=start ptr, outlen[0]=len; return 1 if found, else 0.
20func lsv_field(rec: *u8, reclen: i64, n: i64, outp: *i64, outlen: *i64) -> i64 {
21 var idx: i64 = 0
22 var start: i64 = 0
23 var i: i64 = 0
24 while i <= reclen {
25 var atend: i64 = 0
26 if i == reclen { atend = 1 } else { if rec[i] == 9 as u8 { atend = 1 } }
27 if atend == 1 {
28 if idx == n {
29 outp[0] = (rec as i64) + start
30 outlen[0] = i - start
31 return 1
32 }
33 idx = idx + 1
34 start = i + 1
35 }
36 i = i + 1
37 }
38 return 0
39}
40
41// append the Nth field of rec, JSON-escaped (" and \), to out at off.
42func lsv_cat_field(out: *u8, off: i64, rec: *u8, reclen: i64, n: i64) -> i64 {
43 let po: *i64 = sys_mmap(16) as *i64
44 let lo: *i64 = sys_mmap(16) as *i64
45 if lsv_field(rec, reclen, n, po, lo) == 0 { return off }
46 let fp: *u8 = po[0] as *u8
47 let fn: i64 = lo[0]
48 var i: i64 = 0
49 var o: i64 = off
50 while i < fn {
51 let c: i64 = fp[i] as i64
52 if c == 34 { out[o] = 92 as u8; o = o + 1; out[o] = 34 as u8; o = o + 1 }
53 else { if c == 92 { out[o] = 92 as u8; o = o + 1; out[o] = 92 as u8; o = o + 1 }
54 else { out[o] = fp[i]; o = o + 1 } }
55 i = i + 1
56 }
57 return o
58}
59
60// serve one work as JSON into out; returns byte length, or -1 if not found.
61// record layout: title<TAB>doi<TAB>published<TAB>license<TAB>abstract
62func nx_lib_serve_work(hk: *u8, out: *u8) -> i64 {
63 let po: *i64 = sys_mmap(16) as *i64
64 let lo: *i64 = sys_mmap(16) as *i64
65 if nx_lib_store_get_work(hk, po, lo) < 0 { return 0 - 1 }
66 let rec: *u8 = po[0] as *u8
67 let reclen: i64 = lo[0]
68 var o: i64 = 0
69 o = lsv_cat(out, o, "{\"work_hk\":\"" as *u8)
70 o = lsv_cat(out, o, hk)
71 o = lsv_cat(out, o, "\",\"title\":\"" as *u8)
72 o = lsv_cat_field(out, o, rec, reclen, 0)
73 o = lsv_cat(out, o, "\",\"doi\":\"" as *u8)
74 o = lsv_cat_field(out, o, rec, reclen, 1)
75 o = lsv_cat(out, o, "\",\"published\":\"" as *u8)
76 o = lsv_cat_field(out, o, rec, reclen, 2)
77 o = lsv_cat(out, o, "\",\"license\":\"" as *u8)
78 o = lsv_cat_field(out, o, rec, reclen, 3)
79 o = lsv_cat(out, o, "\",\"abstract\":\"" as *u8)
80 o = lsv_cat_field(out, o, rec, reclen, 4)
81 o = lsv_cat(out, o, "\",\"authors\":\"" as *u8)
82 o = lsv_cat_field(out, o, rec, reclen, 5)
83 o = lsv_cat(out, o, "\"}" as *u8)
84 return o
85}
86
87// serve the catalog work-list as a JSON array of work_hks into out; returns len.
88func nx_lib_serve_list(out: *u8) -> i64 {
89 let idxbuf: *u8 = sys_mmap(K_MAGIC_1048576)
90 let n: i64 = nx_lib_store_index(idxbuf)
91 var o: i64 = 0
92 out[o] = 91 as u8; o = o + 1 // '['
93 var i: i64 = 0
94 var start: i64 = 0
95 var first: i64 = 1
96 while i <= n {
97 var atend: i64 = 0
98 if i == n { atend = 1 } else { if idxbuf[i] == 10 as u8 { atend = 1 } }
99 if atend == 1 {
100 if i > start {
101 if first == 0 { out[o] = 44 as u8; o = o + 1 } // ','
102 first = 0
103 out[o] = 34 as u8; o = o + 1 // '"'
104 var c: i64 = start
105 while c < i { out[o] = idxbuf[c]; o = o + 1; c = c + 1 }
106 out[o] = 34 as u8; o = o + 1 // '"'
107 }
108 start = i + 1
109 }
110 i = i + 1
111 }
112 out[o] = 93 as u8; o = o + 1 // ']'
113 return o
114}