jspurefix 5.0.0 → 5.2.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 (121) hide show
  1. package/BACKPORT_PLAN.md +135 -62
  2. package/README.md +1 -2
  3. package/dist/buffer/ascii/ascii-parser-state.js +0 -7
  4. package/dist/buffer/ascii/ascii-parser-state.js.map +1 -1
  5. package/dist/buffer/ascii/ascii-parser.d.ts +1 -0
  6. package/dist/buffer/ascii/ascii-parser.js +8 -2
  7. package/dist/buffer/ascii/ascii-parser.js.map +1 -1
  8. package/dist/buffer/fixml/fixml-view.js.map +1 -1
  9. package/dist/buffer/msg-encoder.js +34 -1
  10. package/dist/buffer/msg-encoder.js.map +1 -1
  11. package/dist/buffer/msg-parser.js +34 -1
  12. package/dist/buffer/msg-parser.js.map +1 -1
  13. package/dist/buffer/msg-view.js.map +1 -1
  14. package/dist/collections/index.js +1 -0
  15. package/dist/config/winston-logger.js.map +1 -1
  16. package/dist/dict-parser.js +34 -1
  17. package/dist/dict-parser.js.map +1 -1
  18. package/dist/dictionary/compiler/enum-compiler.js +37 -4
  19. package/dist/dictionary/compiler/enum-compiler.js.map +1 -1
  20. package/dist/dictionary/compiler/msg-compiler.js +36 -3
  21. package/dist/dictionary/compiler/msg-compiler.js.map +1 -1
  22. package/dist/dictionary/compiler/standard-snippet.js +34 -1
  23. package/dist/dictionary/compiler/standard-snippet.js.map +1 -1
  24. package/dist/dictionary/contained/contained-field-set.js +2 -0
  25. package/dist/dictionary/contained/contained-field-set.js.map +1 -1
  26. package/dist/dictionary/definition/simple-field-definition.js +34 -1
  27. package/dist/dictionary/definition/simple-field-definition.js.map +1 -1
  28. package/dist/dictionary/fix-parser.js +34 -1
  29. package/dist/dictionary/fix-parser.js.map +1 -1
  30. package/dist/dictionary/parser/fix-repository/repository-type.js +1 -0
  31. package/dist/dictionary/parser/fix-repository/repository-xml-parser.js +35 -2
  32. package/dist/dictionary/parser/fix-repository/repository-xml-parser.js.map +1 -1
  33. package/dist/dictionary/parser/fixml/fields-parser.js.map +1 -1
  34. package/dist/dictionary/parser/fixml/fix-xsd-parser.js +34 -1
  35. package/dist/dictionary/parser/fixml/fix-xsd-parser.js.map +1 -1
  36. package/dist/dictionary/parser/fixml/include-graph.js +35 -2
  37. package/dist/dictionary/parser/fixml/include-graph.js.map +1 -1
  38. package/dist/dictionary/parser/fixml/node-definitions.js +1 -0
  39. package/dist/dictionary/parser/fixml/xsd-parser.js +34 -1
  40. package/dist/dictionary/parser/fixml/xsd-parser.js.map +1 -1
  41. package/dist/jsfix-cmd.js +39 -3
  42. package/dist/jsfix-cmd.js.map +1 -1
  43. package/dist/runtime/session-launcher.js +34 -1
  44. package/dist/runtime/session-launcher.js.map +1 -1
  45. package/dist/sample/http/oms/app.js +34 -1
  46. package/dist/sample/http/oms/app.js.map +1 -1
  47. package/dist/sample/tcp/recovering-skeleton/app.js +34 -1
  48. package/dist/sample/tcp/recovering-skeleton/app.js.map +1 -1
  49. package/dist/store/fix-msg-ascii-store-resend.js +1 -1
  50. package/dist/store/fix-msg-ascii-store-resend.js.map +1 -1
  51. package/dist/transport/ascii/ascii-session.d.ts +6 -0
  52. package/dist/transport/ascii/ascii-session.js +122 -5
  53. package/dist/transport/ascii/ascii-session.js.map +1 -1
  54. package/dist/transport/duplex/http-duplex.js +4 -1
  55. package/dist/transport/duplex/http-duplex.js.map +1 -1
  56. package/dist/transport/duplex/tcp-duplex.js +34 -1
  57. package/dist/transport/duplex/tcp-duplex.js.map +1 -1
  58. package/dist/transport/fix-acceptor.js +34 -1
  59. package/dist/transport/fix-acceptor.js.map +1 -1
  60. package/dist/transport/fix-entity.js +34 -1
  61. package/dist/transport/fix-entity.js.map +1 -1
  62. package/dist/transport/fixml/fixml-msg-transmitter.js +1 -1
  63. package/dist/transport/fixml/fixml-msg-transmitter.js.map +1 -1
  64. package/dist/transport/http/http-acceptor.js +34 -1
  65. package/dist/transport/http/http-acceptor.js.map +1 -1
  66. package/dist/transport/msg-transmitter.js +34 -1
  67. package/dist/transport/msg-transmitter.js.map +1 -1
  68. package/dist/transport/session/a-session-msg-factory.d.ts +1 -1
  69. package/dist/transport/session/a-session-msg-factory.js.map +1 -1
  70. package/dist/transport/session/fix-clock.d.ts +6 -0
  71. package/dist/transport/session/fix-clock.js +10 -0
  72. package/dist/transport/session/fix-clock.js.map +1 -0
  73. package/dist/transport/session/fix-session.d.ts +1 -0
  74. package/dist/transport/session/fix-session.js +43 -1
  75. package/dist/transport/session/fix-session.js.map +1 -1
  76. package/dist/transport/session/index.d.ts +4 -0
  77. package/dist/transport/session/index.js +4 -0
  78. package/dist/transport/session/index.js.map +1 -1
  79. package/dist/transport/session/resend-request-manager.d.ts +69 -0
  80. package/dist/transport/session/resend-request-manager.js +208 -0
  81. package/dist/transport/session/resend-request-manager.js.map +1 -0
  82. package/dist/transport/session/session-msg-factory.d.ts +1 -1
  83. package/dist/transport/session/session-msg-factory.js.map +1 -1
  84. package/dist/transport/session/session-sequence-coordinator.d.ts +38 -0
  85. package/dist/transport/session/session-sequence-coordinator.js +180 -0
  86. package/dist/transport/session/session-sequence-coordinator.js.map +1 -0
  87. package/dist/transport/session/session-sequence-store.d.ts +14 -0
  88. package/dist/transport/session/session-sequence-store.js +36 -0
  89. package/dist/transport/session/session-sequence-store.js.map +1 -0
  90. package/dist/transport/tcp/tcp-acceptor.js.map +1 -1
  91. package/dist/transport/tcp/tcp-initiator.js +34 -1
  92. package/dist/transport/tcp/tcp-initiator.js.map +1 -1
  93. package/dist/types/FIX4.4/index.js +1 -0
  94. package/dist/util/buffer-helper.js +34 -1
  95. package/dist/util/buffer-helper.js.map +1 -1
  96. package/dist/util/definition-factory.js +35 -2
  97. package/dist/util/definition-factory.js.map +1 -1
  98. package/jsfix.test_client.txt +67 -66
  99. package/jsfix.test_server.txt +64 -63
  100. package/package.json +11 -10
  101. package/src/buffer/ascii/ascii-parser-state.ts +4 -7
  102. package/src/buffer/ascii/ascii-parser.ts +14 -3
  103. package/src/buffer/fixml/fixml-view.ts +1 -1
  104. package/src/buffer/msg-view.ts +1 -1
  105. package/src/config/winston-logger.ts +3 -3
  106. package/src/dictionary/contained/contained-field-set.ts +2 -1
  107. package/src/dictionary/parser/fixml/fields-parser.ts +2 -2
  108. package/src/jsfix-cmd.ts +1 -1
  109. package/src/store/fix-msg-ascii-store-resend.ts +1 -1
  110. package/src/transport/ascii/ascii-session.ts +166 -5
  111. package/src/transport/fixml/fixml-msg-transmitter.ts +1 -1
  112. package/src/transport/http/http-acceptor.ts +1 -1
  113. package/src/transport/session/a-session-msg-factory.ts +1 -1
  114. package/src/transport/session/fix-clock.ts +9 -0
  115. package/src/transport/session/fix-session.ts +12 -0
  116. package/src/transport/session/index.ts +4 -0
  117. package/src/transport/session/resend-request-manager.ts +268 -0
  118. package/src/transport/session/session-msg-factory.ts +1 -1
  119. package/src/transport/session/session-sequence-coordinator.ts +272 -0
  120. package/src/transport/session/session-sequence-store.ts +33 -0
  121. package/src/transport/tcp/tcp-acceptor.ts +2 -2
