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