Show More
@@ -39,6 +39,8 b' typedef struct {' | |||||
39 |
|
39 | |||
40 | typedef struct { |
|
40 | typedef struct { | |
41 | int abi_version; |
|
41 | int abi_version; | |
|
42 | Py_ssize_t (*index_length)(const indexObject *); | |||
|
43 | const char *(*index_node)(indexObject *, Py_ssize_t); | |||
42 | int (*index_parents)(PyObject *, int, int *); |
|
44 | int (*index_parents)(PyObject *, int, int *); | |
43 | } Revlog_CAPI; |
|
45 | } Revlog_CAPI; | |
44 |
|
46 | |||
@@ -2877,7 +2879,9 b' bail:' | |||||
2877 | static Revlog_CAPI CAPI = { |
|
2879 | static Revlog_CAPI CAPI = { | |
2878 | /* increment the abi_version field upon each change in the Revlog_CAPI |
|
2880 | /* increment the abi_version field upon each change in the Revlog_CAPI | |
2879 | struct or in the ABI of the listed functions */ |
|
2881 | struct or in the ABI of the listed functions */ | |
2880 |
|
|
2882 | 2, | |
|
2883 | index_length, | |||
|
2884 | index_node, | |||
2881 | HgRevlogIndex_GetParents, |
|
2885 | HgRevlogIndex_GetParents, | |
2882 | }; |
|
2886 | }; | |
2883 |
|
2887 |
@@ -44,6 +44,7 b' type NodeData = [u8; NODE_BYTES_LENGTH];' | |||||
44 | /// [`nybbles_len`]: #method.nybbles_len |
|
44 | /// [`nybbles_len`]: #method.nybbles_len | |
45 | /// [`ExactLengthRequired`]: struct.NodeError#variant.ExactLengthRequired |
|
45 | /// [`ExactLengthRequired`]: struct.NodeError#variant.ExactLengthRequired | |
46 | #[derive(Clone, Debug, PartialEq)] |
|
46 | #[derive(Clone, Debug, PartialEq)] | |
|
47 | #[repr(transparent)] | |||
47 | pub struct Node { |
|
48 | pub struct Node { | |
48 | data: NodeData, |
|
49 | data: NodeData, | |
49 | } |
|
50 | } |
@@ -11,14 +11,21 b'' | |||||
11 | //! but this will take some time to get there. |
|
11 | //! but this will take some time to get there. | |
12 |
|
12 | |||
13 | use cpython::{exc::ImportError, PyClone, PyErr, PyObject, PyResult, Python}; |
|
13 | use cpython::{exc::ImportError, PyClone, PyErr, PyObject, PyResult, Python}; | |
|
14 | use hg::revlog::{Node, RevlogIndex}; | |||
14 | use hg::{Graph, GraphError, Revision, WORKING_DIRECTORY_REVISION}; |
|
15 | use hg::{Graph, GraphError, Revision, WORKING_DIRECTORY_REVISION}; | |
15 | use libc::c_int; |
|
16 | use libc::c_int; | |
16 |
|
17 | |||
17 |
const REVLOG_CABI_VERSION: c_int = |
|
18 | const REVLOG_CABI_VERSION: c_int = 2; | |
18 |
|
19 | |||
19 | #[repr(C)] |
|
20 | #[repr(C)] | |
20 | pub struct Revlog_CAPI { |
|
21 | pub struct Revlog_CAPI { | |
21 | abi_version: c_int, |
|
22 | abi_version: c_int, | |
|
23 | index_length: | |||
|
24 | unsafe extern "C" fn(index: *mut revlog_capi::RawPyObject) -> c_int, | |||
|
25 | index_node: unsafe extern "C" fn( | |||
|
26 | index: *mut revlog_capi::RawPyObject, | |||
|
27 | rev: c_int, | |||
|
28 | ) -> *const Node, | |||
22 | index_parents: unsafe extern "C" fn( |
|
29 | index_parents: unsafe extern "C" fn( | |
23 | index: *mut revlog_capi::RawPyObject, |
|
30 | index: *mut revlog_capi::RawPyObject, | |
24 | rev: c_int, |
|
31 | rev: c_int, | |
@@ -131,3 +138,30 b' impl Graph for Index {' | |||||
131 | } |
|
138 | } | |
132 | } |
|
139 | } | |
133 | } |
|
140 | } | |
|
141 | ||||
|
142 | impl RevlogIndex for Index { | |||
|
143 | /// Note C return type is Py_ssize_t (hence signed), but we shall | |||
|
144 | /// force it to unsigned, because it's a length | |||
|
145 | fn len(&self) -> usize { | |||
|
146 | unsafe { (self.capi.index_length)(self.index.as_ptr()) as usize } | |||
|
147 | } | |||
|
148 | ||||
|
149 | fn node<'a>(&'a self, rev: Revision) -> Option<&'a Node> { | |||
|
150 | let raw = unsafe { | |||
|
151 | (self.capi.index_node)(self.index.as_ptr(), rev as c_int) | |||
|
152 | }; | |||
|
153 | if raw.is_null() { | |||
|
154 | None | |||
|
155 | } else { | |||
|
156 | // TODO it would be much better for the C layer to give us | |||
|
157 | // a length, since the hash length will change in the near | |||
|
158 | // future, but that's probably out of scope for the nodemap | |||
|
159 | // patch series. | |||
|
160 | // | |||
|
161 | // The root of that unsafety relies in the signature of | |||
|
162 | // `capi.index_node()` itself: returning a `Node` pointer | |||
|
163 | // whereas it's a `char *` in the C counterpart. | |||
|
164 | Some(unsafe { &*raw }) | |||
|
165 | } | |||
|
166 | } | |||
|
167 | } |
General Comments 0
You need to be logged in to leave comments.
Login now