Skip to content

Commit a0b370c

Browse files
committed
First cleanup
0 parents  commit a0b370c

22 files changed

+2367
-0
lines changed

.babelrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"presets": ["es2015"]
3+
}

.eslintrc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"parserOptions": {
3+
"ecmaFeatures": {}
4+
},
5+
"plugins": [],
6+
"extends": ["airbnb/base"],
7+
"globals": {},
8+
"rules": {
9+
"no-underscore-dangle": ["error", { "allow": ["_id"] }],
10+
"import/no-unresolved": [2, {}]
11+
}
12+
}

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules/
2+
.idea
3+
.directory

.npmignore

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Logs
2+
logs
3+
*.log
4+
5+
# Runtime data
6+
pids
7+
*.pid
8+
*.seed
9+
10+
# Directory for instrumented libs generated by jscoverage/JSCover
11+
lib-cov
12+
13+
# Coverage directory used by tools like istanbul
14+
coverage
15+
16+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
17+
.grunt
18+
19+
# node-waf configuration
20+
.lock-wscript
21+
22+
# Compiled binary addons (http://nodejs.org/api/addons.html)
23+
build/Release
24+
25+
# Dependency directory
26+
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
27+
node_modules
28+
29+
# npm log file
30+
npm-debug.log
31+
32+
# dist folder
33+
dist/

