From b6e3e58a7be223268e09114156934d7ca2c0fc00 Mon Sep 17 00:00:00 2001 From: Andika Wasisto Date: Mon, 17 Aug 2020 05:03:36 +0700 Subject: [PATCH] Support Linux --- libqwqng-wrapper.so | Bin 0 -> 17560 bytes quanttp/__main__.py | 9 +- quanttp/data/qng_wrapper_linux.py | 82 ++++++++++++++++++ ...{qng_wrapper.py => qng_wrapper_windows.py} | 5 +- requirements.txt | 2 +- 5 files changed, 89 insertions(+), 9 deletions(-) create mode 100644 libqwqng-wrapper.so create mode 100644 quanttp/data/qng_wrapper_linux.py rename quanttp/data/{qng_wrapper.py => qng_wrapper_windows.py} (97%) diff --git a/libqwqng-wrapper.so b/libqwqng-wrapper.so new file mode 100644 index 0000000000000000000000000000000000000000..d1c01cf2b8465364ef2edde0ed425c2aabdcfce6 GIT binary patch literal 17560 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 literal 0 HcmV?d00001 diff --git a/quanttp/__main__.py b/quanttp/__main__.py index cbaf2ae..2842c10 100644 --- a/quanttp/__main__.py +++ b/quanttp/__main__.py @@ -17,7 +17,7 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. - +import os import threading from flask import Flask, request, Response @@ -25,15 +25,14 @@ from flask_sockets import Sockets from gevent import pywsgi from geventwebsocket.handler import WebSocketHandler -from quanttp.data.qng_wrapper import QngWrapper -from quanttp.data.qng_wrapper_mock import QngWrapperMock +from quanttp.data.qng_wrapper_linux import QngWrapperLinux +from quanttp.data.qng_wrapper_windows import QngWrapperWindows app = Flask(__name__) sockets = Sockets(app) -qng_wrapper = QngWrapper() -# qng_wrapper = QngWrapperMock() +qng_wrapper = QngWrapperWindows() if (os.name == 'nt') else QngWrapperLinux() @app.route('/api/randint32') diff --git a/quanttp/data/qng_wrapper_linux.py b/quanttp/data/qng_wrapper_linux.py new file mode 100644 index 0000000..4333974 --- /dev/null +++ b/quanttp/data/qng_wrapper_linux.py @@ -0,0 +1,82 @@ +# Copyright (c) 2020 Andika Wasisto +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ctypes import cdll, c_void_p, c_int, c_double, POINTER, c_char + + +class QngWrapperLinux: + + def __init__(self): + self.libqwqng_wrapper = cdll.LoadLibrary('./libqwqng-wrapper.so') + self.libqwqng_wrapper.GetQwqngInstance.restype = c_void_p + self.libqwqng_wrapper.RandInt32.argtypes = [c_void_p] + self.libqwqng_wrapper.RandInt32.restype = c_int + self.libqwqng_wrapper.RandUniform.argtypes = [c_void_p] + self.libqwqng_wrapper.RandUniform.restype = c_double + self.libqwqng_wrapper.RandNormal.argtypes = [c_void_p] + self.libqwqng_wrapper.RandNormal.restype = c_double + self.libqwqng_wrapper.RandBytes.argtypes = [c_void_p, c_int] + self.libqwqng_wrapper.RandBytes.restype = POINTER(c_char) + self.libqwqng_wrapper.Clear.argtypes = [c_void_p] + self.libqwqng_wrapper.Reset.argtypes = [c_void_p] + self.qng = self.libqwqng_wrapper.GetQwqngInstance() + + def randint32(self): + try: + return self.libqwqng_wrapper.RandInt32(self.qng) + except: + self.libqwqng_wrapper.Reset(self.qng) + return self.libqwqng_wrapper.RandInt32(self.qng) + + def randuniform(self): + try: + return self.libqwqng_wrapper.RandUniform(self.qng) + except: + self.libqwqng_wrapper.Reset(self.qng) + return self.libqwqng_wrapper.RandUniform(self.qng) + + def randnormal(self): + try: + return self.libqwqng_wrapper.RandNormal(self.qng) + except: + self.libqwqng_wrapper.Reset(self.qng) + return self.libqwqng_wrapper.RandNormal(self.qng) + + def randbytes(self, length): + try: + return self._randbytes_arbitrary_length(length) + except: + self.libqwqng_wrapper.Reset(self.qng) + return self._randbytes_arbitrary_length(length) + + def _randbytes_arbitrary_length(self, length): + if length <= 8192: + return self.libqwqng_wrapper.RandBytes(self.qng, length)[:length] + else: + data = bytearray() + for x in range(length // 8192): + data.extend(self.libqwqng_wrapper.RandBytes(self.qng, 8192)[:8192]) + bytes_needed = length % 8192 + if bytes_needed != 0: + data.extend(self.libqwqng_wrapper.RandBytes(self.qng, bytes_needed)[:bytes_needed]) + return bytes(data) + + def clear(self): + self.libqwqng_wrapper.Clear(self.qng) diff --git a/quanttp/data/qng_wrapper.py b/quanttp/data/qng_wrapper_windows.py similarity index 97% rename from quanttp/data/qng_wrapper.py rename to quanttp/data/qng_wrapper_windows.py index 80710e5..8618567 100644 --- a/quanttp/data/qng_wrapper.py +++ b/quanttp/data/qng_wrapper_windows.py @@ -18,12 +18,11 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -import win32com.client - -class QngWrapper: +class QngWrapperWindows: def __init__(self): + import win32com.client self.qng = win32com.client.Dispatch("QWQNG.QNG") def randint32(self): diff --git a/requirements.txt b/requirements.txt index 850fa69..4f072ce 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,4 @@ Flask==1.1.2 Flask-Sockets==0.2.1 gevent==20.5.0 gevent-websocket==0.10.1 -pywin32==227 \ No newline at end of file +pywin32==227; platform_system == 'Windows'