~libbls/libbls/libbls-package

« back to all changes in this revision

Viewing changes to bindings/libbls.i

  • Committer: Alexandros Frantzis
  • Date: 2011-10-01 10:10:46 UTC
  • Revision ID: alf82@freemail.gr-20111001101046-etz52jurwzwc007x
Tags: upstream-0.3.2
ImportĀ upstreamĀ versionĀ 0.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
%module libbls
 
2
 
 
3
%include "typemaps.i"
 
4
%include "cpointer.i"
 
5
 
 
6
%{
 
7
#include "type_limits.h"
 
8
#include "segment.h"
 
9
#include "segcol.h"
 
10
#include "segcol_list.h"
 
11
#include "data_object.h"
 
12
#include "data_object_memory.h"
 
13
#include "data_object_file.h"
 
14
#include "buffer.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"
 
20
#include "list.h"
 
21
#include "util.h"
 
22
#include "buffer_action.h"
 
23
#include "buffer_action_edit.h"
 
24
%}
 
25
 
 
26
%pointer_class (size_t, size_tp)
 
27
 
 
28
 
 
29
%apply long long { ssize_t };
 
30
%apply unsigned long long { size_t };
 
31
%apply long long { off_t };
 
32
 
 
33
/* Don't perform any conversions on void pointers */
 
34
%typemap(in) void *
 
35
{
 
36
    $1 = $input;
 
37
}
 
38
 
 
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).
 
42
 */
 
43
%typemap(in) bless_buffer_source_t * = SWIGTYPE *;
 
44
 
 
45
/*
 
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).
 
49
 */
 
50
 
 
51
/*
 
52
 * Typemaps that handle double pointers.
 
53
 */
 
54
 
 
55
/* Essentially ignore input */
 
56
%typemap(in,numinputs=0) segment_t ** ($*1_type retval)
 
57
{
 
58
    /* in */
 
59
    retval = NULL;
 
60
    $1 = &retval;
 
61
}
 
62
 
 
63
/* Append segment_t * to return list */
 
64
%typemap(argout) segment_t ** 
 
65
{
 
66
    %append_output(SWIG_NewPointerObj(SWIG_as_voidptr(retval$argnum), $*1_descriptor, 0));
 
67
}
 
68
 
 
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 **}
 
74
 
 
75
 
 
76
/* Exception for void **: Append void * to return list without conversion */
 
77
%typemap(argout) void ** 
 
78
{
 
79
    %append_output((PyObject *)retval$argnum);
 
80
    Py_INCREF((PyObject *)retval$argnum);
 
81
}
 
82
 
 
83
/* Exception for char **: Append char * to return list as a python string */
 
84
%typemap(argout) char ** 
 
85
{
 
86
    char *str = retval$argnum;
 
87
    if (str != NULL) {
 
88
        Py_ssize_t size = strlen(str);
 
89
        %append_output(PyString_FromStringAndSize(str, size));
 
90
    } else {
 
91
        %append_output(Py_None);
 
92
    }
 
93
    
 
94
}
 
95
 
 
96
/* Match segment_new() and increase reference count of stored data */
 
97
%typemap(check) (segment_t **seg, void *data)
 
98
{
 
99
    if ($2 != NULL)
 
100
        Py_INCREF((PyObject *)$2);
 
101
}
 
102
 
 
103
/* Decrease reference count of data stored in a segment_t when it is freed */
 
104
%exception segment_free
 
105
{
 
106
    if (arg1 != NULL) {
 
107
        void *data = NULL;
 
108
        segment_get_data(arg1, &data);
 
109
        if (data != NULL) {
 
110
            Py_DECREF((PyObject *)data);
 
111
        }
 
112
    }
 
113
    $action
 
114
}
 
115
 
 
116
/* handle 'length' in data_object_get_data() */
 
117
%typemap(in) off_t *length = size_t *INPUT;
 
118
 
 
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)
 
