github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/validator/sawtooth_validator/ffi.py (about) 1 # Copyright 2016 Intel Corporation 2 # 3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # you may not use this file except in compliance with the License. 5 # You may obtain a copy of the License at 6 # 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # See the License for the specific language governing permissions and 13 # limitations under the License. 14 # ------------------------------------------------------------------------------ 15 16 from abc import ABCMeta 17 import ctypes 18 from enum import IntEnum 19 import logging 20 import os 21 import sys 22 23 24 LOGGER = logging.getLogger(__name__) 25 26 27 class Library: 28 29 def __init__(self, library_loader): 30 lib_prefix_mapping = { 31 "darwin": "lib", 32 "linux": "lib", 33 "linux2": "lib", 34 } 35 lib_suffix_mapping = { 36 "darwin": ".dylib", 37 "linux": ".so", 38 "linux2": ".so", 39 } 40 41 os_name = sys.platform 42 43 lib_location = os.environ.get('SAWTOOTH_LIB_HOME', '') 44 if lib_location and lib_location[-1:] != '/': 45 lib_location += '/' 46 47 try: 48 lib_prefix = lib_prefix_mapping[os_name] 49 lib_suffix = lib_suffix_mapping[os_name] 50 except KeyError: 51 raise OSError("OS isn't supported: {}".format(os_name)) 52 53 library_path = "{}{}sawtooth_validator{}".format( 54 lib_location, lib_prefix, lib_suffix) 55 56 LOGGER.debug("loading library %s", library_path) 57 58 self._cdll = library_loader(library_path) 59 60 def call(self, name, *args): 61 return getattr(self._cdll, name)(*args) 62 63 64 LIBRARY = Library(ctypes.CDLL) 65 LIBRARY.call("pylogger_init", LOGGER.getEffectiveLevel()) 66 PY_LIBRARY = Library(ctypes.PyDLL) 67 68 69 def prepare_byte_result(): 70 """Returns pair of byte pointer and size value for use as return parameters 71 in a LIBRARY call 72 """ 73 return (ctypes.POINTER(ctypes.c_uint8)(), ctypes.c_size_t(0)) 74 75 76 def from_c_bytes(c_data, c_data_len): 77 """Takes a byte pointer and a length and converts it into a python bytes 78 value. 79 """ 80 # pylint: disable=invalid-slice-index 81 return bytes(c_data[:c_data_len.value]) 82 83 84 class OwnedPointer(object, metaclass=ABCMeta): 85 """An owned pointer will call drop when this pointer is garbage collected. 86 """ 87 def __init__(self, drop_ffi_call_fn, initialized_ptr=None): 88 """Constructs an owned pointer. 89 Initializing the pointer is left to the extending classes 90 91 Args: 92 drop_ffi_call_fn (str): the name of the FFI function to call on 93 drop or garbage collection. 94 initialized_ptr (ctypes.c_void_p:optional): a preinitialized 95 pointer to the native memory 96 """ 97 if initialized_ptr is not None: 98 self._ptr = initialized_ptr 99 else: 100 self._ptr = ctypes.c_void_p() 101 102 self._drop_ffi_fn = drop_ffi_call_fn 103 104 def drop(self): 105 """Explicitly drop this pointer. The memory will be deallocated via 106 the drop_ffi_call_fn passed to the constructor. 107 """ 108 if self._ptr: 109 LIBRARY.call(self._drop_ffi_fn, self._ptr) 110 self._ptr = None 111 112 def __del__(self): 113 self.drop() 114 115 @property 116 def pointer(self): 117 """Return a reference to the pointer, for use in other ffi wrappers. 118 """ 119 return self._ptr 120 121 def as_ref(self): 122 return RefPointer(self.pointer) 123 124 125 class RefPointer(object): 126 """A reference to a pointer. 127 128 This pointer does not manage any deallocation of the underlying memory. 129 """ 130 def __init__(self, ptr): 131 self._ptr = ptr 132 133 @property 134 def pointer(self): 135 return self._ptr 136 137 138 class CommonErrorCode(IntEnum): 139 Success = 0 140 NullPointerProvided = 0x01 141 142 Unknown = 0xff 143 144 145 def python_to_sender_callback(sender): 146 """Wraps a sender in a callback. The sender must have a "send" function 147 which receive the arguments from the callback 148 149 Args: 150 sender (:obj:) an object that has a "send" function 151 152 Returns: 153 a function 154 """ 155 def callback_wrapper(*args): 156 return sender.send(*args) 157 158 return callback_wrapper