]> git.lizzy.rs Git - rust.git/blob - src/libstd/c_vec.rs
libstd: rename c_vec::size to len.
[rust.git] / src / libstd / c_vec.rs
1 /*
2 Module: c_vec
3
4 Library to interface with chunks of memory allocated in C.
5
6 It is often desirable to safely interface with memory allocated from C,
7 encapsulating the unsafety into allocation and destruction time.  Indeed,
8 allocating memory externally is currently the only way to give Rust shared
9 mutable state with C programs that keep their own references; vectors are
10 unsuitable because they could be reallocated or moved at any time, and
11 importing C memory into a vector takes a one-time snapshot of the memory.
12
13 This module simplifies the usage of such external blocks of memory.  Memory
14 is encapsulated into an opaque object after creation; the lifecycle of the
15 memory can be optionally managed by Rust, if an appropriate destructor
16 closure is provided.  Safety is ensured by bounds-checking accesses, which
17 are marshalled through get and set functions.
18
19 There are three unsafe functions: the two introduction forms, and the
20 pointer elimination form.  The introduction forms are unsafe for the obvious
21 reason (they act on a pointer that cannot be checked inside the method), but
22 the elimination form is somewhat more subtle in its unsafety.  By using a
23 pointer taken from a c_vec::t without keeping a reference to the c_vec::t
24 itself around, the c_vec could be garbage collected, and the memory within
25 could be destroyed.  There are legitimate uses for the pointer elimination
26 form -- for instance, to pass memory back into C -- but great care must be
27 taken to ensure that a reference to the c_vec::t is still held if needed.
28
29  */
30
31 export t;
32 export create, create_with_dtor;
33 export get, set;
34 export len;
35 export ptr;
36
37 /*
38  Type: t
39
40  The type representing a native chunk of memory.  Wrapped in a tag for
41  opacity; FIXME #818 when it is possible to have truly opaque types, this
42  should be revisited.
43  */
44
45 tag t<T> {
46     t({ base: *mutable T, len: uint, rsrc: @dtor_res});
47 }
48
49 resource dtor_res(dtor: option::t<fn@()>) {
50     alt dtor {
51       option::none. { }
52       option::some(f) { f(); }
53     }
54 }
55
56 /*
57  Section: Introduction forms
58  */
59
60 /*
61 Function: create
62
63 Create a c_vec::t from a native buffer with a given length.
64
65 Parameters:
66
67 base - A native pointer to a buffer
68 len - The number of elements in the buffer
69 */
70 unsafe fn create<T>(base: *mutable T, len: uint) -> t<T> {
71     ret t({base: base,
72            len: len,
73            rsrc: @dtor_res(option::none)
74           });
75 }
76
77 /*
78 Function: create_with_dtor
79
80 Create a c_vec::t from a native buffer, with a given length,
81 and a function to run upon destruction.
82
83 Parameters:
84
85 base - A native pointer to a buffer
86 len - The number of elements in the buffer
87 dtor - A function to run when the value is destructed, useful
88        for freeing the buffer, etc.
89 */
90 unsafe fn create_with_dtor<T>(base: *mutable T, len: uint, dtor: fn@())
91   -> t<T> {
92     ret t({base: base,
93            len: len,
94            rsrc: @dtor_res(option::some(dtor))
95           });
96 }
97
98 /*
99  Section: Operations
100  */
101
102 /*
103 Function: get
104
105 Retrieves an element at a given index
106
107 Failure:
108
109 If `ofs` is greater or equal to the length of the vector
110 */
111 fn get<T: copy>(t: t<T>, ofs: uint) -> T {
112     assert ofs < len(t);
113     ret unsafe { *ptr::mut_offset((*t).base, ofs) };
114 }
115
116 /*
117 Function: set
118
119 Sets the value of an element at a given index
120
121 Failure:
122
123 If `ofs` is greater or equal to the length of the vector
124 */
125 fn set<T: copy>(t: t<T>, ofs: uint, v: T) {
126     assert ofs < len(t);
127     unsafe { *ptr::mut_offset((*t).base, ofs) = v };
128 }
129
130 /*
131  Section: Elimination forms
132  */
133
134 /*
135 Function: len
136
137 Returns the length of the vector
138 */
139 fn len<T>(t: t<T>) -> uint {
140     ret (*t).len;
141 }
142
143 /*
144 Function: ptr
145
146 Returns a pointer to the first element of the vector
147 */
148 unsafe fn ptr<T>(t: t<T>) -> *mutable T {
149     ret (*t).base;
150 }