Skip to content

Instantly share code, notes, and snippets.

@Geokureli
Created December 20, 2024 22:54
Show Gist options
  • Save Geokureli/e567dc2d7cdc9d722b4533e4b08d41eb to your computer and use it in GitHub Desktop.
Save Geokureli/e567dc2d7cdc9d722b4533e4b08d41eb to your computer and use it in GitHub Desktop.
package data.tools;
enum MissingData
{
CLASS(name:String, fields:Any);
CLASS_T(name:String);
ENUM(name:String, tag:MissingEnumTag, args:Array<Any>);
ENUM_T(name:String);
}
enum MissingEnumTag
{
INDEX(i:Int);
NAME(n:String);
}
class NoFailUnserializer extends haxe.Unserializer
{
override function unserialize():Dynamic
{
@:keep final startPos = pos;
switch get(pos++)
{
case "c".code:
var name = unserialize();
var cl = resolver.resolveClass(name);
if (cl == null)
{
final proxy = {};
unserializeObject(proxy);
final o = MissingData.CLASS(name, proxy);
cache.push(o);
return o;
}
var o = Type.createEmptyInstance(cl);
cache.push(o);
unserializeObject(o);
return o;
case "w".code:
var name = unserialize();
var edecl = resolver.resolveEnum(name);
if (edecl == null)
{
final tag = MissingEnumTag.NAME(unserialize());
final e = unserializeNullEnum(name, tag);
cache.push(e);
return e;
}
var e = unserializeEnum(edecl, unserialize());
cache.push(e);
return e;
case "j".code:
var name = unserialize();
var edecl = resolver.resolveEnum(name);
if (edecl == null)
{
pos++; /* skip ':' */
final tag = MissingEnumTag.INDEX(readDigits());
final e = unserializeNullEnum(name, tag);
cache.push(e);
return e;
}
pos++; /* skip ':' */
var index = readDigits();
var tag = Type.getEnumConstructs(edecl)[index];
if (tag == null)
throw "Unknown enum index " + name + "@" + index;
var e = unserializeEnum(edecl, tag);
cache.push(e);
return e;
case "C".code:
var name = unserialize();
var cl = resolver.resolveClass(name);
if (cl == null)
{
final o = MissingData.CLASS(name, null);
cache.push(o);
if (get(pos++) != "g".code)
throw "Invalid custom data";
return null;
}
var o:Dynamic = Type.createEmptyInstance(cl);
cache.push(o);
o.hxUnserialize(this);
if (get(pos++) != "g".code)
throw "Invalid custom data";
return o;
case "A".code:
var name = unserialize();
var cl = resolver.resolveClass(name);
if (cl == null)
return MissingData.CLASS_T(name);
return cl;
case "B".code:
var name = unserialize();
var e = resolver.resolveEnum(name);
if (e == null)
return MissingData.ENUM_T(name);
return e;
case unhandled:
@:keep final char = String.fromCharCode(unhandled);
pos--;
return super.unserialize();
}
}
override function unserializeEnum<T>(edecl:Enum<T>, tag:String)
{
if (edecl == null)
throw "null enum";
return super.unserializeEnum(edecl, tag);
}
function unserializeNullEnum<T>(name:String, tag:MissingEnumTag)
{
if (get(pos++) != ":".code)
throw "Invalid enum format";
var nargs = readDigits();
final args = new Array();
while (nargs-- > 0)
args.push(unserialize());
return MissingData.ENUM(name, tag, args);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment