mirror of
https://github.com/NuSkooler/enigma-bbs.git
synced 2025-08-05 09:21:30 +02:00
Major commit for new message network WIP
This commit is contained in:
parent
6750c05f07
commit
317af8419a
40 changed files with 1747 additions and 599 deletions
165
core/sauce.js
Normal file
165
core/sauce.js
Normal file
|
@ -0,0 +1,165 @@
|
|||
/* jslint node: true */
|
||||
'use strict';
|
||||
|
||||
var binary = require('binary');
|
||||
var iconv = require('iconv-lite');
|
||||
|
||||
exports.readSAUCE = readSAUCE;
|
||||
|
||||
|
||||
const SAUCE_SIZE = 128;
|
||||
const SAUCE_ID = new Buffer([0x53, 0x41, 0x55, 0x43, 0x45]); // 'SAUCE'
|
||||
const COMNT_ID = new Buffer([0x43, 0x4f, 0x4d, 0x4e, 0x54]); // 'COMNT'
|
||||
|
||||
// :TODO: SAUCE should be a class
|
||||
// - with getFontName()
|
||||
// - ...other methods
|
||||
|
||||
//
|
||||
// See
|
||||
// http://www.acid.org/info/sauce/sauce.htm
|
||||
//
|
||||
function readSAUCE(data, cb) {
|
||||
if(data.length < SAUCE_SIZE) {
|
||||
cb(new Error('No SAUCE record present'));
|
||||
return;
|
||||
}
|
||||
|
||||
var offset = data.length - SAUCE_SIZE;
|
||||
var sauceRec = data.slice(offset);
|
||||
|
||||
binary.parse(sauceRec)
|
||||
.buffer('id', 5)
|
||||
.buffer('version', 2)
|
||||
.buffer('title', 35)
|
||||
.buffer('author', 20)
|
||||
.buffer('group', 20)
|
||||
.buffer('date', 8)
|
||||
.word32lu('fileSize')
|
||||
.word8('dataType')
|
||||
.word8('fileType')
|
||||
.word16lu('tinfo1')
|
||||
.word16lu('tinfo2')
|
||||
.word16lu('tinfo3')
|
||||
.word16lu('tinfo4')
|
||||
.word8('numComments')
|
||||
.word8('flags')
|
||||
.buffer('tinfos', 22) // SAUCE 00.5
|
||||
.tap(function onVars(vars) {
|
||||
|
||||
if(!SAUCE_ID.equals(vars.id)) {
|
||||
cb(new Error('No SAUCE record present'));
|
||||
return;
|
||||
}
|
||||
|
||||
var ver = iconv.decode(vars.version, 'cp437');
|
||||
|
||||
if('00' !== ver) {
|
||||
cb(new Error('Unsupported SAUCE version: ' + ver));
|
||||
return;
|
||||
}
|
||||
|
||||
var sauce = {
|
||||
id : iconv.decode(vars.id, 'cp437'),
|
||||
version : iconv.decode(vars.version, 'cp437').trim(),
|
||||
title : iconv.decode(vars.title, 'cp437').trim(),
|
||||
author : iconv.decode(vars.author, 'cp437').trim(),
|
||||
group : iconv.decode(vars.group, 'cp437').trim(),
|
||||
date : iconv.decode(vars.date, 'cp437').trim(),
|
||||
fileSize : vars.fileSize,
|
||||
dataType : vars.dataType,
|
||||
fileType : vars.fileType,
|
||||
tinfo1 : vars.tinfo1,
|
||||
tinfo2 : vars.tinfo2,
|
||||
tinfo3 : vars.tinfo3,
|
||||
tinfo4 : vars.tinfo4,
|
||||
numComments : vars.numComments,
|
||||
flags : vars.flags,
|
||||
tinfos : vars.tinfos,
|
||||
};
|
||||
|
||||
var dt = SAUCE_DATA_TYPES[sauce.dataType];
|
||||
if(dt && dt.parser) {
|
||||
sauce[dt.name] = dt.parser(sauce);
|
||||
}
|
||||
|
||||
cb(null, sauce);
|
||||
});
|
||||
}
|
||||
|
||||
// :TODO: These need completed:
|
||||
var SAUCE_DATA_TYPES = {};
|
||||
SAUCE_DATA_TYPES[0] = { name : 'None' };
|
||||
SAUCE_DATA_TYPES[1] = { name : 'Character', parser : parseCharacterSAUCE };
|
||||
SAUCE_DATA_TYPES[2] = 'Bitmap';
|
||||
SAUCE_DATA_TYPES[3] = 'Vector';
|
||||
SAUCE_DATA_TYPES[4] = 'Audio';
|
||||
SAUCE_DATA_TYPES[5] = 'BinaryText';
|
||||
SAUCE_DATA_TYPES[6] = 'XBin';
|
||||
SAUCE_DATA_TYPES[7] = 'Archive';
|
||||
SAUCE_DATA_TYPES[8] = 'Executable';
|
||||
|
||||
var SAUCE_CHARACTER_FILE_TYPES = {};
|
||||
SAUCE_CHARACTER_FILE_TYPES[0] = 'ASCII';
|
||||
SAUCE_CHARACTER_FILE_TYPES[1] = 'ANSi';
|
||||
SAUCE_CHARACTER_FILE_TYPES[2] = 'ANSiMation';
|
||||
SAUCE_CHARACTER_FILE_TYPES[3] = 'RIP script';
|
||||
SAUCE_CHARACTER_FILE_TYPES[4] = 'PCBoard';
|
||||
SAUCE_CHARACTER_FILE_TYPES[5] = 'Avatar';
|
||||
SAUCE_CHARACTER_FILE_TYPES[6] = 'HTML';
|
||||
SAUCE_CHARACTER_FILE_TYPES[7] = 'Source';
|
||||
SAUCE_CHARACTER_FILE_TYPES[8] = 'TundraDraw';
|
||||
|
||||
//
|
||||
// Map of SAUCE font -> encoding hint
|
||||
//
|
||||
// Note that this is the same mapping that x84 uses. Be compatible!
|
||||
//
|
||||
var SAUCE_FONT_TO_ENCODING_HINT = {
|
||||
'Amiga MicroKnight' : 'amiga',
|
||||
'Amiga MicroKnight+' : 'amiga',
|
||||
'Amiga mOsOul' : 'amiga',
|
||||
'Amiga P0T-NOoDLE' : 'amiga',
|
||||
'Amiga Topaz 1' : 'amiga',
|
||||
'Amiga Topaz 1+' : 'amiga',
|
||||
'Amiga Topaz 2' : 'amiga',
|
||||
'Amiga Topaz 2+' : 'amiga',
|
||||
'Atari ATASCII' : 'atari',
|
||||
'IBM EGA43' : 'cp437',
|
||||
'IBM EGA' : 'cp437',
|
||||
'IBM VGA25G' : 'cp437',
|
||||
'IBM VGA50' : 'cp437',
|
||||
'IBM VGA' : 'cp437',
|
||||
};
|
||||
|
||||
['437', '720', '737', '775', '819', '850', '852', '855', '857', '858',
|
||||
'860', '861', '862', '863', '864', '865', '866', '869', '872'].forEach(function onPage(page) {
|
||||
var codec = 'cp' + page;
|
||||
SAUCE_FONT_TO_ENCODING_HINT['IBM EGA43 ' + page] = codec;
|
||||
SAUCE_FONT_TO_ENCODING_HINT['IBM EGA ' + page] = codec;
|
||||
SAUCE_FONT_TO_ENCODING_HINT['IBM VGA25g ' + page] = codec;
|
||||
SAUCE_FONT_TO_ENCODING_HINT['IBM VGA50 ' + page] = codec;
|
||||
SAUCE_FONT_TO_ENCODING_HINT['IBM VGA ' + page] = codec;
|
||||
});
|
||||
|
||||
function parseCharacterSAUCE(sauce) {
|
||||
var result = {};
|
||||
|
||||
result.fileType = SAUCE_CHARACTER_FILE_TYPES[sauce.fileType] || 'Unknown';
|
||||
|
||||
if(sauce.fileType === 0 || sauce.fileType === 1 || sauce.fileType === 2) {
|
||||
// convience: create ansiFlags
|
||||
sauce.ansiFlags = sauce.flags;
|
||||
|
||||
var i = 0;
|
||||
while(i < sauce.tinfos.length && sauce.tinfos[i] !== 0x00) {
|
||||
++i;
|
||||
}
|
||||
var fontName = iconv.decode(sauce.tinfos.slice(0, i), 'cp437');
|
||||
if(fontName.length > 0) {
|
||||
result.fontName = fontName;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue