sproto.js 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788
  1. /* eslint-disable no-console */
  2. /* eslint-disable no-redeclare */
  3. /* eslint-disable indent */
  4. /* eslint-disable camelcase */
  5. // sproto.js 解析
  6. let sproto = (function () {
  7. let t = {};
  8. let host = {};
  9. let header_tmp = {};
  10. // 常量定义
  11. let SPROTO_REQUEST = 0;
  12. let SPROTO_RESPONSE = 1;
  13. // type (sproto_arg.type)
  14. let SPROTO_TINTEGER = 0;
  15. let SPROTO_TBOOLEAN = 1;
  16. let SPROTO_TSTRING = 2;
  17. let SPROTO_TSTRUCT = 3;
  18. let SPROTO_CB_ERROR = -1;
  19. let SPROTO_CB_NIL = -2;
  20. let SPROTO_CB_NOARRAY = -3;
  21. let SPROTO_TARRAY = 0x80;
  22. let SIZEOF_LENGTH = 4;
  23. let SIZEOF_HEADER = 2;
  24. let SIZEOF_FIELD = 2;
  25. let ENCODE_DEEPLEVEL = 64;
  26. // js中只long只能表示到2^52-1, 0xFFFFFFFFFFFFF表示
  27. function expand64 (v) {
  28. let value = v;
  29. if ((value & 0x80000000) != 0) {
  30. value = 0x0000000000000 + (value & 0xFFFFFFFF);
  31. }
  32. return value;
  33. }
  34. function hi_low_uint64 (low, hi) {
  35. let value = (hi & 0xFFFFFFFF) * 0x100000000 + low;
  36. return value;
  37. }
  38. function uint64_rshift (num, offset) {
  39. return Math.floor(num / Math.pow(2, offset));
  40. }
  41. // 2 byte 的数
  42. function toword (stream, sidx = 0) {
  43. return (stream[sidx] & 0xff) | (stream[sidx + 1] & 0xff) << 8;
  44. }
  45. // 4 byte 的数。取绝对值
  46. function todword (stream, sidx = 0) {
  47. return (
  48. (stream[sidx] & 0xff) |
  49. (stream[sidx + 1] & 0xff) << 8 |
  50. (stream[sidx + 2] & 0xff) << 16 |
  51. (stream[sidx + 3] & 0xff) << 24
  52. ) >>> 0;
  53. }
  54. function count_array (stream, sidx = 0) {
  55. let length = todword(stream, sidx);
  56. let n = 0;
  57. sidx += SIZEOF_LENGTH; // 下一个元素的起点
  58. while (length > 0) {
  59. // 异常:尾部不齐
  60. if (length < SIZEOF_LENGTH) {
  61. return -1;
  62. }
  63. let nsz = todword(stream, sidx);
  64. nsz += SIZEOF_LENGTH;
  65. // 异常:stream长度不对
  66. if (nsz > length) {
  67. return -1;
  68. }
  69. ++n;
  70. sidx += nsz;
  71. length -= nsz;
  72. }
  73. return n;
  74. }
  75. function struct_field (stream, sz, sidx = 0) {
  76. if (sz < SIZEOF_HEADER) {
  77. return -1;
  78. }
  79. let fn = toword(stream, sidx);
  80. // 不做检查了!
  81. return fn;
  82. }
  83. // stream 是 arraybuffer
  84. function import_string (stream, sidx = 0) {
  85. let sz = todword(stream, sidx);
  86. sidx += SIZEOF_LENGTH;
  87. let buffer = '';
  88. for (let i = 0; i < sz; i++) {
  89. buffer += String.fromCharCode(stream[sidx + i]);
  90. }
  91. return buffer;
  92. }
  93. function calc_pow (base, n) {
  94. if (n == 0)
  95. return 1;
  96. let r = calc_pow(base * base, Math.floor(n / 2));
  97. if ((n & 1) != 0) {
  98. r *= base;
  99. }
  100. return r;
  101. }
  102. function import_field (s, f, stream, sidx = 0) {
  103. let sz, result, fn;
  104. let array = 0;
  105. let tag = -1;
  106. f.tag = -1;
  107. f.type = -1;
  108. f.name = null;
  109. f.st = null;
  110. f.key = -1;
  111. f.extra = 0;
  112. sz = todword(stream, sidx);
  113. sidx += SIZEOF_LENGTH;
  114. result = sidx + sz;
  115. fn = struct_field(stream, sz, sidx);
  116. if (fn < 0)
  117. return null;
  118. sidx += SIZEOF_HEADER;
  119. for (let i = 0; i < fn; i++) {
  120. let value;
  121. ++tag;
  122. value = toword(stream, sidx + SIZEOF_FIELD * i);
  123. if (value & 1 != 0) {
  124. tag += Math.floor(value / 2);
  125. continue;
  126. }
  127. if (tag == 0) { // name
  128. if (value != 0)
  129. return null;
  130. f.name = import_string(stream, sidx + fn * SIZEOF_FIELD);
  131. continue;
  132. }
  133. if (value == 0)
  134. return null;
  135. value = Math.floor(value / 2) - 1;
  136. switch (tag) {
  137. case 1: { // buildin
  138. if (value >= SPROTO_TSTRUCT) {
  139. return null; // invalid buildin type
  140. }
  141. f.type = value;
  142. break;
  143. }
  144. case 2: { // type index
  145. if (f.type == SPROTO_TINTEGER) {
  146. f.extra = calc_pow(10, value);
  147. } else if (f.type == SPROTO_TSTRING) {
  148. f.extra = value; // string if 0 ; binary is 1
  149. } else {
  150. if (value >= s.type_n) {
  151. return null; // invalid type index
  152. }
  153. if (f.type >= 0) {
  154. return null;
  155. }
  156. f.type = SPROTO_TSTRUCT;
  157. f.st = value;
  158. }
  159. break;
  160. }
  161. case 3: { // tag
  162. f.tag = value;
  163. break;
  164. }
  165. case 4: { // array
  166. if (value != 0) {
  167. array = SPROTO_TARRAY;
  168. }
  169. break;
  170. }
  171. case 5: { // key
  172. f.key = value;
  173. break;
  174. }
  175. default: {
  176. return null;
  177. }
  178. }
  179. }
  180. if (f.tag < 0 || f.type < 0 || f.name == null) {
  181. return null;
  182. }
  183. f.type |= array;
  184. return result;
  185. }
  186. /*
  187. .type {
  188. .field {
  189. name 0 : string
  190. buildin 1 : integer
  191. type 2 : integer
  192. tag 3 : integer
  193. array 4 : boolean
  194. }
  195. name 0 : string
  196. fields 1 : *field
  197. }
  198. */
  199. function import_type (s, t, stream, sidx = 0) {
  200. let result, fn, n, maxn, last;
  201. let sz = todword(stream, sidx);
  202. sidx += SIZEOF_LENGTH;
  203. result = sidx + sz;
  204. fn = struct_field(stream, sz, sidx);
  205. if (fn <= 0 || fn > 2) {
  206. return null;
  207. }
  208. for (let i = 0; i < fn * SIZEOF_FIELD; i += SIZEOF_FIELD) {
  209. // name and fields must encode to 0
  210. let v = toword(stream, sidx + SIZEOF_HEADER + i);
  211. if (v != 0)
  212. return null;
  213. }
  214. t.name = null;
  215. t.n = 0;
  216. t.base = 0;
  217. t.maxn = 0;
  218. t.f = null;
  219. sidx += SIZEOF_HEADER + fn * SIZEOF_FIELD;
  220. t.name = import_string(stream, sidx);
  221. if (fn == 1) {
  222. return result;
  223. }
  224. sidx += todword(stream, sidx) + SIZEOF_LENGTH; // second data
  225. n = count_array(stream, sidx);
  226. if (n < 0) {
  227. return null;
  228. }
  229. sidx += SIZEOF_LENGTH;
  230. maxn = n;
  231. last = -1;
  232. t.n = n;
  233. t.f = [];
  234. for (let i = 0; i < n; i++) {
  235. let tag;
  236. t.f[i] = Object.create(null);
  237. let f = t.f[i];
  238. sidx = import_field(s, f, stream, sidx);
  239. if (sidx == null) {
  240. return null;
  241. }
  242. tag = f.tag;
  243. if (tag <= last) {
  244. return null; // tag must in ascending order
  245. }
  246. if (tag > last + 1) {
  247. ++maxn;
  248. }
  249. last = tag;
  250. }
  251. t.maxn = maxn;
  252. t.base = t.f[0].tag;
  253. n = t.f[n - 1].tag - t.base + 1;
  254. if (n != t.n) {
  255. t.base = -1;
  256. }
  257. return result;
  258. }
  259. /*
  260. .protocol {
  261. name 0 : string
  262. tag 1 : integer
  263. request 2 : integer
  264. response 3 : integer
  265. }
  266. */
  267. function import_protocol (s, p, stream, sidx = 0) {
  268. let result, fn, tag;
  269. let sz = todword(stream, sidx);
  270. sidx += SIZEOF_LENGTH;
  271. result = sidx + sz;
  272. fn = struct_field(stream, sz, sidx);
  273. sidx += SIZEOF_HEADER;
  274. p.name = null;
  275. p.tag = -1;
  276. p.p = [];
  277. p.p[SPROTO_REQUEST] = null;
  278. p.p[SPROTO_RESPONSE] = null;
  279. p.confirm = 0; // TODO
  280. tag = 0;
  281. for (let i = 0; i < fn; i++, tag++) {
  282. let value = toword(stream, sidx + SIZEOF_FIELD * i);
  283. if (value & 1 != 0) {
  284. tag += (value - 1) / 2;
  285. continue;
  286. }
  287. value = value / 2 - 1;
  288. switch (i) {
  289. case 0: { // name
  290. if (value != -1) {
  291. return null;
  292. }
  293. p.name = import_string(stream, sidx + SIZEOF_FIELD * fn);
  294. break;
  295. }
  296. case 1: { // tag
  297. if (value < 0) {
  298. return null;
  299. }
  300. p.tag = value;
  301. break;
  302. }
  303. case 2: { // request
  304. if (value < 0 || value >= s.type_n)
  305. return null;
  306. p.p[SPROTO_REQUEST] = s.type[value];
  307. break;
  308. }
  309. case 3: { // response
  310. if (value < 0 || value >= s.type_n)
  311. return null;
  312. p.p[SPROTO_RESPONSE] = s.type[value];
  313. break;
  314. }
  315. case 4: { // TODO
  316. p.confirm = value;
  317. break;
  318. }
  319. default: {
  320. return null;
  321. }
  322. }
  323. }
  324. if (p.name == null || p.tag < 0) {
  325. return null;
  326. }
  327. return result;
  328. }
  329. function create_from_bundle (s, stream, sz) {
  330. let content, typedata, protocoldata;
  331. let sidx = 0;
  332. let fn = struct_field(stream, sz, sidx);
  333. if (fn < 0 || fn > 2)
  334. return null;
  335. sidx += SIZEOF_HEADER;
  336. content = sidx + fn * SIZEOF_FIELD;
  337. for (let i = 0; i < fn; i++) {
  338. let value = toword(stream, sidx + i * SIZEOF_FIELD);
  339. if (value != 0) {
  340. return null;
  341. }
  342. let n = count_array(stream, content);
  343. if (n < 0) {
  344. return null;
  345. }
  346. if (i == 0) {
  347. typedata = content + SIZEOF_LENGTH;
  348. s.type_n = n;
  349. s.type = [];
  350. } else {
  351. protocoldata = content + SIZEOF_LENGTH;
  352. s.protocol_n = n;
  353. s.proto = [];
  354. }
  355. content += todword(stream, content) + SIZEOF_LENGTH;
  356. }
  357. for (let i = 0; i < s.type_n; i++) {
  358. s.type[i] = Object.create(null);
  359. typedata = import_type(s, s.type[i], stream, typedata);
  360. if (typedata == null) {
  361. return null;
  362. }
  363. }
  364. for (let i = 0; i < s.protocol_n; i++) {
  365. s.proto[i] = Object.create(null);
  366. protocoldata = import_protocol(s, s.proto[i], stream, protocoldata);
  367. if (protocoldata == null) {
  368. return null;
  369. }
  370. }
  371. return s;
  372. }
  373. // query
  374. function sproto_prototag (sp, name) {
  375. for (let i = 0; i < sp.protocol_n; i++) {
  376. if (name == sp.proto[i].name) {
  377. return sp.proto[i].tag;
  378. }
  379. }
  380. return -1;
  381. }
  382. // 二分查找
  383. function query_proto (sp, tag) {
  384. let begin = 0;
  385. let end = sp.protocol_n;
  386. while (begin < end) {
  387. let mid = Math.floor((begin + end) / 2);
  388. let t = sp.proto[mid].tag;
  389. if (t == tag) {
  390. return sp.proto[mid];
  391. }
  392. if (tag > t) {
  393. begin = mid + 1;
  394. } else {
  395. end = mid;
  396. }
  397. }
  398. return null;
  399. }
  400. function sproto_protoquery (sp, proto, what) {
  401. let p = null;
  402. if (what < 0 || what > 1) {
  403. return null;
  404. }
  405. p = query_proto(sp, proto);
  406. if (p) {
  407. return p.p[what];
  408. }
  409. return null;
  410. }
  411. function sproto_protoname (sp, proto) {
  412. let p = query_proto(sp, proto);
  413. if (p) {
  414. return p.name;
  415. }
  416. return null;
  417. }
  418. function sproto_type (sp, type_name) {
  419. for (let i = 0; i < sp.type_n; i++) {
  420. if (type_name == sp.type[i].name) {
  421. return sp.type[i];
  422. }
  423. }
  424. return null;
  425. }
  426. function sproto_name (st) {
  427. return st.name;
  428. }
  429. function findtag (st, tag) {
  430. let begin, end;
  431. if (st.base >= 0) {
  432. tag -= st.base;
  433. if (tag < 0 || tag > st.n) {
  434. return null;
  435. }
  436. return st.f[tag];
  437. }
  438. begin = 0;
  439. end = st.n;
  440. while (begin < end) {
  441. let mid = Math.floor((begin + end) / 2);
  442. let f = st.f[mid];
  443. let t = f.tag;
  444. if (t == tag) {
  445. return f;
  446. }
  447. if (tag > t) {
  448. begin = mid + 1;
  449. } else {
  450. end = mid;
  451. }
  452. }
  453. return null;
  454. }
  455. function fill_size (data, data_idx, sz) {
  456. data[data_idx] = sz & 0xff;
  457. data[data_idx + 1] = (sz >> 8) & 0xff;
  458. data[data_idx + 2] = (sz >> 16) & 0xff;
  459. data[data_idx + 3] = (sz >> 24) & 0xff;
  460. return sz + SIZEOF_LENGTH;
  461. }
  462. function encode_integer (v, data, data_idx, size) {
  463. data[data_idx + 4] = v & 0xff;
  464. data[data_idx + 5] = (v >> 8) & 0xff;
  465. data[data_idx + 6] = (v >> 16) & 0xff;
  466. data[data_idx + 7] = (v >> 24) & 0xff;
  467. return fill_size(data, data_idx, 4);
  468. }
  469. function encode_uint64 (v, data, data_idx, size) {
  470. data[data_idx + 4] = v & 0xff;
  471. data[data_idx + 5] = uint64_rshift(v, 8) & 0xff;
  472. data[data_idx + 6] = uint64_rshift(v, 16) & 0xff;
  473. data[data_idx + 7] = uint64_rshift(v, 24) & 0xff;
  474. data[data_idx + 8] = uint64_rshift(v, 32) & 0xff;
  475. data[data_idx + 9] = uint64_rshift(v, 40) & 0xff;
  476. data[data_idx + 10] = uint64_rshift(v, 48) & 0xff;
  477. data[data_idx + 11] = uint64_rshift(v, 56) & 0xff;
  478. return fill_size(data, data_idx, 8);
  479. }
  480. function encode_object (cb, args, data, data_idx) {
  481. let sz;
  482. args.buffer = data;
  483. args.buffer_idx = data_idx + SIZEOF_LENGTH;
  484. sz = cb(args);
  485. if (sz < 0) {
  486. if (sz == SPROTO_CB_NIL) {
  487. return 0;
  488. }
  489. return -1; // sz == SPROTO_CB_ERROR
  490. }
  491. return fill_size(data, data_idx, sz);
  492. }
  493. function uint32_to_uint64 (negative, buffer, buffer_idx) {
  494. if (negative) {
  495. buffer[buffer_idx + 4] = 0xff;
  496. buffer[buffer_idx + 5] = 0xff;
  497. buffer[buffer_idx + 6] = 0xff;
  498. buffer[buffer_idx + 7] = 0xff;
  499. } else {
  500. buffer[buffer_idx + 4] = 0;
  501. buffer[buffer_idx + 5] = 0;
  502. buffer[buffer_idx + 6] = 0;
  503. buffer[buffer_idx + 7] = 0;
  504. }
  505. }
  506. function encode_integer_array (cb, args, buffer, buffer_idx, noarray) {
  507. let intlen, index;
  508. let header_idx = buffer_idx;
  509. buffer_idx++;
  510. intlen = 4;
  511. index = 1;
  512. noarray.value = 0;
  513. for (;;) {
  514. let sz;
  515. args.value = null;
  516. args.length = 8;
  517. args.index = index;
  518. sz = cb(args);
  519. if (sz <= 0) {
  520. if (sz == SPROTO_CB_NIL) { // nil object, end of array
  521. break;
  522. }
  523. if (sz == SPROTO_CB_NOARRAY) { // no array, don't encode it
  524. noarray.value = 1;
  525. break;
  526. }
  527. return null; // sz == SPROTO_CB_ERROR
  528. }
  529. if (sz == 4) {
  530. let v = args.value;
  531. buffer[buffer_idx] = v & 0xff;
  532. buffer[buffer_idx + 1] = (v >> 8) & 0xff;
  533. buffer[buffer_idx + 2] = (v >> 16) & 0xff;
  534. buffer[buffer_idx + 3] = (v >> 24) & 0xff;
  535. if (intlen == 8) {
  536. uint32_to_uint64(v & 0x80000000, buffer, buffer_idx);
  537. }
  538. } else {
  539. let v;
  540. if (sz != 8) {
  541. return null;
  542. }
  543. if (intlen == 4) {
  544. buffer_idx += (index - 1) * 4;
  545. for (let i = index - 2; i >= 0; i--) {
  546. let negative;
  547. for (let j = (1 + i * 8); j < (1 + i * 8 + 4); j++) {
  548. buffer[header_idx + j] = buffer[header_idx + j - i * 4];
  549. }
  550. negative = buffer[header_idx + 1 + i * 8 + 3] & 0x80;
  551. uint32_to_uint64(negative, buffer, buffer_idx + 1 + i * 8);
  552. }
  553. intlen = 8;
  554. }
  555. v = args.value;
  556. buffer[buffer_idx] = v & 0xff;
  557. buffer[buffer_idx + 1] = (v >> 8) & 0xff;
  558. buffer[buffer_idx + 2] = (v >> 16) & 0xff;
  559. buffer[buffer_idx + 3] = (v >> 24) & 0xff;
  560. buffer[buffer_idx + 4] = (v >> 32) & 0xff;
  561. buffer[buffer_idx + 5] = (v >> 40) & 0xff;
  562. buffer[buffer_idx + 6] = (v >> 48) & 0xff;
  563. buffer[buffer_idx + 7] = (v >> 56) & 0xff;
  564. }
  565. buffer_idx += intlen;
  566. index++;
  567. }
  568. if (buffer_idx == header_idx + 1) {
  569. return header_idx;
  570. }
  571. buffer[header_idx] = intlen & 0xff;
  572. return buffer_idx;
  573. }
  574. function encode_array (cb, args, data, data_idx) {
  575. let sz;
  576. let buffer = data;
  577. let buffer_idx = data_idx + SIZEOF_LENGTH;
  578. switch (args.type) {
  579. case SPROTO_TINTEGER: {
  580. let noarray = {};
  581. noarray.value = 0;
  582. buffer_idx = encode_integer_array(cb, args, buffer, buffer_idx, noarray);
  583. if (buffer_idx == null) {
  584. return -1;
  585. }
  586. if (noarray.value != 0) {
  587. return 0;
  588. }
  589. break;
  590. }
  591. case SPROTO_TBOOLEAN: {
  592. args.index = 1;
  593. for (;;) {
  594. let v = 0;
  595. args.value = v;
  596. args.length = 4;
  597. sz = cb(args);
  598. if (sz < 0) {
  599. if (sz == SPROTO_CB_NIL) // nil object , end of array
  600. break;
  601. if (sz == SPROTO_CB_NOARRAY) // no array, don't encode it
  602. return 0;
  603. return -1; // sz == SPROTO_CB_ERROR
  604. }
  605. if (sz < 1) {
  606. return -1;
  607. }
  608. buffer[buffer_idx] = (args.value == 1) ? 1 : 0;
  609. buffer_idx++;
  610. ++args.index;
  611. }
  612. break;
  613. }
  614. default: {
  615. args.index = 1;
  616. for (;;) {
  617. args.buffer = buffer;
  618. args.buffer_idx = buffer_idx + SIZEOF_LENGTH;
  619. sz = cb(args);
  620. if (sz < 0) {
  621. if (sz == SPROTO_CB_NIL) {
  622. break;
  623. }
  624. if (sz == SPROTO_CB_NOARRAY) { // no array, don't encode it
  625. return 0;
  626. }
  627. return -1; // sz == SPROTO_CB_ERROR
  628. }
  629. fill_size(buffer, buffer_idx, sz);
  630. buffer_idx += SIZEOF_LENGTH + sz;
  631. ++args.index;
  632. }
  633. break;
  634. }
  635. }
  636. sz = buffer_idx - (data_idx + SIZEOF_LENGTH);
  637. if (sz == 0) {
  638. return 0;
  639. }
  640. return fill_size(buffer, data_idx, sz);
  641. }
  642. function decode_array_object (cb, args, stream, sz, sidx = 0) {
  643. let hsz;
  644. let index = 1;
  645. while (sz > 0) {
  646. if (sz < SIZEOF_LENGTH) {
  647. return -1;
  648. }
  649. hsz = todword(stream, sidx);
  650. sidx += SIZEOF_LENGTH;
  651. sz -= SIZEOF_LENGTH;
  652. if (hsz > sz) {
  653. return -1;
  654. }
  655. args.index = index;
  656. args.value = stream.slice(sidx, sidx + hsz);
  657. args.length = hsz;
  658. if (cb(args) != 0) {
  659. return -1;
  660. }
  661. sidx += hsz;
  662. sz -= hsz;
  663. ++index;
  664. }
  665. return 0;
  666. }
  667. function decode_array (cb, args, stream, sidx = 0) {
  668. let sz = todword(stream, sidx);
  669. let type = args.type;
  670. if (sz == 0) {
  671. // It's empty array, call cb with index == -1 to create the empty array.
  672. args.index = -1;
  673. args.value = null;
  674. args.length = 0;
  675. cb(args);
  676. return 0;
  677. }
  678. sidx += SIZEOF_LENGTH;
  679. switch (type) {
  680. case SPROTO_TINTEGER: {
  681. let len = stream[sidx];
  682. ++sidx;
  683. --sz;
  684. if (len == 4) {
  685. if (sz % 4 != 0) {
  686. return -1;
  687. }
  688. for (let i = 0; i < Math.floor(sz / 4); i++) {
  689. let value = expand64(todword(stream, sidx + i * 4));
  690. args.index = i + 1;
  691. args.value = value;
  692. args.length = 8;
  693. cb(args);
  694. }
  695. } else if (len == 8) {
  696. if (sz % 8 != 0) {
  697. return -1;
  698. }
  699. for (let i = 0; i < Math.floor(sz / 8); i++) {
  700. let low = todword(stream, sidx + i * 8);
  701. let hi = todword(stream, sidx + i * 8 + 4);
  702. let value = hi_low_uint64(low, hi);
  703. args.index = i + 1;
  704. args.value = value;
  705. args.length = 8;
  706. cb(args);
  707. }
  708. } else {
  709. return -1;
  710. }
  711. break;
  712. }
  713. case SPROTO_TBOOLEAN: {
  714. for (let i = 0; i < sz; i++) {
  715. let value = stream[sidx + i];
  716. args.index = i + 1;
  717. args.value = value;
  718. args.length = 8;
  719. cb(args);
  720. }
  721. break;
  722. }
  723. case SPROTO_TSTRING:
  724. case SPROTO_TSTRUCT: {
  725. return decode_array_object(cb, args, stream, sz, sidx);
  726. }
  727. default: {
  728. return -1;
  729. }
  730. }
  731. return 0;
  732. }
  733. function pack_seg (src, src_idx, buffer, buffer_idx, sz, n) {
  734. let header = 0;
  735. let notzero = 0;
  736. let obuffer_idx = buffer_idx;
  737. ++buffer_idx;
  738. --sz;
  739. if (sz < 0) {
  740. obuffer_idx = null;
  741. }
  742. for (let i = 0; i < 8; i++) {
  743. if (src[src_idx + i] != 0) {
  744. notzero++;
  745. header |= 1 << i;
  746. if (sz > 0) {
  747. buffer[buffer_idx] = src[src_idx + i];
  748. ++buffer_idx;
  749. --sz;
  750. }
  751. }
  752. }
  753. if ((notzero == 7 || notzero == 6) && n > 0) {
  754. notzero = 8;
  755. }
  756. if (notzero == 8) {
  757. if (n > 0) {
  758. return 8;
  759. } else {
  760. return 10;
  761. }
  762. }
  763. if (obuffer_idx != null) {
  764. buffer[obuffer_idx] = header;
  765. }
  766. return notzero + 1;
  767. }
  768. function write_ff (src, src_idx, des, dest_idx, n) {
  769. let align8_n = (n + 7) & (~7);
  770. des[dest_idx] = 0xff;
  771. des[dest_idx + 1] = Math.floor(align8_n / 8) - 1;
  772. for (let i = 0; i < n; i++) {
  773. des[dest_idx + i + 2] = src[src_idx + i];
  774. }
  775. for (let i = 0; i < align8_n - n; i++) {
  776. des[dest_idx + n + 2 + i] = 0;
  777. }
  778. }
  779. function sproto_pack (srcv, src_idx, bufferv, buffer_idx) {
  780. let tmp = new Array(8);
  781. let ff_srcstart, ff_desstart;
  782. let ff_srcstart_idx = 0;
  783. let ff_desstart_idx = 0;
  784. let ff_n = 0;
  785. let size = 0;
  786. let src = srcv;
  787. let buffer = bufferv;
  788. let srcsz = srcv.length;
  789. let bufsz = 1 << 30;
  790. for (let i = 0; i < srcsz; i += 8) {
  791. let n;
  792. let padding = i + 8 - srcsz;
  793. if (padding > 0) {
  794. for (let j = 0; j < 8 - padding; j++) {
  795. tmp[j] = src[src_idx + j];
  796. }
  797. for (let j = 0; j < padding; j++) {
  798. tmp[7 - j] = 0;
  799. }
  800. src = tmp;
  801. src_idx = 0;
  802. }
  803. n = pack_seg(src, src_idx, buffer, buffer_idx, bufsz, ff_n);
  804. bufsz -= n;
  805. if (n == 10) {
  806. // first FF
  807. ff_srcstart = src;
  808. ff_srcstart_idx = src_idx;
  809. ff_desstart = buffer;
  810. ff_desstart_idx = buffer_idx;
  811. ff_n = 1;
  812. } else if (n == 8 && ff_n > 0) {
  813. ++ff_n;
  814. if (ff_n == 256) {
  815. if (bufsz >= 0) {
  816. write_ff(ff_srcstart, ff_srcstart_idx, ff_desstart, ff_desstart_idx, 256 * 8);
  817. }
  818. ff_n = 0;
  819. }
  820. } else {
  821. if (ff_n > 0) {
  822. if (bufsz >= 0) {
  823. write_ff(ff_srcstart, ff_srcstart_idx, ff_desstart, ff_desstart_idx, ff_n * 8);
  824. }
  825. ff_n = 0;
  826. }
  827. }
  828. src_idx += 8;
  829. buffer_idx += n;
  830. size += n;
  831. }
  832. if (bufsz >= 0) {
  833. if (ff_n == 1) {
  834. write_ff(ff_srcstart, ff_srcstart_idx, ff_desstart, ff_desstart_idx, 8);
  835. } else if (ff_n > 1) {
  836. write_ff(ff_srcstart, ff_srcstart_idx, ff_desstart, ff_desstart_idx, srcsz - ff_srcstart_idx);
  837. }
  838. if (buffer.length > size) {
  839. for (let i = size; i < buffer.length; i++) {
  840. buffer[i] = 0;
  841. }
  842. }
  843. }
  844. return size;
  845. }
  846. function sproto_unpack (srcv, src_idx, bufferv, buffer_idx) {
  847. let src = srcv;
  848. let buffer = bufferv;
  849. let size = 0;
  850. let srcsz = srcv.length;
  851. let bufsz = 1 << 30;
  852. while (srcsz > 0) {
  853. let header = src[src_idx];
  854. --srcsz;
  855. ++src_idx;
  856. if (header == 0xff) {
  857. let n;
  858. if (srcsz < 0) {
  859. return -1;
  860. }
  861. n = (src[src_idx] + 1) * 8;
  862. if (srcsz < n + 1)
  863. return -1;
  864. srcsz -= n + 1;
  865. ++src_idx;
  866. if (bufsz >= n) {
  867. for (let i = 0; i < n; i++) {
  868. buffer[buffer_idx + i] = src[src_idx + i];
  869. }
  870. }
  871. bufsz -= n;
  872. buffer_idx += n;
  873. src_idx += n;
  874. size += n;
  875. } else {
  876. for (let i = 0; i < 8; i++) {
  877. let nz = (header >>> i) & 1;
  878. if (nz != 0) {
  879. if (srcsz < 0)
  880. return -1;
  881. if (bufsz > 0) {
  882. buffer[buffer_idx] = src[src_idx];
  883. --bufsz;
  884. ++buffer_idx;
  885. }
  886. ++src_idx;
  887. --srcsz;
  888. } else {
  889. if (bufsz > 0) {
  890. buffer[buffer_idx] = 0;
  891. --bufsz;
  892. ++buffer_idx;
  893. }
  894. }
  895. ++size;
  896. }
  897. }
  898. }
  899. return size;
  900. }
  901. function string2utf8 (str) {
  902. let back = [];
  903. for (let i = 0; i < str.length; i++) {
  904. let code = str.charCodeAt(i);
  905. if (0x00 <= code && code <= 0x7f) {
  906. back.push(code);
  907. } else if (0x80 <= code && code <= 0x7ff) {
  908. back.push((192 | (31 & (code >> 6))));
  909. back.push((128 | (63 & code)));
  910. } else if ((0x800 <= code && code <= 0xd7ff) || (0xe000 <= code && code <= 0xffff)) {
  911. back.push((224 | (15 & (code >> 12))));
  912. back.push((128 | (63 & (code >> 6))));
  913. back.push((128 | (63 & code)));
  914. }
  915. }
  916. for (let i = 0; i < back.length; i++) {
  917. back[i] &= 0xff;
  918. }
  919. return back;
  920. }
  921. function utf82string (arr) {
  922. if (typeof arr === 'string') {
  923. return null;
  924. }
  925. let UTF = '';
  926. for (let i = 0; i < arr.length; i++) {
  927. if (arr[i] == null) {
  928. break;
  929. }
  930. let one = arr[i].toString(2);
  931. let v = one.match(/^1+?(?=0)/);
  932. if (v && one.length == 8) {
  933. let bytesLength = v[0].length;
  934. let store = arr[i].toString(2).slice(7 - bytesLength);
  935. for (let st = 1; st < bytesLength; st++) {
  936. store += arr[st + i].toString(2).slice(2);
  937. }
  938. UTF += String.fromCharCode(parseInt(store, 2));
  939. i += bytesLength - 1;
  940. } else {
  941. UTF += String.fromCharCode(arr[i]);
  942. }
  943. }
  944. return UTF;
  945. }
  946. function arrayconcat (a1, a2) {
  947. let b = [];
  948. for (let i = 0; i < a1.length; i++) {
  949. b[i] = a1[i];
  950. }
  951. for (let j = a1.length; j < a1.length + a2.length; j++) {
  952. b[j] = a2[j - a1.length];
  953. }
  954. return b;
  955. }
  956. // /////////////////////导出方法///////////////////////////////
  957. t.pack = function (inbuf) {
  958. let src_idx = 0;
  959. let buffer = [];
  960. let buffer_idx = 0;
  961. sproto_pack(inbuf, src_idx, buffer, buffer_idx);
  962. return buffer;
  963. },
  964. t.unpack = function (inbuf) {
  965. let src_idx = 0;
  966. let buffer = [];
  967. let buffer_idx = 0;
  968. sproto_unpack(inbuf, src_idx, buffer, buffer_idx);
  969. return buffer;
  970. },
  971. t.createNew = function (binsch) {
  972. let s = {};
  973. s.type_n = 0;
  974. s.protocol_n = 0;
  975. s.type = null;
  976. s.proto = null;
  977. s.tcache = {};
  978. s.pcache = {};
  979. let sp = create_from_bundle(s, binsch, binsch.length);
  980. if (sp == null)
  981. return null;
  982. function sproto_encode (st, buffer, buffer_idx, cb, ud) {
  983. let args = Object.create(null);
  984. let header_idx = buffer_idx;
  985. let data_idx = buffer_idx;
  986. let header_sz = SIZEOF_HEADER + st.maxn * SIZEOF_FIELD;
  987. let index, lasttag, datasz;
  988. args.ud = ud;
  989. data_idx = header_idx + header_sz;
  990. index = 0;
  991. lasttag = -1;
  992. for (let i = 0; i < st.n; i++) {
  993. let f = st.f[i];
  994. let type = f.type;
  995. let value = 0;
  996. let sz = -1;
  997. args.tagname = f.name;
  998. args.tagid = f.tag;
  999. if (f.st != null) {
  1000. args.subtype = sp.type[f.st];
  1001. } else {
  1002. args.subtype = null;
  1003. }
  1004. args.mainindex = f.key;
  1005. args.extra = f.extra;
  1006. if ((type & SPROTO_TARRAY) != 0) {
  1007. args.type = type & ~SPROTO_TARRAY;
  1008. sz = encode_array(cb, args, buffer, data_idx);
  1009. } else {
  1010. args.type = type;
  1011. args.index = 0;
  1012. switch (type) {
  1013. case SPROTO_TINTEGER:
  1014. case SPROTO_TBOOLEAN: {
  1015. args.value = 0;
  1016. args.length = 8;
  1017. args.buffer = buffer;
  1018. args.buffer_idx = buffer_idx;
  1019. sz = cb(args);
  1020. if (sz < 0) {
  1021. if (sz == SPROTO_CB_NIL)
  1022. continue;
  1023. if (sz == SPROTO_CB_NOARRAY) // no array, don't encode it
  1024. return 0;
  1025. return -1; // sz == SPROTO_CB_ERROR
  1026. }
  1027. if (sz == 4) {
  1028. if (args.value < 0x7fff) {
  1029. value = (args.value + 1) * 2;
  1030. sz = 2; // sz can be any number > 0
  1031. } else {
  1032. sz = encode_integer(args.value, buffer, data_idx, sz);
  1033. }
  1034. } else if (sz == 8) {
  1035. sz = encode_uint64(args.value, buffer, data_idx, sz);
  1036. } else {
  1037. return -1;
  1038. }
  1039. break;
  1040. }
  1041. case SPROTO_TSTRUCT:
  1042. case SPROTO_TSTRING: {
  1043. sz = encode_object(cb, args, buffer, data_idx);
  1044. break;
  1045. }
  1046. }
  1047. }
  1048. if (sz < 0)
  1049. return -1;
  1050. if (sz > 0) {
  1051. let record_idx, tag;
  1052. if (value == 0) {
  1053. data_idx += sz;
  1054. }
  1055. record_idx = header_idx + SIZEOF_HEADER + SIZEOF_FIELD * index;
  1056. tag = f.tag - lasttag - 1;
  1057. if (tag > 0) {
  1058. // skip tag
  1059. tag = (tag - 1) * 2 + 1;
  1060. if (tag > 0xffff)
  1061. return -1;
  1062. buffer[record_idx] = tag & 0xff;
  1063. buffer[record_idx + 1] = (tag >> 8) & 0xff;
  1064. ++index;
  1065. record_idx += SIZEOF_FIELD;
  1066. }
  1067. ++index;
  1068. buffer[record_idx] = value & 0xff;
  1069. buffer[record_idx + 1] = (value >> 8) & 0xff;
  1070. lasttag = f.tag;
  1071. }
  1072. }
  1073. buffer[header_idx] = index & 0xff;
  1074. buffer[header_idx + 1] = (index >> 8) & 0xff;
  1075. datasz = data_idx - (header_idx + header_sz);
  1076. data_idx = header_idx + header_sz;
  1077. if (index != st.maxn) {
  1078. let v = buffer.slice(data_idx, data_idx + datasz); // 拷贝一份
  1079. for (let s = 0; s < datasz; s++) {
  1080. buffer[header_idx + SIZEOF_HEADER + index * SIZEOF_FIELD + s] = v[s];
  1081. }
  1082. buffer.splice(header_idx + SIZEOF_HEADER + index * SIZEOF_FIELD + datasz, buffer.length);
  1083. }
  1084. return SIZEOF_HEADER + index * SIZEOF_FIELD + datasz;
  1085. }
  1086. function encode (args) {
  1087. let self = args.ud;
  1088. if (self.deep >= ENCODE_DEEPLEVEL) {
  1089. alert('table is too deep');
  1090. return -1;
  1091. }
  1092. if (self.indata[args.tagname] == null) {
  1093. return SPROTO_CB_NIL;
  1094. }
  1095. let target = null;
  1096. if (args.index > 0) {
  1097. if (args.tagname != self.array_tag) {
  1098. self.array_tag = args.tagname;
  1099. if (typeof(self.indata[args.tagname]) != 'object') {
  1100. self.array_index = 0;
  1101. return SPROTO_CB_NIL;
  1102. }
  1103. if (self.indata[args.tagname].length == 0 || self.indata[args.tagname].length == null) {
  1104. self.array_index = 0;
  1105. return SPROTO_CB_NOARRAY;
  1106. }
  1107. }
  1108. target = self.indata[args.tagname][args.index - 1];
  1109. if (target == null) {
  1110. return SPROTO_CB_NIL;
  1111. }
  1112. } else {
  1113. target = self.indata[args.tagname];
  1114. }
  1115. switch (args.type) {
  1116. case SPROTO_TINTEGER:
  1117. {
  1118. let v, vh;
  1119. if (args.extra > 0) {
  1120. let vn = target;
  1121. v = Math.floor(vn * args.extra + 0.5);
  1122. } else {
  1123. v = target;
  1124. }
  1125. vh = uint64_rshift(v, 31);
  1126. if (vh == 0 || vh == -1) {
  1127. args.value = v >>> 0;
  1128. return 4;
  1129. } else {
  1130. args.value = v;
  1131. return 8;
  1132. }
  1133. }
  1134. case SPROTO_TBOOLEAN:
  1135. {
  1136. if (target == true) {
  1137. args.value = 1;
  1138. } else if (target == false) {
  1139. args.value = 0;
  1140. }
  1141. return 4;
  1142. }
  1143. case SPROTO_TSTRING:
  1144. {
  1145. let str = target;
  1146. let arr = string2utf8(str);
  1147. let sz = arr.length;
  1148. if (sz > args.length) {
  1149. args.length = sz;
  1150. }
  1151. for (let i = 0; i < arr.length; i++) {
  1152. args.buffer[args.buffer_idx + i] = arr[i];
  1153. }
  1154. return sz;
  1155. }
  1156. case SPROTO_TSTRUCT:
  1157. {
  1158. let sub = Object.create(null);
  1159. sub.st = args.subtype;
  1160. sub.deep = self.deep + 1;
  1161. sub.indata = target;
  1162. let r = sproto_encode(args.subtype, args.buffer, args.buffer_idx, encode, sub);
  1163. if (r < 0) {
  1164. return SPROTO_CB_ERROR;
  1165. }
  1166. return r;
  1167. }
  1168. default:
  1169. alert('Invalid filed type ' + args.type);
  1170. return SPROTO_CB_ERROR;
  1171. }
  1172. }
  1173. function sproto_decode (st, data, size, cb, ud) {
  1174. let args = Object.create(null);
  1175. let total = size;
  1176. let stream, fn, tag;
  1177. if (size < SIZEOF_HEADER)
  1178. return -1;
  1179. stream = data;
  1180. let sidx = 0;
  1181. fn = toword(stream, sidx);
  1182. sidx += SIZEOF_HEADER;
  1183. size -= SIZEOF_HEADER;
  1184. if (size < fn * SIZEOF_FIELD)
  1185. return -1;
  1186. let dsidx = sidx + fn * SIZEOF_FIELD;
  1187. size -= fn * SIZEOF_FIELD;
  1188. args.ud = ud;
  1189. tag = -1;
  1190. for (let i = 0; i < fn; i++) {
  1191. let f = null;
  1192. let value = toword(stream, sidx + i * SIZEOF_FIELD);
  1193. ++tag;
  1194. if (value & 1 != 0) {
  1195. tag += Math.floor(value / 2);
  1196. continue;
  1197. }
  1198. value = Math.floor(value / 2) - 1;
  1199. let currentdataIdx = dsidx;
  1200. if (value < 0) {
  1201. let sz;
  1202. if (size < SIZEOF_LENGTH) {
  1203. return -1;
  1204. }
  1205. sz = todword(stream, dsidx);
  1206. if (size < sz + SIZEOF_LENGTH) {
  1207. return -1;
  1208. }
  1209. dsidx += sz + SIZEOF_LENGTH;
  1210. size -= sz + SIZEOF_LENGTH;
  1211. }
  1212. f = findtag(st, tag);
  1213. if (f == null) {
  1214. continue;
  1215. }
  1216. args.tagname = f.name;
  1217. args.tagid = f.tag;
  1218. args.type = f.type & ~SPROTO_TARRAY;
  1219. if (f.st != null) {
  1220. args.subtype = sp.type[f.st];
  1221. } else {
  1222. args.subtype = null;
  1223. }
  1224. args.index = 0;
  1225. args.mainindex = f.key;
  1226. args.extra = f.extra;
  1227. if (value < 0) {
  1228. if ((f.type & SPROTO_TARRAY) != 0) {
  1229. if (decode_array(cb, args, stream, currentdataIdx)) {
  1230. return -1;
  1231. }
  1232. } else {
  1233. switch (f.type) {
  1234. case SPROTO_TINTEGER: {
  1235. let sz = todword(stream, currentdataIdx);
  1236. if (sz == 4) {
  1237. let v = expand64(todword(stream, currentdataIdx + SIZEOF_LENGTH));
  1238. args.value = v;
  1239. args.length = 8;
  1240. cb(args);
  1241. } else if (sz != 8) {
  1242. return -1;
  1243. } else {
  1244. let low = todword(stream, currentdataIdx + SIZEOF_LENGTH);
  1245. let hi = todword(stream, currentdataIdx + SIZEOF_LENGTH + 4);
  1246. let v = hi_low_uint64(low, hi);
  1247. args.value = v;
  1248. args.length = 8;
  1249. cb(args);
  1250. }
  1251. break;
  1252. }
  1253. case SPROTO_TSTRING:
  1254. case SPROTO_TSTRUCT: {
  1255. let sz = todword(stream, currentdataIdx);
  1256. args.value = stream.slice(currentdataIdx + SIZEOF_LENGTH, currentdataIdx + SIZEOF_LENGTH + sz);
  1257. args.length = sz;
  1258. if (cb(args) != 0) {
  1259. return -1;
  1260. }
  1261. break;
  1262. }
  1263. default: {
  1264. return -1;
  1265. }
  1266. }
  1267. }
  1268. } else if (f.type != SPROTO_TINTEGER && f.type != SPROTO_TBOOLEAN) {
  1269. return -1;
  1270. } else {
  1271. args.value = value;
  1272. args.length = 8;
  1273. cb(args);
  1274. }
  1275. }
  1276. return total - size;
  1277. }
  1278. function decode (args) {
  1279. let self = args.ud;
  1280. let value;
  1281. if (self.deep >= ENCODE_DEEPLEVEL) {
  1282. alert('the table is too deep');
  1283. }
  1284. if (args.index != 0) {
  1285. if (args.tagname != self.array_tag) {
  1286. self.array_tag = args.tagname;
  1287. self.result[args.tagname] = [];
  1288. if (args.index < 0) {
  1289. return 0;
  1290. }
  1291. }
  1292. }
  1293. switch (args.type) {
  1294. case SPROTO_TINTEGER:
  1295. {
  1296. if (args.extra) {
  1297. let v = args.value;
  1298. let vn = v;
  1299. value = vn / args.extra;
  1300. } else {
  1301. value = args.value;
  1302. }
  1303. break;
  1304. }
  1305. case SPROTO_TBOOLEAN:
  1306. {
  1307. if (args.value == 1) {
  1308. value = true;
  1309. } else if (args.value == 0) {
  1310. value = false;
  1311. } else {
  1312. value = null;
  1313. }
  1314. break;
  1315. }
  1316. case SPROTO_TSTRING:
  1317. {
  1318. let arr = [];
  1319. for (let i = 0; i < args.length; i++) {
  1320. arr.push(args.value[i]);
  1321. }
  1322. value = utf82string(arr);
  1323. break;
  1324. }
  1325. case SPROTO_TSTRUCT:
  1326. {
  1327. let sub = Object.create(null);
  1328. let r;
  1329. sub.deep = self.deep + 1;
  1330. sub.array_index = 0;
  1331. sub.array_tag = null;
  1332. sub.result = Object.create(null);
  1333. if (args.mainindex >= 0) {
  1334. sub.mainindex_tag = args.mainindex;
  1335. r = sproto_decode(args.subtype, args.value, args.length, decode, sub);
  1336. if (r < 0 || r != args.length) {
  1337. return r;
  1338. }
  1339. value = sub.result;
  1340. break;
  1341. } else {
  1342. sub.mainindex_tag = -1;
  1343. sub.key_index = 0;
  1344. r = sproto_decode(args.subtype, args.value, args.length, decode, sub);
  1345. if (r < 0) {
  1346. return SPROTO_CB_ERROR;
  1347. }
  1348. if (r != args.length)
  1349. return r;
  1350. value = sub.result;
  1351. break;
  1352. }
  1353. }
  1354. default:
  1355. alert('Invalid type');
  1356. }
  1357. if (args.index > 0) {
  1358. self.result[args.tagname][args.index - 1] = value;
  1359. } else {
  1360. self.result[args.tagname] = value;
  1361. }
  1362. return 0;
  1363. }
  1364. function querytype (sp, typename) {
  1365. let v = sp.tcache[typename];
  1366. if (v === null || v === undefined) {
  1367. v = sproto_type(sp, typename);
  1368. sp.tcache[typename] = v;
  1369. }
  1370. return v;
  1371. }
  1372. function protocol (sp, pname) {
  1373. let tag = null;
  1374. let ret1 = null;
  1375. if (typeof(pname) == 'number') {
  1376. tag = pname;
  1377. ret1 = sproto_protoname(sp, pname);
  1378. if (ret1 === null)
  1379. return null;
  1380. } else {
  1381. tag = sproto_prototag(sp, pname);
  1382. ret1 = tag;
  1383. if (tag === -1)
  1384. return null;
  1385. }
  1386. let request = sproto_protoquery(sp, tag, SPROTO_REQUEST);
  1387. let response = sproto_protoquery(sp, tag, SPROTO_RESPONSE);
  1388. return {
  1389. ret1: ret1,
  1390. request: request,
  1391. response: response
  1392. };
  1393. }
  1394. function queryproto (sp, pname) {
  1395. let v = sp.pcache[pname];
  1396. if (v === null || v === undefined) {
  1397. let ret = protocol(sp, pname);
  1398. if (!ret) {
  1399. return undefined;
  1400. }
  1401. let tag = ret.ret1;
  1402. let req = ret.request;
  1403. let resp = ret.response;
  1404. if (typeof(pname) === 'number') {
  1405. let tmp = tag;
  1406. tag = pname;
  1407. pname = tmp;
  1408. }
  1409. v = {
  1410. request: req,
  1411. response: resp,
  1412. name: pname,
  1413. tag: tag
  1414. };
  1415. sp.pcache[pname] = v;
  1416. sp.pcache[tag] = v;
  1417. }
  1418. return v;
  1419. }
  1420. sp.objlen = function (type, inbuf) {
  1421. let st = null;
  1422. if (typeof(type) === 'string' || typeof(type) === 'number') {
  1423. st = querytype(sp, type);
  1424. if (st == null) {
  1425. return null;
  1426. }
  1427. } else {
  1428. st = type;
  1429. }
  1430. let ud = Object.create(null);
  1431. ud.array_tag = null;
  1432. ud.deep = 0;
  1433. ud.result = Object.create(null);
  1434. return sproto_decode(st, inbuf, inbuf.length, decode, ud);
  1435. };
  1436. sp.encode = function (type, indata) {
  1437. let self = Object.create(null);
  1438. let st = null;
  1439. if (typeof(type) === 'string' || typeof(type) === 'number') {
  1440. st = querytype(sp, type);
  1441. if (st == null)
  1442. return null;
  1443. } else {
  1444. st = type;
  1445. }
  1446. let tbl_index = 2;
  1447. let enbuffer = [];
  1448. let buffer_idx = 0;
  1449. self.st = st;
  1450. self.tbl_index = tbl_index;
  1451. self.indata = indata;
  1452. for (;;) {
  1453. self.array_tag = null;
  1454. self.array_index = 0;
  1455. self.deep = 0;
  1456. self.iter_index = tbl_index + 1;
  1457. let r = sproto_encode(st, enbuffer, buffer_idx, encode, self);
  1458. if (r < 0) {
  1459. return null;
  1460. } else {
  1461. return enbuffer;
  1462. }
  1463. }
  1464. };
  1465. sp.decode = function (type, inbuf) {
  1466. let st = null;
  1467. if (typeof(type) === 'string' || typeof(type) === 'number') {
  1468. st = querytype(sp, type);
  1469. if (st == null) {
  1470. return null;
  1471. }
  1472. } else {
  1473. st = type;
  1474. }
  1475. let buffer = inbuf;
  1476. let sz = inbuf.length;
  1477. let ud = Object.create(null);
  1478. ud.array_tag = null;
  1479. ud.deep = 0;
  1480. ud.result = Object.create(null);
  1481. let r = sproto_decode(st, buffer, sz, decode, ud);
  1482. if (r < 0) {
  1483. return null;
  1484. }
  1485. return ud.result;
  1486. };
  1487. sp.pack = function (inbuf) {
  1488. return t.pack(inbuf);
  1489. };
  1490. sp.unpack = function (inbuf) {
  1491. return t.unpack(inbuf);
  1492. };
  1493. sp.pencode = function (type, inbuf) {
  1494. let obuf = sp.encode(type, inbuf);
  1495. if (obuf == null) {
  1496. return null;
  1497. }
  1498. return sp.pack(obuf);
  1499. };
  1500. sp.pdecode = function (type, inbuf) {
  1501. let obuf = sp.unpack(inbuf);
  1502. if (obuf == null) {
  1503. return null;
  1504. }
  1505. return sp.decode(type, obuf);
  1506. };
  1507. sp.host = function (packagename) {
  1508. function cla (packagename) {
  1509. packagename = packagename ? packagename : 'package';
  1510. this.proto = sp;
  1511. this.package = querytype(sp, packagename);
  1512. this.package = this.package ? this.package : 'package';
  1513. this.session = {};
  1514. }
  1515. cla.prototype = host;
  1516. return new cla(packagename);
  1517. };
  1518. host.attach = function (sp) {
  1519. this.attachsp = sp;
  1520. let self = this;
  1521. return (name, args, session) => {
  1522. let proto = queryproto(sp, name);
  1523. header_tmp.type = proto.tag;
  1524. header_tmp.session = session;
  1525. let headerbuffer = sp.encode(self.package, header_tmp);
  1526. if (session) {
  1527. self.session[session] = proto.response ? proto.response : true;
  1528. }
  1529. if (args) {
  1530. let databuffer = sp.encode(proto.request, args);
  1531. return sp.pack(arrayconcat(headerbuffer, databuffer));
  1532. } else {
  1533. return sp.pack(headerbuffer);
  1534. }
  1535. };
  1536. };
  1537. function gen_response (self, response, session) {
  1538. return function (args) {
  1539. header_tmp.type = null;
  1540. header_tmp.session = session;
  1541. let headerbuffer = self.proto.encode(self.package, header_tmp);
  1542. if (response) {
  1543. let databuffer = self.proto.encode(response, args);
  1544. return self.proto.pack(arrayconcat(headerbuffer, databuffer));
  1545. } else {
  1546. return self.proto.pack(headerbuffer);
  1547. }
  1548. };
  1549. }
  1550. host.dispatch = function (buffer) {
  1551. let sp = this.proto;
  1552. let bin = sp.unpack(buffer);
  1553. header_tmp.type = null;
  1554. header_tmp.session = null;
  1555. header_tmp = sp.decode(this.package, bin);
  1556. let used_sz = sp.objlen(this.package, bin);
  1557. let leftbuffer = bin.slice(used_sz, bin.length);
  1558. if (header_tmp.type) {
  1559. let proto = queryproto(sp, header_tmp.type);
  1560. if (!proto) {
  1561. return {
  1562. type: 'UNKOWN',
  1563. pname: header_tmp.type,
  1564. session: header_tmp.session
  1565. };
  1566. }
  1567. let result;
  1568. if (proto.request) {
  1569. result = sp.decode(proto.request, leftbuffer);
  1570. }
  1571. if (header_tmp.session) {
  1572. return {
  1573. type: 'REQUEST',
  1574. pname: proto.name,
  1575. result: result,
  1576. responseFunc: gen_response(this, proto.response, header_tmp.session),
  1577. session: header_tmp.session
  1578. };
  1579. } else {
  1580. return {
  1581. type: 'REQUEST',
  1582. pname: proto.name,
  1583. result: result
  1584. };
  1585. }
  1586. } else {
  1587. sp = this.attachsp;
  1588. let session = header_tmp.session;
  1589. let response = this.session[session];
  1590. delete this.session[session];
  1591. if (response === true) {
  1592. return {
  1593. type: 'RESPONSE',
  1594. session: session
  1595. };
  1596. } else {
  1597. let result = sp.decode(response, leftbuffer);
  1598. return {
  1599. type: 'RESPONSE',
  1600. session: session,
  1601. result: result
  1602. };
  1603. }
  1604. }
  1605. };
  1606. return sp;
  1607. };
  1608. return t;
  1609. }());
  1610. module.exports = sproto;