Skip to content

Instantly share code, notes, and snippets.

@jasonhuck
Created January 22, 2016 13:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jasonhuck/25eada9eea448617ed34 to your computer and use it in GitHub Desktop.
Save jasonhuck/25eada9eea448617ed34 to your computer and use it in GitHub Desktop.
Optimized JSON encoder for Lasso 8.x
[//lasso
define_tag(
'json',
-namespace='_page_encode_',
-req='value',
-opt='options',
-description='Updated version of [encode_json] with speed improvements by James Harvard.',
-encodenone
);
local(
'escapes' = map(
'\\' = '\\',
'"' = '"',
'\r' = 'r',
'\n' = 'n',
'\t' = 't',
'\f' = 'f',
'\b' = 'b'
),
'output' = '',
'newoptions' = array( -internal)
);
!local_defined('options') || !#options->isa('array') ? local('options') = array;
#options >> -usenative || params >> -usenative ? #newoptions->insert( -usenative);
#options >> -nonative || params >> -nonative ? #newoptions->insert( -nonative);
if(#options !>> -usenative && (: 'set', 'list', 'queue', 'priorityqueue', 'stack') >> #value->type);
#output += encode_json( array->insertfrom(#value->iterator)&, -options=#newoptions);
else(#options !>> -usenative && #value->isa('pair'));
#output += encode_json(array(#value->first, #value->second));
else(#options !>> -internal && (: 'array', 'map') !>> #value->type);
#output += '[' + encode_json(#value, -options=#newoptions) + ']';
else(#value->isa('literal'));
#output += #value;
else(#value->isa('string'));
#output += '"';
local(
'char' = null,
'regexp' = regexp(-find='[\\x{0020}-\\x{21}\\x{23}-\\x{5b}\\x{5d}-\\x{10fff}]')
);
iterate(#value, #char);
#output += (#regexp->input(#char)&matches ? #char | '\\' + (#escapes >> #char ? #escapes->find(#char) | 'u' + string(encode_hex(#char))->padleading(4, '0')&));
/iterate;
#output += '"';
else( (: 'integer', 'decimal', 'boolean') >> #value->type);
#output += string(#value);
else(#value == null);
#output += 'null';
else(#value->isa('date'));
local('format') = '%QT%T' + (#value->gmt ? 'Z');
#output += '"' + #value->format(#format) + '"';
else(#value->isa('array'));
#output += '[';
local('temp');
iterate(#value, #temp);
#output += encode_json(#temp, -options=#newoptions) + ', ';
/iterate;
#output->removetrailing(', ')&append(']');
else(#value->isa('object'));
#output += '{';
local('temp');
iterate(#value, #temp);
#output += #temp->first + ': ' + encode_json(#temp->second, -options=#newoptions) + ', ';
/iterate;
#output->removetrailing(', ')&append('}');
else(#value->isa('map'));
#output += '{';
local('temp');
iterate(#value, #temp);
#output += encode_json(#temp->first, -options=#newoptions) + ': ' + encode_json(#temp->second, -options=#newoptions) + ', ';
/iterate;
#output->removetrailing(', ')&append('}');
else(#value->isa('client_ip') || #value->isa('client_address'));
#output += encode_json(string(#value), -options=#newoptions);
else(#options !>> -nonative);
#output += encode_json(map('__jsonclass__' = array('deserialize', array(#value->serialize))));
/if;
return(@#output);
/define_tag;
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment