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