forked from falconair/fix.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfixFrameDecoder.js
More file actions
106 lines (83 loc) · 3.93 KB
/
fixFrameDecoder.js
File metadata and controls
106 lines (83 loc) · 3.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
"use strict";
var util = require('util');
var events = require('events');
var fixutil = require('./fixutils.js');
var _ = require('underscore');
//static vars
var SOHCHAR = String.fromCharCode(1);
//TODO remove the need to use standard tag names: XXX.Y.Y
var ENDOFTAG8 = 10;
var STARTOFTAG9VAL = ENDOFTAG8 + 2;
var SIZEOFTAG10 = 8;
exports.FixFrameDecoder = FixFrameDecoder;
function FixFrameDecoder(){
this.buffer = '';
var self = this;
this.processData = function(data){
self.buffer = self.buffer + data;
while (self.buffer.length > 0) {
//====================================Step 1: Extract complete FIX message====================================
//If we don't have enough data to start extracting body length, wait for more data
if (self.buffer.length <= ENDOFTAG8) {
return;
}
var _idxOfEndOfTag9Str = self.buffer.substring(ENDOFTAG8).indexOf(SOHCHAR);
var idxOfEndOfTag9 = parseInt(_idxOfEndOfTag9Str, 10) + ENDOFTAG8;
if (isNaN(idxOfEndOfTag9)) {
var error = '[ERROR] Unable to find the location of the end of tag 9. Message probably malformed: '
+ self.buffer.toString();
util.log(error);
self.emit('error','FATAL',error);
return;
}
//If we don't have enough data to stop extracting body length AND we have received a lot of data
//then perhaps there is a problem with how the message is formatted and the session should be killed
if (idxOfEndOfTag9 < 0 && self.buffer.length > 100) {
var error ='[ERROR] Over 100 character received but body length still not extractable. Message malformed: '
+ databuffer.toString();
util.log(error);
self.emit('error','FATAL',error);
return;
}
//If we don't have enough data to stop extracting body length, wait for more data
if (idxOfEndOfTag9 < 0) {
return;
}
var _bodyLengthStr = self.buffer.substring(STARTOFTAG9VAL, idxOfEndOfTag9);
var bodyLength = parseInt(_bodyLengthStr, 10);
if (isNaN(bodyLength)) {
var error = "[ERROR] Unable to parse bodyLength field. Message probably malformed: bodyLength='"
+ _bodyLengthStr + "', msg=" + self.buffer.toString()
util.log(error);
self.emit('error','FATAL',error);
return;
}
var msgLength = bodyLength + idxOfEndOfTag9 + SIZEOFTAG10;
//If we don't have enough data for the whole message, wait for more data
if (self.buffer.length < msgLength) {
return;
}
//Message received!
var msg = self.buffer.substring(0, msgLength);
if (msgLength == self.buffer.length) {
self.buffer = '';
}
else {
var remainingBuffer = self.buffer.substring(msgLength);
self.buffer = remainingBuffer;
}
//====================================Step 2: Validate message====================================
var calculatedChecksum = fixutil.checksum(msg.substr(0, msg.length - 7));
var extractedChecksum = msg.substr(msg.length - 4, 3);
if (calculatedChecksum !== extractedChecksum) {
var error = '[WARNING] Discarding message because body length or checksum are wrong (expected checksum: '
+ calculatedChecksum + ', received checksum: ' + extractedChecksum + '): [' + msg + ']'
util.log(error);
self.emit('error','ERROR',error);
return;
}
self.emit('msg',msg);
}
}
}
util.inherits(FixFrameDecoder, events.EventEmitter);