@netkitty/codec 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (463) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/LICENSE +21 -0
  3. package/README.md +352 -0
  4. package/README.zh-CN.md +342 -0
  5. package/dist/Codec.d.ts +133 -0
  6. package/dist/Codec.js +632 -0
  7. package/dist/PacketHeaders.d.ts +189 -0
  8. package/dist/PacketHeaders.js +384 -0
  9. package/dist/abstracts/BaseHeader.d.ts +325 -0
  10. package/dist/abstracts/BaseHeader.js +734 -0
  11. package/dist/errors/CodecSchemaValidateError.d.ts +4 -0
  12. package/dist/errors/CodecSchemaValidateError.js +11 -0
  13. package/dist/headers/ADSAMS.d.ts +33 -0
  14. package/dist/headers/ADSAMS.js +208 -0
  15. package/dist/headers/AH.d.ts +28 -0
  16. package/dist/headers/AH.js +137 -0
  17. package/dist/headers/AMQP.d.ts +31 -0
  18. package/dist/headers/AMQP.js +316 -0
  19. package/dist/headers/ARP.d.ts +26 -0
  20. package/dist/headers/ARP.js +243 -0
  21. package/dist/headers/BACnetIP.d.ts +27 -0
  22. package/dist/headers/BACnetIP.js +97 -0
  23. package/dist/headers/BFD.d.ts +28 -0
  24. package/dist/headers/BFD.js +155 -0
  25. package/dist/headers/BGP.d.ts +27 -0
  26. package/dist/headers/BGP.js +111 -0
  27. package/dist/headers/BSAPIP.d.ts +33 -0
  28. package/dist/headers/BSAPIP.js +78 -0
  29. package/dist/headers/Babel.d.ts +32 -0
  30. package/dist/headers/Babel.js +224 -0
  31. package/dist/headers/BitTorrent.d.ts +28 -0
  32. package/dist/headers/BitTorrent.js +72 -0
  33. package/dist/headers/C37118.d.ts +26 -0
  34. package/dist/headers/C37118.js +147 -0
  35. package/dist/headers/CAPWAP.d.ts +38 -0
  36. package/dist/headers/CAPWAP.js +275 -0
  37. package/dist/headers/CDP.d.ts +25 -0
  38. package/dist/headers/CDP.js +117 -0
  39. package/dist/headers/CMS.d.ts +33 -0
  40. package/dist/headers/CMS.js +238 -0
  41. package/dist/headers/COTP.d.ts +30 -0
  42. package/dist/headers/COTP.js +193 -0
  43. package/dist/headers/CassandraCQL.d.ts +28 -0
  44. package/dist/headers/CassandraCQL.js +117 -0
  45. package/dist/headers/CoAP.d.ts +29 -0
  46. package/dist/headers/CoAP.js +140 -0
  47. package/dist/headers/Codesys.d.ts +32 -0
  48. package/dist/headers/Codesys.js +119 -0
  49. package/dist/headers/Collectd.d.ts +29 -0
  50. package/dist/headers/Collectd.js +154 -0
  51. package/dist/headers/DCCP.d.ts +30 -0
  52. package/dist/headers/DCCP.js +204 -0
  53. package/dist/headers/DHCP.d.ts +26 -0
  54. package/dist/headers/DHCP.js +148 -0
  55. package/dist/headers/DHCPFailover.d.ts +30 -0
  56. package/dist/headers/DHCPFailover.js +104 -0
  57. package/dist/headers/DHCPv6.d.ts +25 -0
  58. package/dist/headers/DHCPv6.js +145 -0
  59. package/dist/headers/DNP3.d.ts +27 -0
  60. package/dist/headers/DNP3.js +150 -0
  61. package/dist/headers/DNS.d.ts +55 -0
  62. package/dist/headers/DNS.js +309 -0
  63. package/dist/headers/DTLS.d.ts +33 -0
  64. package/dist/headers/DTLS.js +142 -0
  65. package/dist/headers/Diameter.d.ts +34 -0
  66. package/dist/headers/Diameter.js +229 -0
  67. package/dist/headers/EAPOL.d.ts +32 -0
  68. package/dist/headers/EAPOL.js +135 -0
  69. package/dist/headers/EIGRP.d.ts +28 -0
  70. package/dist/headers/EIGRP.js +165 -0
  71. package/dist/headers/ENIP.d.ts +31 -0
  72. package/dist/headers/ENIP.js +164 -0
  73. package/dist/headers/ESP.d.ts +27 -0
  74. package/dist/headers/ESP.js +140 -0
  75. package/dist/headers/Elasticsearch.d.ts +30 -0
  76. package/dist/headers/Elasticsearch.js +125 -0
  77. package/dist/headers/EtherCAT.d.ts +35 -0
  78. package/dist/headers/EtherCAT.js +150 -0
  79. package/dist/headers/EthernetII.d.ts +28 -0
  80. package/dist/headers/EthernetII.js +117 -0
  81. package/dist/headers/FCoE.d.ts +38 -0
  82. package/dist/headers/FCoE.js +210 -0
  83. package/dist/headers/FTP.d.ts +34 -0
  84. package/dist/headers/FTP.js +158 -0
  85. package/dist/headers/Finger.d.ts +41 -0
  86. package/dist/headers/Finger.js +135 -0
  87. package/dist/headers/FoundationFieldbusHSE.d.ts +43 -0
  88. package/dist/headers/FoundationFieldbusHSE.js +163 -0
  89. package/dist/headers/GELF.d.ts +35 -0
  90. package/dist/headers/GELF.js +261 -0
  91. package/dist/headers/GENEVE.d.ts +26 -0
  92. package/dist/headers/GENEVE.js +209 -0
  93. package/dist/headers/GESRTP.d.ts +32 -0
  94. package/dist/headers/GESRTP.js +141 -0
  95. package/dist/headers/GLBP.d.ts +29 -0
  96. package/dist/headers/GLBP.js +159 -0
  97. package/dist/headers/GRE.d.ts +27 -0
  98. package/dist/headers/GRE.js +181 -0
  99. package/dist/headers/GTPU.d.ts +25 -0
  100. package/dist/headers/GTPU.js +203 -0
  101. package/dist/headers/GTPv2C.d.ts +30 -0
  102. package/dist/headers/GTPv2C.js +281 -0
  103. package/dist/headers/GitProtocol.d.ts +34 -0
  104. package/dist/headers/GitProtocol.js +141 -0
  105. package/dist/headers/Goose.d.ts +115 -0
  106. package/dist/headers/Goose.js +1067 -0
  107. package/dist/headers/Gopher.d.ts +43 -0
  108. package/dist/headers/Gopher.js +182 -0
  109. package/dist/headers/HARTIP.d.ts +30 -0
  110. package/dist/headers/HARTIP.js +145 -0
  111. package/dist/headers/HSR.d.ts +27 -0
  112. package/dist/headers/HSR.js +105 -0
  113. package/dist/headers/HSRP.d.ts +26 -0
  114. package/dist/headers/HSRP.js +173 -0
  115. package/dist/headers/HTTP.d.ts +32 -0
  116. package/dist/headers/HTTP.js +153 -0
  117. package/dist/headers/HTTP2.d.ts +34 -0
  118. package/dist/headers/HTTP2.js +190 -0
  119. package/dist/headers/IAX2.d.ts +33 -0
  120. package/dist/headers/IAX2.js +274 -0
  121. package/dist/headers/ICMP.d.ts +15 -0
  122. package/dist/headers/ICMP.js +148 -0
  123. package/dist/headers/ICMPv6.d.ts +15 -0
  124. package/dist/headers/ICMPv6.js +129 -0
  125. package/dist/headers/IEC104_I_Frame.d.ts +23 -0
  126. package/dist/headers/IEC104_I_Frame.js +6489 -0
  127. package/dist/headers/IEC104_S_Frame.d.ts +26 -0
  128. package/dist/headers/IEC104_S_Frame.js +135 -0
  129. package/dist/headers/IEC104_U_Frame.d.ts +27 -0
  130. package/dist/headers/IEC104_U_Frame.js +176 -0
  131. package/dist/headers/IEC61850SampledValues.d.ts +20 -0
  132. package/dist/headers/IEC61850SampledValues.js +420 -0
  133. package/dist/headers/IGMP.d.ts +31 -0
  134. package/dist/headers/IGMP.js +274 -0
  135. package/dist/headers/IMAP.d.ts +32 -0
  136. package/dist/headers/IMAP.js +185 -0
  137. package/dist/headers/IPFIX.d.ts +29 -0
  138. package/dist/headers/IPFIX.js +156 -0
  139. package/dist/headers/IPv4.d.ts +20 -0
  140. package/dist/headers/IPv4.js +370 -0
  141. package/dist/headers/IPv6.d.ts +29 -0
  142. package/dist/headers/IPv6.js +209 -0
  143. package/dist/headers/IPv6HopByHopOptions.d.ts +81 -0
  144. package/dist/headers/IPv6HopByHopOptions.js +495 -0
  145. package/dist/headers/IRC.d.ts +34 -0
  146. package/dist/headers/IRC.js +175 -0
  147. package/dist/headers/ISAKMP.d.ts +29 -0
  148. package/dist/headers/ISAKMP.js +197 -0
  149. package/dist/headers/ISCSI.d.ts +39 -0
  150. package/dist/headers/ISCSI.js +289 -0
  151. package/dist/headers/ISIS.d.ts +25 -0
  152. package/dist/headers/ISIS.js +79 -0
  153. package/dist/headers/ISOSession.d.ts +27 -0
  154. package/dist/headers/ISOSession.js +343 -0
  155. package/dist/headers/Ident.d.ts +42 -0
  156. package/dist/headers/Ident.js +184 -0
  157. package/dist/headers/KNXnetIP.d.ts +30 -0
  158. package/dist/headers/KNXnetIP.js +135 -0
  159. package/dist/headers/Kafka.d.ts +35 -0
  160. package/dist/headers/Kafka.js +128 -0
  161. package/dist/headers/Kerberos.d.ts +30 -0
  162. package/dist/headers/Kerberos.js +217 -0
  163. package/dist/headers/L2TP.d.ts +26 -0
  164. package/dist/headers/L2TP.js +297 -0
  165. package/dist/headers/LACP.d.ts +31 -0
  166. package/dist/headers/LACP.js +151 -0
  167. package/dist/headers/LDAP.d.ts +31 -0
  168. package/dist/headers/LDAP.js +226 -0
  169. package/dist/headers/LDP.d.ts +31 -0
  170. package/dist/headers/LDP.js +138 -0
  171. package/dist/headers/LISP.d.ts +30 -0
  172. package/dist/headers/LISP.js +103 -0
  173. package/dist/headers/LLC.d.ts +27 -0
  174. package/dist/headers/LLC.js +81 -0
  175. package/dist/headers/LLDP.d.ts +26 -0
  176. package/dist/headers/LLDP.js +126 -0
  177. package/dist/headers/LLMNR.d.ts +23 -0
  178. package/dist/headers/LLMNR.js +40 -0
  179. package/dist/headers/LPD.d.ts +31 -0
  180. package/dist/headers/LPD.js +159 -0
  181. package/dist/headers/MACsec.d.ts +34 -0
  182. package/dist/headers/MACsec.js +178 -0
  183. package/dist/headers/MDNS.d.ts +26 -0
  184. package/dist/headers/MDNS.js +45 -0
  185. package/dist/headers/MGCP.d.ts +30 -0
  186. package/dist/headers/MGCP.js +155 -0
  187. package/dist/headers/MMS.d.ts +29 -0
  188. package/dist/headers/MMS.js +243 -0
  189. package/dist/headers/MPLS.d.ts +31 -0
  190. package/dist/headers/MPLS.js +145 -0
  191. package/dist/headers/MQTT.d.ts +30 -0
  192. package/dist/headers/MQTT.js +173 -0
  193. package/dist/headers/MQTTSN.d.ts +34 -0
  194. package/dist/headers/MQTTSN.js +177 -0
  195. package/dist/headers/MarkerProtocol.d.ts +32 -0
  196. package/dist/headers/MarkerProtocol.js +153 -0
  197. package/dist/headers/Megaco.d.ts +32 -0
  198. package/dist/headers/Megaco.js +144 -0
  199. package/dist/headers/Memcached.d.ts +44 -0
  200. package/dist/headers/Memcached.js +285 -0
  201. package/dist/headers/ModbusTCP.d.ts +25 -0
  202. package/dist/headers/ModbusTCP.js +99 -0
  203. package/dist/headers/ModbusUDP.d.ts +26 -0
  204. package/dist/headers/ModbusUDP.js +100 -0
  205. package/dist/headers/MongoDB.d.ts +33 -0
  206. package/dist/headers/MongoDB.js +143 -0
  207. package/dist/headers/MySQL.d.ts +30 -0
  208. package/dist/headers/MySQL.js +114 -0
  209. package/dist/headers/NATS.d.ts +29 -0
  210. package/dist/headers/NATS.js +135 -0
  211. package/dist/headers/NBDS.d.ts +34 -0
  212. package/dist/headers/NBDS.js +176 -0
  213. package/dist/headers/NBNS.d.ts +34 -0
  214. package/dist/headers/NBNS.js +78 -0
  215. package/dist/headers/NBSS.d.ts +36 -0
  216. package/dist/headers/NBSS.js +137 -0
  217. package/dist/headers/NFS.d.ts +36 -0
  218. package/dist/headers/NFS.js +273 -0
  219. package/dist/headers/NHRP.d.ts +32 -0
  220. package/dist/headers/NHRP.js +154 -0
  221. package/dist/headers/NNTP.d.ts +35 -0
  222. package/dist/headers/NNTP.js +162 -0
  223. package/dist/headers/NTP.d.ts +18 -0
  224. package/dist/headers/NTP.js +73 -0
  225. package/dist/headers/NetFlowV5.d.ts +28 -0
  226. package/dist/headers/NetFlowV5.js +205 -0
  227. package/dist/headers/OLSR.d.ts +31 -0
  228. package/dist/headers/OLSR.js +213 -0
  229. package/dist/headers/OPCUA.d.ts +33 -0
  230. package/dist/headers/OPCUA.js +165 -0
  231. package/dist/headers/OPCUAPubSub.d.ts +33 -0
  232. package/dist/headers/OPCUAPubSub.js +144 -0
  233. package/dist/headers/OSPF.d.ts +31 -0
  234. package/dist/headers/OSPF.js +365 -0
  235. package/dist/headers/OmronFINS.d.ts +31 -0
  236. package/dist/headers/OmronFINS.js +90 -0
  237. package/dist/headers/OpenFlow.d.ts +30 -0
  238. package/dist/headers/OpenFlow.js +113 -0
  239. package/dist/headers/OpenVPN.d.ts +35 -0
  240. package/dist/headers/OpenVPN.js +214 -0
  241. package/dist/headers/PCWorx.d.ts +35 -0
  242. package/dist/headers/PCWorx.js +115 -0
  243. package/dist/headers/PIM.d.ts +27 -0
  244. package/dist/headers/PIM.js +129 -0
  245. package/dist/headers/POP3.d.ts +31 -0
  246. package/dist/headers/POP3.js +152 -0
  247. package/dist/headers/POWERLINK.d.ts +28 -0
  248. package/dist/headers/POWERLINK.js +116 -0
  249. package/dist/headers/PPPoEDiscovery.d.ts +29 -0
  250. package/dist/headers/PPPoEDiscovery.js +198 -0
  251. package/dist/headers/PPPoESession.d.ts +28 -0
  252. package/dist/headers/PPPoESession.js +125 -0
  253. package/dist/headers/PPTP.d.ts +30 -0
  254. package/dist/headers/PPTP.js +122 -0
  255. package/dist/headers/PROFINETRT.d.ts +28 -0
  256. package/dist/headers/PROFINETRT.js +74 -0
  257. package/dist/headers/PTP.d.ts +34 -0
  258. package/dist/headers/PTP.js +213 -0
  259. package/dist/headers/PostgreSQL.d.ts +40 -0
  260. package/dist/headers/PostgreSQL.js +236 -0
  261. package/dist/headers/QUIC.d.ts +34 -0
  262. package/dist/headers/QUIC.js +308 -0
  263. package/dist/headers/RADIUS.d.ts +24 -0
  264. package/dist/headers/RADIUS.js +138 -0
  265. package/dist/headers/RDP.d.ts +27 -0
  266. package/dist/headers/RDP.js +93 -0
  267. package/dist/headers/RFB.d.ts +39 -0
  268. package/dist/headers/RFB.js +151 -0
  269. package/dist/headers/RGoose.d.ts +72 -0
  270. package/dist/headers/RGoose.js +340 -0
  271. package/dist/headers/RIP.d.ts +29 -0
  272. package/dist/headers/RIP.js +133 -0
  273. package/dist/headers/RIPng.d.ts +26 -0
  274. package/dist/headers/RIPng.js +140 -0
  275. package/dist/headers/RMCP.d.ts +26 -0
  276. package/dist/headers/RMCP.js +155 -0
  277. package/dist/headers/RSVP.d.ts +31 -0
  278. package/dist/headers/RSVP.js +263 -0
  279. package/dist/headers/RTCP.d.ts +34 -0
  280. package/dist/headers/RTCP.js +217 -0
  281. package/dist/headers/RTP.d.ts +33 -0
  282. package/dist/headers/RTP.js +291 -0
  283. package/dist/headers/RTPS.d.ts +33 -0
  284. package/dist/headers/RTPS.js +182 -0
  285. package/dist/headers/RTSP.d.ts +36 -0
  286. package/dist/headers/RTSP.js +184 -0
  287. package/dist/headers/RawData.d.ts +17 -0
  288. package/dist/headers/RawData.js +43 -0
  289. package/dist/headers/Redis.d.ts +32 -0
  290. package/dist/headers/Redis.js +202 -0
  291. package/dist/headers/Rlogin.d.ts +42 -0
  292. package/dist/headers/Rlogin.js +139 -0
  293. package/dist/headers/Rsync.d.ts +28 -0
  294. package/dist/headers/Rsync.js +117 -0
  295. package/dist/headers/S7comm.d.ts +36 -0
  296. package/dist/headers/S7comm.js +244 -0
  297. package/dist/headers/SCTP.d.ts +35 -0
  298. package/dist/headers/SCTP.js +174 -0
  299. package/dist/headers/SFlow.d.ts +29 -0
  300. package/dist/headers/SFlow.js +242 -0
  301. package/dist/headers/SIP.d.ts +27 -0
  302. package/dist/headers/SIP.js +146 -0
  303. package/dist/headers/SLMP.d.ts +36 -0
  304. package/dist/headers/SLMP.js +154 -0
  305. package/dist/headers/SLP.d.ts +30 -0
  306. package/dist/headers/SLP.js +207 -0
  307. package/dist/headers/SLPv1.d.ts +32 -0
  308. package/dist/headers/SLPv1.js +138 -0
  309. package/dist/headers/SMB1.d.ts +37 -0
  310. package/dist/headers/SMB1.js +200 -0
  311. package/dist/headers/SMB2.d.ts +36 -0
  312. package/dist/headers/SMB2.js +203 -0
  313. package/dist/headers/SMPP.d.ts +33 -0
  314. package/dist/headers/SMPP.js +119 -0
  315. package/dist/headers/SMTP.d.ts +33 -0
  316. package/dist/headers/SMTP.js +157 -0
  317. package/dist/headers/SNAP.d.ts +22 -0
  318. package/dist/headers/SNAP.js +68 -0
  319. package/dist/headers/SNMP.d.ts +28 -0
  320. package/dist/headers/SNMP.js +302 -0
  321. package/dist/headers/SOCKS4.d.ts +42 -0
  322. package/dist/headers/SOCKS4.js +302 -0
  323. package/dist/headers/SOCKS5.d.ts +45 -0
  324. package/dist/headers/SOCKS5.js +223 -0
  325. package/dist/headers/SSDP.d.ts +27 -0
  326. package/dist/headers/SSDP.js +161 -0
  327. package/dist/headers/SSH.d.ts +44 -0
  328. package/dist/headers/SSH.js +274 -0
  329. package/dist/headers/STOMP.d.ts +48 -0
  330. package/dist/headers/STOMP.js +177 -0
  331. package/dist/headers/STP.d.ts +26 -0
  332. package/dist/headers/STP.js +150 -0
  333. package/dist/headers/STUN.d.ts +25 -0
  334. package/dist/headers/STUN.js +183 -0
  335. package/dist/headers/SercosIII.d.ts +43 -0
  336. package/dist/headers/SercosIII.js +199 -0
  337. package/dist/headers/Skinny.d.ts +32 -0
  338. package/dist/headers/Skinny.js +139 -0
  339. package/dist/headers/StatsD.d.ts +27 -0
  340. package/dist/headers/StatsD.js +134 -0
  341. package/dist/headers/SunRPC.d.ts +34 -0
  342. package/dist/headers/SunRPC.js +268 -0
  343. package/dist/headers/Syslog.d.ts +21 -0
  344. package/dist/headers/Syslog.js +91 -0
  345. package/dist/headers/TCP.d.ts +19 -0
  346. package/dist/headers/TCP.js +905 -0
  347. package/dist/headers/TFTP.d.ts +28 -0
  348. package/dist/headers/TFTP.js +224 -0
  349. package/dist/headers/TLS_Alert.d.ts +24 -0
  350. package/dist/headers/TLS_Alert.js +639 -0
  351. package/dist/headers/TLS_ApplicationData.d.ts +24 -0
  352. package/dist/headers/TLS_ApplicationData.js +170 -0
  353. package/dist/headers/TLS_ChangeCipherSpec.d.ts +23 -0
  354. package/dist/headers/TLS_ChangeCipherSpec.js +168 -0
  355. package/dist/headers/TLS_Handshake.d.ts +65 -0
  356. package/dist/headers/TLS_Handshake.js +860 -0
  357. package/dist/headers/TLS_Heartbeat.d.ts +27 -0
  358. package/dist/headers/TLS_Heartbeat.js +247 -0
  359. package/dist/headers/TPKT.d.ts +26 -0
  360. package/dist/headers/TPKT.js +99 -0
  361. package/dist/headers/TacacsPlus.d.ts +27 -0
  362. package/dist/headers/TacacsPlus.js +133 -0
  363. package/dist/headers/Telnet.d.ts +40 -0
  364. package/dist/headers/Telnet.js +193 -0
  365. package/dist/headers/Teredo.d.ts +40 -0
  366. package/dist/headers/Teredo.js +251 -0
  367. package/dist/headers/TimeProtocol.d.ts +25 -0
  368. package/dist/headers/TimeProtocol.js +53 -0
  369. package/dist/headers/UDP.d.ts +19 -0
  370. package/dist/headers/UDP.js +171 -0
  371. package/dist/headers/VLAN_802dot1Q.d.ts +24 -0
  372. package/dist/headers/VLAN_802dot1Q.js +96 -0
  373. package/dist/headers/VRRP.d.ts +26 -0
  374. package/dist/headers/VRRP.js +309 -0
  375. package/dist/headers/VXLAN.d.ts +24 -0
  376. package/dist/headers/VXLAN.js +75 -0
  377. package/dist/headers/WCCP.d.ts +29 -0
  378. package/dist/headers/WCCP.js +117 -0
  379. package/dist/headers/WHOIS.d.ts +37 -0
  380. package/dist/headers/WHOIS.js +126 -0
  381. package/dist/headers/WSDiscovery.d.ts +29 -0
  382. package/dist/headers/WSDiscovery.js +118 -0
  383. package/dist/headers/WakeOnLAN.d.ts +30 -0
  384. package/dist/headers/WakeOnLAN.js +126 -0
  385. package/dist/headers/WebSocket.d.ts +26 -0
  386. package/dist/headers/WebSocket.js +173 -0
  387. package/dist/headers/WireGuard.d.ts +38 -0
  388. package/dist/headers/WireGuard.js +216 -0
  389. package/dist/headers/XMPP.d.ts +37 -0
  390. package/dist/headers/XMPP.js +149 -0
  391. package/dist/headers/Zabbix.d.ts +35 -0
  392. package/dist/headers/Zabbix.js +153 -0
  393. package/dist/headers/cms/AcsiPdu.d.ts +45 -0
  394. package/dist/headers/cms/AcsiPdu.js +112 -0
  395. package/dist/headers/cms/PerDecoder.d.ts +68 -0
  396. package/dist/headers/cms/PerDecoder.js +211 -0
  397. package/dist/headers/cms/PerReader.d.ts +64 -0
  398. package/dist/headers/cms/PerReader.js +155 -0
  399. package/dist/helper/BufferToHex.d.ts +5 -0
  400. package/dist/helper/BufferToHex.js +10 -0
  401. package/dist/helper/BufferToIP.d.ts +12 -0
  402. package/dist/helper/BufferToIP.js +23 -0
  403. package/dist/helper/BufferToNumber.d.ts +18 -0
  404. package/dist/helper/BufferToNumber.js +47 -0
  405. package/dist/helper/HexToBuffer.d.ts +7 -0
  406. package/dist/helper/HexToBuffer.js +27 -0
  407. package/dist/helper/HexToNumber.d.ts +18 -0
  408. package/dist/helper/HexToNumber.js +48 -0
  409. package/dist/helper/IPToBuffer.d.ts +12 -0
  410. package/dist/helper/IPToBuffer.js +34 -0
  411. package/dist/helper/NumberToBERBuffer.d.ts +18 -0
  412. package/dist/helper/NumberToBERBuffer.js +31 -0
  413. package/dist/helper/NumberToBERHex.d.ts +18 -0
  414. package/dist/helper/NumberToBERHex.js +52 -0
  415. package/dist/helper/NumberToBuffer.d.ts +18 -0
  416. package/dist/helper/NumberToBuffer.js +38 -0
  417. package/dist/helper/NumberToHex.d.ts +18 -0
  418. package/dist/helper/NumberToHex.js +35 -0
  419. package/dist/index.d.ts +52 -0
  420. package/dist/index.js +113 -0
  421. package/dist/lib/FlexibleObject.d.ts +27 -0
  422. package/dist/lib/FlexibleObject.js +113 -0
  423. package/dist/lib/GetBERIntegerLengthFromBuffer.d.ts +6 -0
  424. package/dist/lib/GetBERIntegerLengthFromBuffer.js +16 -0
  425. package/dist/lib/ProcessPacketPostHandlers.d.ts +13 -0
  426. package/dist/lib/ProcessPacketPostHandlers.js +53 -0
  427. package/dist/lib/SortPostHandlers.d.ts +7 -0
  428. package/dist/lib/SortPostHandlers.js +11 -0
  429. package/dist/lib/StringContentEncodingEnum.d.ts +10 -0
  430. package/dist/lib/StringContentEncodingEnum.js +14 -0
  431. package/dist/schema/ProtocolFieldJSONSchema.d.ts +35 -0
  432. package/dist/schema/ProtocolFieldJSONSchema.js +2 -0
  433. package/dist/schema/ProtocolFieldJSONSchemaDefinition.d.ts +2 -0
  434. package/dist/schema/ProtocolFieldJSONSchemaDefinition.js +2 -0
  435. package/dist/schema/ProtocolJSONSchema.d.ts +32 -0
  436. package/dist/schema/ProtocolJSONSchema.js +2 -0
  437. package/dist/types/CodecData.d.ts +7 -0
  438. package/dist/types/CodecData.js +2 -0
  439. package/dist/types/CodecDecodeResult.d.ts +10 -0
  440. package/dist/types/CodecDecodeResult.js +2 -0
  441. package/dist/types/CodecEncodeInput.d.ts +2 -0
  442. package/dist/types/CodecEncodeInput.js +2 -0
  443. package/dist/types/CodecEncodeResult.d.ts +5 -0
  444. package/dist/types/CodecEncodeResult.js +2 -0
  445. package/dist/types/CodecErrorInfo.d.ts +5 -0
  446. package/dist/types/CodecErrorInfo.js +2 -0
  447. package/dist/types/CodecModule.d.ts +2 -0
  448. package/dist/types/CodecModule.js +2 -0
  449. package/dist/types/CodecModuleConstructor.d.ts +2 -0
  450. package/dist/types/CodecModuleConstructor.js +2 -0
  451. package/dist/types/CodecSchema.d.ts +6 -0
  452. package/dist/types/CodecSchema.js +2 -0
  453. package/dist/types/DemuxProducer.d.ts +23 -0
  454. package/dist/types/DemuxProducer.js +2 -0
  455. package/dist/types/Dissection.d.ts +23 -0
  456. package/dist/types/Dissection.js +2 -0
  457. package/dist/types/HeaderTreeNode.d.ts +4 -0
  458. package/dist/types/HeaderTreeNode.js +2 -0
  459. package/dist/types/LayerGraph.d.ts +32 -0
  460. package/dist/types/LayerGraph.js +2 -0
  461. package/dist/types/PostHandlerItem.d.ts +4 -0
  462. package/dist/types/PostHandlerItem.js +2 -0
  463. package/package.json +141 -0
