127 lines
4.3 KiB
JavaScript

var getField = require("../utils").getField;
var debug = require("../debug");
var evalCondition = require("../utils").evalCondition;
module.exports = {
'array': [readArray, writeArray, sizeOfArray],
'count': [readCount, writeCount, sizeOfCount],
'container': [readContainer, writeContainer, sizeOfContainer]
};
function evalCount(count, fields) {
if(fields[count["field"]] in count["map"])
return count["map"][fields[count["field"]]];
return count["default"];
}
function readArray(buffer, offset, typeArgs, rootNode) {
var results = {
value: [],
size: 0
};
var count;
if(typeof typeArgs.count === "object")
count = evalCount(typeArgs.count, rootNode);
else if (typeof typeArgs.count !== "undefined")
count = getField(typeArgs.count, rootNode);
else if (typeof typeArgs.countType !== "undefined") {
var countResults = this.read(buffer, offset, { type: typeArgs.countType, typeArgs: typeArgs.countTypeArgs }, rootNode);
results.size += countResults.size;
offset += countResults.size;
count = countResults.value;
} else // TODO : broken schema, should probably error out.
count = 0;
for(var i = 0; i < count; i++) {
var readResults = this.read(buffer, offset, typeArgs.type, rootNode);
results.size += readResults.size;
offset += readResults.size;
results.value.push(readResults.value);
}
return results;
}
function writeArray(value, buffer, offset, typeArgs, rootNode) {
if (typeof typeArgs.count === "undefined" &&
typeof typeArgs.countType !== "undefined") {
offset = this.write(value.length, buffer, offset, { type: typeArgs.countType, typeArgs: typeArgs.countTypeArgs }, rootNode);
} else if (typeof typeArgs.count === "undefined") { // Broken schema, should probably error out
}
for(var index in value) {
offset = this.write(value[index], buffer, offset, typeArgs.type, rootNode);
}
return offset;
}
function sizeOfArray(value, typeArgs, rootNode) {
var size = 0;
if (typeof typeArgs.count === "undefined" &&
typeof typeArgs.countType !== "undefined") {
size = this.sizeOf(value.length, { type: typeArgs.countType, typeArgs: typeArgs.countTypeArgs }, rootNode);
}
for(var index in value) {
size += this.sizeOf(value[index], typeArgs.type, rootNode);
}
return size;
}
function readContainer(buffer, offset, typeArgs, rootNode) {
var results = {
value: {},
size: 0
};
// BLEIGH. Huge hack because I have no way of knowing my current name.
// TODO : either pass fieldInfo instead of typeArgs as argument (bleigh), or send name as argument (verybleigh).
// TODO : what I do inside of roblabla/Protocols is have each "frame" create a new empty slate with just a "super" object pointing to the parent.
var backupThis = rootNode.this;
rootNode.this = results.value;
for(var index in typeArgs) {
var readResults = this.read(buffer, offset, typeArgs[index].type, rootNode);
if(readResults == null || readResults.value == null) {
continue;
}
results.size += readResults.size;
offset += readResults.size;
results.value[typeArgs[index].name] = readResults.value;
}
rootNode.this = backupThis;
return results;
}
function writeContainer(value, buffer, offset, typeArgs, rootNode) {
var backupThis = rootNode.this;
rootNode.this = value;
for(var index in typeArgs) {
offset = this.write(value[typeArgs[index].name], buffer, offset, typeArgs[index].type, rootNode);
}
rootNode.this = backupThis;
return offset;
}
function sizeOfContainer(value, typeArgs, rootNode) {
var size = 0;
var backupThis = rootNode.this;
rootNode.this = value;
for(var index in typeArgs) {
size += this.sizeOf(value[typeArgs[index].name], typeArgs[index].type, rootNode);
}
rootNode.this = backupThis;
return size;
}
function readCount(buffer, offset, typeArgs, rootNode) {
return this.read(buffer, offset, typeArgs.type, rootNode);
}
function writeCount(value, buffer, offset, typeArgs, rootNode) {
// Actually gets the required field, and writes its length. Value is unused.
// TODO : a bit hackityhack.
return this.write(getField(typeArgs.countFor, rootNode).length, buffer, offset, typeArgs.type, rootNode);
}
function sizeOfCount(value, typeArgs, rootNode) {
// TODO : should I use value or getField().length ?
return this.sizeOf(getField(typeArgs.countFor, rootNode).length, typeArgs.type, rootNode);
}