summaryrefslogtreecommitdiffstats
path: root/cython/restore.pxi
blob: 9d0393582d8c5569a26d27e0333cd3b642693b5e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
cdef extern from "libimobiledevice/restore.h":
    cdef struct restored_client_private:
        pass
    ctypedef restored_client_private *restored_client_t

    ctypedef enum restored_error_t:
        RESTORE_E_SUCCESS = 0
        RESTORE_E_INVALID_ARG = -1
        RESTORE_E_PLIST_ERROR = -2
        RESTORE_E_MUX_ERROR = -3
        RESTORE_E_NOT_ENOUGH_DATA = -4
        RESTORE_E_RECEIVE_TIMEOUT = -5
        RESTORE_E_UNKNOWN_ERROR = -256

    restored_error_t restored_client_new(idevice_t device, restored_client_t *client, char *label)
    restored_error_t restored_client_free(restored_client_t client)

    restored_error_t restored_query_type(restored_client_t client, char **tp, uint64_t *version)
    restored_error_t restored_query_value(restored_client_t client, char *key, plist.plist_t *value)
    restored_error_t restored_get_value(restored_client_t client, char *key, plist.plist_t *value)
    restored_error_t restored_send(restored_client_t client, plist.plist_t plist)
    restored_error_t restored_receive(restored_client_t client, plist.plist_t *plist)
    restored_error_t restored_goodbye(restored_client_t client)

    restored_error_t restored_start_restore(restored_client_t client, plist.plist_t options, uint64_t version)
    restored_error_t restored_reboot(restored_client_t client)

    void restored_client_set_label(restored_client_t client, char *label)

cdef class RestoreError(BaseError):
    def __init__(self, *args, **kwargs):
        self._lookup_table = {
            RESTORE_E_SUCCESS: "Success",
            RESTORE_E_INVALID_ARG: "Invalid argument",
            RESTORE_E_PLIST_ERROR: "Property list error",
            RESTORE_E_MUX_ERROR: "MUX Error",
            RESTORE_E_NOT_ENOUGH_DATA: "Not enough data",
            RESTORE_E_RECEIVE_TIMEOUT: "Receive timeout",
            RESTORE_E_UNKNOWN_ERROR: "Unknown error"
        }
        BaseError.__init__(self, *args, **kwargs)

cdef class RestoreClient(PropertyListService):
    cdef restored_client_t _c_client

    def __cinit__(self, iDevice device not None, bytes label=b'', *args, **kwargs):
        cdef:
            restored_error_t err
            char* c_label = NULL
        if label:
            c_label = label
        err = restored_client_new(device._c_dev, &self._c_client, c_label)
        self.handle_error(err)

        self.device = device

    def __dealloc__(self):
        cdef restored_error_t err
        if self._c_client is not NULL:
            err = restored_client_free(self._c_client)
            self.handle_error(err)

    cdef inline BaseError _error(self, int16_t ret):
        return RestoreError(ret)

    cdef inline int16_t _send(self, plist.plist_t node):
        return restored_send(self._c_client, node)

    cdef inline int16_t _receive(self, plist.plist_t* node):
        return restored_receive(self._c_client, node)

    cpdef tuple query_type(self):
        cdef:
            restored_error_t err
            char* c_type = NULL
            uint64_t c_version = 0
            tuple result
        err = restored_query_type(self._c_client, &c_type, &c_version)
        try:
            self.handle_error(err)
            result = (c_type, c_version)
            return result
        except BaseError, e:
            raise
        finally:
            if c_type != NULL:
                free(c_type)

    cpdef plist.Node query_value(self, bytes key=None):
        cdef:
            restored_error_t err
            plist.plist_t c_node = NULL
            char* c_key = NULL
        if key is not None:
            c_key = key
        err = restored_query_value(self._c_client, c_key, &c_node)
        try:
            self.handle_error(err)
            return plist.plist_t_to_node(c_node)
        except BaseError, e:
            if c_node != NULL:
                plist.plist_free(c_node)
            raise

    cpdef plist.Node get_value(self, bytes key=None):
        cdef:
            restored_error_t err
            plist.plist_t c_node = NULL
            char* c_key = NULL
        if key is not None:
            c_key = key
        err = restored_get_value(self._c_client, c_key, &c_node)
        try:
            self.handle_error(err)
            return plist.plist_t_to_node(c_node)
        except BaseError, e:
            if c_node != NULL:
                plist.plist_free(c_node)
            raise

    cpdef goodbye(self):
        self.handle_error(restored_goodbye(self._c_client))

    cpdef start_restore(self, plist.Node options, uint64_t version):
        self.handle_error(restored_start_restore(self._c_client, options._c_node, version))

    cpdef reboot(self):
        self.handle_error(restored_reboot(self._c_client))

    cpdef set_label(self, bytes label):
        restored_client_set_label(self._c_client, label)