@@ -0,0 +1,734 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BaseHeader = void 0;
4
+ const SortPostHandlers_1 = require("../lib/SortPostHandlers");
5
+ const FlexibleObject_1 = require("../lib/FlexibleObject");
6
+ const ajv_1 = require("ajv");
7
+ const CodecSchemaValidateError_1 = require("../errors/CodecSchemaValidateError");
8
+ const BufferToNumber_1 = require("../helper/BufferToNumber");
9
+ const NumberToBuffer_1 = require("../helper/NumberToBuffer");
10
+ const BufferToHex_1 = require("../helper/BufferToHex");
11
+ const HexToBuffer_1 = require("../helper/HexToBuffer");
12
+ const BufferToIP_1 = require("../helper/BufferToIP");
13
+ const IPToBuffer_1 = require("../helper/IPToBuffer");
14
+ const StringContentEncodingEnum_1 = require("../lib/StringContentEncodingEnum");
15
+ const CONSTRUCTOR_VALIDATE_KEY = '__validate';
16
+ //Per-codec-class cached MATCH probe. Content-heuristic selection calls MATCH() on many candidates
17
+ //per layer; each used to build a whole fresh instance (rebuilding the SCHEMA) just to run match().
18
+ //Since match() only inspects the previous layer and the raw buffer, one reusable probe per class
19
+ //suffices — see BaseHeader.MATCH / bindContext.
20
+ const MATCH_PROBE_KEY = '__matchProbe';
21
+ /**
22
+ * The base class every protocol header extends, and the surface a custom-codec author works against.
23
+ *
24
+ * A subclass declares a `SCHEMA` (an executable JSON Schema whose fields carry per-field
25
+ * `decode`/`encode` closures), a stable `id`/`name`/`nickname`, and a `match()` that decides —
26
+ * by inspecting the previously decoded layers (`prevCodecModule`/`prevCodecModules`) — whether
27
+ * this header applies at the current offset. Optional `matchKeys`/`demuxProducers` wire the
28
+ * header into the codec's O(1) dispatch table instead of the content-heuristic chain.
29
+ *
30
+ * Field closures read and write the shared packet buffer through the header-relative helpers
31
+ * `readBytes`/`writeBytes` (whole octets) and `readBits`/`writeBits` (bit fields), which
32
+ * auto-expand the buffer on write, and store values on the path-tracking `instance`. Malformed
33
+ * input is reported via `recordError()` rather than thrown, so decode/encode never crash. Headers
34
+ * register cross-field/cross-layer fixups (lengths, checksums) with the post-handler methods
35
+ * (`addPostSelfEncodeHandler`/`addPostSelfDecodeHandler` for layer-internal, `addPostPacketEncodeHandler`/
36
+ * `addPostPacketDecodeHandler` for packet-level).
37
+ */
38
+ class BaseHeader {
39
+ static get CODEC_INSTANCE() {
40
+ return new this();
41
+ }
42
+ static CREATE_CODEC_INSTANCE_WITCH_CODEC_MODULES(codecData, codecModules) {
43
+ return this.CREATE_INSTANCE(codecData, codecModules);
44
+ }
45
+ static get PROTOCOL_ID() {
46
+ return this.CODEC_INSTANCE.id;
47
+ }
48
+ static get PROTOCOL_NAME() {
49
+ return this.CODEC_INSTANCE.name;
50
+ }
51
+ /**
52
+ * Demux keys this header registers in the codec dispatch table.
53
+ * Empty (the default) means the header is matched by its content-heuristic
54
+ * match() instead of by an upper-layer demultiplexing value.
55
+ */
56
+ static get MATCH_KEYS() {
57
+ return this.CODEC_INSTANCE.matchKeys;
58
+ }
59
+ /**
60
+ * Demux keys this header produces for its child layer (from its own field values). Reversed by the
61
+ * codec to route the next layer, and read by the editor projection. Empty (the default) means this
62
+ * header is a leaf — nothing demuxes off it.
63
+ */
64
+ static get DEMUX_PRODUCERS() {
65
+ return this.CODEC_INSTANCE.demuxProducers;
66
+ }
67
+ /**
68
+ * When true, this header is also placed in the content-heuristic fallback list even though it has
69
+ * demux matchKeys. Lets a protocol with a reliable content signature (TLS, IEC104) take the O(1)
70
+ * bucket on its well-known port yet still be recognized on any other port via its match(). Default
71
+ * false: matchKeys → bucket only; no matchKeys → heuristic only.
72
+ */
73
+ static get HEURISTIC_FALLBACK() {
74
+ return this.CODEC_INSTANCE.heuristicFallback;
75
+ }
76
+ /** Higher is tried first within a demux bucket and within the heuristic chain; ties keep registration order. */
77
+ static get MATCH_PRIORITY() {
78
+ return this.CODEC_INSTANCE.matchPriority;
79
+ }
80
+ static get PROTOCOL_SCHEMA() {
81
+ const schema = JSON.parse(JSON.stringify(this.CODEC_INSTANCE.SCHEMA));
82
+ if (!Object.hasOwn(this, CONSTRUCTOR_VALIDATE_KEY)) {
83
+ const validate = new ajv_1.Ajv({
84
+ strict: false,
85
+ useDefaults: true,
86
+ coerceTypes: true
87
+ }).compile(schema);
88
+ Object.defineProperty(this, CONSTRUCTOR_VALIDATE_KEY, {
89
+ enumerable: false,
90
+ configurable: false,
91
+ value: validate
92
+ });
93
+ }
94
+ return schema;
95
+ }
96
+ static MATCH(codecData, codecModules) {
97
+ //Reuse one cached probe instance per codec class instead of rebuilding a full instance (and its
98
+ //SCHEMA) for every candidate. match() only reads the previous layer and the raw buffer, never
99
+ //this header's SCHEMA/instance, so rebinding context is enough. selectCodec runs synchronously,
100
+ //so the shared probe never overlaps across concurrent decodes.
101
+ let probe = Object.hasOwn(this, MATCH_PROBE_KEY) ? this[MATCH_PROBE_KEY] : undefined;
102
+ if (!probe) {
103
+ probe = new this();
104
+ Object.defineProperty(this, MATCH_PROBE_KEY, { enumerable: false, configurable: false, value: probe });
105
+ }
106
+ probe.bindContext(codecData, codecModules ? codecModules : []);
107
+ return probe.match();
108
+ }
109
+ static CREATE_INSTANCE(codecData, codecModules) {
110
+ return new this(codecData, codecModules);
111
+ }
112
+ //Dissect-only instrumentation: when #byteRanges is non-null, each field read records the packet
113
+ //span it covered (keyed by the field being decoded). Off (null) during normal decode/encode, so
114
+ //the hot path is untouched. See enableByteRangeTracking() / getByteRanges().
115
+ #byteRanges;
116
+ #currentFieldPath;
117
+ /**
118
+ * Turn on byte-range collection for a dissect pass (call before decode()). Additive and
119
+ * read-only: it changes nothing about the decoded values, only records where each field lives.
120
+ */
121
+ enableByteRangeTracking() {
122
+ this.#byteRanges = new Map();
123
+ }
124
+ /** The byte span each field occupied, or null if this header was not dissected. */
125
+ getByteRanges() {
126
+ return this.#byteRanges;
127
+ }
128
+ /**
129
+ * Entire packet buffer data getter
130
+ */
131
+ get packet() {
132
+ //Expose only the logical bytes. When physical === logical (the decode path never grows the
133
+ //buffer) return it directly with zero allocation; only slice a view when encode left headroom.
134
+ const buffer = this.codecData.packet;
135
+ const length = this.codecData.packetLength;
136
+ return (length === undefined || length === buffer.length) ? buffer : buffer.subarray(0, length);
137
+ }
138
+ /**
139
+ * Entire packet buffer data setter
140
+ * @param packet
141
+ */
142
+ set packet(packet) {
143
+ this.codecData.packet = packet;
144
+ this.codecData.packetLength = packet.length;
145
+ }
146
+ /**
147
+ * The end position of this header in the entire packet's buffer
148
+ */
149
+ get endPos() {
150
+ return this.startPos + this.headerLength;
151
+ }
152
+ /**
153
+ * Readonly Header length
154
+ */
155
+ get length() {
156
+ return this.headerLength;
157
+ }
158
+ /**
159
+ * Post packet handlers
160
+ * @protected
161
+ */
162
+ get postPacketHandlers() {
163
+ if (this.codecData.postHandlers[this.headerIndex] === undefined)
164
+ this.codecData.postHandlers[this.headerIndex] = [];
165
+ return this.codecData.postHandlers[this.headerIndex];
166
+ }
167
+ constructor(codecData, codecModules) {
168
+ /**
169
+ * Current header is a protocol or not
170
+ */
171
+ this.isProtocol = true;
172
+ /**
173
+ * Upper-layer demultiplexing keys that select this header, e.g.
174
+ * ['ethertype:0800'] or ['ipproto:6']. Registered in the codec dispatch
175
+ * table for O(1) selection during decode. Leave empty for headers that
176
+ * must inspect their own bytes to match (TLS, IEC104, tunnels); those fall
177
+ * back to the content-heuristic match() list.
178
+ */
179
+ this.matchKeys = [];
180
+ /**
181
+ * Demux keys this header produces for its child (see DemuxProducer). Declared per-schema so a new
182
+ * demux dimension (port, GUID, …) is a per-protocol declaration, not a core change. Default: none
183
+ * (a leaf header). Example: Ethernet declares `[{field:'etherType', namespace:'ethertype',
184
+ * kind:'string'}]`; IPv4 declares `[{field:'protocol', namespace:'ipproto', kind:'uint'}]`.
185
+ */
186
+ this.demuxProducers = [];
187
+ /**
188
+ * Also register in the content-heuristic fallback list despite having matchKeys — so a
189
+ * content-signed protocol keeps working off its well-known port. See static HEURISTIC_FALLBACK.
190
+ */
191
+ this.heuristicFallback = false;
192
+ /** Selection priority within a bucket / the heuristic chain (higher first; ties keep registration order). */
193
+ this.matchPriority = 0;
194
+ /**
195
+ * Encode/Decode error info objects
196
+ */
197
+ this.errors = [];
198
+ /**
199
+ * Header schema instance
200
+ */
201
+ this.instance = new FlexibleObject_1.FlexibleObject();
202
+ //Dissect-only instrumentation: when #byteRanges is non-null, each field read records the packet
203
+ //span it covered (keyed by the field being decoded). Off (null) during normal decode/encode, so
204
+ //the hot path is untouched. See enableByteRangeTracking() / getByteRanges().
205
+ this.#byteRanges = null;
206
+ this.#currentFieldPath = '';
207
+ /**
208
+ * The start position of this header in the entire packet's buffer
209
+ */
210
+ this.startPos = 0;
211
+ /**
212
+ * Header length
213
+ * @protected
214
+ */
215
+ this.headerLength = 0;
216
+ /**
217
+ * Current header index in packet headers
218
+ * @protected
219
+ */
220
+ this.headerIndex = 0;
221
+ /**
222
+ * Registered post encode handlers (CodecModule)
223
+ * @protected
224
+ */
225
+ this.postSelfEncodeHandlers = [];
226
+ /**
227
+ * Registered post decode handlers (CodecModule)
228
+ * @protected
229
+ */
230
+ this.postSelfDecodeHandlers = [];
231
+ this.bindContext(codecData, codecModules);
232
+ }
233
+ /**
234
+ * (Re)bind this instance's decode/match context. Extracted from the constructor so the static
235
+ * MATCH probe can reuse a single cached instance across heuristic candidates instead of rebuilding
236
+ * the whole SCHEMA for each — match() only reads the previous layer and the raw buffer.
237
+ */
238
+ bindContext(codecData, codecModules) {
239
+ this.codecData = codecData;
240
+ this.startPos = codecData?.startPos ? codecData.startPos : 0;
241
+ codecModules = codecModules ? codecModules : [];
242
+ this.codecModules = codecModules;
243
+ this.prevCodecModules = [...codecModules];
244
+ const prevCodecModuleIndex = this.prevCodecModules.length - 1;
245
+ this.prevCodecModule = this.prevCodecModules[prevCodecModuleIndex > -1 ? prevCodecModuleIndex : 0];
246
+ this.headerIndex = this.prevCodecModules.length;
247
+ }
248
+ /**
249
+ * Get packet data offset
250
+ * @param offset
251
+ * @protected
252
+ */
253
+ getPacketOffset(offset) {
254
+ return this.startPos + offset;
255
+ }
256
+ /**
257
+ * Internal read bytes from buffer
258
+ * @param offset
259
+ * @param length
260
+ * @param expandBufferLength
261
+ * @param changeHeaderLength
262
+ * @private
263
+ */
264
+ #readBytes(offset, length, expandBufferLength, changeHeaderLength) {
265
+ const packetOffset = this.getPacketOffset(offset);
266
+ let readEndPos = packetOffset + length;
267
+ const codecData = this.codecData;
268
+ const logicalLength = codecData.packetLength ?? codecData.packet.length;
269
+ if (logicalLength < readEndPos) {
270
+ if (expandBufferLength) {
271
+ if (codecData.packet.length < readEndPos) {
272
+ //Amortized doubling: a run of small field writes grows the buffer O(log n) times
273
+ //instead of reallocating + copying the whole packet on every write (O(n^2)). Only the
274
+ //logical bytes are copied forward; the headroom stays zero-filled from Buffer.alloc.
275
+ const capacity = Math.max(readEndPos, codecData.packet.length * 2);
276
+ const grown = Buffer.alloc(capacity, 0);
277
+ codecData.packet.copy(grown, 0, 0, logicalLength);
278
+ codecData.packet = grown;
279
+ }
280
+ codecData.packetLength = readEndPos;
281
+ }
282
+ else {
283
+ readEndPos = logicalLength;
284
+ }
285
+ }
286
+ const headerLength = readEndPos - this.startPos;
287
+ if (changeHeaderLength)
288
+ this.headerLength = this.headerLength < headerLength ? headerLength : this.headerLength;
289
+ //Dissect instrumentation: attribute this read's absolute span to the field being decoded,
290
+ //extending the field's range if it reads more than once (e.g. an address + its value).
291
+ if (this.#byteRanges && this.#currentFieldPath) {
292
+ const existing = this.#byteRanges.get(this.#currentFieldPath);
293
+ if (existing) {
294
+ const start = Math.min(existing.offset, packetOffset);
295
+ const end = Math.max(existing.offset + existing.length, packetOffset + length);
296
+ this.#byteRanges.set(this.#currentFieldPath, { offset: start, length: end - start });
297
+ }
298
+ else {
299
+ this.#byteRanges.set(this.#currentFieldPath, { offset: packetOffset, length: length });
300
+ }
301
+ }
302
+ //Clamp the returned view to readEndPos (which the branches above already clamped to the logical
303
+ //length on a non-expanding out-of-range read), so encode-time forward reads past the write
304
+ //high-water mark stay truncated exactly as before rather than exposing zero-filled headroom.
305
+ return this.codecData.packet.subarray(packetOffset, readEndPos);
306
+ }
307
+ /**
308
+ * Read bytes from buffer
309
+ * @param offset
310
+ * @param length
311
+ * @param dryRun
312
+ * @protected
313
+ */
314
+ readBytes(offset, length, dryRun = false) {
315
+ return this.#readBytes(offset, length, false, !dryRun);
316
+ }
317
+ /**
318
+ * Write bytes to buffer
319
+ * @param offset
320
+ * @param buffer
321
+ * @protected
322
+ */
323
+ writeBytes(offset, buffer) {
324
+ const packetOffset = this.getPacketOffset(offset);
325
+ const writeEndPos = packetOffset + buffer.length;
326
+ this.#readBytes(offset, buffer.length, true, true);
327
+ this.codecData.packet.fill(buffer, packetOffset, writeEndPos);
328
+ }
329
+ /**
330
+ * Read bits from buffer
331
+ * @param offset
332
+ * @param length
333
+ * @param bitOffset
334
+ * @param bitLength
335
+ * @protected
336
+ */
337
+ readBits(offset, length, bitOffset, bitLength) {
338
+ const buffer = this.#readBytes(offset, length, false, true);
339
+ //MSB-first bit extraction over a `length`-octet window. Available bytes occupy the low end;
340
+ //missing (truncated) high bits read as 0.
341
+ const shift = length * 8 - bitOffset - bitLength;
342
+ if (shift < 0)
343
+ return 0;
344
+ if (length <= 4) {
345
+ //A window of ≤4 octets (≤32 bits) fits a JS number exactly — skip BigInt boxing. Use
346
+ //arithmetic (not <</>>, which are 32-bit-signed in JS) so 32-bit widths stay correct.
347
+ let narrow = 0;
348
+ for (const byte of buffer)
349
+ narrow = narrow * 256 + byte;
350
+ return Math.floor(narrow / 2 ** shift) % (2 ** bitLength);
351
+ }
352
+ //Wider windows (48/64-bit GOOSE/SV fields) keep full precision via BigInt.
353
+ let value = 0n;
354
+ for (const byte of buffer)
355
+ value = (value << 8n) | BigInt(byte);
356
+ const mask = (1n << BigInt(bitLength)) - 1n;
357
+ return Number((value >> BigInt(shift)) & mask);
358
+ }
359
+ /**
360
+ * Write bits to buffer
361
+ * @param offset
362
+ * @param length
363
+ * @param bitOffset
364
+ * @param bitLength
365
+ * @param value
366
+ * @protected
367
+ */
368
+ writeBits(offset, length, bitOffset, bitLength, value) {
369
+ const buffer = this.#readBytes(offset, length, true, true);
370
+ //Overlay `bitLength` bits of `value` at `bitOffset` (MSB-first) into the octet window. Only
371
+ //the low `bitLength` bits of value are written (out-of-range values wrap, matching a
372
+ //fixed-width field), and encode never crashes.
373
+ const out = Buffer.alloc(buffer.length);
374
+ if (length <= 4) {
375
+ //≤32-bit window: plain number arithmetic, no BigInt boxing. Split the window into the
376
+ //untouched high part, the target field, and the low part, then reassemble — all via
377
+ //multiply/divide/modulo to stay correct at 32-bit widths (JS bit-ops are 32-bit-signed).
378
+ let current = 0;
379
+ for (const byte of buffer)
380
+ current = current * 256 + byte;
381
+ const shift = buffer.length * 8 - bitOffset - bitLength;
382
+ const modulo = 2 ** bitLength;
383
+ const divisor = 2 ** shift;
384
+ const field = (((Math.trunc(Number(value)) || 0) % modulo) + modulo) % modulo;
385
+ const blockSize = modulo * divisor;
386
+ let written = Math.floor(current / blockSize) * blockSize + field * divisor + current % divisor;
387
+ for (let i = buffer.length - 1; i >= 0; i--) {
388
+ out[i] = written % 256;
389
+ written = Math.floor(written / 256);
390
+ }
391
+ this.writeBytes(offset, out);
392
+ return;
393
+ }
394
+ //Wider windows keep exact via BigInt.
395
+ let current = 0n;
396
+ for (const byte of buffer)
397
+ current = (current << 8n) | BigInt(byte);
398
+ const shift = BigInt(buffer.length * 8 - bitOffset - bitLength);
399
+ const fieldMask = (1n << BigInt(bitLength)) - 1n;
400
+ const field = (BigInt(Math.trunc(Number(value)) || 0) & fieldMask) << shift;
401
+ const written = (current & ~(fieldMask << shift)) | field;
402
+ let v = written;
403
+ for (let i = buffer.length - 1; i >= 0; i--) {
404
+ out[i] = Number(v & 0xffn);
405
+ v >>= 8n;
406
+ }
407
+ this.writeBytes(offset, out);
408
+ }
409
+ // ===== Field building blocks =====
410
+ // Declarative field factories: one call yields the whole {type,label,min,max,decode,encode}
411
+ // schema field, generating the decode/encode twin from a single declaration so the byte offset
412
+ // and width live in one place (not duplicated across two hand-mirrored closures — the source of
413
+ // the historical decode≠encode bugs). Closures re-resolve this.instance[name] at run time because
414
+ // encode swaps in a fresh instance. Irregular fields keep their hand-written closures (escape hatch).
415
+ /**
416
+ * An unsigned big-endian integer field of `byteLength` octets at `offset`. Decode reads it into
417
+ * `name`; encode clamps to the field's range (recording an error, never throwing) and writes it —
418
+ * byte-for-byte identical to the hand-written pattern it replaces.
419
+ * @protected
420
+ */
421
+ static fieldUInt(name, offset, byteLength, label) {
422
+ const maximum = byteLength === 1 ? 255 : byteLength === 2 ? 65535 : 4294967295;
423
+ const read = byteLength === 1 ? BufferToNumber_1.BufferToUInt8 : byteLength === 2 ? BufferToNumber_1.BufferToUInt16 : BufferToNumber_1.BufferToUInt32;
424
+ const write = byteLength === 1 ? NumberToBuffer_1.UInt8ToBuffer : byteLength === 2 ? NumberToBuffer_1.UInt16ToBuffer : NumberToBuffer_1.UInt32ToBuffer;
425
+ return {
426
+ type: 'integer',
427
+ label: label,
428
+ minimum: 0,
429
+ maximum: maximum,
430
+ decode: function () {
431
+ this.instance[name].setValue(read(this.readBytes(offset, byteLength)));
432
+ },
433
+ encode: function () {
434
+ const node = this.instance[name];
435
+ let value = node.getValue(0, (nodePath) => this.recordError(nodePath, 'Not Found'));
436
+ if (value > maximum) {
437
+ this.recordError(node.getPath(), `Maximum value is ${maximum}`);
438
+ value = maximum;
439
+ }
440
+ if (value < 0) {
441
+ this.recordError(node.getPath(), 'Minimum value is 0');
442
+ value = 0;
443
+ }
444
+ node.setValue(value);
445
+ this.writeBytes(offset, write(value));
446
+ }
447
+ };
448
+ }
449
+ /**
450
+ * A signed 8-bit integer field at `offset` (e.g. NTP poll/precision — power-of-two exponents).
451
+ * Decode reads it as int8 into `name`; encode clamps to [-128, 127] (recording an error, never
452
+ * throwing) and writes it — byte-for-byte identical to a hand-written int8 field for in-range values.
453
+ * @protected
454
+ */
455
+ static fieldInt8(name, offset, label) {
456
+ return {
457
+ type: 'integer',
458
+ label: label,
459
+ minimum: -128,
460
+ maximum: 127,
461
+ decode: function () {
462
+ this.instance[name].setValue((0, BufferToNumber_1.BufferToInt8)(this.readBytes(offset, 1)));
463
+ },
464
+ encode: function () {
465
+ const node = this.instance[name];
466
+ let value = node.getValue(0, (nodePath) => this.recordError(nodePath, 'Not Found'));
467
+ if (value > 127) {
468
+ this.recordError(node.getPath(), 'Maximum value is 127');
469
+ value = 127;
470
+ }
471
+ if (value < -128) {
472
+ this.recordError(node.getPath(), 'Minimum value is -128');
473
+ value = -128;
474
+ }
475
+ node.setValue(value);
476
+ this.writeBytes(offset, (0, NumberToBuffer_1.Int8ToBuffer)(value));
477
+ }
478
+ };
479
+ }
480
+ /**
481
+ * A raw byte field of `byteLength` octets at `offset`, kept verbatim as a lower-case hex string
482
+ * (e.g. NTP timestamps / reference id — bytes an editor should see and round-trip untouched).
483
+ * Decode reads the bytes to hex; encode writes the hex back (default: all-zero). Byte-for-byte
484
+ * identical to the hand-written pattern it replaces.
485
+ * @protected
486
+ */
487
+ static fieldHex(name, offset, byteLength, label) {
488
+ const zero = '00'.repeat(byteLength);
489
+ return {
490
+ type: 'string',
491
+ label: label,
492
+ contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX,
493
+ decode: function () {
494
+ this.instance[name].setValue((0, BufferToHex_1.BufferToHex)(this.readBytes(offset, byteLength)));
495
+ },
496
+ encode: function () {
497
+ this.writeBytes(offset, (0, HexToBuffer_1.HexToBuffer)(this.instance[name].getValue(zero)));
498
+ }
499
+ };
500
+ }
501
+ /**
502
+ * A 4-octet IPv4 address field at `offset`, stored as a dotted-quad string (e.g. DHCP
503
+ * ciaddr/yiaddr/siaddr/giaddr). Decode reads it to `a.b.c.d`; encode writes it back (default
504
+ * '0.0.0.0', recording a Not Found error if the value is missing). Byte-for-byte identical to the
505
+ * hand-written IPv4-address pattern (see IPv4.sip/dip).
506
+ * @protected
507
+ */
508
+ static fieldIPv4(name, offset, label) {
509
+ return {
510
+ type: 'string',
511
+ label: label,
512
+ //Match IPv4.sip/dip exactly: the same length bounds + ipv4 content encoding, so Ajv
513
+ //validation and the editor's field metadata are identical to the hand-written pattern.
514
+ minLength: 7,
515
+ maxLength: 15,
516
+ contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.IPv4,
517
+ decode: function () {
518
+ this.instance[name].setValue((0, BufferToIP_1.BufferToIPv4)(this.readBytes(offset, 4)));
519
+ },
520
+ encode: function () {
521
+ const node = this.instance[name];
522
+ const value = node.getValue('0.0.0.0', (nodePath) => this.recordError(nodePath, 'Not Found'));
523
+ node.setValue(value);
524
+ this.writeBytes(offset, (0, IPToBuffer_1.IPv4ToBuffer)(value));
525
+ }
526
+ };
527
+ }
528
+ /**
529
+ * Get field codecs from schema tree
530
+ * @param schema
531
+ * @param codecName
532
+ * @param execBeforeSubCodecs
533
+ * @param codecs
534
+ * @protected
535
+ */
536
+ getFieldCodecs(schema, codecName, execBeforeSubCodecs, codecs = [], paths = null, pathPrefix = '') {
537
+ if (!schema.properties)
538
+ return codecs;
539
+ for (const propertyName of Object.keys(schema.properties)) {
540
+ const fieldSchema = schema.properties[propertyName];
541
+ const codec = fieldSchema[codecName];
542
+ //Push the raw closure (no async double-wrap) and skip fields with no codec entirely, so
543
+ //decode/encode call each synchronously and only await genuine Promises. When `paths` is
544
+ //provided (dissect only) a dotted field path is collected in parallel; otherwise there is
545
+ //zero extra cost on the hot path (no per-field object, no string concat).
546
+ const path = paths ? (pathPrefix ? `${pathPrefix}.${propertyName}` : propertyName) : '';
547
+ if (execBeforeSubCodecs && codec) {
548
+ codecs.push(codec);
549
+ if (paths)
550
+ paths.push(path);
551
+ }
552
+ if (fieldSchema.properties)
553
+ this.getFieldCodecs(fieldSchema, codecName, execBeforeSubCodecs, codecs, paths, path);
554
+ if (!execBeforeSubCodecs && codec) {
555
+ codecs.push(codec);
556
+ if (paths)
557
+ paths.push(path);
558
+ }
559
+ }
560
+ return codecs;
561
+ }
562
+ /**
563
+ * Record encode/decode error
564
+ * @param path
565
+ * @param message
566
+ * @protected
567
+ */
568
+ recordError(path, message) {
569
+ this.errors.push({
570
+ id: this.id,
571
+ path: path,
572
+ message: message
573
+ });
574
+ }
575
+ /**
576
+ * Register post encode handler for current codec
577
+ * @param handler
578
+ * @param priority
579
+ * @protected
580
+ */
581
+ addPostSelfEncodeHandler(handler, priority = 0) {
582
+ this.postSelfEncodeHandlers.push({
583
+ priority: priority,
584
+ handler: handler
585
+ });
586
+ }
587
+ /**
588
+ * Register post decode handler for current codec
589
+ * @param handler
590
+ * @param priority
591
+ * @protected
592
+ */
593
+ addPostSelfDecodeHandler(handler, priority = 0) {
594
+ this.postSelfDecodeHandlers.push({
595
+ priority: priority,
596
+ handler: handler
597
+ });
598
+ }
599
+ /**
600
+ * Register post encode handler for packet
601
+ * @description Registered handler call sequence: LIFO (Last In First Out)
602
+ * @param handler
603
+ * @param priority
604
+ * @protected
605
+ */
606
+ addPostPacketEncodeHandler(handler, priority = 0) {
607
+ this.postPacketHandlers.push({
608
+ priority: priority,
609
+ handler: handler
610
+ });
611
+ }
612
+ /**
613
+ * Register post decode handler for packet
614
+ * @description Registered handler call sequence: FIFO (First In First Out)
615
+ * @param handler
616
+ * @param priority
617
+ * @protected
618
+ */
619
+ addPostPacketDecodeHandler(handler, priority = 0) {
620
+ this.postPacketHandlers.push({
621
+ priority: priority,
622
+ handler: handler
623
+ });
624
+ }
625
+ /**
626
+ * Validate input json node is valid
627
+ * @param headerTreeNode
628
+ */
629
+ validate(headerTreeNode) {
630
+ let validate = this.constructor[CONSTRUCTOR_VALIDATE_KEY];
631
+ if (!validate) {
632
+ validate = new ajv_1.Ajv({
633
+ strict: false,
634
+ useDefaults: true,
635
+ coerceTypes: true
636
+ }).compile(this.SCHEMA);
637
+ this.constructor[CONSTRUCTOR_VALIDATE_KEY] = validate;
638
+ }
639
+ const isValid = validate(headerTreeNode);
640
+ if (!isValid) {
641
+ let errorObject;
642
+ if (validate.errors)
643
+ errorObject = validate.errors[0];
644
+ const errorMessage = errorObject?.message ? errorObject.message : 'Unknown Error';
645
+ throw new CodecSchemaValidateError_1.CodecSchemaValidateError(errorMessage);
646
+ }
647
+ return headerTreeNode;
648
+ }
649
+ /**
650
+ * Decode packet header field by field
651
+ */
652
+ async decode() {
653
+ const paths = this.#byteRanges ? [] : null;
654
+ const decodes = this.getFieldCodecs(this.SCHEMA, 'decode', true, [], paths);
655
+ for (let i = 0; i < decodes.length; i++) {
656
+ //Decode must never throw (error-accumulation contract): a truncated/corrupt packet can
657
+ //make a field's byte read run past the buffer or hit an invalid value. Contain that to a
658
+ //recorded error so the remaining fields and layers still decode best-effort.
659
+ //Call synchronously and only await genuine Promises — the vast majority of field
660
+ //closures are synchronous, so this avoids a promise allocation + scheduler turn per field.
661
+ if (paths)
662
+ this.#currentFieldPath = paths[i];
663
+ try {
664
+ //Invoke with the current instance as `this`. Arrow closures (headers not yet migrated)
665
+ //ignore the binding and use their captured lexical this — the same instance — so this is
666
+ //behaviour-neutral for them; migrated headers use plain functions whose dynamic `this`
667
+ //this provides, letting their SCHEMA be class-cached instead of rebuilt per packet.
668
+ const result = decodes[i].call(this);
669
+ if (result && typeof result.then === 'function')
670
+ await result;
671
+ }
672
+ catch (e) {
673
+ this.recordError('', `Decode error: ${e.message}`);
674
+ }
675
+ }
676
+ //Post-handler reads (cross-field/cross-layer fixups) are not a single field's bytes — clear
677
+ //the tracked path so they are not attributed to whichever field decoded last.
678
+ this.#currentFieldPath = '';
679
+ const postSelfDecodeHandlers = (0, SortPostHandlers_1.SortPostHandlers)(this.postSelfDecodeHandlers);
680
+ let postDecodeHandler = postSelfDecodeHandlers.shift();
681
+ while (postDecodeHandler) {
682
+ try {
683
+ await postDecodeHandler.handler();
684
+ }
685
+ catch (e) {
686
+ this.recordError('', `Decode error: ${e.message}`);
687
+ }
688
+ postDecodeHandler = postSelfDecodeHandlers.shift();
689
+ }
690
+ }
691
+ /**
692
+ * Encode packet header field by field
693
+ */
694
+ async encode() {
695
+ const encodes = this.getFieldCodecs(this.SCHEMA, 'encode', false);
696
+ for (const encode of encodes) {
697
+ //Shape validation is the deliberate fast-fail at the encode entry point (Ajv, in
698
+ //Codec.#encode); it runs before we get here. Past that, a field's encode closure must
699
+ //not crash the whole encode on an edge-case value — contain it to a recorded error so
700
+ //the packet still assembles best-effort (matches the decode contract).
701
+ //Synchronous fast-path (see decode): only await a genuinely returned Promise.
702
+ try {
703
+ //See decode: .call(this) is neutral for arrow closures, dynamic-`this` for migrated ones.
704
+ const result = encode.call(this);
705
+ if (result && typeof result.then === 'function')
706
+ await result;
707
+ }
708
+ catch (e) {
709
+ this.recordError('', `Encode error: ${e.message}`);
710
+ }
711
+ }
712
+ const postSelfEncodeHandlers = (0, SortPostHandlers_1.SortPostHandlers)(this.postSelfEncodeHandlers);
713
+ let postEncodeHandler = postSelfEncodeHandlers.shift();
714
+ while (postEncodeHandler) {
715
+ try {
716
+ await postEncodeHandler.handler();
717
+ }
718
+ catch (e) {
719
+ this.recordError('', `Encode error: ${e.message}`);
720
+ }
721
+ postEncodeHandler = postSelfEncodeHandlers.shift();
722
+ }
723
+ //Encode grows `packet` with headroom (amortized doubling). Restore it to the exact logical
724
+ //length so every reader of codecData.packet — packet-level post handlers, the encode result,
725
+ //and single-layer callers — sees no trailing headroom. subarray is a view (no copy); a
726
+ //following layer simply re-grows from here.
727
+ const encodedLength = this.codecData.packetLength;
728
+ if (encodedLength !== undefined && encodedLength < this.codecData.packet.length) {
729
+ this.codecData.packet = this.codecData.packet.subarray(0, encodedLength);
730
+ }
731
+ this.codecData.packetLength = undefined;
732
+ }
733
+ }
734
+ exports.BaseHeader = BaseHeader;