122
{
 
123
    if (($5 | DATA_OBJECT_RW) != 0)
 
124
        %append_output(PyBuffer_FromReadWriteMemory(*((unsigned char **)$2), *$4));
 
125
    else
 
126
        %append_output(PyBuffer_FromMemory(*((unsigned char **)$2), *$4));
 
127
}
 
128
 
 
129
%{
 
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)
 
132
{
 
133
    PyTypeObject *tobj = obj->ob_type;
 
134
 
 
135
    PyBufferProcs *procs = tobj->tp_as_buffer;
 
136
 
 
137
    /* if object does not support the buffer interface... */
 
138
    if (procs == NULL)
 
139
        return NULL;
 
140
 
 
141
    readbufferproc proc = procs->bf_getreadbuffer;
 
142
 
 
143
    void *ptr;
 
144
 
 
145
    *size = (*proc)(obj, 0, &ptr);
 
146
 
 
147
    if (*size == -1)
 
148
        return NULL;
 
149
        
 
150
    void *data_copy = malloc(*size);
 
151
    memcpy(data_copy, ptr, *size);
 
152
 
 
153
    return data_copy;
 
154
}
 
155
 
 
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)
 
158
{
 
159
    PyTypeObject *tobj = obj->ob_type;
 
160
 
 
161
    PyBufferProcs *procs = tobj->tp_as_buffer;
 
162
 
 
163
    /* if object does not support the buffer interface... */
 
164
    if (procs == NULL)
 
165
        return NULL;
 
166
 
 
167
    writebufferproc proc = procs->bf_getwritebuffer;
 
168
 
 
169
    void *ptr;
 
170
 
 
171
    *size = (*proc)(obj, 0, &ptr);
 
172
 
 
173
    return ptr;
 
174
}
 
175
%}
 
176
 
 
177
/* 
 
178
 * Make the bless_buffer_append() binding accept as data input objects that
 
179
 * support the PyBuffer interface.
 
180
 */
 
181
%exception bless_buffer_source_memory
 
182
{
 
183
    ssize_t s;
 
184
    arg2 = get_read_buf_pyobj_copy(obj0, &s);
 
185
 
 
186
    if (s != -1 && s >= arg3) {
 
187
        $action
 
188
    }
 
189
    else
 
190
        result = 666;
 
191
}
 
192
 
 
193
/* 
 
194
 * Make the bless_buffer_read() binding accept as data input objects that
 
195
 * support the PyBuffer interface.
 
196
 */
 
197
%exception bless_buffer_read
 
198
{
 
199
    ssize_t s;
 
200
 
 
201
    arg3 = get_write_buf_pyobj(obj2, &s);
 
202
 
 
203
    if (s != -1 && s >= arg5) {
 
204
        $action
 
205
    }
 
206
    else
 
207
        result = 666;
 
208
}
 
209
 
 
210
/* 
 
211
 * Make the read_data_object() binding accept as data input objects that
 
212
 * support the PyBuffer interface.
 
213
 */
 
214
%exception read_data_object
 
215
{
 
216
    ssize_t s;
 
217
 
 
218
    arg3 = get_write_buf_pyobj(obj2, &s);
 
219
 
 
220
    if (s != -1 && s >= arg4) {
 
221
        $action
 
222
    }
 
223
    else
 
224
        result = 666;
 
225
}
 
226
 
 
227
/*
 
228
 * Typemaps that handle output arguments.
 
229
 */
 
230
 
 
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 * };
 
235
 
 
236
/* in priority_queue_add size_t *pos is a normal pointer (not output) */
 
237
%apply SWIGTYPE * { size_t *pos };
 
238
 
 
239
/*
 
240
 * Helper functions available only in python code for testing purposes.
 
241
 *
 
242
 * These should be placed at the end of the SWIG file so the typemaps 
 
243
 * will apply to them.
 
244
 */
 
