Template:Groningen/message js

var Message = {};

(function(){ /* Structure: * * Start: 'Spy': 3 * 3 base-pairs * Length: 16 bit number: 8 base-pairs * CRC32: 16 bit number: 8 base-pairs * Data: '...': length * 3 base-pairs * End: 'GEM': 3 * 3 base-pairs */ var lengths = { 'start': 3 * 3, 'len': 8, 'crc': 8, 'end': 3 * 3 }; var offsets = {}; offsets.start = 0; offsets.len = offsets.start + lengths.start; offsets.crc = offsets.len + lengths.len; offsets.data = offsets.crc + lengths.crc;

var packDNA = function(dna, ext){ var len = dna.length, crc = CRC.crc16(dna), dnaStart = SixFour.encodeStr('Spy'), dnaEnd = SixFour.encodeStr('GEM'), dnaLen = DNA.padUInt(DNA.encodeUInt(len), lengths.len), dnaCrc = DNA.padUInt(DNA.encodeUInt(crc), lengths.crc), msg = dnaStart + dnaLen + dnaCrc + dna + dnaEnd;

if(ext){ return { 'msg': msg, 'len': len, 'crc': crc, 'dnaStart': dnaStart, 'dnaEnd': dnaEnd, 'dnaLen': dnaLen, 'dnaCrc': dnaCrc }; }

return msg; };

var unpackDNA = function(msg, ext){ var dnaStart = msg.substr(offsets.start, lengths.start), start = SixFour.decodeStr(dnaStart);

if(start !== 'Spy'){ // start mismatch throw new Error("Start mismatch: '"+start+"' / 'Spy'"); return null; }

var dnaLen = msg.substr(offsets.len, lengths.len), len = DNA.decodeUInt(dnaLen), dnaCrc = msg.substr(offsets.crc, lengths.crc), crc = DNA.decodeUInt(dnaCrc), data = msg.substr(offsets.data, len);

if(CRC.crc16(data) !== crc){ // checksum mismatch throw new Error('CRC mismatch: '+CRC.crc16(data)+' / '+crc); return null; }

var dnaEnd = msg.substr(offsets.data + len, lengths.end), end = SixFour.decodeStr(dnaEnd);

if(end !== 'GEM'){ throw new Error("End mismatch: '"+end+"' / 'GEM'"); return null; }

if(ext){ return { 'data': data, 'len': len, 'crc': crc, 'dnaStart': dnaStart, 'dnaEnd': dnaEnd, 'dnaLen': dnaLen, 'dnaCrc': dnaCrc }; }

return data; };

Message = { 'packDNA': packDNA, 'unpackDNA': unpackDNA }; })();