1 module tagion.betterC.mobile.DocumentWrapperApi; 2 3 import tagion.betterC.hibon.Document; 4 import tagion.betterC.hibon.HiBON; 5 import tagion.betterC.mobile.Recycle; 6 import tagion.betterC.utils.Memory; 7 8 // import tagion.basic.Recycle; 9 // import tagion.gossip.GossipNet; 10 // import tagion.betterC.wallet.Net : SecureNet; 11 // import tagion.wallet.KeyRecover; 12 13 // import core.runtime : rt_init, rt_term; 14 // import core.stdc.stdlib; 15 import std.conv; 16 import std.stdint; 17 import std.string; 18 import tagion.basic.Types : Buffer; 19 20 // import tagion.hibon.HiBONJSON; 21 22 public Recycle!Document recyclerDoc; 23 24 // static this() { 25 // recyclerDoc = recyclerDoc.init; 26 // } 27 28 // { 29 // auto recyclerDoc = new reecycle!Document; 30 // recycleDoc._active .... -> fine; 31 // free(recyclerDoc); 32 // recyclerDoc._active -> fail; 33 // } 34 35 extern (C) { 36 enum BAD_RESULT = 0; 37 38 string[] parse_string(const char* str, const uint len) { 39 string[] result; 40 return result; 41 } 42 43 /// Functions called from d-lang through dart:ffi 44 45 /// Creating Document by ubyte array 46 // export uint32_t create_test_doc() 47 // { 48 // auto hibon = HiBON(); 49 // auto inner_hibon = HiBON(); 50 // auto arr_hibon = HiBON(); 51 // hibon["teststr"] = "test string"; 52 // hibon["testnum"] = 123; 53 // hibon["testpk"] = cast(Buffer) [1,1,1,1]; 54 // const testarr = ["first", "second", "third"]; 55 // foreach(i, a; testarr){ 56 // arr_hibon[i] = a; 57 // } 58 // hibon["testarr"] = Document(arr_hibon); 59 // inner_hibon["teststr"] = "inner test string"; 60 // hibon["inner"] = Document(inner_hibon); 61 // auto doc = Document(hibon); 62 // if (doc.isInorder()) 63 // { 64 // auto docId = recyclerDoc.create(doc); 65 // return docId; 66 // } 67 // return BAD_RESULT; 68 // } 69 /// Creating Document by ubyte array 70 export uint32_t create_doc(const uint8_t* data_ptr, const uint32_t len) { 71 // immutable(ubyte)[] data = cast(immutable(ubyte)[]) data_ptr[0 .. len]; 72 ubyte[] data; 73 data.create(len); 74 for (size_t i = 0; i < len; i++) { 75 data[i] = data_ptr[i]; 76 } 77 auto doc = Document(cast(immutable)(data)); 78 if (doc.isInorder()) { 79 auto docId = recyclerDoc.create(doc); 80 return docId; 81 } 82 return BAD_RESULT; 83 } 84 85 /// Deleting the specific Document 86 export void delete_doc_by_id(const uint32_t id) { 87 if (id !is BAD_RESULT) { 88 recyclerDoc.erase(id); 89 } 90 } 91 92 // /// Getting the int value from Document by integer index 93 // export int32_t doc_get_int_by_id(const uint32_t doc_id, const uint32_t index) 94 // { 95 // if (recyclerDoc(doc_id).hasMember(index)) 96 // { 97 // return recyclerDoc(doc_id)[index].get; 98 // } 99 // return BAD_RESULT; 100 // } 101 102 /// Getting the int value from Document by string key 103 export int32_t doc_get_int_by_key(const uint32_t doc_id, const char* key_str, const uint32_t len) { 104 // immutable key = cast(immutable)(key_str[0 .. len]); 105 char[] key; 106 key.create(len); 107 for (int i = 0; i < len; i++) { 108 key[i] = key_str[i]; 109 } 110 if (recyclerDoc(doc_id).hasMember(cast(string)(key))) { 111 return recyclerDoc(doc_id)[cast(string) key].get!int; 112 } 113 return BAD_RESULT; 114 } 115 /// Getting the ulong value from Document by string key 116 export int64_t doc_get_ulong_by_key(const uint32_t doc_id, const char* key_str, const uint32_t len) { 117 char[] key; 118 key.create(len); 119 for (int i = 0; i < len; i++) { 120 key[i] = key_str[i]; 121 } 122 if (recyclerDoc(doc_id).hasMember(cast(string)(key))) { 123 return recyclerDoc(doc_id)[cast(string) key].get!ulong; 124 } 125 return BAD_RESULT; 126 } 127 // /// Getting the string value from Document by index 128 // /// It uses UF-16 codding 129 // export const(char*) doc_get_str_by_id(const uint32_t doc_id, const uint32_t index) 130 // { 131 // if (recyclerDoc(doc_id).hasMember(index)) 132 // { 133 // string str = recyclerDoc(doc_id)[index].get!string; 134 // return toStringz(str); 135 // } 136 // return null; 137 // } 138 139 // /// getting the string value from Document by string key 140 // /// It uses UF-16 codding 141 export const(char*) doc_get_str_by_key(const uint32_t doc_id, const char* key_str, const uint32_t len) { 142 char[] key; 143 key.create(len); 144 for (int i = 0; i < len; i++) { 145 key[i] = key_str[i]; 146 } 147 if (recyclerDoc(doc_id).hasMember(cast(string)(key))) { 148 string str = recyclerDoc(doc_id)[cast(string) key].get!string; 149 return str.ptr; 150 } 151 return null; 152 } 153 154 // /// return doc as json 155 // /// It uses UF-16 codding 156 // export const(char*) doc_as_json(const uint32_t doc_id) 157 // { 158 // auto doc = recyclerDoc(doc_id); 159 // const json = doc.toJSON.toString(); 160 // return toStringz(json); 161 // } 162 163 // /// Getting the Document value from Document by index 164 // /// It uses UF-16 codding 165 // export uint64_t doc_get_docLen_by_id(const uint32_t doc_id, const uint32_t index) 166 // { 167 // if (recyclerDoc(doc_id).hasMember(index)) 168 // { 169 // const doc = recyclerDoc(doc_id)[index].get!Document; 170 // return doc.serialize.length; 171 // } 172 // return BAD_RESULT; 173 // } 174 175 // /// getting the Document value from Document by string key 176 // /// It uses UF-16 codding 177 export uint64_t doc_get_docLen_by_key(const uint32_t doc_id, const char* key_str, const uint32_t len) { 178 char[] key; 179 key.create(len); 180 for (int i = 0; i < len; i++) { 181 key[i] = key_str[i]; 182 } 183 if (recyclerDoc(doc_id).hasMember(cast(string)(key))) { 184 const doc = recyclerDoc(doc_id)[cast(string) key].get!Document; 185 return doc.serialize.length; 186 } 187 return BAD_RESULT; 188 } 189 190 // /// Getting the Document value from Document by index 191 // /// It uses UF-16 codding 192 // export uint8_t* doc_get_docPtr_by_id(const uint32_t doc_id, const uint32_t index) 193 // { 194 // if (recyclerDoc(doc_id).hasMember(index)) 195 // { 196 // const doc = recyclerDoc(doc_id)[index].get!Document; 197 // return cast(ubyte*) doc.serialize.ptr; 198 // } 199 // return null; 200 // } 201 202 // /// getting the Document value from Document by string key 203 // /// It uses UF-16 codding 204 export uint8_t* doc_get_docPtr_by_key(const uint32_t doc_id, const char* key_str, const uint32_t len) { 205 char[] key; 206 key.create(len); 207 for (int i = 0; i < len; i++) { 208 key[i] = key_str[i]; 209 } 210 if (recyclerDoc(doc_id).hasMember(cast(string)(key))) { 211 const doc = recyclerDoc(doc_id)[cast(string) key].get!Document; 212 return cast(ubyte*) doc.serialize.ptr; 213 } 214 return null; 215 } 216 217 // /// getting the Document value 218 // /// It uses UF-16 codding 219 export uint64_t get_docLen(const uint32_t doc_id) { 220 const doc = recyclerDoc(doc_id); 221 return doc.serialize.length; 222 } 223 224 // /// getting the Document value 225 // /// It uses UF-16 codding 226 export uint8_t* get_docPtr(const uint32_t doc_id) { 227 const doc = recyclerDoc(doc_id); 228 return cast(ubyte*) doc.serialize.ptr; 229 } 230 231 // export uint64_t doc_get_bufferLen_by_id(const uint32_t doc_id, const uint32_t index) 232 // { 233 // if (recyclerDoc(doc_id).hasMember(index)) 234 // { 235 // const buf = recyclerDoc(doc_id)[index].get!Buffer; 236 // return buf.length; 237 // } 238 // return BAD_RESULT; 239 // } 240 241 export uint64_t doc_get_bufferLen_by_key(const uint32_t doc_id, const char* key_str, const uint32_t len) { 242 char[] key; 243 key.create(len); 244 for (int i = 0; i < len; i++) { 245 key[i] = key_str[i]; 246 } 247 if (recyclerDoc(doc_id).hasMember(cast(string)(key))) { 248 const buf = recyclerDoc(doc_id)[cast(string) key].get!Buffer; 249 return buf.length; 250 } 251 return BAD_RESULT; 252 } 253 254 // export uint8_t* doc_get_bufferPtr_by_id(const uint32_t doc_id, const uint32_t index) 255 // { 256 // if (recyclerDoc(doc_id).hasMember(index)) 257 // { 258 // const doc = recyclerDoc(doc_id)[index].get!Buffer; 259 // return cast(ubyte*) doc.ptr; 260 // } 261 // return null; 262 // } 263 264 export uint8_t* doc_get_bufferPtr_by_key(const uint32_t doc_id, const char* key_str, const uint32_t len) { 265 char[] key; 266 key.create(len); 267 for (int i = 0; i < len; i++) { 268 key[i] = key_str[i]; 269 } 270 if (recyclerDoc(doc_id).hasMember(cast(string)(key))) { 271 const doc = recyclerDoc(doc_id)[cast(string) key].get!Buffer; 272 return cast(ubyte*) doc.ptr; 273 } 274 return null; 275 } 276 277 export uint64_t doc_get_memberCount(const uint32_t doc_id) { 278 return recyclerDoc(doc_id).length; 279 } 280 // /// Getting the keys of Document 281 // /// It uses UF-16 codding 282 // export const(char*) doc_get_keys(const uint32_t doc_id) 283 // { 284 // if (recyclerDoc.exists(doc_id)) 285 // { 286 // string[] keys = recyclerDoc(doc_id).keys(); 287 // string keysStr = join(keys, ";"); 288 // return toStringz(keysStr); 289 // } 290 // return null; 291 // } 292 293 // unittest 294 // { 295 // import std.stdio : writeln, writefln; 296 // import std.string : fromStringz; 297 // import tagion.hibon.HiBON : HiBON; 298 299 // // Aux HiBON for testing 300 // auto hib = new HiBON; 301 // hib["doc2"] = "test_str_with_key"; 302 303 // // Tests for create_doc() 304 // { 305 // // Test for null request 306 // assert(create_doc(null, 0) is 1); 307 308 // // Test for empty array 309 // const(ubyte)[] empty_data = new ubyte[0]; 310 // assert(create_doc(empty_data.ptr, 0) is 2); 311 312 // // Tests for ubytes' sequence 313 // const data1 = hib.serialize; 314 // const data2 = hib.serialize; 315 316 // //assert(create_doc(data1.ptr, data1.length) is 2); 317 // //assert(create_doc(data2.ptr, data2.length) is 3); 318 // } 319 320 // // Tests for delete_doc_by_id() 321 // { 322 // delete_doc_by_id(1); 323 // delete_doc_by_id(2); 324 325 // assert(!recyclerDoc.exists(0)); 326 // assert(!recyclerDoc.exists(1)); 327 328 // // Append two docs and check whether they exists by indicies 329 // const data = hib.serialize; 330 // create_doc(data.ptr, cast(uint) data.length); 331 // assert(recyclerDoc.exists(1)); 332 333 // create_doc(data.ptr, cast(uint) data.length); 334 // assert(recyclerDoc.exists(0)); 335 // } 336 // // Range of Document' indexes in RecyclerDoc [0 .. 3] 337 338 // // Tests for doc_get_int_by_key() 339 // { 340 // assert(doc_get_int_by_key(0, "doc1", 4) is 100); 341 // assert(doc_get_int_by_key(1, "doc1", 4) is 100); 342 // assert(doc_get_int_by_key(2, "doc1", 4) is 100); 343 // assert(doc_get_int_by_key(3, "doc1", 4) is 100); 344 345 // // Testing an absense of the key 346 // assert(doc_get_int_by_key(0, "doc", 3) is BAD_RESULT); 347 // assert(doc_get_int_by_key(1, "doc", 3) is BAD_RESULT); 348 // assert(doc_get_int_by_key(2, "doc", 3) is BAD_RESULT); 349 // assert(doc_get_int_by_key(3, "doc", 3) is BAD_RESULT); 350 351 // // Testing a wrong key size with correct key 352 // assert(doc_get_int_by_key(0, "doc1", 3) is BAD_RESULT); 353 // assert(doc_get_int_by_key(1, "doc1", 3) is BAD_RESULT); 354 // assert(doc_get_int_by_key(2, "doc1", 3) is BAD_RESULT); 355 // assert(doc_get_int_by_key(3, "doc1", 3) is BAD_RESULT); 356 357 // // Testing a wrong key size with incorrect key 358 // assert(doc_get_int_by_key(0, "doc", 10) is BAD_RESULT); 359 // assert(doc_get_int_by_key(1, "doc", 10) is BAD_RESULT); 360 // assert(doc_get_int_by_key(2, "doc", 10) is BAD_RESULT); 361 // assert(doc_get_int_by_key(3, "doc", 10) is BAD_RESULT); 362 // } 363 364 // // Tests for doc_get_int_by_id() 365 // { 366 // assert(doc_get_int_by_id(0, 1) is 101); 367 // assert(doc_get_int_by_id(1, 1) is 101); 368 // assert(doc_get_int_by_id(2, 1) is 101); 369 // assert(doc_get_int_by_id(3, 1) is 101); 370 371 // // Testing an absense of the key 372 // assert(doc_get_int_by_id(0, 3) is BAD_RESULT); 373 // assert(doc_get_int_by_id(1, 3) is BAD_RESULT); 374 // assert(doc_get_int_by_id(2, 3) is BAD_RESULT); 375 // assert(doc_get_int_by_id(3, 3) is BAD_RESULT); 376 // } 377 378 // // Tests for doc_get_str_by_id() 379 // { 380 // const(char)[] expected_str = "test_str_with_id"; 381 382 // assert(fromStringz(doc_get_str_by_id(0, 2)) == expected_str); 383 // assert(fromStringz(doc_get_str_by_id(1, 2)) == expected_str); 384 // assert(fromStringz(doc_get_str_by_id(2, 2)) == expected_str); 385 // assert(fromStringz(doc_get_str_by_id(3, 2)) == expected_str); 386 387 // // Testing an existed document with wrong id 388 // assert(doc_get_str_by_id(0, 0) is null); 389 // assert(doc_get_str_by_id(1, 0) is null); 390 // assert(doc_get_str_by_id(2, 0) is null); 391 // assert(doc_get_str_by_id(3, 0) is null); 392 // } 393 394 // // Tests for doc_get_str_by_key() 395 // { 396 // const(char)[] expected_str = "test_str_with_key"; 397 398 // assert(fromStringz(doc_get_str_by_key(0, "doc2", 4)) == expected_str); 399 // assert(fromStringz(doc_get_str_by_key(1, "doc2", 4)) == expected_str); 400 // assert(fromStringz(doc_get_str_by_key(2, "doc2", 4)) == expected_str); 401 // assert(fromStringz(doc_get_str_by_key(3, "doc2", 4)) == expected_str); 402 403 // // Testing an absense of the key 404 // assert(doc_get_str_by_key(0, "doc", 3) is null); 405 // assert(doc_get_str_by_key(1, "doc", 3) is null); 406 // assert(doc_get_str_by_key(2, "doc", 3) is null); 407 // assert(doc_get_str_by_key(3, "doc", 3) is null); 408 409 // // Testing a wrong key's size with correct key 410 // assert(doc_get_str_by_key(0, "doc2", 3) is null); 411 // assert(doc_get_str_by_key(1, "doc2", 3) is null); 412 // assert(doc_get_str_by_key(2, "doc2", 3) is null); 413 // assert(doc_get_str_by_key(3, "doc2", 3) is null); 414 415 // // Testing a wrong key's size with incorrect key 416 // assert(doc_get_str_by_key(0, "doc", 10) is null); 417 // assert(doc_get_str_by_key(1, "doc", 10) is null); 418 // assert(doc_get_str_by_key(2, "doc", 10) is null); 419 // assert(doc_get_str_by_key(3, "doc", 10) is null); 420 // } 421 422 // { 423 // import std.algorithm; 424 // auto hib1 = new HiBON; 425 // hib1["test"] = "test"; 426 // hib["doc3"] = Document(hib1); 427 // const expected = hib1.serialize; 428 429 // const data = hib.serialize; 430 // auto index = create_doc(data.ptr, cast(uint) data.length); 431 432 // const docLen = doc_get_docLen_by_key(index, "test", 4); 433 // immutable docPtr = cast(immutable) doc_get_docPtr_by_key(index, "test", 4); 434 // const doc = Document(docPtr[0..cast(uint)docLen]); 435 // assert(equal(expected, doc.serialize)); 436 // } 437 // } 438 }