245
%inline %{
 
246
/* Get the maximum value of off_t */
 
247
off_t get_max_off_t(void)
 
248
{
 
249
    return __MAX(off_t);
 
250
}
 
251
 
 
252
/* Get the maximum value of size_t */
 
253
size_t get_max_size_t(void)
 
254
{
 
255
    return __MAX(size_t);
 
256
}
 
257
 
 
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)
 
261
{
 
262
    return segment_new(seg, (void *)ptr, start, size, data_usage_func);
 
263
}
 
264
 
 
265
/* Set the segcol of a bless_buffer_t */
 
266
void set_buffer_segcol(bless_buffer_t *buf, segcol_t *segcol)
 
267
{
 
268
    segcol_free(buf->segcol);
 
269
    buf->segcol = segcol;
 
270
}
 
271
 
 
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)
 
274
{
 
275
    return data_object_memory_new(o, (void *)ptr, len);
 
276
}
 
277
 
 
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)
 
280
{
 
281
    return bless_buffer_source_memory(src, (void *)ptr, len, func);
 
282
}
 
283
 
 
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)
 
287
{
 
288
    return bless_buffer_read(src, src_offset, (void *)dst, dst_offset, length);
 
289
}
 
290
 
 
291
/* Append a segment to buffer */ 
 
292
int bless_buffer_append_segment(bless_buffer_t *buf, segment_t *seg)
 
293
{
 
294
    if (buf == NULL || seg == NULL) 
 
295
        return EINVAL;
 
296
 
 
297
    segcol_t *sc = buf->segcol;
 
298
 
 
299
    /* Append segment to the segcol */
 
300
    int err = segcol_append(sc, seg);
 
301
    if (err) {
 
302
        return err;
 
303
    }
 
304
 
 
305
    return 0;
 
306
}
 
307
 
 
308
/* Malloc memory and return the address cast to size_t */
 
309
size_t bless_malloc(size_t s)
 
310
{
 
311
    void *p = malloc(s);
 
312
 
 
313
    return (size_t)p;
 
314
}
 
315
 
 
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)
 
318
{
 
319
    return segcol_delete(segcol, NULL, offset, length);
 
320
}
 
321
 
 
322
/* 
 
323
 * Prints a list of segment edges assuming that the segment data 
 
324
 * is a PyString value.
 
325
 */
 
326
void print_edge_list(list_t *edges, int fd)
 
327
{
 
328
    FILE *fp = fdopen(fd, "w");
 
329
    struct list_node *node;
 
330
 
 
331
    list_for_each(list_head(edges)->next, node) {
 
332
        struct edge_entry *e = list_entry(node, struct edge_entry, ln);
 
333
        PyObject *str1;
 
334
        segment_get_data(e->src, (void **)&str1);
 
335
        PyObject *str2;
 
336
        segment_get_data(e->dst, (void **)&str2);
 
337
 
 
338
        fprintf(fp, "%s -> %s\n", PyString_AsString(str1),
 
339
            PyString_AsString(str2));
 
340
    }
 
341
 
 
342
    fclose(fp);
 
343
}
 
344
 
 
345
/* 
 
346
 * Prints a list of segment vertices assuming that the segment data 
 
347
 * is a PyString value.
 
348
 */
 
349
void print_vertex_list(list_t *vertices, int fd)
 
350
{
 
351
    FILE *fp = fdopen(fd, "w");
 
352
    struct list_node *node;
 
353
 
 
354
    list_for_each(list_head(vertices)->next, node) {
 
355
        struct vertex_entry *e = list_entry(node, struct vertex_entry, ln);
 
356
        PyObject *str1;
 
357
        segment_get_data(e->segment, (void **)&str1);
 
358
 
 
359
        fprintf(fp, "%s\n", PyString_AsString(str1));
 
360
    }
 
361
 
 
362
    fclose(fp);
 
363
}
 
364
%}
 
365
 
 
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"
 
383