@@ -48,6 +48,21 @@ fn mut_offset<T>(ptr: *mut T, count: uint) -> *mut T {
48
48
( ptr as uint + count * sys:: size_of :: < T > ( ) ) as * mut T
49
49
}
50
50
51
+ #[ doc = "Return the offset of the first null pointer in `buf`." ]
52
+ #[ inline( always) ]
53
+ unsafe fn buf_len < T > ( buf : * * T ) -> uint {
54
+ position ( buf) { |i| i == null ( ) }
55
+ }
56
+
57
+ #[ doc = "Return the first offset `i` such that `f(buf[i]) == true`." ]
58
+ #[ inline( always) ]
59
+ unsafe fn position < T > ( buf : * T , f : fn ( T ) -> bool ) -> uint {
60
+ let mut i = 0 u;
61
+ loop {
62
+ if f ( * offset ( buf, i) ) { ret i; }
63
+ else { i += 1 u; }
64
+ }
65
+ }
51
66
52
67
#[ doc = "Create an unsafe null pointer" ]
53
68
#[ inline( always) ]
@@ -111,4 +126,32 @@ fn test() unsafe {
111
126
ptr:: memcpy ( ptr:: offset ( vec:: unsafe:: to_ptr ( v1) , 2 u) ,
112
127
vec:: unsafe:: to_ptr ( v0) , 1 u) ;
113
128
assert ( v1[ 0 ] == 32002u16 && v1[ 1 ] == 32001u16 && v1[ 2 ] == 32000u16 ) ;
129
+ }
130
+
131
+ #[ test]
132
+ fn test_position ( ) unsafe {
133
+ import str:: as_c_str;
134
+ import libc:: c_char;
135
+
136
+ let s = "hello" ;
137
+ assert 2 u == as_c_str ( s) { |p| position ( p) { |c| c == 'l' as c_char } } ;
138
+ assert 4 u == as_c_str ( s) { |p| position ( p) { |c| c == 'o' as c_char } } ;
139
+ assert 5 u == as_c_str ( s) { |p| position ( p) { |c| c == 0 as c_char } } ;
140
+ }
141
+
142
+ #[ test]
143
+ fn test_buf_len ( ) unsafe {
144
+ let s0 = "hello" ;
145
+ let s1 = "there" ;
146
+ let s2 = "thing" ;
147
+ str:: as_c_str ( s0) { |p0|
148
+ str:: as_c_str ( s1) { |p1|
149
+ str:: as_c_str ( s2) { |p2|
150
+ let v = [ p0, p1, p2, null ( ) ] ;
151
+ vec:: as_buf ( v) { |vp|
152
+ assert buf_len ( vp) == 3 u;
153
+ }
154
+ }
155
+ }
156
+ }
114
157
}
0 commit comments