Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

fix deserialization of collection types

  • Loading branch information...
commit d919466ab43104ae4207220e25ac3a4afa26f3b5 1 parent e717734
@devdazed devdazed authored
Showing with 84 additions and 62 deletions.
  1. +0 −44 lib/marshal/deserializers.js
  2. +84 −18 lib/marshal/index.js
View
44 lib/marshal/deserializers.js
@@ -46,50 +46,6 @@ Deserializers.decodeBinary = function(val){
return new Buffer(val, 'binary');
};
-// https://github.com/simplereach/helenus/issues/96
-Deserializers.decodeCollection = function (deserializers) {
- return function(str) {
- if(str === null || str === undefined) {
- return null;
- }
-
- var buf = new Buffer(str, 'binary'),
- pos = 3, len, keys = [], vals = [], i = 0, result;
-
- while(pos < buf.length){
- if(i > deserializers.length - 1) {
- i = 0;
- }
-
- len = buf.readUInt16BE(pos);
- pos += 2;
-
- if(i == 0 && deserializers.length == 2) {
- keys.push(deserializers[i](buf.slice(pos, len + pos)));
- }
- else if(i == 0 && deserializers.length == 1 || i == 1 && deserializers.length == 2) {
- vals.push(deserializers[i](buf.slice(pos, len + pos)));
- }
-
- i += 1;
-
- pos += len;
- }
-
- if(keys.length === vals.length) {
- result = {}
- for(var i = 0, len = keys.length; i < len; i++) {
- result[keys[i]] = vals[i];
- }
- }
- else {
- result = vals;
- }
-
- return result;
- };
-};
-
/**
* Decodes a Long (Int64)
* @static
View
102 lib/marshal/index.js
@@ -58,15 +58,18 @@ function getType(str){
}
function getMapType(str){
- return 'MapType';
+ var index = str.indexOf('<');
+ return index > 0 ? getCompositeTypes(str.substring(index + 1, str.length - 1)) : str;
}
function getSetType(str){
- return 'SetType';
+ var index = str.indexOf('<');
+ return index > 0 ? getType(str.substring(index + 1, str.length - 1)) : str;
}
function getListType(str){
- return 'ListType';
+ var index = str.indexOf('<');
+ return index > 0 ? getType(str.substring(index + 1, str.length - 1)) : str;
}
@@ -108,23 +111,23 @@ function getCompositeTypes(str){
*/
function parseTypeString(type){
if (type.indexOf('CompositeType') > -1){
- return getCompositeTypes(type);
+ return { baseType: 'CompositeType', subType: getCompositeTypes(type) };
} else if(type.indexOf('ReversedType') > -1){
- return getType(getInnerType(type));
+ return { baseType: 'ReversedType', subType: getType(getInnerType(type)) };
}
else if(type.indexOf('org.apache.cassandra.db.marshal.SetType') > -1){
- return getSetType(type);
+ return { baseType: 'SetType', subType: getType(getInnerType(type)) };
}
else if(type.indexOf('org.apache.cassandra.db.marshal.ListType') > -1){
- return getListType(type);
+ return { baseType: 'ListType', subType: getType(getInnerType(type)) };
}
else if(type.indexOf('org.apache.cassandra.db.marshal.MapType') > -1){
- return getMapType(type);
+ return { baseType: 'MapType', subType: getCompositeTypes(type) };
}
else if(type === null || type === undefined) {
- return 'BytesType';
+ return { baseType: null, subType: 'BytesType' };
} else {
- return getType(type);
+ return {baseType: null, subType: getType(type) };
}
}
@@ -224,20 +227,74 @@ function compositeDeserializer(deserializers){
}
/**
+ * Descodes SetType and ListType
+ * @private
+ * @memberOf Marshal
+ */
+function listDeserializer(deserializer){
+ return function(str){
+ var buf = new Buffer(str, 'binary'),
+ pos = 2, len, vals = [], key, value;
+
+ while( pos < buf.length){
+ len = buf.readUInt16BE(pos);
+ pos += 2
+ value = deserializer(buf.slice(pos, len + pos));
+ pos += len
+
+ vals.push(value)
+ }
+
+ return vals;
+ };
+}
+
+/**
+ * Descodes MapType
+ * @private
+ * @memberOf Marshal
+ */
+function mapDeserializer(deserializers){
+ return function(str){
+ var buf = new Buffer(str, 'binary'),
+ pos = 2, len, vals = {}, key, value;
+
+ while( pos < buf.length){
+ len = buf.readUInt16BE(pos);
+ pos += 2
+ key = deserializers[0](buf.slice(pos, len + pos))
+ pos += len
+
+ len = buf.readUInt16BE(pos);
+ pos += 2;
+ value = deserializers[1](buf.slice(pos, len + pos))
+ pos += len
+ vals[key] = value;
+ }
+
+ return vals;
+ };
+}
+
+/**
* Gets the serializer(s) for a specific type
* @private
* @memberOf Marshal
*/
function getSerializer(type){
- if (Array.isArray(type)){
- var i = 0, typeLength = type.length, serializers = [];
+ if (type.baseType === 'CompositeType'){
+ var i = 0, typeLength = type.subType.length, serializers = [];
for(; i < typeLength; i += 1){
- serializers.push( getSerializer(type[i]));
+ serializers.push( getSerializer(type.subType[i]));
}
return compositeSerializer(serializers);
+ } else if (type.baseType === 'ListType' || type.baseType == 'SetType' || type.baseType === 'MapType'){
+ return function(){
+ throw('Serializing MapType, ListType and SetType is not currently supported');
+ }
} else {
- return TYPES[type.replace(/^\s+|\s+$/g,'')].ser;
+ return TYPES[type.subType.replace(/^\s+|\s+$/g,'')].ser;
}
}
@@ -247,16 +304,22 @@ function getSerializer(type){
* @memberOf Marshal
*/
function getDeserializer(type){
- if (Array.isArray(type)){
+ if (type.baseType === 'CompositeType'){
var i = 0, typeLength = type.length, deserializers = [];
for(; i < typeLength; i += 1){
- deserializers.push( getDeserializer(type[i]));
+ deserializers.push( TYPES[type.subType].de );
}
return compositeDeserializer(deserializers);
+ } else if (type.baseType === 'ListType' || type.baseType == 'SetType'){
+ var subtypeDeserializer = getDeserializer({ baseType:null, subType: type.subType });
+ return listDeserializer(subtypeDeserializer);
+ } else if (type.baseType === 'MapType'){
+ var subtypeDeserializers = type.subType.map(function(t){ return getDeserializer(t) });
+ return mapDeserializer(subtypeDeserializers);
} else {
return function(val) {
- return val !== null ? TYPES[type].de(val) : null;
+ return val !== null ? TYPES[type.subType].de(val) : null;
};
}
}
@@ -269,7 +332,10 @@ function getDeserializer(type){
var Marshal = function(type){
var parsedType = parseTypeString(type);
this.type = parsedType;
- this.isComposite = Array.isArray(parsedType);
+ this.isComposite = parsedType.baseType === 'CompositeType'
+ this.isMap = parsedType.baseType === 'MapType';
+ this.isList = parsedType.baseType === 'ListType';
+ this.isSet = parsedType.baseType === 'SetType';
/**
* Serializes data for the type specified
Please sign in to comment.
Something went wrong with that request. Please try again.