UNPKG

protodef

Version:

A simple yet powerful way to define binary protocols

91 lines (79 loc) 3.27 kB
const { getField, getCount, sendCount, calcCount, tryDoc } = require("../utils"); module.exports = { 'array': [readArray, writeArray, sizeOfArray, require('../../ProtoDef/schemas/structures')['array']], 'count': [readCount, writeCount, sizeOfCount, require('../../ProtoDef/schemas/structures')['count']], 'container': [readContainer, writeContainer, sizeOfContainer, require('../../ProtoDef/schemas/structures')['container']] }; function readArray(buffer, offset, typeArgs, rootNode) { const results = { value: [], size: 0 }; let value; let { count, size } = getCount.call(this, buffer, offset, typeArgs, rootNode); offset += size; results.size += size; for(let i = 0; i < count; i++) { ({size,value}=tryDoc(() => this.read(buffer, offset, typeArgs.type, rootNode), i)); results.size += size; offset += size; results.value.push(value); } return results; } function writeArray(value, buffer, offset, typeArgs, rootNode) { offset = sendCount.call(this, value.length, buffer, offset, typeArgs, rootNode); return value.reduce((offset,v,index) =>tryDoc(() => this.write(v, buffer, offset, typeArgs.type, rootNode),index),offset); } function sizeOfArray(value, typeArgs, rootNode) { let size = calcCount.call(this, value.length, typeArgs, rootNode); size = value.reduce((size,v,index) =>tryDoc(() => size+this.sizeOf(v, typeArgs.type, rootNode), index),size); return size; } function readContainer(buffer, offset, typeArgs, context) { const results = { value: { "..": context }, size: 0 }; typeArgs.forEach(({type,name,anon}) => { tryDoc(() => { const readResults = this.read(buffer, offset, type, results.value); results.size += readResults.size; offset += readResults.size; if (anon) { if(readResults.value !== undefined) Object.keys(readResults.value).forEach(function(key) { results.value[key] = readResults.value[key]; }); } else results.value[name] = readResults.value; }, name ? name : "unknown"); }); delete results.value[".."]; return results; } function writeContainer(value, buffer, offset, typeArgs, context) { value[".."] = context; offset=typeArgs.reduce((offset,{type,name,anon}) => tryDoc(() => this.write(anon ? value : value[name], buffer, offset, type, value),name ? name : "unknown"),offset); delete value[".."]; return offset; } function sizeOfContainer(value, typeArgs, context) { value[".."] = context; const size = typeArgs.reduce((size,{type,name,anon}) => size + tryDoc(() => this.sizeOf(anon ? value : value[name], type, value), name ? name : "unknown"),0); delete value[".."]; return size; } function readCount(buffer, offset, {type}, rootNode) { return this.read(buffer, offset, type, rootNode); } function writeCount(value, buffer, offset, {countFor,type}, rootNode) { // Actually gets the required field, and writes its length. Value is unused. // TODO : a bit hackityhack. return this.write(getField(countFor, rootNode).length, buffer, offset, type, rootNode); } function sizeOfCount(value, {countFor,type}, rootNode) { // TODO : should I use value or getField().length ? return this.sizeOf(getField(countFor, rootNode).length, type, rootNode); }