• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/ucode/tests/custom/17_lib_ffi/22_index_ref

  1 The `cdata.index()` method returns raw cdata references for further manipulation,
  2 unlike `get()` which returns converted ucode values.
  3 
  4 Basic index() returns cdata reference.
  5 
  6 -- Testcase --
  7 {%
  8 import * as ffi from 'ffi';
  9 
 10 ffi.cdef('typedef int intarr[3];');
 11 let a = ffi.ctype('intarr', 10, 20, 30);
 12 
 13 // index() returns cdata reference
 14 let ref = a.index(0);
 15 print("type of index: ", type(ref), "\n");
 16 
 17 // Can call get() on the reference to convert
 18 print("value: ", ref.get(), "\n");
 19 -- End --
 20 
 21 -- Expect stdout --
 22 type of index: resource
 23 value: 10
 24 -- End --
 25 
 26 
 27 index() supports chaining with set().
 28 
 29 -- Testcase --
 30 {%
 31 import * as ffi from 'ffi';
 32 
 33 ffi.cdef('typedef int intarr[3];');
 34 let a = ffi.ctype('intarr', 10, 20, 30);
 35 
 36 // Chain index().set() to modify through reference
 37 a.index(1).set(99);
 38 print("array: ", a.get(0), " ", a.get(1), " ", a.get(2), "\n");
 39 -- End --
 40 
 41 -- Expect stdout --
 42 array: 10 99 30
 43 -- End --
 44 
 45 
 46 index() works with struct fields.
 47 
 48 -- Testcase --
 49 {%
 50 import * as ffi from 'ffi';
 51 
 52 ffi.cdef('typedef struct { int x; int y; } point;');
 53 let p = ffi.ctype('point', 100, 200);
 54 
 55 // index() returns cdata reference to field
 56 let xref = p.index('x');
 57 print("type: ", type(xref), "\n");
 58 print("value: ", xref.get(), "\n");
 59 
 60 // Modify through reference
 61 p.index('y').set(999);
 62 print("y after set: ", p.get('y'), "\n");
 63 -- End --
 64 
 65 -- Expect stdout --
 66 type: resource
 67 value: 100
 68 y after set: 999
 69 -- End --
 70 
 71 
 72 index() supports path notation.
 73 
 74 -- Testcase --
 75 {%
 76 import * as ffi from 'ffi';
 77 
 78 ffi.cdef('struct point { int x; int y; }; struct rect { struct point min; struct point max; };');
 79 let r = ffi.ctype('struct rect', {
 80     min: {x: 1, y: 2},
 81     max: {x: 3, y: 4}
 82 });
 83 
 84 // index() with path returns cdata reference
 85 let ref = r.index('min.x');
 86 print("type: ", type(ref), "\n");
 87 print("value: ", ref.get(), "\n");
 88 
 89 // Modify through path reference
 90 r.index('max.y').set(999);
 91 print("max.y after set: ", r.get('max.y'), "\n");
 92 -- End --
 93 
 94 -- Expect stdout --
 95 type: resource
 96 value: 1
 97 max.y after set: 999
 98 -- End --
 99 
100 
101 index() works with pointer arithmetic.
102 
103 -- Testcase --
104 {%
105 import * as ffi from 'ffi';
106 
107 ffi.cdef('typedef int intarr[5];');
108 let a = ffi.ctype('intarr', 10, 20, 30, 40, 50);
109 let ptr = ffi.ctype('int *', a.ptr());
110 
111 // index() on pointer for arithmetic
112 print("ptr[0]: ", ptr.index(0).get(), "\n");
113 print("ptr[2]: ", ptr.index(2).get(), "\n");
114 print("ptr[4]: ", ptr.index(4).get(), "\n");
115 
116 // Modify through pointer index
117 ptr.index(1).set(99);
118 print("after set: ", a.get(1), "\n");
119 -- End --
120 
121 -- Expect stdout --
122 ptr[0]: 10
123 ptr[2]: 30
124 ptr[4]: 50
125 after set: 99
126 -- End --
127 
128 
129 index() with char* for byte-level access.
130 
131 -- Testcase --
132 {%
133 import * as ffi from 'ffi';
134 
135 ffi.cdef('char *strdup(const char *); void free(void *);');
136 let strdup = ffi.C.wrap('char *strdup(const char *)');
137 let free = ffi.C.wrap('void free(void *)');
138 
139 let ptr = strdup("hello");
140 
141 // index() for byte access
142 print("ptr[0]: ", ptr.index(0).get(), "\n");
143 print("ptr[1]: ", ptr.index(1).get(), "\n");
144 print("ptr[4]: ", ptr.index(4).get(), "\n");
145 
146 // Modify through index
147 ptr.index(0).set(65);  // 'A'
148 print("after mod: ", ffi.string(ptr), "\n");
149 
150 free(ptr);
151 -- End --
152 
153 -- Expect stdout --
154 ptr[0]: 104
155 ptr[1]: 101
156 ptr[4]: 111
157 after mod: Aello
158 -- End --
159 
160 
161 Compare get() vs index() return types.
162 
163 -- Testcase --
164 {%
165 import * as ffi from 'ffi';
166 
167 ffi.cdef('typedef int intarr[3];');
168 let a = ffi.ctype('intarr', 10, 20, 30);
169 
170 // get() returns converted value
171 let v1 = a.get(0);
172 print("get() type: ", type(v1), " value: ", v1, "\n");
173 
174 // index() returns cdata reference
175 let v2 = a.index(0);
176 print("index() type: ", type(v2), "\n");
177 
178 // Must call get() on index() result
179 print("index().get() type: ", type(v2.get()), " value: ", v2.get(), "\n");
180 -- End --
181 
182 -- Expect stdout --
183 get() type: int value: 10
184 index() type: resource
185 index().get() type: int value: 10
186 -- End --
187 
188 
189 index() on nested arrays.
190 
191 -- Testcase --
192 {%
193 import * as ffi from 'ffi';
194 
195 ffi.cdef('typedef int intarr2d[2][3];');
196 let m = ffi.ctype('intarr2d', [1, 2, 3], [4, 5, 6]);
197 
198 // First index returns row cdata
199 let row0 = m.index(0);
200 print("row0 type: ", type(row0), "\n");
201 
202 // Second index on row returns element cdata
203 let elem = row0.index(1);
204 print("elem type: ", type(elem), "\n");
205 print("value: ", elem.get(), "\n");
206 
207 // Chain for modification
208 m.index(1).index(2).set(999);
209 print("m[1][2]: ", m.get('[1][2]'), "\n");
210 -- End --
211 
212 -- Expect stdout --
213 row0 type: resource
214 elem type: resource
215 value: 2
216 m[1][2]: 999
217 -- End --
218 
219 
220 index() with const types still returns reference.
221 
222 -- Testcase --
223 {%
224 import * as ffi from 'ffi';
225 
226 ffi.cdef('typedef int intarr[3];');
227 let a = ffi.ctype('intarr', 10, 20, 30);
228 
229 // Get const pointer
230 let const_ptr = ffi.ctype('const int *', a.ptr());
231 
232 // index() on const pointer
233 let ref = const_ptr.index(0);
234 print("type: ", type(ref), "\n");
235 print("value: ", ref.get(), "\n");
236 -- End --
237 
238 -- Expect stdout --
239 type: resource
240 value: 10
241 -- End --
242 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt