################################################################################
#  THIS FILE IS 100% GENERATED BY ZPROJECT; DO NOT EDIT EXCEPT EXPERIMENTALLY  #
#  Read the zproject/README.md for information about making permanent changes. #
################################################################################
from . import utils
from . import destructors
libczmq_destructors = destructors.lib

class Zhashx(object):
    """
    extended generic type-free hash container
    """

    def __init__(self):
        """
        Create a new, empty hash container
        """
        p = utils.lib.zhashx_new()
        if p == utils.ffi.NULL:
            raise MemoryError("Could not allocate person")

        # ffi.gc returns a copy of the cdata object which will have the
        # destructor called when the Python object is GC'd:
        # https://cffi.readthedocs.org/en/latest/using.html#ffi-interface
        self._p = utils.ffi.gc(p, libczmq_destructors.zhashx_destroy_py)

    @staticmethod
    def unpack(frame):
        """
        Unpack binary frame into a new hash table. Packed data must follow format
        defined by zhashx_pack. Hash table is set to autofree. An empty frame
        unpacks to an empty hash table.
        """
        return utils.lib.zhashx_unpack(frame._p)

    @staticmethod
    def unpack_own(frame, deserializer):
        """
        Same as unpack but uses a user-defined deserializer function to convert
        a longstr back into item format.
        """
        return utils.lib.zhashx_unpack_own(frame._p, deserializer)

    def insert(self, key, item):
        """
        Insert item into hash table with specified key and item.
        If key is already present returns -1 and leaves existing item unchanged
        Returns 0 on success.
        """
        return utils.lib.zhashx_insert(self._p, key._p, item._p)

    def update(self, key, item):
        """
        Update or insert item into hash table with specified key and item. If the
        key is already present, destroys old item and inserts new one. If you set
        a container item destructor, this is called on the old value. If the key
        was not already present, inserts a new item. Sets the hash cursor to the
        new item.
        """
        utils.lib.zhashx_update(self._p, key._p, item._p)

    def delete(self, key):
        """
        Remove an item specified by key from the hash table. If there was no such
        item, this function does nothing.
        """
        utils.lib.zhashx_delete(self._p, key._p)

    def purge(self):
        """
        Delete all items from the hash table. If the key destructor is
        set, calls it on every key. If the item destructor is set, calls
        it on every item.
        """
        utils.lib.zhashx_purge(self._p)

    def lookup(self, key):
        """
        Return the item at the specified key, or null
        """
        return utils.lib.zhashx_lookup(self._p, key._p)

    def rename(self, old_key, new_key):
        """
        Reindexes an item from an old key to a new key. If there was no such
        item, does nothing. Returns 0 if successful, else -1.
        """
        return utils.lib.zhashx_rename(self._p, old_key._p, new_key._p)

    def freefn(self, key, free_fn):
        """
        Set a free function for the specified hash table item. When the item is
        destroyed, the free function, if any, is called on that item.
        Use this when hash items are dynamically allocated, to ensure that
        you don't have memory leaks. You can pass 'free' or NULL as a free_fn.
        Returns the item, or NULL if there is no such item.
        """
        return utils.lib.zhashx_freefn(self._p, key._p, free_fn)

    def size(self):
        """
        Return the number of keys/items in the hash table
        """
        return utils.lib.zhashx_size(self._p)

    def keys(self):
        """
        Return a zlistx_t containing the keys for the items in the
        table. Uses the key_duplicator to duplicate all keys and sets the
        key_destructor as destructor for the list.
        """
        return utils.lib.zhashx_keys(self._p)

    def values(self):
        """
        Return a zlistx_t containing the values for the items in the
        table. Uses the duplicator to duplicate all items and sets the
        destructor as destructor for the list.
        """
        return utils.lib.zhashx_values(self._p)

    def first(self):
        """
        Simple iterator; returns first item in hash table, in no given order,
        or NULL if the table is empty. This method is simpler to use than the
        foreach() method, which is deprecated. To access the key for this item
        use zhashx_cursor(). NOTE: do NOT modify the table while iterating.
        """
        return utils.lib.zhashx_first(self._p)

    def next(self):
        """
        Simple iterator; returns next item in hash table, in no given order,
        or NULL if the last item was already returned. Use this together with
        zhashx_first() to process all items in a hash table. If you need the
        items in sorted order, use zhashx_keys() and then zlistx_sort(). To
        access the key for this item use zhashx_cursor(). NOTE: do NOT modify
        the table while iterating.
        """
        return utils.lib.zhashx_next(self._p)

    def cursor(self):
        """
        After a successful first/next method, returns the key for the item that
        was returned. This is a constant string that you may not modify or
        deallocate, and which lasts as long as the item in the hash. After an
        unsuccessful first/next, returns NULL.
        """
        return utils.lib.zhashx_cursor(self._p)

    def comment(self, format, *format_args):
        """
        Add a comment to hash table before saving to disk. You can add as many
        comment lines as you like. These comment lines are discarded when loading
        the file. If you use a null format, all comments are deleted.
        """
        utils.lib.zhashx_comment(self._p, format, *format_args)

    def save(self, filename):
        """
        Save hash table to a text file in name=value format. Hash values must be
        printable strings; keys may not contain '=' character. Returns 0 if OK,
        else -1 if a file error occurred.
        """
        return utils.lib.zhashx_save(self._p, utils.to_bytes(filename))

    def load(self, filename):
        """
        Load hash table from a text file in name=value format; hash table must
        already exist. Hash values must printable strings; keys may not contain
        '=' character. Returns 0 if OK, else -1 if a file was not readable.
        """
        return utils.lib.zhashx_load(self._p, utils.to_bytes(filename))

    def refresh(self):
        """
        When a hash table was loaded from a file by zhashx_load, this method will
        reload the file if it has been modified since, and is "stable", i.e. not
        still changing. Returns 0 if OK, -1 if there was an error reloading the
        file.
        """
        return utils.lib.zhashx_refresh(self._p)

    def pack(self):
        """
        Serialize hash table to a binary frame that can be sent in a message.
        The packed format is compatible with the 'dictionary' type defined in
        http://rfc.zeromq.org/spec:35/FILEMQ, and implemented by zproto:

           ; A list of name/value pairs
           dictionary      = dict-count *( dict-name dict-value )
           dict-count      = number-4
           dict-value      = longstr
           dict-name       = string

           ; Strings are always length + text contents
           longstr         = number-4 *VCHAR
           string          = number-1 *VCHAR

           ; Numbers are unsigned integers in network byte order
           number-1        = 1OCTET
           number-4        = 4OCTET

        Comments are not included in the packed data. Item values MUST be
        strings.
        """
        return utils.lib.zhashx_pack(self._p)

    def pack_own(self, serializer):
        """
        Same as pack but uses a user-defined serializer function to convert items
        into longstr.
        """
        return utils.lib.zhashx_pack_own(self._p, serializer)

    def dup(self):
        """
        Make a copy of the list; items are duplicated if you set a duplicator
        for the list, otherwise not. Copying a null reference returns a null
        reference. Note that this method's behavior changed slightly for CZMQ
        v3.x, as it does not set nor respect autofree. It does however let you
        duplicate any hash table safely. The old behavior is in zhashx_dup_v2.
        """
        return utils.lib.zhashx_dup(self._p)

    def set_destructor(self, destructor):
        """
        Set a user-defined deallocator for hash items; by default items are not
        freed when the hash is destroyed.
        """
        utils.lib.zhashx_set_destructor(self._p, destructor)

    def set_duplicator(self, duplicator):
        """
        Set a user-defined duplicator for hash items; by default items are not
        copied when the hash is duplicated.
        """
        utils.lib.zhashx_set_duplicator(self._p, duplicator)

    def set_key_destructor(self, destructor):
        """
        Set a user-defined deallocator for keys; by default keys are freed
        when the hash is destroyed using free().
        """
        utils.lib.zhashx_set_key_destructor(self._p, destructor)

    def set_key_duplicator(self, duplicator):
        """
        Set a user-defined duplicator for keys; by default keys are duplicated
        using strdup.
        """
        utils.lib.zhashx_set_key_duplicator(self._p, duplicator)

    def set_key_comparator(self, comparator):
        """
        Set a user-defined comparator for keys; by default keys are
        compared using strcmp.
        The callback function should return zero (0) on matching
        items.
        """
        utils.lib.zhashx_set_key_comparator(self._p, comparator)

    def set_key_hasher(self, hasher):
        """
        Set a user-defined hash function for keys; by default keys are
        hashed by a modified Bernstein hashing function.
        """
        utils.lib.zhashx_set_key_hasher(self._p, hasher)

    def dup_v2(self):
        """
        Make copy of hash table; if supplied table is null, returns null.
        Does not copy items themselves. Rebuilds new table so may be slow on
        very large tables. NOTE: only works with item values that are strings
        since there's no other way to know how to duplicate the item value.
        """
        return utils.lib.zhashx_dup_v2(self._p)

    @staticmethod
    def test(verbose):
        """
        Self test of this class.
        """
        utils.lib.zhashx_test(verbose)

################################################################################
#  THIS FILE IS 100% GENERATED BY ZPROJECT; DO NOT EDIT EXCEPT EXPERIMENTALLY  #
#  Read the zproject/README.md for information about making permanent changes. #
################################################################################
