code wiki / (root) / nx_mcp_control.nx

nx_mcp_control.nx source

↩ module page · 180 lines · 7513 B

1// Borrowed MCP control metadata. JSON stays at the boundary; no value tree 2// survives in the long-lived connector. Scratch sizes derive from this input. 3import "nx_json.nx" 4import "nx_mcp_route.nx" 5 6struct NxMcpControl { 7 method: i64, 8 id_kind: i64, 9 id_off: i64, 10 id_len: i64, 11 cancel_kind: i64, 12 cancel_off: i64, 13 cancel_len: i64, 14} 15struct NxMcpControlFrame { mode: i64, key: i64, params: i64 } 16 17// Object modes: key-or-end, colon, value, comma-or-end, mandatory-key. 18// Array modes: value-or-end, comma-or-end, mandatory-value. 19const MCT_OBJ_KEY: i64 = 1 20const MCT_OBJ_COLON: i64 = 2 21const MCT_OBJ_VALUE: i64 = 3 22const MCT_OBJ_NEXT: i64 = 4 23const MCT_OBJ_REQUIRED: i64 = 5 24const MCT_ARR_VALUE: i64 = 6 25const MCT_ARR_NEXT: i64 = 7 26const MCT_ARR_REQUIRED: i64 = 8 27const MCT_INITIALIZE: i64 = 1 28const MCT_INITIALIZED: i64 = 2 29const MCT_CANCEL: i64 = 3 30const MCT_OTHER: i64 = 4 31 32func mct_frame(frames: *u8, index: i64) -> *NxMcpControlFrame { 33 return (frames + index*__size_of(NxMcpControlFrame)) as *NxMcpControlFrame 34} 35 36func mct_scan(t: *NxJsonTok, frames: *u8, scratch: *u8, out: *NxMcpControl) -> i64 { 37 if nx_json_next(t) != NX_JSON_LBRACE { return -1 } 38 var depth: i64 = 1 39 let root_frame: *NxMcpControlFrame = mct_frame(frames,0) 40 root_frame.mode = MCT_OBJ_KEY 41 var root_seen: i64 = 0 42 var cancel_seen: i64 = 0 43 while depth > 0 { 44 let token: i64 = nx_json_next(t) 45 if token == NX_JSON_ERROR { return -1 } 46 if token == NX_JSON_EOF { return -1 } 47 let f: *NxMcpControlFrame = mct_frame(frames,depth-1) 48 var decoded: i64 = -1 49 if token == NX_JSON_STRING { 50 decoded = jx_decode_span(t.src+t.tok_off+1,t.tok_len-2,scratch,t.len+1) 51 if decoded < 0 { return -1 } 52 } 53 if f.mode == MCT_OBJ_KEY || f.mode == MCT_OBJ_REQUIRED { 54 if token == NX_JSON_RBRACE { 55 if f.mode == MCT_OBJ_REQUIRED { return -1 } 56 depth = depth-1; continue 57 } 58 if token != NX_JSON_STRING { return -1 } 59 f.key = 0 60 if depth == 1 { 61 if mr_equal(scratch,decoded,"method" as *u8) == 1 { f.key = 1 } 62 if mr_equal(scratch,decoded,"id" as *u8) == 1 { f.key = 2 } 63 if mr_equal(scratch,decoded,"params" as *u8) == 1 { f.key = 4 } 64 if mr_equal(scratch,decoded,"jsonrpc" as *u8) == 1 { f.key = 8 } 65 if f.key != 0 { 66 if (root_seen & f.key) != 0 { return -1 } 67 root_seen = root_seen | f.key 68 } 69 } 70 if f.params != 0 { 71 if mr_equal(scratch,decoded,"requestId" as *u8) == 1 { 72 if cancel_seen != 0 { return -1 } 73 cancel_seen = 1; f.key = 16 74 } 75 } 76 f.mode = MCT_OBJ_COLON; continue 77 } 78 if f.mode == MCT_OBJ_COLON { 79 if token != NX_JSON_COLON { return -1 } 80 f.mode = MCT_OBJ_VALUE; continue 81 } 82 if f.mode == MCT_OBJ_NEXT { 83 if token == NX_JSON_RBRACE { depth = depth-1; continue } 84 if token != NX_JSON_COMMA { return -1 } 85 f.mode = MCT_OBJ_REQUIRED; continue 86 } 87 if f.mode == MCT_ARR_NEXT { 88 if token == NX_JSON_RBRACKET { depth = depth-1; continue } 89 if token != NX_JSON_COMMA { return -1 } 90 f.mode = MCT_ARR_REQUIRED; continue 91 } 92 if f.mode == MCT_ARR_VALUE { 93 if token == NX_JSON_RBRACKET { depth = depth-1; continue } 94 } 95 let key: i64 = f.key 96 if f.mode != MCT_OBJ_VALUE { f.key = 0 } 97 if f.mode == MCT_OBJ_VALUE { f.mode = MCT_OBJ_NEXT } else { f.mode = MCT_ARR_NEXT } 98 if depth == 1 { 99 if key == 1 { 100 if token != NX_JSON_STRING { return -1 } 101 out.method = MCT_OTHER 102 if mr_equal(scratch,decoded,"initialize" as *u8) == 1 { out.method = MCT_INITIALIZE } 103 if mr_equal(scratch,decoded,"notifications/initialized" as *u8) == 1 { out.method = MCT_INITIALIZED } 104 if mr_equal(scratch,decoded,"notifications/cancelled" as *u8) == 1 { out.method = MCT_CANCEL } 105 } 106 if key == 8 { 107 if token != NX_JSON_STRING { return -1 } 108 if mr_equal(scratch,decoded,"2.0" as *u8) != 1 { return -1 } 109 } 110 } 111 if key == 2 || key == 16 { 112 if token != NX_JSON_STRING { if token != NX_JSON_NUMBER { return -1 } } 113 if token == NX_JSON_NUMBER { 114 var digit: i64 = 0 115 if t.src[t.tok_off] == (45 as u8) { digit=1 } 116 if digit >= t.tok_len { return -1 } 117 if t.src[t.tok_off+digit] == (48 as u8) { if t.tok_len-digit != 1 { return -1 } } 118 while digit < t.tok_len { 119 if nx_ascii_is_digit(t.src[t.tok_off+digit]) == 0 { return -1 } 120 digit=digit+1 121 } 122 } 123 var offset: i64 = t.tok_off 124 var count: i64 = t.tok_len 125 if token == NX_JSON_STRING { offset = offset+1; count = count-2 } 126 if key == 2 { out.id_kind=token; out.id_off=offset; out.id_len=count } 127 if key == 16 { out.cancel_kind=token; out.cancel_off=offset; out.cancel_len=count } 128 } 129 if token == NX_JSON_LBRACE || token == NX_JSON_LBRACKET { 130 let child: *NxMcpControlFrame = mct_frame(frames,depth) 131 child.mode = MCT_OBJ_KEY 132 if token == NX_JSON_LBRACKET { child.mode = MCT_ARR_VALUE } 133 child.key = 0; child.params = 0 134 if depth == 1 { if key == 4 { if token == NX_JSON_LBRACE { child.params=1 } } } 135 depth = depth+1; continue 136 } 137 if token != NX_JSON_STRING { if token != NX_JSON_NUMBER { 138 if token != NX_JSON_TRUE { if token != NX_JSON_FALSE { if token != NX_JSON_NULL { return -1 } } } 139 } } 140 } 141 if nx_json_next(t) != NX_JSON_EOF { return -1 } 142 if (root_seen & 9) != 9 { return -1 } 143 if out.method == MCT_INITIALIZE { if out.id_kind == 0 { return -1 } } 144 if out.method == MCT_INITIALIZED { if out.id_kind != 0 { return -1 } } 145 if out.method == MCT_CANCEL { 146 if out.id_kind != 0 { return -1 } 147 if out.cancel_kind == 0 { return -1 } 148 } 149 return 0 150} 151 152func mct_read(src: *u8, n: i64, out: *NxMcpControl) -> i64 { 153 if n <= 0 { return -1 } 154 out.method=0; out.id_kind=0; out.id_off=0; out.id_len=0 155 out.cancel_kind=0; out.cancel_off=0; out.cancel_len=0 156 let t: *NxJsonTok = nx_json_new(src,n) 157 var depth: i64 = 0 158 var peak: i64 = 0 159 var valid: i64 = 1 160 while true { 161 let k: i64 = nx_json_next(t) 162 if k == NX_JSON_ERROR { valid=0; break } 163 if k == NX_JSON_EOF { break } 164 if k == NX_JSON_LBRACE || k == NX_JSON_LBRACKET { depth=depth+1; if depth>peak { peak=depth } } 165 if k == NX_JSON_RBRACE || k == NX_JSON_RBRACKET { depth=depth-1; if depth<0 { valid=0; break } } 166 } 167 var result: i64 = -1 168 if depth != 0 { valid=0 } 169 if peak == 0 { valid=0 } 170 if valid != 0 { 171 let frame_bytes: i64 = peak*__size_of(NxMcpControlFrame) 172 let frames: *u8 = sys_mmap(frame_bytes) 173 let scratch: *u8 = sys_mmap(n+1) 174 t.pos=0 175 result=mct_scan(t,frames,scratch,out) 176 sys_munmap(frames,frame_bytes); sys_munmap(scratch,n+1) 177 } 178 sys_munmap(t as *u8,__size_of(NxJsonTok)) 179 return result 180}