package/BACKPORT_PLAN.md CHANGED
@@ -97,31 +97,60 @@ Also resets transient coordinator state (logon retry count, timeout recovery att
97
97
 
98
98
  The TS version has sequence state scattered across `fix-session-state.ts` and `ascii-session.ts` with no single source of truth. This makes it hard to reason about recovery, reset, and reconnect behaviour. The C# version centralises all of this.
99
99
 
100
- ### C# Solution
100
+ ### Delivery: 3 PRs
101
101
 
102
- | File | Purpose |
103
- |------|---------|
104
- | `PureFix.Transport/Session/SessionSequenceCoordinator.cs` | Single source of truth for sender/target sequences |
102
+ #### PR 3A: Coordinator + Minimal Interfaces (new files only, zero risk)
105
103
 
106
- **Key capabilities missing from TS:**
104
+ | File | Action |
105
+ |------|--------|
106
+ | New: `src/transport/session/session-sequence-coordinator.ts` | Port from `SessionSequenceCoordinator.cs` — single source of truth for sender/target sequences, logon retry, timeout recovery |
107
+ | New: `src/transport/session/session-sequence-store.ts` | Minimal `ISessionSequenceStore` interface (senderSeqNum, targetSeqNum, setSenderSeqNum, setTargetSeqNum, reset) |
108
+ | New: `src/transport/session/fix-clock.ts` | `IFixClock` interface (just `now(): Date`) |
109
+ | New: `src/transport/session/resend-manager-config.ts` | Config options with defaults |
110
+ | New: `src/test/session/session-sequence-coordinator.test.ts` | ~20 unit tests: init, sender/target tracking, gap detection, reset, logon retry, timeout recovery |
107
111
 
108
- - `PrepareForReconnect()` — resets transient state, preserves sequences
109
- - `HandlePeerReset()` — coordinates ResetSeqNumFlag=Y from peer
110
- - `ResetAsAcceptor()` — acceptor-initiated reset
111
- - `PossDupFlag` handling — messages with PossDupFlag=Y bypass normal sequence checks
112
- - Logon retry with `MaxLogonRetries=100`
113
- - Timeout recovery with `MaxTimeoutRecoveryAttempts=3` (handles sleep/wake scenarios)
114
- - `ResendRequestManager` integration — storm protection, pending request tracking
115
- - Delayed message acceptance — out-of-order messages that fill pending gap ranges
112
+ **Key design:** No threading in TS (unlike C# locks), so coordinator is plain synchronous code. Async only for store calls. The `ISessionSequenceStore` interface is intentionally minimal both `FixMsgMemoryStore` (adapted) and future `IFixSessionStore` will implement it.
116
113
 
117
- ### TS Files to Modify
114
+ #### PR 3B: ResendRequestManager (new files only, zero risk)
118
115
 
119
- | File | Change |
116
+ | File | Action |
120
117
  |------|--------|
121
- | New: `src/transport/session/session-sequence-coordinator.ts` | Port coordinator |
122
- | `src/transport/session/fix-session.ts` | Integrate coordinator as sequence authority |
123
- | `src/transport/ascii/ascii-session.ts` | Replace inline sequence logic with coordinator calls |
124
- | `src/transport/session/fix-session-state.ts` | May reduce scope coordinator takes over sequence tracking |
118
+ | New: `src/transport/session/resend-request-manager.ts` | Port `ResendRequestManager`, `PendingResendRange`, `ResendAction`, `ResendActionType` |
119
+ | New: `src/test/session/resend-request-manager.test.ts` | ~10 unit tests: storm protection, pending tracking, overlap detection, timeout cleanup |
120
+
121
+ PRs 3A and 3B can be done **in parallel** no dependencies between them.
122
+
123
+ #### PR 3C: Integrate coordinator into AsciiSession — pure refactor (HIGH RISK)
124
+
125
+ **Approach:** Same behaviour, same tests pass, just routing through the coordinator. No new features.
126
+ This makes it reviewable and safe despite touching `checkSeqNo`.
127
+
128
+ | File | Action |
129
+ |------|--------|
130
+ | `src/transport/ascii/ascii-session.ts` | Refactor `checkSeqNo` to delegate to coordinator; `onSessionMsg` SequenceReset uses `coordinator.onGapFillReceived()`; `sendResendRequest` uses coordinator gap detection + `recordResendRequestSent()`; `tick` TerminateOnError uses `coordinator.incrementTimeoutRecovery()`; `peerLogon` calls `coordinator.resetLogonRetryCount()` |
131
+ | `src/transport/session/fix-session.ts` | Add coordinator as member |
132
+ | `src/transport/session/fix-session-state.ts` | `lastPeerMsgSeqNum` becomes pass-through getter/setter to coordinator (backward compat) |
133
+ | `src/config/js-fix-config.ts` | Add optional `IFixClock` |
134
+
135
+ **Risk areas:**
136
+ - `checkSeqNo` is the core message acceptance path — any mistake breaks all session tests
137
+ - `FixSessionState.lastPeerMsgSeqNum` is read by tests directly — must remain as pass-through
138
+ - `AsciiMsgTransmitter.msgSeqNum` owns outgoing sequence — leave as-is for now, keep coordinator in sync
139
+
140
+ **Validation:** All existing tests must pass with zero changes.
141
+
142
+ #### PR 3D: New coordinator capabilities (MEDIUM RISK)
143
+
144
+ Add new features that the C# version has, one at a time with new tests for each:
145
+
146
+ | Feature | Method | What it does |
147
+ |---------|--------|-------------|
148
+ | **Logon retry** | `handleLogonRejected()` | Uses `coordinator.onLogonRejectedForSequence()` — retries failed logons when sequence numbers mismatch |
149
+ | **PossDupFlag handling** | in `checkSeqNo` | Messages with PossDupFlag=Y bypass normal sequence checks — they are replays we may have already seen |
150
+ | **ResetSeqNumFlag coordination** | in `peerLogon` | Comprehensive reset handling: `coordinator.handlePeerReset()` when peer sends reset, `coordinator.resetAsAcceptor()` when we initiate |
151
+ | **PrepareForReconnect** | new method | Calls `coordinator.prepareForReconnect()` to reset transient state while preserving sequences |
152
+
153
+ Each capability has a clear C# reference implementation and can be tested independently.
125
154
 
126
155
  ---
127
156
 
@@ -133,65 +162,109 @@ The TS version has sequence state scattered across `fix-session-state.ts` and `a
133
162
 
134
163
  The TS version only has `FixMsgMemoryStore` — all message history and sequence state is lost on process restart. The C# version has a QuickFix-compatible file store that persists across restarts.
135
164
 
136
- ### C# Solution
165
+ ### Delivery: 4 PRs
137
166
 
138
- | File | Purpose |
139
- |------|---------|
140
- | `PureFix.Transport/Store/IFixSessionStore.cs` | Unified persistence interface |
141
- | `PureFix.Transport/Store/FileSessionStore.cs` | QuickFix-compatible file storage |
142
- | `PureFix.Transport/Store/MemorySessionStore.cs` | In-memory implementation |
143
- | `PureFix.Transport/Store/FileSessionStoreFactory.cs` | Factory pattern for store creation |
144
- | `PureFix.Transport/Store/FixMsgStoreRecord.cs` | Persisted message record |
145
-
146
- **QuickFix file format:**
147
- - `.seqnums` — 20-char padded sender:target sequence numbers
148
- - `.session` — creation timestamp
149
- - `.header` — seqnum,offset,length index
150
- - `.body` — raw FIX message bytes
151
-
152
- ### Key Integration Points
153
-
154
- - `StoreEncodedMessage()` — persist every sent message
155
- - `InitializeSessionStore()` — load state on startup
156
- - Store factory in config — deferred creation
157
- - Store reset on `ResetSeqNumFlag=Y`
158
- - Resender recreation after reset
167
+ #### PR 4A: IFixSessionStore interface + MemorySessionStore (new files only, zero risk)
159
168
 
160
- ### TS Files to Modify
169
+ | File | Action |
170
+ |------|--------|
171
+ | New: `src/store/fix-session-store.ts` | Port `IFixSessionStore` — unified interface combining message storage and sequence management |
172
+ | New: `src/store/session-id.ts` | Port `SessionId` record |
173
+ | New: `src/store/memory-session-store.ts` | Port `MemorySessionStore` implementing `IFixSessionStore` |
174
+ | New: `src/store/fix-session-store-factory.ts` | `IFixSessionStoreFactory`, `MemorySessionStoreFactory` |
175
+ | New: `src/test/store/memory-session-store.test.ts` | ~10 unit tests |
161
176
 
162
- | File | Change |
177
+ Old `IFixMsgStore` and `FixMsgMemoryStore` remain untouched.
178
+
179
+ #### PR 4B: Stream Providers for file I/O (new files only, zero risk)
180
+
181
+ | File | Action |
163
182
  |------|--------|
164
- | New: `src/store/fix-session-store.ts` | Port IFixSessionStore interface |
165
- | New: `src/store/file-session-store.ts` | Port FileSessionStore |
166
- | New: `src/store/file-session-store-factory.ts` | Port factory |
167
- | `src/store/fix-msg-memory-store.ts` | Align with IFixSessionStore interface |
168
- | `src/transport/ascii/ascii-session.ts` | Integrate store lifecycle |
169
- | `src/config/js-fix-config.ts` | Add SessionStoreFactory to config |
183
+ | New: `src/store/session-stream-provider.ts` | `ISessionStreamProvider` interface — adapted for Node.js `fs.promises` |
184
+ | New: `src/store/file-session-stream-provider.ts` | Node.js file implementation using `fs.open()` for random-access read/write |
185
+ | New: `src/store/memory-session-stream-provider.ts` | In-memory implementation for testing |
186
+ | New: `src/test/store/memory-session-stream-provider.test.ts` | ~5 tests |
187
+
188
+ PRs 4A and 4B can be done **in parallel**.
189
+
190
+ #### PR 4C: FileSessionStore (new files only, low risk)
191
+
192
+ | File | Action |
193
+ |------|--------|
194
+ | New: `src/store/file-session-store.ts` | Port QuickFix-compatible file store (`.seqnums`, `.session`, `.header`, `.body` files) |
195
+ | New: `src/store/file-session-store-factory.ts` | `FileSessionStoreFactory` |
196
+ | New: `src/test/store/file-session-store.test.ts` | ~10 tests (using MemorySessionStreamProvider + 1 integration test with real files) |
197
+
198
+ Depends on 4A + 4B.
199
+
200
+ #### PR 4D: Wire store into AsciiSession (medium risk)
201
+
202
+ | File | Action |
203
+ |------|--------|
204
+ | `src/config/js-fix-config.ts` | Add optional `sessionStoreFactory?: IFixSessionStoreFactory` |
205
+ | `src/transport/ascii/ascii-session.ts` | Create store from factory; store messages on `txOnEncoded` |
206
+ | `src/store/fix-msg-ascii-store-resend.ts` | Accept `IFixSessionStore` (add overload, keep old constructor) |
207
+ | `src/store/index.ts` | Export new types |
208
+
209
+ **Risk area:** Storing messages in the send path — must handle store errors gracefully (log and continue, never block sends).
210
+
211
+ **Validation:** All existing tests pass (default MemorySessionStoreFactory is the fallback).
170
212
 
171
213
  ---
172
214
 
173
215
  ## Phase 5: Resend Request Improvements
174
216
 
175
- **Priority: Medium | Risk: Low-Medium | Scope: Small**
217
+ **Priority: Medium | Risk: Low | Scope: Small**
176
218
 
177
- ### Problem
219
+ ### Delivery: 2 PRs
178
220
 
179
- The TS version sends a simple ResendRequest on gap detection with no protection against request storms or tracking of pending requests.
221
+ #### PR 5A: Storm protection wiring (low risk)
180
222
 
181
- ### C# Solution
223
+ | File | Action |
224
+ |------|--------|
225
+ | `src/transport/ascii/ascii-session.ts` | Use `ResendAction` from coordinator to decide between sending ResendRequest, waiting, or gap-filling |
226
+ | New: `src/test/session/resend-storm-protection.test.ts` | ~5 tests |
182
227
 
183
- `ResendRequestManager` in the coordinator provides:
184
- - Pending request tracking (`PendingResendRequests` collection)
185
- - Storm protection — after N requests without response, accepts the gap
186
- - Delayed message detection — clears pending requests when gap-filling messages arrive
187
- - `ResendGapFillOnly` mode — sends GapFill instead of replaying stored messages (prevents duplicate executions)
228
+ Mostly already done if 3A-3C are complete — this PR wires the `ResendActionType` responses into session control flow.
188
229
 
189
- ### TS Files to Modify
230
+ #### PR 5B: ResendGapFillOnly mode (zero risk, independent)
190
231
 
191
- | File | Change |
232
+ | File | Action |
192
233
  |------|--------|
193
- | New: `src/transport/session/resend-request-manager.ts` | Port manager |
194
- | `src/transport/ascii/ascii-session.ts` | Integrate with gap detection |
234
+ | `src/config/js-fix-config.ts` | Add optional `resendGapFillOnly?: boolean` |
235
+ | `src/store/fix-msg-ascii-store-resend.ts` | Early return path when enabled — always GapFill instead of replaying |
236
+ | New: `src/test/store/resend-gap-fill-only.test.ts` | ~3 tests |
237
+
238
+ Can be done at **any time** — independent of all other PRs.
239
+
240
+ ---
241
+
242
+ ## Dependency Graph
243
+
244
+ ```
245
+ PR 3A (Coordinator) ────────────┐
246
+ ├─→ PR 3C (Pure refactor) ──→ PR 3D (New capabilities) ──→ PR 5A (Storm wiring)
247
+ PR 3B (ResendRequestManager) ──┘
248
+
249
+ PR 4A (IFixSessionStore) ──────┐
250
+ ├─→ PR 4C (FileSessionStore) ──→ PR 4D (Wire into session)
251
+ PR 4B (StreamProviders) ───────┘
252
+
253
+ PR 5B (ResendGapFillOnly) ──── independent, can be done anytime
254
+ ```
255
+
256
+ ## Risk Summary
257
+
258
+ | PR | Risk | Reason |
259
+ |----|------|--------|
260
+ | 3A, 3B | None | New files only — **DONE** |
261
+ | 3C | HIGH | Refactors `checkSeqNo` — pure refactor, same behaviour, but core message path — **DONE** |
262
+ | 3D | Medium | Adds new capabilities (logon retry, PossDupFlag, ResetSeqNum, timeout recovery) — **DONE** |
263
+ | 4A, 4B | None | New files only |
264
+ | 4C | Low | New file, tested with mocks |
265
+ | 4D | Medium | Changes send path, store errors must not block sends |
266
+ | 5A | Low | Wiring only, coordinator makes decisions |
267
+ | 5B | None | Additive config option |
195
268
 
196
269
  ---
197
270
 
package/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # jspurefix
2
2
 
3
- [![Build status](https://ci.appveyor.com/api/projects/status/2w2eag4trnijg5d3?svg=true)](https://ci.appveyor.com/project/TimelordUK/jsfix)
4
- [![Build Status](https://travis-ci.org/TimelordUK/jspurefix.svg?branch=master)](https://travis-ci.org/TimelordUK/jspurefix)
3
+ [![CI](https://github.com/TimelordUK/jspurefix/actions/workflows/ci.yml/badge.svg)](https://github.com/TimelordUK/jspurefix/actions/workflows/ci.yml)
5
4
  [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
6
5
 
7
6
  ## C# Port Available
@@ -73,7 +73,6 @@ let AsciiParserState = class AsciiParserState {
73
73
  const tag = this.currentTag;
74
74
  const locations = this.locations;
75
75
  const buffer = this.elasticBuffer;
76
- const terminates = this.checksumExpectedPos;
77
76
  switch (this.parseState) {
78
77
  case parse_state_1.ParseState.ParsingValue:
79
78
  case parse_state_1.ParseState.ParsingRawData: {
@@ -115,16 +114,10 @@ let AsciiParserState = class AsciiParserState {
115
114
  break;
116
115
  }
117
116
  case tags_1.Tags.CheckSumTag: {
118
- if (valueEndPos < this.bodyLen) {
119
- throw new Error(`CheckSumTag: [${valueEndPos}] expected after ${this.bodyLen}`);
120
- }
121
117
  this.parseState = parse_state_1.ParseState.MsgComplete;
122
118
  break;
123
119
  }
124
120
  default: {
125
- if (terminates && valueEndPos > terminates) {
126
- throw new Error(`Tag: [${tag}] cant be after ${terminates}`);
127
- }
128
121
  break;
129
122
  }
130
123
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ascii-parser-state.js","sourceRoot":"","sources":["../../../src/buffer/ascii/ascii-parser-state.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,sCAAkC;AAElC,sDAAiD;AACjD,+CAA0C;AAC1C,uCAA6C;AAC7C,uDAAkD;AAG3C,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;IAgB3B,YAA2D,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IACvF,CAAC;IAEM,QAAQ,CAAE,GAAW;QAC1B,IAAI,CAAC,UAAU,GAAG,wBAAU,CAAC,UAAU,CAAA;QACvC,IAAI,CAAC,WAAW,GAAG,GAAG,CAAA;QACtB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,CAAA;QACrC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAA;IACrB,CAAC;IAEM,MAAM,CAAE,GAAW;QACxB,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAA;QACnB,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAA;QAC7B,QAAQ,KAAK,EAAE,CAAC;YACd,KAAK,wBAAU,CAAC,UAAU,CAAC,CAAC,CAAC;gBAC3B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,CAAC,CAAA;gBAC9E,MAAK;YACP,CAAC;YAED;gBACE,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,EAAE,CAAC,CAAA;QACxD,CAAC;QAED,IAAI,CAAC,WAAW,EAAE,CAAA;IACpB,CAAC;IAEM,MAAM;QACX,EAAE,IAAI,CAAC,WAAW,CAAA;QAClB,OAAO,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,UAAU,GAAG,CAAC,CAAA;IACjD,CAAC;IAEM,WAAW;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAA;QACxB,IAAI,CAAC,CAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,WAAW,CAAA,EAAE,CAAC;YAEtB,IAAI,CAAC,UAAU,GAAG,wBAAU,CAAC,YAAY,CAAA;YACzC,OAAM;QACR,CAAC;QAGD,MAAM,YAAY,GAAY,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAClE,IAAI,YAAY,EAAE,CAAC;YACjB,IAAI,CAAC,UAAU,GAAG,wBAAU,CAAC,oBAAoB,CAAA;QACnD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,WAAW,GAAG,CAAC,CAAA;YACpB,MAAM,MAAM,GAAY,IAAI,CAAC,UAAU,GAAG,CAAC,CAAA;YAC3C,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,UAAU,GAAG,wBAAU,CAAC,cAAc,CAAA;YAC7C,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,UAAU,GAAG,wBAAU,CAAC,YAAY,CAAA;YAC3C,CAAC;QACH,CAAC;IACH,CAAC;IAEM,KAAK;QACV,MAAM,WAAW,GAAW,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;QAC3D,IAAI,CAAC,WAAW,GAAG,WAAW,CAAA;QAC9B,MAAM,QAAQ,GAAW,IAAI,CAAC,QAAQ,CAAA;QACtC,MAAM,GAAG,GAAW,IAAI,CAAC,UAAU,CAAA;QACnC,MAAM,SAAS,GAAS,IAAI,CAAC,SAAS,CAAA;QACtC,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAA;QACjC,MAAM,UAAU,GAAG,IAAI,CAAC,mBAAmB,CAAA;QAE3C,QAAQ,IAAI,CAAC,UAAU,EAAE,CAAC;YACxB,KAAK,wBAAU,CAAC,YAAY,CAAC;YAC7B,KAAK,wBAAU,CAAC,cAAc,CAAC,CAAC,CAAC;gBAC/B,IAAI,CAAC,UAAU,GAAG,CAAC,CAAA;gBACnB,SAAS,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE,WAAW,GAAG,QAAQ,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;gBAC9D,MAAK;YACP,CAAC;YAED,KAAK,wBAAU,CAAC,oBAAoB,CAAC,CAAC,CAAC;gBACrC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,cAAc,CAAC,QAAQ,GAAG,CAAC,EAAE,WAAW,GAAG,CAAC,CAAC,CAAA;gBACtE,SAAS,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE,WAAW,GAAG,QAAQ,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;gBAC9D,MAAK;YACP,CAAC;QACH,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,wBAAU,CAAC,UAAU,CAAA;QACvC,IAAI,CAAC,KAAK,EAAE,CAAA;QACZ,MAAM,UAAU,GAAG,SAAS,CAAC,UAAU,CAAA;QAEvC,QAAQ,GAAG,EAAE,CAAC;YACZ,KAAK,WAAI,CAAC,WAAW,CAAC,CAAC,CAAC;gBACtB,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;oBACrB,MAAM,IAAI,KAAK,CAAC,0CAA0C,UAAU,GAAG,CAAC,CAAA;gBAC1E,CAAC;gBACD,MAAK;YACP,CAAC;YAED,KAAK,WAAI,CAAC,aAAa,CAAC,CAAC,CAAC;gBACxB,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;oBACrB,MAAM,IAAI,KAAK,CAAC,4CAA4C,UAAU,GAAG,CAAC,CAAA;gBAC5E,CAAC;gBACD,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,cAAc,CAAC,QAAQ,GAAG,CAAC,EAAE,WAAW,GAAG,CAAC,CAAC,CAAA;gBACnE,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,OAAO,GAAG,WAAW,CAAA;gBACrD,IAAI,CAAC,aAAa,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;gBAChD,MAAK;YACP,CAAC;YAED,KAAK,WAAI,CAAC,MAAM,CAAC,CAAC,CAAC;gBACjB,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;oBACrB,MAAM,IAAI,KAAK,CAAC,qCAAqC,UAAU,GAAG,CAAC,CAAA;gBACrE,CAAC;gBACD,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,GAAG,CAAC,EAAE,WAAW,CAAC,CAAA;gBAC1D,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;gBACzD,MAAK;YACP,CAAC;YAED,KAAK,WAAI,CAAC,WAAW,CAAC,CAAC,CAAC;gBACtB,IAAI,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;oBAC/B,MAAM,IAAI,KAAK,CAAC,iBAAiB,WAAW,oBAAoB,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;gBACjF,CAAC;gBACD,IAAI,CAAC,UAAU,GAAG,wBAAU,CAAC,WAAW,CAAA;gBACxC,MAAK;YACP,CAAC;YAED,OAAO,CAAC,CAAC,CAAC;gBACR,IAAI,UAAU,IAAI,WAAW,GAAG,UAAU,EAAE,CAAC;oBAC3C,MAAM,IAAI,KAAK,CAAC,SAAS,GAAG,mBAAmB,UAAU,EAAE,CAAC,CAAA;gBAC9D,CAAC;gBACD,MAAK;YACP,CAAC;QACH,CAAC;QAED,QAAQ,UAAU,EAAE,CAAC;YACnB,KAAK,CAAC,CAAC,CAAC,CAAC;gBACP,IAAI,GAAG,KAAK,WAAI,CAAC,WAAW,EAAE,CAAC;oBAC7B,MAAM,IAAI,KAAK,CAAC,eAAe,GAAG,2BAA2B,CAAC,CAAA;gBAChE,CAAC;gBACD,MAAK;YACP,CAAC;YACD,KAAK,CAAC,CAAC,CAAC,CAAC;gBACP,IAAI,GAAG,KAAK,WAAI,CAAC,aAAa,EAAE,CAAC;oBAC/B,MAAM,IAAI,KAAK,CAAC,eAAe,GAAG,6BAA6B,CAAC,CAAA;gBAClE,CAAC;gBACD,MAAK;YACP,CAAC;YACD,KAAK,CAAC,CAAC,CAAC,CAAC;gBACP,IAAI,GAAG,KAAK,WAAI,CAAC,MAAM,EAAE,CAAC;oBACxB,MAAM,IAAI,KAAK,CAAC,eAAe,GAAG,uBAAuB,CAAC,CAAA;gBAC5D,CAAC;gBACD,MAAK;YACP,CAAC;QACH,CAAC;IACH,CAAC;IAEM,YAAY;QACjB,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAA;QAC1B,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAA;QACtB,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAA;QAC5B,IAAI,CAAC,UAAU,GAAG,wBAAU,CAAC,UAAU,CAAA;QACvC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAA;QACd,IAAI,CAAC,UAAU,GAAG,CAAC,CAAA;QACnB,IAAI,CAAC,WAAW,GAAG,CAAC,CAAA;QACpB,IAAI,CAAC,WAAW,GAAG,CAAC,CAAA;QACpB,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAA;QACjB,IAAI,CAAC,WAAW,GAAG,CAAC,CAAA;QACpB,IAAI,CAAC,UAAU,GAAG,CAAC,CAAA;QACnB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAA;QAChB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;IACrB,CAAC;CACF,CAAA;AAlLY,4CAAgB;2BAAhB,gBAAgB;IAD5B,IAAA,qBAAU,GAAE;IAiBG,WAAA,IAAA,iBAAM,EAAC,oBAAQ,CAAC,WAAW,CAAC,CAAA;qCAAgC,8BAAa;GAhB5E,gBAAgB,CAkL5B","sourcesContent":["import { Tags } from '../tag/tags'\nimport { FixDefinitions, MessageDefinition } from '../../dictionary/definition'\nimport { ElasticBuffer } from '../elastic-buffer'\nimport { ParseState } from './parse-state'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\n\n@injectable()\nexport class AsciiParserState {\n public message: MessageDefinition | undefined\n public locations: Tags\n public parseState: ParseState\n public bodyLen: number\n public checksumExpectedPos: number\n public tagStartPos: number\n public equalPos: number\n public valueEndPos: number\n public count: number\n public currentTag: number\n public rawDataLen: number\n public rawDataRead: number\n public definitions: FixDefinitions\n public msgType: string | null\n\n constructor (@inject(DITokens.ParseBuffer) public readonly elasticBuffer: ElasticBuffer) {\n }\n\n public beginTag (pos: number): void {\n this.parseState = ParseState.ParsingTag\n this.tagStartPos = pos\n this.equalPos = this.valueEndPos = -1\n this.currentTag = 0\n }\n\n public endTag (pos: number): void {\n this.equalPos = pos\n const state = this.parseState\n switch (state) {\n case ParseState.ParsingTag: {\n this.currentTag = this.elasticBuffer.getWholeNumber(this.tagStartPos, pos - 1)\n break\n }\n\n default:\n throw new Error(`EndTag: unexpected state ${state}`)\n }\n // if a raw tag, then need length to skip that many bytes\n this.checkRawTag()\n }\n\n public incRaw (): boolean {\n ++this.rawDataRead\n return this.rawDataRead === this.rawDataLen + 1\n }\n\n public checkRawTag (): void {\n const msg = this.message\n if (!msg?.containsRaw) {\n // optimisation as will never hit raw data\n this.parseState = ParseState.ParsingValue\n return\n }\n // if this is a raw data tag then need to keep track of the length\n // on this field to skip that many bytes.\n const isDataLength: boolean = msg.containedLength[this.currentTag]\n if (isDataLength) {\n this.parseState = ParseState.ParsingRawDataLength\n } else {\n this.rawDataRead = 0\n const isData: boolean = this.rawDataLen > 0\n if (isData) {\n this.parseState = ParseState.ParsingRawData\n } else {\n this.parseState = ParseState.ParsingValue\n }\n }\n }\n\n public store (): void {\n const valueEndPos: number = this.elasticBuffer.getPos() - 1\n this.valueEndPos = valueEndPos\n const equalPos: number = this.equalPos\n const tag: number = this.currentTag\n const locations: Tags = this.locations\n const buffer = this.elasticBuffer\n const terminates = this.checksumExpectedPos\n\n switch (this.parseState) {\n case ParseState.ParsingValue:\n case ParseState.ParsingRawData: {\n this.rawDataLen = 0\n locations.store(equalPos + 1, valueEndPos - equalPos - 1, tag)\n break\n }\n\n case ParseState.ParsingRawDataLength: {\n this.rawDataLen = buffer.getWholeNumber(equalPos + 1, valueEndPos - 1)\n locations.store(equalPos + 1, valueEndPos - equalPos - 1, tag)\n break\n }\n }\n\n this.parseState = ParseState.BeginField\n this.count++\n const nextTagPos = locations.nextTagPos\n\n switch (tag) {\n case Tags.BeginString: {\n if (nextTagPos !== 1) {\n throw new Error(`BeginString: not expected at position [${nextTagPos}]`)\n }\n break\n }\n\n case Tags.BodyLengthTag: {\n if (nextTagPos !== 2) {\n throw new Error(`BodyLengthTag: not expected at position [${nextTagPos}]`)\n }\n this.bodyLen = buffer.getWholeNumber(equalPos + 1, valueEndPos - 1)\n this.checksumExpectedPos = this.bodyLen + valueEndPos\n this.elasticBuffer.checkGrowBuffer(this.bodyLen)\n break\n }\n\n case Tags.MsgTag: {\n if (nextTagPos !== 3) {\n throw new Error(`MsgTag: not expected at position [${nextTagPos}]`)\n }\n this.msgType = buffer.getString(equalPos + 1, valueEndPos)\n this.message = this.definitions.message.get(this.msgType)\n break\n }\n\n case Tags.CheckSumTag: {\n if (valueEndPos < this.bodyLen) {\n throw new Error(`CheckSumTag: [${valueEndPos}] expected after ${this.bodyLen}`)\n }\n this.parseState = ParseState.MsgComplete\n break\n }\n\n default: {\n if (terminates && valueEndPos > terminates) {\n throw new Error(`Tag: [${tag}] cant be after ${terminates}`)\n }\n break\n }\n }\n\n switch (nextTagPos) {\n case 1: {\n if (tag !== Tags.BeginString) {\n throw new Error(`position 1 [${tag}] must be BeginString: 8=`)\n }\n break\n }\n case 2: {\n if (tag !== Tags.BodyLengthTag) {\n throw new Error(`position 2 [${tag}] must be BodyLengthTag: 9=`)\n }\n break\n }\n case 3: {\n if (tag !== Tags.MsgTag) {\n throw new Error(`position 3 [${tag}] must be MsgTag: 35=`)\n }\n break\n }\n }\n }\n\n public beginMessage (): void {\n this.elasticBuffer.reset()\n this.locations.reset()\n this.checksumExpectedPos = 0\n this.parseState = ParseState.BeginField\n this.count = 0\n this.currentTag = 0\n this.tagStartPos = 0\n this.valueEndPos = 0\n this.equalPos = 0\n this.rawDataRead = 0\n this.rawDataLen = 0\n this.bodyLen = 0\n this.msgType = null\n }\n}\n"]}
1
+ {"version":3,"file":"ascii-parser-state.js","sourceRoot":"","sources":["../../../src/buffer/ascii/ascii-parser-state.ts"],"names":[],"mappings":"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","sourcesContent":["import { Tags } from '../tag/tags'\nimport { FixDefinitions, MessageDefinition } from '../../dictionary/definition'\nimport { ElasticBuffer } from '../elastic-buffer'\nimport { ParseState } from './parse-state'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\n\n@injectable()\nexport class AsciiParserState {\n public message: MessageDefinition | undefined\n public locations: Tags\n public parseState: ParseState\n public bodyLen: number\n public checksumExpectedPos: number\n public tagStartPos: number\n public equalPos: number\n public valueEndPos: number\n public count: number\n public currentTag: number\n public rawDataLen: number\n public rawDataRead: number\n public definitions: FixDefinitions\n public msgType: string | null\n\n constructor (@inject(DITokens.ParseBuffer) public readonly elasticBuffer: ElasticBuffer) {\n }\n\n public beginTag (pos: number): void {\n this.parseState = ParseState.ParsingTag\n this.tagStartPos = pos\n this.equalPos = this.valueEndPos = -1\n this.currentTag = 0\n }\n\n public endTag (pos: number): void {\n this.equalPos = pos\n const state = this.parseState\n switch (state) {\n case ParseState.ParsingTag: {\n this.currentTag = this.elasticBuffer.getWholeNumber(this.tagStartPos, pos - 1)\n break\n }\n\n default:\n throw new Error(`EndTag: unexpected state ${state}`)\n }\n // if a raw tag, then need length to skip that many bytes\n this.checkRawTag()\n }\n\n public incRaw (): boolean {\n ++this.rawDataRead\n return this.rawDataRead === this.rawDataLen + 1\n }\n\n public checkRawTag (): void {\n const msg = this.message\n if (!msg?.containsRaw) {\n // optimisation as will never hit raw data\n this.parseState = ParseState.ParsingValue\n return\n }\n // if this is a raw data tag then need to keep track of the length\n // on this field to skip that many bytes.\n const isDataLength: boolean = msg.containedLength[this.currentTag]\n if (isDataLength) {\n this.parseState = ParseState.ParsingRawDataLength\n } else {\n this.rawDataRead = 0\n const isData: boolean = this.rawDataLen > 0\n if (isData) {\n this.parseState = ParseState.ParsingRawData\n } else {\n this.parseState = ParseState.ParsingValue\n }\n }\n }\n\n public store (): void {\n const valueEndPos: number = this.elasticBuffer.getPos() - 1\n this.valueEndPos = valueEndPos\n const equalPos: number = this.equalPos\n const tag: number = this.currentTag\n const locations: Tags = this.locations\n const buffer = this.elasticBuffer\n\n switch (this.parseState) {\n case ParseState.ParsingValue:\n case ParseState.ParsingRawData: {\n this.rawDataLen = 0\n locations.store(equalPos + 1, valueEndPos - equalPos - 1, tag)\n break\n }\n\n case ParseState.ParsingRawDataLength: {\n this.rawDataLen = buffer.getWholeNumber(equalPos + 1, valueEndPos - 1)\n locations.store(equalPos + 1, valueEndPos - equalPos - 1, tag)\n break\n }\n }\n\n this.parseState = ParseState.BeginField\n this.count++\n const nextTagPos = locations.nextTagPos\n\n switch (tag) {\n case Tags.BeginString: {\n if (nextTagPos !== 1) {\n throw new Error(`BeginString: not expected at position [${nextTagPos}]`)\n }\n break\n }\n\n case Tags.BodyLengthTag: {\n if (nextTagPos !== 2) {\n throw new Error(`BodyLengthTag: not expected at position [${nextTagPos}]`)\n }\n this.bodyLen = buffer.getWholeNumber(equalPos + 1, valueEndPos - 1)\n this.checksumExpectedPos = this.bodyLen + valueEndPos\n this.elasticBuffer.checkGrowBuffer(this.bodyLen)\n break\n }\n\n case Tags.MsgTag: {\n if (nextTagPos !== 3) {\n throw new Error(`MsgTag: not expected at position [${nextTagPos}]`)\n }\n this.msgType = buffer.getString(equalPos + 1, valueEndPos)\n this.message = this.definitions.message.get(this.msgType)\n break\n }\n\n case Tags.CheckSumTag: {\n // do not enforce body length constraint - manually edited messages\n // may have mismatched body length but are otherwise valid\n this.parseState = ParseState.MsgComplete\n break\n }\n\n default: {\n // do not enforce body length boundary - manually edited messages\n // may have fields added or modified beyond the original body length\n break\n }\n }\n\n switch (nextTagPos) {\n case 1: {\n if (tag !== Tags.BeginString) {\n throw new Error(`position 1 [${tag}] must be BeginString: 8=`)\n }\n break\n }\n case 2: {\n if (tag !== Tags.BodyLengthTag) {\n throw new Error(`position 2 [${tag}] must be BodyLengthTag: 9=`)\n }\n break\n }\n case 3: {\n if (tag !== Tags.MsgTag) {\n throw new Error(`position 3 [${tag}] must be MsgTag: 35=`)\n }\n break\n }\n }\n }\n\n public beginMessage (): void {\n this.elasticBuffer.reset()\n this.locations.reset()\n this.checksumExpectedPos = 0\n this.parseState = ParseState.BeginField\n this.count = 0\n this.currentTag = 0\n this.tagStartPos = 0\n this.valueEndPos = 0\n this.equalPos = 0\n this.rawDataRead = 0\n this.rawDataLen = 0\n this.bodyLen = 0\n this.msgType = null\n }\n}\n"]}
@@ -15,6 +15,7 @@ export declare class AsciiParser extends MsgParser {
15
15
  readonly writeDelimiter: number;
16
16
  constructor(config: IJsFixConfig, readStream: Readable | null, receivingBuffer: ElasticBuffer);
17
17
  private subscribe;
18
+ reset(): void;
18
19
  private msg;
19
20
  parseText(text: string): void;
20
21
  private parse;
@@ -75,6 +75,9 @@ let AsciiParser = AsciiParser_1 = class AsciiParser extends msg_parser_1.MsgPars
75
75
  this.emit('end');
76
76
  });
77
77
  }
78
+ reset() {
79
+ this.state.beginMessage();
80
+ }
78
81
  msg(ptr) {
79
82
  const receivingBuffer = this.receivingBuffer;
80
83
  const state = this.state;
@@ -128,9 +131,12 @@ let AsciiParser = AsciiParser_1 = class AsciiParser extends msg_parser_1.MsgPars
128
131
  }
129
132
  state.store();
130
133
  }
131
- else {
132
- throw new Error(`delimiter (${delimiter}) expected at position ${readPtr} when value is ${charAtPos}`);
134
+ }
135
+ else if (charAtPos === delimiter) {
136
+ if (switchDelimiter) {
137
+ receivingBuffer.switchChar(writeDelimiter);
133
138
  }
139
+ state.store();
134
140
  }
135
141
  break;
136
142
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ascii-parser.js","sourceRoot":"","sources":["../../../src/buffer/ascii/ascii-parser.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsciiChars } from './ascii-chars'\nimport { AsciiView } from './ascii-view'\nimport { AsciiSegmentParser } from './ascii-segment-parser'\nimport { AsciiParserState } from './ascii-parser-state'\nimport { Structure } from '../structure'\nimport { Tags } from '../tag/tags'\nimport { MsgParser } from '../msg-parser'\nimport { MsgView } from '../msg-view'\nimport { Readable } from 'stream'\nimport { ElasticBuffer } from '../elastic-buffer'\nimport { SegmentDescription } from '../segment/segment-description'\nimport { ParseState } from './parse-state'\nimport { IJsFixConfig } from '../../config/js-fix-config'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\nimport { SegmentType } from '../segment/segment-type'\nimport { AsciiParserError } from './ascii-segment-parser-error'\n\n@injectable()\nexport class AsciiParser extends MsgParser {\n private static nextId: number = 0\n public readonly id: number\n public readonly state: AsciiParserState\n private readonly segmentParser: AsciiSegmentParser\n public readonly delimiter: number\n public readonly writeDelimiter: number\n\n // allocate enough in receive buffer so buffer does not constant resize back after large messages\n // want to keep one slice of memory and constantly reuse it\n\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig,\n @inject(DITokens.readStream) public readonly readStream: Readable | null,\n @inject(DITokens.ParseBuffer) protected readonly receivingBuffer: ElasticBuffer) {\n super()\n\n this.delimiter = config.delimiter ?? AsciiChars.Soh\n this.writeDelimiter = config.logDelimiter ?? AsciiChars.Pipe\n this.id = AsciiParser.nextId++\n this.segmentParser = config.sessionContainer.resolve<AsciiSegmentParser>(AsciiSegmentParser)\n this.state = config.sessionContainer.resolve<AsciiParserState>(AsciiParserState)\n this.state.locations = new Tags(this.receivingBuffer.size / 10)\n this.state.definitions = this.config.definitions\n this.state.beginMessage()\n if (readStream !== null) {\n this.subscribe()\n }\n }\n\n private subscribe (): void {\n const inst: AsciiParser = this\n const Writable = require('stream').Writable\n const stream = this.readStream\n\n const receiver = new Writable({\n write: (data: Buffer, _: any, done: Function) => {\n try {\n inst.parse(data, data.length)\n done()\n } catch (e) {\n done(e)\n }\n }\n })\n receiver.on('error', (e: Error) => {\n this.emit('error', e)\n })\n\n // receive from say a socket or file and pipe to parser which discovers messages\n stream?.pipe(receiver).on('finish', () => {\n this.emit('done')\n })\n stream?.on('error', (e) => {\n this.emit('error', e)\n })\n stream?.on('end', () => {\n this.emit('end')\n })\n }\n\n private msg (ptr: number): void {\n const receivingBuffer: ElasticBuffer = this.receivingBuffer\n const state = this.state\n if (this.listeners('decoded')) {\n this.emit('decoded', state.msgType, receivingBuffer, ptr)\n }\n this.emit('msg', state.msgType, this.getView(ptr))\n state.beginMessage()\n }\n\n /**\n * useful helper for testing where characters are parsed as if from the transport\n * @param text to be parsed\n */\n public parseText (text: string): void {\n const buff = Buffer.from(text)\n this.parse(buff, buff.length)\n }\n\n private parse (readBuffer: Buffer, end: number): void {\n const state = this.state\n const eq: number = AsciiChars.Eq\n const zero: number = AsciiChars.Zero\n const nine: number = AsciiChars.Nine\n const delimiter: number = this.delimiter\n const writeDelimiter: number = this.writeDelimiter\n const receivingBuffer: ElasticBuffer = this.receivingBuffer\n const switchDelimiter = writeDelimiter !== delimiter\n let readPtr: number = 0\n\n while (readPtr < end) {\n const charAtPos: number = readBuffer[readPtr]\n\n const writePtr = receivingBuffer.saveChar(charAtPos) - 1\n switch (state.parseState) {\n case ParseState.MsgComplete: {\n this.msg(writePtr)\n continue\n }\n\n case ParseState.BeginField: {\n const atDigit: boolean = charAtPos >= zero && charAtPos <= nine\n if (atDigit) {\n state.beginTag(writePtr)\n }\n break\n }\n\n case ParseState.ParsingTag: {\n const isEquals: boolean = charAtPos === eq\n if (isEquals) {\n state.endTag(writePtr)\n }\n break\n }\n\n case ParseState.ParsingRawData: {\n // keep skipping until length read, regardless of delimiter or not\n if (state.incRaw()) {\n // having consumed the raw field expecting delimiter\n if (charAtPos === delimiter) {\n if (switchDelimiter) {\n receivingBuffer.switchChar(writeDelimiter)\n }\n state.store()\n } else {\n throw new Error(`delimiter (${delimiter}) expected at position ${readPtr} when value is ${charAtPos}`)\n }\n }\n break\n }\n\n case ParseState.ParsingRawDataLength:\n case ParseState.ParsingValue: {\n if (charAtPos === delimiter) {\n if (switchDelimiter) {\n receivingBuffer.switchChar(writeDelimiter)\n }\n state.store()\n }\n break\n }\n\n default: {\n const st = state.parseState\n throw new Error(`fix parser in unknown state ${st}`)\n }\n }\n readPtr++\n }\n\n switch (state.parseState) {\n case ParseState.MsgComplete: {\n this.msg(receivingBuffer.getPos())\n break\n }\n }\n }\n\n private getView (ptr: number): MsgView | null {\n const state = this.state\n const locations = state.locations\n const source = this.receivingBuffer\n const delimiter = this.delimiter\n const definitions = this.config.definitions\n const replace = this.writeDelimiter\n const msgType = state.msgType ?? null\n if (!msgType) return null\n if (state.message) {\n try {\n const structure: Structure | null = this.segmentParser.parse(msgType, locations,\n locations.nextTagPos - 1)\n if (!structure) return null\n return new AsciiView(definitions, structure.msg(),\n source,\n structure,\n ptr,\n delimiter,\n replace)\n } catch (error) {\n if (error instanceof AsciiParserError) {\n error.summary.buffer = source.toString()\n this.emit('error', error)\n }\n throw error\n }\n }\n\n const structure = new Structure(locations, [])\n const segment = new SegmentDescription('unknown', locations.tagPos[0].tag, null, 0, 1, SegmentType.Unknown)\n segment.endPosition = locations.nextTagPos - 1\n return new AsciiView(this.config.definitions, segment, source, structure, ptr, delimiter, replace)\n }\n}\n"]}
1
+ {"version":3,"file":"ascii-parser.js","sourceRoot":"","sources":["../../../src/buffer/ascii/ascii-parser.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsciiChars } from './ascii-chars'\nimport { AsciiView } from './ascii-view'\nimport { AsciiSegmentParser } from './ascii-segment-parser'\nimport { AsciiParserState } from './ascii-parser-state'\nimport { Structure } from '../structure'\nimport { Tags } from '../tag/tags'\nimport { MsgParser } from '../msg-parser'\nimport { MsgView } from '../msg-view'\nimport { Readable } from 'stream'\nimport { ElasticBuffer } from '../elastic-buffer'\nimport { SegmentDescription } from '../segment/segment-description'\nimport { ParseState } from './parse-state'\nimport { IJsFixConfig } from '../../config/js-fix-config'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\nimport { SegmentType } from '../segment/segment-type'\nimport { AsciiParserError } from './ascii-segment-parser-error'\n\n@injectable()\nexport class AsciiParser extends MsgParser {\n private static nextId: number = 0\n public readonly id: number\n public readonly state: AsciiParserState\n private readonly segmentParser: AsciiSegmentParser\n public readonly delimiter: number\n public readonly writeDelimiter: number\n\n // allocate enough in receive buffer so buffer does not constant resize back after large messages\n // want to keep one slice of memory and constantly reuse it\n\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig,\n @inject(DITokens.readStream) public readonly readStream: Readable | null,\n @inject(DITokens.ParseBuffer) protected readonly receivingBuffer: ElasticBuffer) {\n super()\n\n this.delimiter = config.delimiter ?? AsciiChars.Soh\n this.writeDelimiter = config.logDelimiter ?? AsciiChars.Pipe\n this.id = AsciiParser.nextId++\n this.segmentParser = config.sessionContainer.resolve<AsciiSegmentParser>(AsciiSegmentParser)\n this.state = config.sessionContainer.resolve<AsciiParserState>(AsciiParserState)\n this.state.locations = new Tags(this.receivingBuffer.size / 10)\n this.state.definitions = this.config.definitions\n this.state.beginMessage()\n if (readStream !== null) {\n this.subscribe()\n }\n }\n\n private subscribe (): void {\n const inst: AsciiParser = this\n const Writable = require('stream').Writable\n const stream = this.readStream\n\n const receiver = new Writable({\n write: (data: Buffer, _: any, done: Function) => {\n try {\n inst.parse(data, data.length)\n done()\n } catch (e) {\n done(e)\n }\n }\n })\n receiver.on('error', (e: Error) => {\n this.emit('error', e)\n })\n\n // receive from say a socket or file and pipe to parser which discovers messages\n stream?.pipe(receiver).on('finish', () => {\n this.emit('done')\n })\n stream?.on('error', (e) => {\n this.emit('error', e)\n })\n stream?.on('end', () => {\n this.emit('end')\n })\n }\n\n public reset (): void {\n this.state.beginMessage()\n }\n\n private msg (ptr: number): void {\n const receivingBuffer: ElasticBuffer = this.receivingBuffer\n const state = this.state\n if (this.listeners('decoded')) {\n this.emit('decoded', state.msgType, receivingBuffer, ptr)\n }\n this.emit('msg', state.msgType, this.getView(ptr))\n state.beginMessage()\n }\n\n /**\n * useful helper for testing where characters are parsed as if from the transport\n * @param text to be parsed\n */\n public parseText (text: string): void {\n const buff = Buffer.from(text)\n this.parse(buff, buff.length)\n }\n\n private parse (readBuffer: Buffer, end: number): void {\n const state = this.state\n const eq: number = AsciiChars.Eq\n const zero: number = AsciiChars.Zero\n const nine: number = AsciiChars.Nine\n const delimiter: number = this.delimiter\n const writeDelimiter: number = this.writeDelimiter\n const receivingBuffer: ElasticBuffer = this.receivingBuffer\n const switchDelimiter = writeDelimiter !== delimiter\n let readPtr: number = 0\n\n while (readPtr < end) {\n const charAtPos: number = readBuffer[readPtr]\n\n const writePtr = receivingBuffer.saveChar(charAtPos) - 1\n switch (state.parseState) {\n case ParseState.MsgComplete: {\n this.msg(writePtr)\n continue\n }\n\n case ParseState.BeginField: {\n const atDigit: boolean = charAtPos >= zero && charAtPos <= nine\n if (atDigit) {\n state.beginTag(writePtr)\n }\n break\n }\n\n case ParseState.ParsingTag: {\n const isEquals: boolean = charAtPos === eq\n if (isEquals) {\n state.endTag(writePtr)\n }\n break\n }\n\n case ParseState.ParsingRawData: {\n // keep skipping until length read, regardless of delimiter or not\n if (state.incRaw()) {\n // having consumed the declared raw data length, expect delimiter.\n // if not found (e.g. replayed messages with pretty-printed XML where\n // the stored length undershoots), keep scanning forward to the actual\n // delimiter rather than throwing.\n if (charAtPos === delimiter) {\n if (switchDelimiter) {\n receivingBuffer.switchChar(writeDelimiter)\n }\n state.store()\n }\n } else if (charAtPos === delimiter) {\n // hit delimiter before declared length exhausted — store what we have\n if (switchDelimiter) {\n receivingBuffer.switchChar(writeDelimiter)\n }\n state.store()\n }\n break\n }\n\n case ParseState.ParsingRawDataLength:\n case ParseState.ParsingValue: {\n if (charAtPos === delimiter) {\n if (switchDelimiter) {\n receivingBuffer.switchChar(writeDelimiter)\n }\n state.store()\n }\n break\n }\n\n default: {\n const st = state.parseState\n throw new Error(`fix parser in unknown state ${st}`)\n }\n }\n readPtr++\n }\n\n switch (state.parseState) {\n case ParseState.MsgComplete: {\n this.msg(receivingBuffer.getPos())\n break\n }\n }\n }\n\n private getView (ptr: number): MsgView | null {\n const state = this.state\n const locations = state.locations\n const source = this.receivingBuffer\n const delimiter = this.delimiter\n const definitions = this.config.definitions\n const replace = this.writeDelimiter\n const msgType = state.msgType ?? null\n if (!msgType) return null\n if (state.message) {\n try {\n const structure: Structure | null = this.segmentParser.parse(msgType, locations,\n locations.nextTagPos - 1)\n if (!structure) return null\n return new AsciiView(definitions, structure.msg(),\n source,\n structure,\n ptr,\n delimiter,\n replace)\n } catch (error) {\n if (error instanceof AsciiParserError) {\n error.summary.buffer = source.toString()\n this.emit('error', error)\n }\n throw error\n }\n }\n\n const structure = new Structure(locations, [])\n const segment = new SegmentDescription('unknown', locations.tagPos[0].tag, null, 0, 1, SegmentType.Unknown)\n segment.endPosition = locations.nextTagPos - 1\n return new AsciiView(this.config.definitions, segment, source, structure, ptr, delimiter, replace)\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"fixml-view.js","sourceRoot":"","sources":["../../../src/buffer/fixml/fixml-view.ts"],"names":[],"mappings":"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","sourcesContent":["import { MsgView } from '../msg-view'\nimport { FixDefinitions, SimpleFieldDefinition } from '../../dictionary/definition'\nimport { Structure } from '../structure'\nimport { SegmentDescription } from '../segment/segment-description'\nimport { AsciiChars } from '../ascii/'\nimport * as moment from 'moment'\nimport { TagType } from '../tag/tag-type'\n\nexport class FixmlView extends MsgView {\n constructor (public definitions: FixDefinitions, public readonly segment: SegmentDescription,\n public readonly values: string[],\n public readonly structure: Structure) {\n super(definitions, segment, structure)\n }\n\n private static getTimestamp (s: string, useUtc: boolean): Date {\n const m = moment(s)\n return useUtc ? m.utc(true).toDate() : m.toDate()\n }\n\n // 01:00:08.201\n private static getTimeOnly (s: string, useUtc: boolean): Date {\n const m = moment(s, [moment.HTML5_FMT.TIME_MS, moment.HTML5_FMT.TIME_SECONDS])\n return useUtc ? m.utc(true).toDate() : m.toDate()\n }\n\n private static getDateOnly (s: string, useUtc: boolean): Date {\n const m = moment(s)\n let d: Date\n if (useUtc) {\n d = m.utc(true).toDate()\n } else {\n d = m.toDate()\n }\n return d\n }\n\n // if the view is to be kept beyond the event on which it arrives, must be cloned\n public clone (): MsgView {\n return new FixmlView(this.definitions, this.segment, this.values, new Structure(this.structure.tags.clone(), this.structure.segments))\n }\n\n public checksum (): number {\n return 0\n }\n\n protected create (singleton: SegmentDescription): FixmlView {\n return new FixmlView(this.definitions, singleton,\n this.values,\n this.structure)\n }\n\n protected stringAtPosition (position: number): string {\n if (position < 0 || position >= this.values.length) {\n throw new Error(`illegal position ${position}`)\n }\n return this.values[position]\n }\n\n protected toTyped (field: SimpleFieldDefinition): any {\n const position: number = this.getPosition(field.tag)\n if (position >= 0) {\n const s: string = this.values[position]\n switch (field.tagType) {\n case TagType.String : {\n return this.stringAtPosition(position)\n }\n\n case TagType.Int:\n case TagType.Length: {\n return parseInt(s, 10)\n }\n\n case TagType.Float: {\n return parseFloat(s)\n }\n\n case TagType.Boolean: {\n return s && s.length > 0 && AsciiChars.firstChar(s) === AsciiChars.Y\n }\n\n case TagType.UtcTimestamp: {\n // 20150417-01:00:08.201\n return FixmlView.getTimestamp(s, true)\n }\n // 01:00:08.201\n case TagType.UtcTimeOnly: {\n return FixmlView.getTimeOnly(s, true)\n }\n\n case TagType.UtcDateOnly: {\n return FixmlView.getDateOnly(s, true)\n }\n\n case TagType.LocalDate: {\n return FixmlView.getDateOnly(s, true)\n }\n\n case TagType.RawData: {\n return Buffer.alloc(s.length, s, 'utf8')\n }\n\n default: {\n return this.stringAtPosition(position)\n }\n }\n }\n return this.stringAtPosition(position)\n }\n}\n"]}
1
+ {"version":3,"file":"fixml-view.js","sourceRoot":"","sources":["../../../src/buffer/fixml/fixml-view.ts"],"names":[],"mappings":"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","sourcesContent":["import { MsgView } from '../msg-view'\nimport { FixDefinitions, SimpleFieldDefinition } from '../../dictionary/definition'\nimport { Structure } from '../structure'\nimport { SegmentDescription } from '../segment/segment-description'\nimport { AsciiChars } from '../ascii/'\nimport moment = require('moment')\nimport { TagType } from '../tag/tag-type'\n\nexport class FixmlView extends MsgView {\n constructor (public definitions: FixDefinitions, public readonly segment: SegmentDescription,\n public readonly values: string[],\n public readonly structure: Structure) {\n super(definitions, segment, structure)\n }\n\n private static getTimestamp (s: string, useUtc: boolean): Date {\n const m = moment(s)\n return useUtc ? m.utc(true).toDate() : m.toDate()\n }\n\n // 01:00:08.201\n private static getTimeOnly (s: string, useUtc: boolean): Date {\n const m = moment(s, [moment.HTML5_FMT.TIME_MS, moment.HTML5_FMT.TIME_SECONDS])\n return useUtc ? m.utc(true).toDate() : m.toDate()\n }\n\n private static getDateOnly (s: string, useUtc: boolean): Date {\n const m = moment(s)\n let d: Date\n if (useUtc) {\n d = m.utc(true).toDate()\n } else {\n d = m.toDate()\n }\n return d\n }\n\n // if the view is to be kept beyond the event on which it arrives, must be cloned\n public clone (): MsgView {\n return new FixmlView(this.definitions, this.segment, this.values, new Structure(this.structure.tags.clone(), this.structure.segments))\n }\n\n public checksum (): number {\n return 0\n }\n\n protected create (singleton: SegmentDescription): FixmlView {\n return new FixmlView(this.definitions, singleton,\n this.values,\n this.structure)\n }\n\n protected stringAtPosition (position: number): string {\n if (position < 0 || position >= this.values.length) {\n throw new Error(`illegal position ${position}`)\n }\n return this.values[position]\n }\n\n protected toTyped (field: SimpleFieldDefinition): any {\n const position: number = this.getPosition(field.tag)\n if (position >= 0) {\n const s: string = this.values[position]\n switch (field.tagType) {\n case TagType.String : {\n return this.stringAtPosition(position)\n }\n\n case TagType.Int:\n case TagType.Length: {\n return parseInt(s, 10)\n }\n\n case TagType.Float: {\n return parseFloat(s)\n }\n\n case TagType.Boolean: {\n return s && s.length > 0 && AsciiChars.firstChar(s) === AsciiChars.Y\n }\n\n case TagType.UtcTimestamp: {\n // 20150417-01:00:08.201\n return FixmlView.getTimestamp(s, true)\n }\n // 01:00:08.201\n case TagType.UtcTimeOnly: {\n return FixmlView.getTimeOnly(s, true)\n }\n\n case TagType.UtcDateOnly: {\n return FixmlView.getDateOnly(s, true)\n }\n\n case TagType.LocalDate: {\n return FixmlView.getDateOnly(s, true)\n }\n\n case TagType.RawData: {\n return Buffer.alloc(s.length, s, 'utf8')\n }\n\n default: {\n return this.stringAtPosition(position)\n }\n }\n }\n return this.stringAtPosition(position)\n }\n}\n"]}
@@ -1,7 +1,40 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.MsgEncoder = void 0;
4
- const events = require("events");
37
+ const events = __importStar(require("events"));
5
38
  class MsgEncoder extends events.EventEmitter {
6
39
  constructor(definitions) {
7
40
  super();
@@ -1 +1 @@
1
- {"version":3,"file":"msg-encoder.js","sourceRoot":"","sources":["../../src/buffer/msg-encoder.ts"],"names":[],"mappings":";;;AAGA,iCAAgC;AAEhC,MAAsB,UAAW,SAAQ,MAAM,CAAC,YAAY;IAC1D,YAAuC,WAA2B;QAChE,KAAK,EAAE,CAAA;QAD8B,gBAAW,GAAX,WAAW,CAAgB;IAElE,CAAC;IAEM,MAAM,CAAE,CAAe,EAAE,IAAY;;QAC1C,MAAM,GAAG,GAA8B,MAAA,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,mCACvE,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACtC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAM;QACR,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IACxB,CAAC;CAKF;AAjBD,gCAiBC","sourcesContent":["import { ILooseObject } from '../collections/collection'\nimport { FixDefinitions } from '../dictionary/definition'\nimport { IContainedSet } from '../dictionary/contained'\nimport * as events from 'events'\n\nexport abstract class MsgEncoder extends events.EventEmitter {\n protected constructor (public readonly definitions: FixDefinitions) {\n super()\n }\n\n public encode (o: ILooseObject, name: string): void {\n const set: IContainedSet | undefined = this.definitions.message.get(name) ??\n this.definitions.component.get(name)\n if (!set) {\n return\n }\n this.encodeSet(o, set)\n }\n\n public abstract reset (): void\n public abstract trim (): Buffer\n public abstract encodeSet (o: ILooseObject, set: IContainedSet): void\n}\n"]}
1
+ {"version":3,"file":"msg-encoder.js","sourceRoot":"","sources":["../../src/buffer/msg-encoder.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,+CAAgC;AAEhC,MAAsB,UAAW,SAAQ,MAAM,CAAC,YAAY;IAC1D,YAAuC,WAA2B;QAChE,KAAK,EAAE,CAAA;QAD8B,gBAAW,GAAX,WAAW,CAAgB;IAElE,CAAC;IAEM,MAAM,CAAE,CAAe,EAAE,IAAY;;QAC1C,MAAM,GAAG,GAA8B,MAAA,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,mCACvE,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACtC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAM;QACR,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IACxB,CAAC;CAKF;AAjBD,gCAiBC","sourcesContent":["import { ILooseObject } from '../collections/collection'\nimport { FixDefinitions } from '../dictionary/definition'\nimport { IContainedSet } from '../dictionary/contained'\nimport * as events from 'events'\n\nexport abstract class MsgEncoder extends events.EventEmitter {\n protected constructor (public readonly definitions: FixDefinitions) {\n super()\n }\n\n public encode (o: ILooseObject, name: string): void {\n const set: IContainedSet | undefined = this.definitions.message.get(name) ??\n this.definitions.component.get(name)\n if (!set) {\n return\n }\n this.encodeSet(o, set)\n }\n\n public abstract reset (): void\n public abstract trim (): Buffer\n public abstract encodeSet (o: ILooseObject, set: IContainedSet): void\n}\n"]}
@@ -1,7 +1,40 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.MsgParser = void 0;
4
- const events = require("events");
37
+ const events = __importStar(require("events"));
5
38
  class MsgParser extends events.EventEmitter {
6
39
  }
7
40
  exports.MsgParser = MsgParser;
@@ -1 +1 @@
1
- {"version":3,"file":"msg-parser.js","sourceRoot":"","sources":["../../src/buffer/msg-parser.ts"],"names":[],"mappings":";;;AAAA,iCAAgC;AAEhC,MAAsB,SAAU,SAAQ,MAAM,CAAC,YAAY;CAC1D;AADD,8BACC","sourcesContent":["import * as events from 'events'\n\nexport abstract class MsgParser extends events.EventEmitter {\n}\n"]}
1
+ {"version":3,"file":"msg-parser.js","sourceRoot":"","sources":["../../src/buffer/msg-parser.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAgC;AAEhC,MAAsB,SAAU,SAAQ,MAAM,CAAC,YAAY;CAC1D;AADD,8BACC","sourcesContent":["import * as events from 'events'\n\nexport abstract class MsgParser extends events.EventEmitter {\n}\n"]}