diff --git a/weaseljson.py b/weaseljson.py index 046b263..4b20012 100644 --- a/weaseljson.py +++ b/weaseljson.py @@ -33,52 +33,7 @@ class WeaselJsonStatus(enum.Enum): OVERFLOW = 3 -class WeaselJsonParserBase: - def __init__( - self, - build_dir: Optional[str] = None, - stackSize: int = 1024, - ) -> None: - self._lib = None - if build_dir is None: - build_dir = os.path.dirname(__file__) + "/build" - for f in (build_dir + "/" + "libweaseljson.so",): - try: - self._lib = ctypes.cdll.LoadLibrary(f) - except OSError: - print("Could not load " + f) - pass - - if self._lib is None: - import sys - - print( - "Could not find libweaseljson implementation", - file=sys.stderr, - ) - sys.exit(1) - - self._lib.WeaselJsonParser_create.argtypes = ( - ctypes.c_int, - ctypes.POINTER(WeaselJsonCallbacks), - ctypes.c_void_p, - ) - self._lib.WeaselJsonParser_create.restype = ctypes.c_void_p - self._lib.WeaselJsonParser_reset.argtypes = (ctypes.c_void_p,) - self._lib.WeaselJsonParser_destroy.argtypes = (ctypes.c_void_p,) - self._lib.WeaselJsonParser_parse.argtypes = ( - ctypes.c_void_p, - ctypes.c_void_p, - ctypes.c_int, - ) - self._lib.WeaselJsonParser_parse.restype = WeaselJsonStatus - - self.p = self._lib.WeaselJsonParser_create( - stackSize, - callbacks, - ctypes.cast(ctypes.pointer(ctypes.py_object(self)), ctypes.c_void_p), - ) - +class WeaselJsonCallbacksBase: def on_begin_object(self): pass @@ -118,6 +73,57 @@ class WeaselJsonParserBase: def on_null_literal(self): pass + +class WeaselJsonParser: + def __init__( + self, + callbacks: WeaselJsonCallbacksBase, + build_dir: Optional[str] = None, + stackSize: int = 1024, + ) -> None: + self._lib = None + if build_dir is None: + build_dir = os.path.dirname(__file__) + "/build" + for f in (build_dir + "/" + "libweaseljson.so",): + try: + self._lib = ctypes.cdll.LoadLibrary(f) + except OSError: + print("Could not load " + f) + pass + + if self._lib is None: + import sys + + print( + "Could not find libweaseljson implementation", + file=sys.stderr, + ) + sys.exit(1) + + self._lib.WeaselJsonParser_create.argtypes = ( + ctypes.c_int, + ctypes.POINTER(WeaselJsonCallbacks), + ctypes.c_void_p, + ) + self._lib.WeaselJsonParser_create.restype = ctypes.c_void_p + self._lib.WeaselJsonParser_reset.argtypes = (ctypes.c_void_p,) + self._lib.WeaselJsonParser_destroy.argtypes = (ctypes.c_void_p,) + self._lib.WeaselJsonParser_parse.argtypes = ( + ctypes.c_void_p, + ctypes.c_void_p, + ctypes.c_int, + ) + self._lib.WeaselJsonParser_parse.restype = WeaselJsonStatus + self.voidp_callbacks = ctypes.cast( + ctypes.pointer(ctypes.py_object(callbacks)), ctypes.c_void_p + ) + + self.p = self._lib.WeaselJsonParser_create( + stackSize, + c_callbacks, + self.voidp_callbacks, + ) + def parse(self, data: bytes) -> WeaselJsonStatus: buf = (ctypes.c_ubyte * len(data)).from_buffer(bytearray(data)) return self._lib.WeaselJsonParser_parse(self.p, buf, len(data)) @@ -215,7 +221,7 @@ def on_null_literal(p): self.on_null_literal() -callbacks = WeaselJsonCallbacks( +c_callbacks = WeaselJsonCallbacks( on_begin_object, on_end_object, on_begin_string, @@ -232,13 +238,13 @@ callbacks = WeaselJsonCallbacks( ) -class JsonParser(WeaselJsonParserBase): +class MyCallbacks(WeaselJsonCallbacksBase): # override callbacks def on_string_data(self, data): print(data) -with JsonParser() as parser: +with WeaselJsonParser(MyCallbacks()) as parser: raw = json.dumps({"hello": "world", "foo": 42}).encode() i = 0 stride = 1