Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Basic attempt at a php deserializer in CFML
component {
public any function run(required string data){
variables.data = arguments.data;
variables.position = 1;
variables.bytebuffer = CreateObject("java", "java.nio.ByteBuffer");
return deserializeItem();
}
private any function deserializeItem(){
// Don't use readUntil for this, because some types (like Null) use a different stop char
var type = Mid(variables.data, variables.position, 1);
variables.position += 2; //Skip over the : or ; after type
switch(type){
case 'a':
var shell = {};
var numKeys = readUntil(':');
variables.position += 1; // Skip the opening {
var isArrayLike = true;
for( var i = 0; i < numKeys; i++ ){
var key = deserializeItem();
var value = deserializeItem();
isArrayLike = isArrayLike && IsSimpleValue(key) && key == i;
shell[key] = value;
}
if( isArrayLike ){
var arrShell = [];
for( var i = 0; i < numKeys; i++ ){
arrShell.Append(shell[i]);
}
shell = arrShell;
}
variables.position += 1; // Skip over closing }
return shell;
break;
case 'b':
return !!Val(readUntil(';'));
break;
case 'd':
case 'i':
return readUntil(';');
break;
case 'N':
return ''; // Or w/e you want to be "null"
break;
case 's':
var length = readUntil(':');
var value = getString(length);
variables.position += 3 + Len(value); // Skip value, with enclosing quotes and the ;
return value;
break;
default:
throw( message = "Unknown Type: #type# Current position: #variables.position#",
detail = Mid(variables.data, variables.position - 20, 20));
}
}
/* Gets a string value of a specific bytelength, doesn't alter position */
private string function getString(required numeric length){
var applicableString = Mid(variables.data, variables.position + 1, arguments.length);
var asbinary = charsetDecode( applicableString, "utf-8" );
var buffer = variables.bytebuffer.Allocate( JavaCast( "int", arguments.length ) );
buffer.Put( asbinary, JavaCast( "int", 0 ), JavaCast( "int", arguments.length ) );
var binarySubString = buffer.Array();
return charsetEncode( binarySubString, "utf-8" );
}
/* Gets the value from current position to stop char, then sets the position to one after the stop char */
private string function readUntil(required string stopChar){
var stopCharPos = Find(arguments.stopChar, variables.data, variables.position);
var length = stopCharPos - variables.position;
var value = Mid(variables.data, variables.position, length);
variables.position = stopCharPos + 1;
return value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment