madden-franchise 2.5.4 → 3.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.
- package/.vscode/launch.json +17 -0
- package/FranchiseEnum.js +5 -1
- package/FranchiseFile.js +1 -1
- package/FranchiseFileField.js +174 -149
- package/FranchiseFileRecord.js +77 -59
- package/FranchiseFileTable.js +190 -184
- package/FranchiseFileTable2Field.js +27 -18
- package/data/schemas/22/M22_329_0.gz +0 -0
- package/data/schemas/extra-schemas.json +174 -0
- package/package.json +2 -1
- package/scripts/deflate.js +2 -2
- package/scripts/getTableId.js +14 -5
- package/services/schemaPicker.js +1 -1
- package/services/utilService.js +15 -0
- package/strategies/common/table2Field/FTCTable2FieldStrategy.js +3 -5
- package/strategies/common/table2Field/FranchiseTable2FieldStrategy.js +3 -5
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Use IntelliSense to learn about possible attributes.
|
|
3
|
+
// Hover to view descriptions of existing attributes.
|
|
4
|
+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
+
"version": "0.2.0",
|
|
6
|
+
"configurations": [
|
|
7
|
+
{
|
|
8
|
+
"type": "pwa-node",
|
|
9
|
+
"request": "launch",
|
|
10
|
+
"name": "Launch Program",
|
|
11
|
+
"skipFiles": [
|
|
12
|
+
"<node_internals>/**"
|
|
13
|
+
],
|
|
14
|
+
"program": "${file}"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
package/FranchiseEnum.js
CHANGED
|
@@ -45,7 +45,11 @@ class FranchiseEnum {
|
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
getMemberByValue(value) {
|
|
48
|
-
|
|
48
|
+
const matches = this._members.filter((member) => { return member.name !== 'First_' && member.name !== 'Last_' && member.value === value; });
|
|
49
|
+
if (matches.length === 0) { throw new Error(`Argument is not a valid enum value for this field. You passed in ${value}. Field name: ${this.name}`); }
|
|
50
|
+
|
|
51
|
+
const matchesNoUnderscore = matches.find((member) => { return member.name[member.name.length - 1] !== '_'});
|
|
52
|
+
return matchesNoUnderscore ? matchesNoUnderscore : matches[0];
|
|
49
53
|
};
|
|
50
54
|
|
|
51
55
|
getMemberByUnformattedValue(value) {
|
package/FranchiseFile.js
CHANGED
|
@@ -113,7 +113,7 @@ class FranchiseFile extends EventEmitter {
|
|
|
113
113
|
|
|
114
114
|
for (let i = 0; i < tableIndicies.length; i++) {
|
|
115
115
|
const currentTable = tableIndicies[i];
|
|
116
|
-
const nextTable = tableIndicies.length
|
|
116
|
+
const nextTable = tableIndicies.length > i+1 ? tableIndicies[i+1] : this.unpackedFileContents.length - 8; // Ignore trailing 8 bytes on last table
|
|
117
117
|
|
|
118
118
|
const tableData = this.unpackedFileContents.slice(currentTable, nextTable);
|
|
119
119
|
|
package/FranchiseFileField.js
CHANGED
|
@@ -1,22 +1,19 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { BitView } = require('bit-buffer');
|
|
2
|
+
|
|
2
3
|
const utilService = require('./services/utilService');
|
|
3
4
|
const FranchiseFileTable2Field = require('./FranchiseFileTable2Field');
|
|
4
5
|
|
|
5
|
-
class FranchiseFileField
|
|
6
|
-
constructor(key, value, offset) {
|
|
7
|
-
super();
|
|
6
|
+
class FranchiseFileField {
|
|
7
|
+
constructor(key, value, offset, parent) {
|
|
8
8
|
this._key = key;
|
|
9
|
-
this.
|
|
10
|
-
this.
|
|
9
|
+
this._recordBuffer = value;
|
|
10
|
+
this._unformattedValue = null;
|
|
11
11
|
this._offset = offset;
|
|
12
|
+
this._parent = parent;
|
|
12
13
|
|
|
13
14
|
if (offset.valueInSecondTable) {
|
|
14
|
-
this.secondTableField = new FranchiseFileTable2Field(
|
|
15
|
+
this.secondTableField = new FranchiseFileTable2Field(this._recordBuffer.readUInt32BE(offset.offset / 8), offset.maxLength);
|
|
15
16
|
this.secondTableField.fieldReference = this;
|
|
16
|
-
|
|
17
|
-
this.secondTableField.on('change', function () {
|
|
18
|
-
this._value = this.secondTableField.value;
|
|
19
|
-
}.bind(this));
|
|
20
17
|
}
|
|
21
18
|
};
|
|
22
19
|
|
|
@@ -29,6 +26,14 @@ class FranchiseFileField extends EventEmitter {
|
|
|
29
26
|
};
|
|
30
27
|
|
|
31
28
|
get value () {
|
|
29
|
+
if (this._unformattedValue === null) {
|
|
30
|
+
this._setUnformattedValueIfEmpty();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (this._value === null) {
|
|
34
|
+
this._value = this._parseFieldValue(this._unformattedValue, this._offset);
|
|
35
|
+
}
|
|
36
|
+
|
|
32
37
|
return this._value;
|
|
33
38
|
};
|
|
34
39
|
|
|
@@ -37,193 +42,213 @@ class FranchiseFileField extends EventEmitter {
|
|
|
37
42
|
};
|
|
38
43
|
|
|
39
44
|
get referenceData () {
|
|
45
|
+
if (this._unformattedValue === null) {
|
|
46
|
+
this._setUnformattedValueIfEmpty();
|
|
47
|
+
}
|
|
48
|
+
|
|
40
49
|
if (this.isReference) {
|
|
41
|
-
return utilService.
|
|
50
|
+
return utilService.getReferenceDataFromBitview(this._unformattedValue, this.offset.offset);
|
|
42
51
|
}
|
|
43
52
|
|
|
44
53
|
return null;
|
|
45
54
|
};
|
|
46
55
|
|
|
47
|
-
set value (value) {
|
|
56
|
+
set value (value) {
|
|
57
|
+
if (this._unformattedValue === null) {
|
|
58
|
+
this._setUnformattedValueIfEmpty();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
this._value = value;
|
|
62
|
+
|
|
48
63
|
if (this.offset.valueInSecondTable) {
|
|
49
64
|
this.secondTableField.value = value.toString();
|
|
50
65
|
} else {
|
|
66
|
+
let actualValue;
|
|
67
|
+
|
|
51
68
|
if (this.offset.isReference) {
|
|
52
69
|
if (!utilService.isString(value)) { throw new Error(`Argument must be of type string. You passed in a ${typeof unformattedValue}.`); }
|
|
53
70
|
else if (!utilService.stringOnlyContainsBinaryDigits(value)) { throw new Error(`Argument must only contain binary digits 1 and 0. If you would like to set the value, please set the 'value' attribute instead.`)}
|
|
71
|
+
const referenceData = utilService.getReferenceData(value);
|
|
72
|
+
this._unformattedValue.setBits(this.offset.offset, referenceData.tableId, 15);
|
|
73
|
+
this._unformattedValue.setBits((this.offset.offset + 15), referenceData.rowNumber, 17);
|
|
74
|
+
}
|
|
75
|
+
else if (this.offset.enum) {
|
|
76
|
+
try {
|
|
77
|
+
let theEnum = this._getEnumFromValue(value);
|
|
78
|
+
|
|
79
|
+
// Enums can have negative values and Madden negative numbers are not standard. We need to convert it here.
|
|
80
|
+
// Ex: In Madden, binary "1000" = -1 for an enum with a max length of 4. But for everything else, "1000" = 8, so we need to get the "real" value here.
|
|
81
|
+
const decimalEquivalent = utilService.bin2dec(theEnum.unformattedValue);
|
|
82
|
+
this._unformattedValue.setBits(this.offset.offset, decimalEquivalent, this.offset.length);
|
|
83
|
+
this._value = theEnum.name;
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
this._value = null;
|
|
87
|
+
throw err;
|
|
88
|
+
}
|
|
54
89
|
}
|
|
90
|
+
else {
|
|
91
|
+
switch (this.offset.type) {
|
|
92
|
+
case 's_int':
|
|
93
|
+
actualValue = parseInt(value);
|
|
94
|
+
this._value = actualValue;
|
|
95
|
+
this._unformattedValue.setBits(this.offset.offset, actualValue - this.offset.minValue, this.offset.length);
|
|
96
|
+
break;
|
|
97
|
+
default:
|
|
98
|
+
case 'int':
|
|
99
|
+
actualValue = parseInt(value);
|
|
100
|
+
this._value = actualValue;
|
|
101
|
+
|
|
102
|
+
if (this.offset.minValue || this.offset.maxValue) {
|
|
103
|
+
// return utilService.dec2bin(formatted, offset.length);
|
|
104
|
+
this._unformattedValue.setBits(this.offset.offset, actualValue, this.offset.length);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
const maxValueBinary = getMaxValueBinary(this.offset);
|
|
108
|
+
const maxValue = utilService.bin2dec(maxValueBinary);
|
|
109
|
+
// return utilService.dec2bin(formatted + maxValue, offset.length);
|
|
110
|
+
this._unformattedValue.setBits(this.offset.offset, actualValue + maxValue, this.offset.length);
|
|
111
|
+
}
|
|
112
|
+
break;
|
|
113
|
+
case 'bool':
|
|
114
|
+
// return (formatted == 1 || (formatted.toString().toLowerCase() == 'true')) ? '1' : '0';
|
|
115
|
+
actualValue = (value == 1 || (value.toString().toLowerCase() == 'true'));
|
|
116
|
+
this._value = actualValue;
|
|
117
|
+
this._unformattedValue.setBits(this.offset.offset, actualValue, 1);
|
|
118
|
+
break;
|
|
119
|
+
case 'float':
|
|
120
|
+
actualValue = parseFloat(value);
|
|
121
|
+
this._value = actualValue;
|
|
122
|
+
// return utilService.float2Bin(formatted);
|
|
123
|
+
// this._unformattedValue.setBits(this.offset.offset, value, this.offset.length);
|
|
124
|
+
this._unformattedValue.setFloat32(this.offset.offset, actualValue);
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// this._value = setFormattedValue(value, this._offset);
|
|
130
|
+
// this._unformattedValue = parseFormattedValue(value, this._offset);
|
|
131
|
+
|
|
55
132
|
|
|
56
|
-
this.
|
|
57
|
-
this.
|
|
58
|
-
this.emit('change');
|
|
133
|
+
// this.emit('change');
|
|
134
|
+
this._parent.onEvent('change', this);
|
|
59
135
|
}
|
|
60
136
|
};
|
|
61
137
|
|
|
62
138
|
get unformattedValue () {
|
|
139
|
+
if (this._unformattedValue === null) {
|
|
140
|
+
this._setUnformattedValueIfEmpty();
|
|
141
|
+
}
|
|
142
|
+
|
|
63
143
|
return this._unformattedValue;
|
|
64
144
|
};
|
|
65
145
|
|
|
66
146
|
set unformattedValue (unformattedValue) {
|
|
67
147
|
this.setUnformattedValueWithoutChangeEvent(unformattedValue);
|
|
68
|
-
this.
|
|
148
|
+
this._value = null;
|
|
149
|
+
this._parent.onEvent('change', this);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
_setUnformattedValueIfEmpty() {
|
|
153
|
+
this._value = null;
|
|
154
|
+
this._unformattedValue = new BitView(this._recordBuffer, this._recordBuffer.byteOffset);
|
|
155
|
+
this._unformattedValue.bigEndian = true;
|
|
69
156
|
};
|
|
70
157
|
|
|
71
158
|
setUnformattedValueWithoutChangeEvent(unformattedValue, suppressErrors) {
|
|
72
|
-
if (!
|
|
73
|
-
else if (!utilService.stringOnlyContainsBinaryDigits(unformattedValue)) { throw new Error(`Argument must only contain binary digits 1 and 0. If you would like to set the value, please set the 'value' attribute instead.`)}
|
|
159
|
+
if (!(unformattedValue instanceof BitView)) { throw new Error(`Argument must be of type BitView. You passed in a(n) ${typeof unformattedValue}.`); }
|
|
74
160
|
else {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (this.offset.valueInSecondTable) {
|
|
78
|
-
value = this.secondTableField.value;
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
value = parseFieldValue(unformattedValue.padStart(this._offset.length, '0'), this._offset);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// check for 'allowed' error - this will be true if the unformatted value is invalid.
|
|
85
|
-
if (this._offset.enum && value === unformattedValue.padStart(this._offset.length, '0') && !suppressErrors) {
|
|
86
|
-
throw new Error(`Argument is not a valid unformatted value for this field. You passed in ${value}.`)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
this._value = value;
|
|
90
|
-
|
|
91
|
-
if (this._offset.enum) {
|
|
92
|
-
this._unformattedValue = this._offset.enum.getMemberByName(this._value).unformattedValue.padStart(this._offset.length, '0');
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
this._unformattedValue = unformattedValue;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
module.exports = FranchiseFileField;
|
|
102
|
-
|
|
103
|
-
function setFormattedValue(value, offset) {
|
|
104
|
-
if (offset.enum) {
|
|
105
|
-
const theEnum = offset.enum.getMemberByName(value);
|
|
106
|
-
if (!theEnum) {
|
|
107
|
-
const theEnumByValue = offset.enum.getMemberByValue(value);
|
|
108
|
-
|
|
109
|
-
if (!theEnumByValue) {
|
|
110
|
-
throw new Error(`Argument is not a valid enum value for this field. You passed in ${value}.`);
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
return theEnumByValue.name;
|
|
114
|
-
}
|
|
115
|
-
} else {
|
|
116
|
-
return theEnum.name;
|
|
161
|
+
this._unformattedValue = unformattedValue;
|
|
162
|
+
this._value = null;
|
|
117
163
|
}
|
|
118
164
|
}
|
|
119
165
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
case 'int':
|
|
123
|
-
return parseInt(value);
|
|
124
|
-
case 'bool':
|
|
125
|
-
return value == 1 || (value.toString().toLowerCase() == 'true');
|
|
126
|
-
case 'float':
|
|
127
|
-
return parseFloat(value);
|
|
128
|
-
default:
|
|
129
|
-
return value.toString();
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
function parseFieldValue(unformatted, offset) {
|
|
134
|
-
if (offset.enum) {
|
|
135
|
-
try {
|
|
136
|
-
const theEnum = offset.enum.getMemberByUnformattedValue(unformatted);
|
|
137
|
-
|
|
138
|
-
if (theEnum) {
|
|
139
|
-
return theEnum.name;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
catch (err) {
|
|
143
|
-
// console.log(err);
|
|
144
|
-
}
|
|
166
|
+
_getEnumFromValue(value) {
|
|
167
|
+
const enumName = this.offset.enum.getMemberByName(value);
|
|
145
168
|
|
|
146
|
-
return unformatted;
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
switch (offset.type) {
|
|
150
|
-
case 's_int':
|
|
151
|
-
return utilService.bin2dec(unformatted) + offset.minValue;
|
|
152
|
-
case 'int':
|
|
153
|
-
if (offset.minValue || offset.maxValue) {
|
|
154
|
-
return utilService.bin2dec(unformatted);
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
const maxValueBinary = getMaxValueBinary(offset);
|
|
158
|
-
const maxValue = utilService.bin2dec(maxValueBinary);
|
|
159
|
-
const newValue = utilService.bin2dec(unformatted);
|
|
160
|
-
|
|
161
|
-
if (newValue === 0) {
|
|
162
|
-
return 0;
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
return newValue - maxValue;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
case 'bool':
|
|
169
|
-
return unformatted[0] === '1' ? true : false;
|
|
170
|
-
case 'float':
|
|
171
|
-
return utilService.bin2Float(unformatted);
|
|
172
|
-
default:
|
|
173
|
-
return unformatted;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
function parseFormattedValue(formatted, offset) {
|
|
179
|
-
if (offset.enum) {
|
|
180
|
-
const enumName = offset.enum.getMemberByName(formatted);
|
|
181
|
-
|
|
182
169
|
if (enumName) {
|
|
183
|
-
return enumName
|
|
170
|
+
return enumName;
|
|
184
171
|
}
|
|
185
172
|
else {
|
|
186
|
-
const formattedEnum = offset.enum.getMemberByValue(
|
|
173
|
+
const formattedEnum = this.offset.enum.getMemberByValue(value)
|
|
187
174
|
|
|
188
175
|
if (formattedEnum) {
|
|
189
|
-
return formattedEnum
|
|
176
|
+
return formattedEnum;
|
|
190
177
|
}
|
|
191
178
|
else {
|
|
192
|
-
const unformattedEnum = offset.enum.getMemberByUnformattedValue(
|
|
179
|
+
const unformattedEnum = this.offset.enum.getMemberByUnformattedValue(value);
|
|
193
180
|
|
|
194
181
|
if (unformattedEnum) {
|
|
195
|
-
return unformattedEnum
|
|
182
|
+
return unformattedEnum;
|
|
196
183
|
}
|
|
197
184
|
else {
|
|
198
|
-
return offset.enum.members[0]
|
|
185
|
+
return this.offset.enum.members[0];
|
|
199
186
|
}
|
|
200
187
|
}
|
|
201
188
|
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
return
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
_parseFieldValue(unformatted, offset) {
|
|
192
|
+
if (offset.valueInSecondTable) {
|
|
193
|
+
return this.secondTableField.value;
|
|
194
|
+
}
|
|
195
|
+
else if (offset.enum) {
|
|
196
|
+
const enumUnformattedValue = utilService.dec2bin(this.unformattedValue.getBits(this.offset.offset, this.offset.length), offset.enum._maxLength);
|
|
197
|
+
|
|
198
|
+
try {
|
|
199
|
+
const theEnum = offset.enum.getMemberByUnformattedValue(enumUnformattedValue);
|
|
200
|
+
|
|
201
|
+
if (theEnum) {
|
|
202
|
+
return theEnum.name;
|
|
216
203
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
204
|
+
}
|
|
205
|
+
catch (err) {
|
|
206
|
+
// console.log(err);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return enumUnformattedValue;
|
|
223
210
|
}
|
|
224
|
-
|
|
211
|
+
else if (offset.isReference) {
|
|
212
|
+
const referenceData = utilService.getReferenceDataFromBitview(this._unformattedValue, this.offset.offset);
|
|
213
|
+
return utilService.getBinaryReferenceData(referenceData.tableId, referenceData.rowNumber);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
switch (offset.type) {
|
|
217
|
+
case 's_int':
|
|
218
|
+
// return utilService.bin2dec(unformatted) + offset.minValue;
|
|
219
|
+
return unformatted.getBits(offset.offset, offset.length) + offset.minValue;
|
|
220
|
+
case 'int':
|
|
221
|
+
if (offset.minValue || offset.maxValue) {
|
|
222
|
+
return unformatted.getBits(offset.offset, offset.length);
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
// This is for int[] tables.
|
|
226
|
+
|
|
227
|
+
const maxValueBinary = getMaxValueBinary(offset);
|
|
228
|
+
const maxValue = utilService.bin2dec(maxValueBinary);
|
|
229
|
+
const newValue = unformatted.getBits(offset.offset, offset.length);
|
|
230
|
+
|
|
231
|
+
if (newValue === 0) {
|
|
232
|
+
return 0;
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
return newValue - maxValue;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
case 'bool':
|
|
239
|
+
return unformatted.getBits(offset.offset, 1) ? true : false;
|
|
240
|
+
case 'float':
|
|
241
|
+
// return utilService.bin2Float(unformatted);
|
|
242
|
+
return unformatted.getFloat32(offset.offset, offset.length);
|
|
243
|
+
default:
|
|
244
|
+
return unformatted;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
};
|
|
225
248
|
};
|
|
226
249
|
|
|
250
|
+
module.exports = FranchiseFileField;
|
|
251
|
+
|
|
227
252
|
function getMaxValueBinary(offset) {
|
|
228
253
|
let maxValue = '1';
|
|
229
254
|
for (let j = 0; j < (offset.length - 1); j++) {
|
package/FranchiseFileRecord.js
CHANGED
|
@@ -1,79 +1,62 @@
|
|
|
1
|
-
const EventEmitter = require('events').EventEmitter;
|
|
2
1
|
const utilService = require('./services/utilService');
|
|
3
2
|
const FranchiseFileField = require('./FranchiseFileField');
|
|
4
3
|
|
|
5
|
-
class FranchiseFileRecord
|
|
6
|
-
constructor(data, index, offsetTable) {
|
|
7
|
-
super();
|
|
4
|
+
class FranchiseFileRecord {
|
|
5
|
+
constructor(data, index, offsetTable, parent) {
|
|
8
6
|
this._data = data;
|
|
9
7
|
this._offsetTable = offsetTable;
|
|
10
8
|
this.index = index;
|
|
11
|
-
this.
|
|
9
|
+
this._fieldsArray = [];
|
|
10
|
+
this._fields = this.parseRecordFields(data, offsetTable, this);
|
|
12
11
|
this.isChanged = false;
|
|
13
12
|
this.arraySize = null;
|
|
14
13
|
this.isEmpty = false;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
this
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
14
|
+
this._parent = parent;
|
|
15
|
+
|
|
16
|
+
return new Proxy(this, {
|
|
17
|
+
get: function (target, prop, receiver) {
|
|
18
|
+
return target.fields[prop] !== undefined ? target.fields[prop].value : target[prop] !== undefined ? target[prop] : null;
|
|
19
|
+
},
|
|
20
|
+
set: function (target, prop, receiver) {
|
|
21
|
+
if (target.fields[prop] !== undefined) {
|
|
22
|
+
target.fields[prop].value = receiver;
|
|
24
23
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
field.on('change', function () {
|
|
28
|
-
that._data = utilService.replaceAt(that._data, this.offset.offset, this.unformattedValue);
|
|
29
|
-
|
|
30
|
-
// NOTE: At this time, we can only change the size of arrays of references.
|
|
31
|
-
// I'm not sure how to change the size of non-reference arrays, or if it's even possible.
|
|
32
|
-
if (that.arraySize !== null && that.arraySize !== undefined) {
|
|
33
|
-
const referenceData = this.referenceData;
|
|
34
|
-
|
|
35
|
-
// If the field is outside of the previous array size and was edited to a valid reference,
|
|
36
|
-
// then reset the array size
|
|
37
|
-
if (this.offset.index >= that.arraySize) {
|
|
38
|
-
if (this.isReference) {
|
|
39
|
-
if (referenceData.tableId !== 0 || referenceData.rowNumber !== 0) {
|
|
40
|
-
that.arraySize = this.offset.index + 1;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// If the value was changed to 0s, then shrink the array size to this index.
|
|
46
|
-
else if (this.isReference) {
|
|
47
|
-
if (referenceData.tableId === 0 && referenceData.rowNumber === 0) {
|
|
48
|
-
that.arraySize = this.offset.index;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
24
|
+
else {
|
|
25
|
+
target[prop] = receiver;
|
|
51
26
|
}
|
|
52
27
|
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
})
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
})
|
|
56
31
|
};
|
|
57
32
|
|
|
58
33
|
get hexData () {
|
|
59
|
-
return
|
|
34
|
+
return this._data;
|
|
60
35
|
};
|
|
61
36
|
|
|
62
37
|
get fields () {
|
|
63
38
|
return this._fields;
|
|
64
39
|
};
|
|
65
40
|
|
|
41
|
+
get fieldsArray () {
|
|
42
|
+
return this._fieldsArray;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
get data() {
|
|
46
|
+
return this._data;
|
|
47
|
+
};
|
|
48
|
+
|
|
66
49
|
set data (data) {
|
|
67
50
|
this._data = data;
|
|
68
51
|
|
|
69
|
-
this.
|
|
52
|
+
this._fieldsArray.forEach((field) => {
|
|
70
53
|
const unformattedValue = data.slice(field.offset.offset, field.offset.offset + field.offset.length);
|
|
71
54
|
field.setUnformattedValueWithoutChangeEvent(unformattedValue);
|
|
72
55
|
});
|
|
73
56
|
};
|
|
74
57
|
|
|
75
58
|
getFieldByKey(key) {
|
|
76
|
-
return this._fields
|
|
59
|
+
return this._fields[key];
|
|
77
60
|
};
|
|
78
61
|
|
|
79
62
|
getValueByKey(key) {
|
|
@@ -86,22 +69,57 @@ class FranchiseFileRecord extends EventEmitter {
|
|
|
86
69
|
return field ? field.referenceData : null;
|
|
87
70
|
};
|
|
88
71
|
|
|
72
|
+
parseRecordFields(data, offsetTable, record) {
|
|
73
|
+
let fields = {};
|
|
74
|
+
|
|
75
|
+
for (let j = 0; j < offsetTable.length; j++) {
|
|
76
|
+
const offset = offsetTable[j];
|
|
77
|
+
|
|
78
|
+
// Push the entire record buffer to the field. No need to perform a calculation
|
|
79
|
+
// to subarray the buffer, BitView will take care of it in the Field.
|
|
80
|
+
fields[offset.name] = new FranchiseFileField(offset.name, data, offset, record);
|
|
81
|
+
|
|
82
|
+
this._fieldsArray.push(fields[offset.name]);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return fields;
|
|
86
|
+
};
|
|
87
|
+
|
|
89
88
|
empty() {
|
|
90
|
-
this.
|
|
89
|
+
this._parent.onEvent('empty', this);
|
|
91
90
|
this.isEmpty = true;
|
|
92
91
|
};
|
|
93
|
-
};
|
|
94
92
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
93
|
+
onEvent(name, field) {
|
|
94
|
+
if (name === 'change') {
|
|
95
|
+
// this._data = utilService.replaceAt(this._data, field.offset.offset, field.unformattedValue);
|
|
96
|
+
|
|
97
|
+
// NOTE: At field time, we can only change the size of arrays of references.
|
|
98
|
+
// I'm not sure how to change the size of non-reference arrays, or if it's even possible.
|
|
99
|
+
if (this.arraySize !== null && this.arraySize !== undefined) {
|
|
100
|
+
const referenceData = field.referenceData;
|
|
101
|
+
|
|
102
|
+
// If the field is outside of the previous array size and was edited to a valid reference,
|
|
103
|
+
// then reset the array size
|
|
104
|
+
if (field.offset.index >= this.arraySize) {
|
|
105
|
+
if (field.isReference) {
|
|
106
|
+
if (referenceData.tableId !== 0 || referenceData.rowNumber !== 0) {
|
|
107
|
+
this.arraySize = field.offset.index + 1;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// If the value was changed to 0s, then shrink the array size to field index.
|
|
113
|
+
else if (field.isReference) {
|
|
114
|
+
if (referenceData.tableId === 0 && referenceData.rowNumber === 0) {
|
|
115
|
+
this.arraySize = field.offset.index;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
99
119
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
120
|
+
this._parent.onEvent('change', this);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
};
|
|
105
124
|
|
|
106
|
-
|
|
107
|
-
};
|
|
125
|
+
module.exports = FranchiseFileRecord;
|