jParser делает простым чтение структур данных из двоичных файлов джаваскриптом.
Методы jParser:
Конструктор jParser:
Обычная структура Си
Вы можете описыватьСи-подобные структуры данных. Это джаваскриптовый объект, в котором поля являются именами данных, а их значения — типами.
Ссылки
Структуры могут содержать другие структуры. Используйте имя структуры в виде строки, чтобы сослаться на её описание. Нижеследующий пример является частью структуры файла, содержащего модель для World of Warcraft:
Функции-помощники
Вам будет несложно определять новые элементарные типы. Вы можете использовать существующие виды конструкций, такие как объекты (float3 в нижеследующем примере) или массивы (float4 в примере). Если же вы желаете определить более сложный тип, то всегда есть возможность определить новую функцию, полагающуюся на метод this.parse для первичного анализа (hex32и string0 в нижеследующем примере):
Обратные связи
Если размер массива заранее не известен, то можете поместить на его место в структуре функцию, возвращающую целое число. В этой функции вы можете через this.current обратиться к объекту, в настоящее время подвергающемуся анализу, считывать ужé полученные поля его.
Развитый анализ данных
Приятнейшая особенность jParser заключается в том, что сложные алгоритмы обработки можно выразить функциями внутри описания структуры данных. Это позволяет анализировать сложные файлы, не отделяя описание структуры от кода её обработчиков.
На движке NodeJS
Просто используйте npm для установки jParser —и вы готовы :-)
Во браузере
Я пропатчил jQuery, обеспечив скачивание двоичных файлов в наилучшем двоичном формате. Подключите этот пропатченный код jQuery, а также jDataView и jParser —и вы готовы :-)
Этот иструмент в своей работе полагается на недокументированную особенность JavaScript: обход полей объекта работает в том порядке, в каком они указывались. Имейте в виду, что в Chrome и в Opera это неявное правило не работает для полей с цифровыми именами.
Следуйте вот каким двум правилам, чтобы эта библиотека работала во всех существующих реализациях языка JavaScript:
Анализ ICO. Это простой пример анализа двоичного файла на движке NodeJS. Он показывает, как решаются многие типичные задачи, возникающие при разборе двоичных данных.
Распаковщик Tar. Это простой пример разбора двоичного файла внутри браузера.
Средство показа моделей World of Warcraft. Использует jParser для чтения двоичного кода трёхмерной модели, затем WebGL для её отображения.
![[скриншот]](http://habrastorage.org/r/w1560/storage2/a69/478/a17/a69478a173a7edeff68ee0108454944a.png)
Внутренние файлы Diablo 3
- Вы один раз описываете структуру, анализ её происходит автоматически.
- Процесс анализа данных может быть расширен самописными функциями. Чем упрощается разбор нетривиальных файлов.
- jParser действует и во браузере, и в NodeJS, потому что работает на основе jDataView.
API
Элементарные структуры:- Целые числа без знака: uint8, uint16, uint32
- Со знаком: int8, int16, int32
- Дробные с плавающей точкой: float32, float64
- Строковые: char, string(len)
- Массив: array(type, len)
- Положение: tell, skip(len), seek(pos), seek(pos, func)
Методы jParser:
- parse(value) — запускает анализ, может использоваться рекурсивно. Поведение зависит от типа аргумента:
- функция: вызывает функцию;
- строка: разыменование (по указанному имени берётся значение из структуры);
- массив: вызов функции, имя которой — первый элемент массива, а последующие элементы служат аргументами;
- объект: возвращает объект с теми же именами полей, но проанализированными значениями.
- функция: вызывает функцию;
- tell() — возвращает текущее положение (смещение) в анализируемом файле.
- skip(count) — передвинуться в файле
на count байтов вперёд (пропустить их).
- seek(position) — перейти к указанному смещению в анализируемом файле.
- seek(position, callback) — перейти к указанному смещению, там выполнить callback(), затем возвратиться к прежнему положению.
- current — Текущий объект, подвергаемый анализу. Используйте для доступа к результатам, ужé достигнутым во время анализа.
Конструктор jParser:
- new jParser(data, structure)
- data — это jDataView с данными, подвергаемыми анализу. Можете передать строку байтов (String), можете передать ArrayBuffer
или буфер Node.js — эти типы данных преобразуются в jDataView автоматически.
- structure — объект с описанием всех структур данных.
- data — это jDataView с данными, подвергаемыми анализу. Можете передать строку байтов (String), можете передать ArrayBuffer
Примеры
Обычная структура Си
Вы можете описывать
var parser = new jParser(file, {
header: {
fileId: 'int32',
recordIndex: 'int32',
hash: ['array', 'uint32', 4],
fileName: ['string', 256],
}
});
parser.parse('header');
// {
// fileId: 42,
// recordIndex: 6002,
// hash: [4237894687, 3491173757, 3626834111, 2631772842],
// fileName: ".\\Resources\\Excel\\Items_Weapons.xls"
// }
Ссылки
Структуры могут содержать другие структуры. Используйте имя структуры в виде строки, чтобы сослаться на её описание. Нижеследующий пример является частью структуры файла, содержащего модель для World of Warcraft:
nofs: {
count: 'uint32',
offset: 'uint32'
},
animationBlock: {
interpolationType: 'uint16',
globalSequenceID: 'int16',
timestamps: 'nofs',
keyFrame: 'nofs'
},
uvAnimation: {
translation: 'animationBlock',
rotation: 'animationBlock',
scaling: 'animationBlock'
}
Функции-помощники
Вам будет несложно определять новые элементарные типы. Вы можете использовать существующие виды конструкций, такие как объекты (float3 в нижеследующем примере) или массивы (float4 в примере). Если же вы желаете определить более сложный тип, то всегда есть возможность определить новую функцию, полагающуюся на метод this.parse для первичного анализа (hex32
float3: {
x: 'float32',
y: 'float32',
z: 'float32'
},
float4: ['array', 'float32', 4],
hex32: function () {
return '0x' + this.parse('uint32').toString(16);
},
string0: function (length) {
return this.parse(['string', length]).replace(/\0+$/g, '');
}
Обратные связи
Если размер массива заранее не известен, то можете поместить на его место в структуре функцию, возвращающую целое число. В этой функции вы можете через this.current обратиться к объекту, в настоящее время подвергающемуся анализу, считывать ужé полученные поля его.
image: {
width: 'uint8',
height: 'uint8',
pixels: [
'array',
['array', 'rgba', function () { return this.current.width; }],
function () { return this.current.height; }
]
}
Развитый анализ данных
Приятнейшая особенность jParser заключается в том, что сложные алгоритмы обработки можно выразить функциями внутри описания структуры данных. Это позволяет анализировать сложные файлы, не отделяя описание структуры от кода её обработчиков.
entryHeader: {
start: 'int32',
count: 'int32'
},
entry: function (type) {
var that = this;
var header = this.parse('entryHeader');
var res = [];
this.seek(header.start, function () {
for (var i = 0; i < header.count; ++i) {
res.push(that.parse(type));
}
});
return res;
},
name: {
language: 'int32',
text: ['string', 256]
},
file: {
names: ['entry', 'name']
}
Начало работы
На движке NodeJS
Просто используйте npm для установки jParser —
npm install jParser
var fs = require('fs');
var jParser = require('jParser');
fs.readFile('file.bin', function (err, data) {
var parser = new jParser(data, {
magic: ['array', 'uint8', 4]
});
console.log(parser.parse('magic'));
});
Во браузере
Я пропатчил jQuery, обеспечив скачивание двоичных файлов в наилучшем двоичном формате. Подключите этот пропатченный код jQuery, а также jDataView и jParser —
<script src="https://raw.github.com/vjeux/jDataView/master/jquery/jquery-1.7.1-binary-ajax.js"></script>
<script src="https://raw.github.com/vjeux/jDataView/master/src/jdataview.js"></script>
<script src="https://raw.github.com/vjeux/jParser/master/src/jparser.js"></script>
<script>
$.get('file.bin', function (data) {
var parser = new jParser(data, {
magic: ['array', 'uint8', 4]
});
console.log(parser.parse('magic'));
}, 'dataview');
</script>
Предосторожности
Этот иструмент в своей работе полагается на недокументированную особенность JavaScript: обход полей объекта работает в том порядке, в каком они указывались. Имейте в виду, что в Chrome и в Opera это неявное правило не работает для полей с цифровыми именами.
Следуйте вот каким двум правилам, чтобы эта библиотека работала во всех существующих реализациях языка JavaScript:
- Не начинайте имя поля цифрою в описании структуры данных.
- Не переопределяйте поле с однажды заданным именем, не помещайте в тот же объект другое одноимённое поле.
Демо
Анализ ICO. Это простой пример анализа двоичного файла на движке NodeJS. Он показывает, как решаются многие типичные задачи, возникающие при разборе двоичных данных.
Распаковщик Tar. Это простой пример разбора двоичного файла внутри браузера.
- tar.html — структура jParser.
Средство показа моделей World of Warcraft. Использует jParser для чтения двоичного кода трёхмерной модели, затем WebGL для её отображения.
- m2.js — структура jParser.
- model.json — итог анализа.
![[скриншот]](http://habrastorage.org/r/w1560/storage2/a69/478/a17/a69478a173a7edeff68ee0108454944a.png)
Внутренние файлы Diablo 3
- convert.coffee — структура для jParser. Кофескриптом записывать структуру файла ещё проще.
- Примеры обработанных файлов: