7
#include "type_limits.h"
10
#include "segcol_list.h"
11
#include "data_object.h"
12
#include "data_object_memory.h"
13
#include "data_object_file.h"
15
#include "buffer_internal.h"
16
#include "priority_queue.h"
17
#include "overlap_graph.h"
18
#include "disjoint_set.h"
19
#include "buffer_util.h"
22
#include "buffer_action.h"
23
#include "buffer_action_edit.h"
26
%pointer_class (size_t, size_tp)
29
%apply long long { ssize_t };
30
%apply unsigned long long { size_t };
31
%apply long long { off_t };
33
/* Don't perform any conversions on void pointers */
39
/* Handle bless_buffer_source_t normally. This is needed because
40
* bless_buffer_source_t is typedef void and the previous rule is
41
* used (but we don't want to).
43
%typemap(in) bless_buffer_source_t * = SWIGTYPE *;
46
* The typemaps below are used to handle functions that return values in arguments.
47
* If a function is of the form 'int func(type **t, type1 p)' the resulting binding
48
* is of the form (int, type *) = func(type1).
52
* Typemaps that handle double pointers.
55
/* Essentially ignore input */
56
%typemap(in,numinputs=0) segment_t ** ($*1_type retval)
63
/* Append segment_t * to return list */
64
%typemap(argout) segment_t **
66
%append_output(SWIG_NewPointerObj(SWIG_as_voidptr(retval$argnum), $*1_descriptor, 0));
69
/* The same rules for segment_t ** apply to other ** types */
70
%apply segment_t ** { segcol_t ** , segcol_iter_t **, data_object_t **, void **}
71
%apply segment_t ** { bless_buffer_t **, bless_buffer_source_t ** }
72
%apply segment_t ** { priority_queue_t **, overlap_graph_t **, disjoint_set_t ** }
73
%apply segment_t ** { list_t **, char **, buffer_action_t **}
76
/* Exception for void **: Append void * to return list without conversion */
77
%typemap(argout) void **
79
%append_output((PyObject *)retval$argnum);
80
Py_INCREF((PyObject *)retval$argnum);
83
/* Exception for char **: Append char * to return list as a python string */
84
%typemap(argout) char **
86
char *str = retval$argnum;
88
Py_ssize_t size = strlen(str);
89
%append_output(PyString_FromStringAndSize(str, size));
91
%append_output(Py_None);
96
/* Match segment_new() and increase reference count of stored data */
97
%typemap(check) (segment_t **seg, void *data)
100
Py_INCREF((PyObject *)$2);
103
/* Decrease reference count of data stored in a segment_t when it is freed */
104
%exception segment_free
108
segment_get_data(arg1, &data);
110
Py_DECREF((PyObject *)data);
116
/* handle 'length' in data_object_get_data() */
117
%typemap(in) off_t *length = size_t *INPUT;
119
/* Make data_object_get_data() binding output a PyBuffer */
120
%typemap(argout) (data_object_t *obj, void **buf, off_t offset,
121
off_t *length, data_object_flags flags)
123
if (($5 | DATA_OBJECT_RW) != 0)
124
%append_output(PyBuffer_FromReadWriteMemory(*((unsigned char **)$2), *$4));
126
%append_output(PyBuffer_FromMemory(*((unsigned char **)$2), *$4));
130
/* Gets a pointer to a copy of the first segment of raw data of a PyBuffer */
131
void *get_read_buf_pyobj_copy(PyObject *obj, ssize_t *size)
133
PyTypeObject *tobj = obj->ob_type;
135
PyBufferProcs *procs = tobj->tp_as_buffer;
137
/* if object does not support the buffer interface... */
141
readbufferproc proc = procs->bf_getreadbuffer;
145
*size = (*proc)(obj, 0, &ptr);
150
void *data_copy = malloc(*size);
151
memcpy(data_copy, ptr, *size);
156
/* Gets a write pointer to the first segment of raw data of a PyBuffer */
157
void *get_write_buf_pyobj(PyObject *obj, ssize_t *size)
159
PyTypeObject *tobj = obj->ob_type;
161
PyBufferProcs *procs = tobj->tp_as_buffer;
163
/* if object does not support the buffer interface... */
167
writebufferproc proc = procs->bf_getwritebuffer;
171
*size = (*proc)(obj, 0, &ptr);
178
* Make the bless_buffer_append() binding accept as data input objects that
179
* support the PyBuffer interface.
181
%exception bless_buffer_source_memory
184
arg2 = get_read_buf_pyobj_copy(obj0, &s);
186
if (s != -1 && s >= arg3) {
194
* Make the bless_buffer_read() binding accept as data input objects that
195
* support the PyBuffer interface.
197
%exception bless_buffer_read
201
arg3 = get_write_buf_pyobj(obj2, &s);
203
if (s != -1 && s >= arg5) {
211
* Make the read_data_object() binding accept as data input objects that
212
* support the PyBuffer interface.
214
%exception read_data_object
218
arg3 = get_write_buf_pyobj(obj2, &s);
220
if (s != -1 && s >= arg4) {
228
* Typemaps that handle output arguments.
231
%apply int *OUTPUT { int * };
232
%apply long long *OUTPUT { off_t * };
233
%apply unsigned long long *OUTPUT { size_t * };
234
%apply unsigned long long *OUTPUT { uint64_t * };
236
/* in priority_queue_add size_t *pos is a normal pointer (not output) */
237
%apply SWIGTYPE * { size_t *pos };
240
* Helper functions available only in python code for testing purposes.
242
* These should be placed at the end of the SWIG file so the typemaps
243
* will apply to them.
246
/* Get the maximum value of off_t */
247
off_t get_max_off_t(void)
252
/* Get the maximum value of size_t */
253
size_t get_max_size_t(void)
255
return __MAX(size_t);
258
/* Create a segment with the data pointer as size_t */
259
int segment_new_ptr(segment_t **seg, size_t ptr, off_t start, off_t size,
260
segment_data_usage_func data_usage_func)
262
return segment_new(seg, (void *)ptr, start, size, data_usage_func);
265
/* Set the segcol of a bless_buffer_t */
266
void set_buffer_segcol(bless_buffer_t *buf, segcol_t *segcol)
268
segcol_free(buf->segcol);
269
buf->segcol = segcol;
272
/* Call data_object_memory_new with the data pointer as size_t */
273
int data_object_memory_new_ptr(data_object_t **o, size_t ptr, size_t len)
275
return data_object_memory_new(o, (void *)ptr, len);
278
/* Call bless_buffer_source_memory with the data pointer as size_t */
279
int bless_buffer_source_memory_ptr(bless_buffer_source_t **src, size_t ptr, size_t len, bless_mem_free_func *func)
281
return bless_buffer_source_memory(src, (void *)ptr, len, func);
284
/* Call bless_buffer_read with the data pointer as size_t */
285
int bless_buffer_read_ptr(bless_buffer_t *src, off_t src_offset, size_t dst,
286
size_t dst_offset, size_t length)
288
return bless_buffer_read(src, src_offset, (void *)dst, dst_offset, length);
291
/* Append a segment to buffer */
292
int bless_buffer_append_segment(bless_buffer_t *buf, segment_t *seg)
294
if (buf == NULL || seg == NULL)
297
segcol_t *sc = buf->segcol;
299
/* Append segment to the segcol */
300
int err = segcol_append(sc, seg);
308
/* Malloc memory and return the address cast to size_t */
309
size_t bless_malloc(size_t s)
316
/* Delete a range from a segment but don't return the deleted segments */
317
int segcol_delete_no_deleted(segcol_t *segcol, off_t offset, off_t length)
319
return segcol_delete(segcol, NULL, offset, length);
323
* Prints a list of segment edges assuming that the segment data
324
* is a PyString value.
326
void print_edge_list(list_t *edges, int fd)
328
FILE *fp = fdopen(fd, "w");
329
struct list_node *node;
331
list_for_each(list_head(edges)->next, node) {
332
struct edge_entry *e = list_entry(node, struct edge_entry, ln);
334
segment_get_data(e->src, (void **)&str1);
336
segment_get_data(e->dst, (void **)&str2);
338
fprintf(fp, "%s -> %s\n", PyString_AsString(str1),
339
PyString_AsString(str2));
346
* Prints a list of segment vertices assuming that the segment data
347
* is a PyString value.
349
void print_vertex_list(list_t *vertices, int fd)
351
FILE *fp = fdopen(fd, "w");
352
struct list_node *node;
354
list_for_each(list_head(vertices)->next, node) {
355
struct vertex_entry *e = list_entry(node, struct vertex_entry, ln);
357
segment_get_data(e->segment, (void **)&str1);
359
fprintf(fp, "%s\n", PyString_AsString(str1));
366
%include "../src/segment.h"
367
%include "../src/segcol.h"
368
%include "../src/segcol_list.h"
369
%include "../src/data_object.h"
370
%include "../src/data_object_memory.h"
371
%include "../src/data_object_file.h"
372
%include "../src/buffer.h"
373
%include "../src/buffer_source.h"
374
%include "../src/priority_queue.h"
375
%include "../src/overlap_graph.h"
376
%include "../src/disjoint_set.h"
377
%include "../src/buffer_util.h"
378
%include "../src/list.h"
379
%include "../src/buffer_options.h"
380
%include "../src/util.h"
381
%include "../src/buffer_action.h"
382
%include "../src/buffer_action_edit.h"