CONTRIBUTORS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Base code: @mlofjard (https://github.com/mlofjard/jsonfit)

LICENSE

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2015 Pierre Jacquier
4+
http://pierrejacquier.com | @pierremtb
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+

README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# easy-fit
2+
3+
> Parse your .FIT files easily, directly from JS.
4+
> Written in ES6.
5+
6+
7+
## Install
8+
9+
```
10+
$ npm install easy-fit --save
11+
```
12+
13+
## How to use
14+
15+
See in [examples](./examples) folder:
16+
17+
```
18+
var EasyFit = require('./../dist/easy-fit.js').default;
19+
var fs = require('fs');
20+
21+
var path = './example.fit';
22+
23+
fs.readFile(path, function (err, content) {
24+
var easyFit = new EasyFit({
25+
force: true,
26+
speedUnit: 'km/h',
27+
lengthUnit: 'km',
28+
temperatureUnit: 'kelvin',
29+
});
30+
31+
easyFit.parse(content, function (error, data) {
32+
if (error) {
33+
console.log(error);
34+
} else {
35+
console.log(JSON.stringify(data));
36+
}
37+
});
38+
});
39+
```
40+
41+
## License
42+
43+
MIT license; see [LICENSE](./LICENSE).
44+
45+
(c) 2016 by Pierre Jacquier

dist/binary.js

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
'use strict';
2+
3+
Object.defineProperty(exports, "__esModule", {
4+
value: true
5+
});
6+
exports.addEndian = addEndian;
7+
exports.readRecord = readRecord;
8+
exports.getArrayBuffer = getArrayBuffer;
9+
exports.calculateCRC = calculateCRC;
10+
11+
var _fit = require('./fit');
12+
13+
var _messages = require('./messages');
14+
15+
function addEndian(littleEndian, bytes) {
16+
var result = 0;
17+
if (!littleEndian) bytes.reverse();
18+
for (var i = 0; i < bytes.length; i++) {
19+
result += bytes[i] << (i << 3) >>> 0;
20+
}
21+
22+
return result;
23+
}
24+
25+
function readData(blob, fDef, startIndex) {
26+
if (fDef.endianAbility === true) {
27+
var temp = [];
28+
for (var i = 0; i < fDef.size; i++) {
29+
temp.push(blob[startIndex + i]);
30+
}
31+
var uint32Rep = addEndian(fDef.littleEndian, temp);
32+
33+
if (fDef.dataType === 'sint32') {
34+
return uint32Rep >> 0;
35+
}
36+
37+
return uint32Rep;
38+
}
39+
return blob[startIndex];
40+
}
41+
42+
function formatByType(data, type, scale, offset) {
43+
switch (type) {
44+
case 'date_time':
45+
return new Date(data * 1000 + 631062000000);
46+
case 'sint32':
47+
case 'sint16':
48+
return data * _fit.FIT.scConst;
49+
case 'uint32':
50+
case 'uint16':
51+
return scale ? data / scale + offset : data;
52+
default:
53+
return data;
54+
}
55+
}
56+
57+
function convertTo(data, unitsList, speedUnit) {
58+
var unitObj = _fit.FIT.options[unitsList][speedUnit];
59+
return unitObj ? data * unitObj.multiplier + unitObj.offset : data;
60+
}
61+
62+
function applyOptions(data, field, options) {
63+
switch (field) {
64+
case 'speed':
65+
case 'enhanced_speed':
66+
case 'vertical_speed':
67+
case 'avg_speed':
68+
case 'max_speed':
69+
case 'speed_1s':
70+
case 'ball_speed':
71+
case 'enhanced_avg_speed':
72+
case 'enhanced_max_speed':
73+
case 'avg_pos_vertical_speed':
74+
case 'max_pos_vertical_speed':
75+
case 'avg_neg_vertical_speed':
76+
case 'max_neg_vertical_speed':
77+
return convertTo(data, 'speedUnits', options.speedUnit);
78+
case 'distance':
79+
case 'total_distance':
80+
case 'enhanced_avg_altitude':
81+
case 'enhanced_min_altitude':
82+
case 'enhanced_max_altitude':
83+
case 'enhanced_altitude':
84+
case 'height':
85+
case 'odometer':
86+
case 'avg_stroke_distance':
87+
case 'min_altitude':
88+
case 'avg_altitude':
89+
case 'max_altitude':
90+
case 'total_ascent':
91+
case 'total_descent':
92+
case 'altitude':
93+
case 'cycle_length':
94+
case 'auto_wheelsize':
95+
case 'custom_wheelsize':
96+
case 'gps_accuracy':
97+
return convertTo(data, 'lengthUnits', options.lengthUnit);
98+
case 'temperature':
99+
case 'avg_temperature':
100+
case 'max_temperature':
101+
return convertTo(data, 'temperatureUnits', options.temperatureUnit);
102+
default:
103+
return data;
104+
}
105+
}
106+
107+
function readRecord(blob, messageTypes, startIndex, options) {
108+
var recordHeader = blob[startIndex];
109+
var localMessageType = recordHeader & 15;
110+
111+
if ((recordHeader & 64) === 64) {
112+
// is definition message
113+
// startIndex + 1 is reserved
114+
115+
var lEnd = blob[startIndex + 2] === 0;
116+
var mTypeDef = {
117+
littleEndian: lEnd,
118+
globalMessageNumber: addEndian(lEnd, [blob[startIndex + 3], blob[startIndex + 4]]),
119+
numberOfFields: blob[startIndex + 5],
120+
fieldDefs: []
121+
};
122+
123+
var _message = (0, _messages.getFitMessage)(mTypeDef.globalMessageNumber);
124+
125+
for (var i = 0; i < mTypeDef.numberOfFields; i++) {
126+
var fDefIndex = startIndex + 6 + i * 3;
127+
var baseType = blob[fDefIndex + 2];
128+
129+
var _message$getAttribute = _message.getAttributes(blob[fDefIndex]);
130+
131+
var field = _message$getAttribute.field;
132+
var type = _message$getAttribute.type;
133+
134+
var fDef = {
135+
type: type,
136+
fDefNo: blob[fDefIndex],
137+
size: blob[fDefIndex + 1],
138+
endianAbility: (baseType & 128) === 128,
139+
littleEndian: lEnd,
140+
baseTypeNo: baseType & 15,
141+
name: field,
142+
dataType: (0, _messages.getFitMessageBaseType)(baseType & 15)
143+
};
144+
145+
mTypeDef.fieldDefs.push(fDef);
146+
}
147+
messageTypes[localMessageType] = mTypeDef;
148+
149+
return {
150+
messageType: 'fieldDescription',
151+
nextIndex: startIndex + 6 + mTypeDef.numberOfFields * 3
152+
};
153+
}
154+
155+
var messageType = void 0;
156+
157+
if (messageTypes[localMessageType]) {
158+
messageType = messageTypes[localMessageType];
159+
} else {
160+
messageType = messageTypes[0];
161+
}
162+
163+
// TODO: handle compressed header ((recordHeader & 128) == 128)
164+
165+
// uncompressed header
166+
var messageSize = 0;
167+
var readDataFromIndex = startIndex + 1;
168+
var fields = {};
169+
var message = (0, _messages.getFitMessage)(messageType.globalMessageNumber);
170+
171+
for (var _i = 0; _i < messageType.fieldDefs.length; _i++) {
172+
var _fDef = messageType.fieldDefs[_i];
173+
var data = readData(blob, _fDef, readDataFromIndex);
174+
175+
var _message$getAttribute2 = message.getAttributes(_fDef.fDefNo);
176+
177+
var field = _message$getAttribute2.field;
178+
var type = _message$getAttribute2.type;
179+
var scale = _message$getAttribute2.scale;
180+
var offset = _message$getAttribute2.offset;
181+
182+
if (field !== 'unknown' && field !== '') {
183+
fields[field] = applyOptions(formatByType(data, type, scale, offset), field, options);
184+
}
185+
readDataFromIndex += _fDef.size;
186+
messageSize += _fDef.size;
187+
}
188+
189+
var result = {
190+
messageType: message.name,
191+
nextIndex: startIndex + messageSize + 1,
192+
message: fields
193+
};
194+
195+
switch (messageType.globalMessageNumber) {
196+
case _fit.FIT.TYPE.RECORD:
197+
break;
198+
case _fit.FIT.TYPE.LAP:
199+
break;
200+
case _fit.FIT.TYPE.SESSION:
201+
break;
202+
default:
203+
break;
204+
}
205+
206+
return result;
207+
}
208+
209+
function getArrayBuffer(buffer) {
210+
var ab = new ArrayBuffer(buffer.length);
211+
var view = new Uint8Array(ab);
212+
for (var i = 0; i < buffer.length; ++i) {
213+
view[i] = buffer[i];
214+
}
215+
return ab;
216+
}
217+
218+
function calculateCRC(blob, start, end) {
219+
var crcTable = [0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400];
220+
221+
var crc = 0;
222+
for (var i = start; i < end; i++) {
223+
var byte = blob[i];
224+
var tmp = crcTable[crc & 0xF];
225+
crc = crc >> 4 & 0x0FFF;
226+
crc = crc ^ tmp ^ crcTable[byte & 0xF];
227+
tmp = crcTable[crc & 0xF];
228+
crc = crc >> 4 & 0x0FFF;
229+
crc = crc ^ tmp ^ crcTable[byte >> 4 & 0xF];
230+
}
231+
232+
return crc;
233+
}

0 commit comments

Comments
 (0)