1 module tagion.tools.dartutil.dartindex; 2 3 import std.format; 4 import tagion.basic.Types : Buffer; 5 import tagion.crypto.SecureInterfaceNet : HashNet; 6 import tagion.dart.DARTBasic : DARTIndex, dartKey; 7 import tagion.hibon.Document; 8 import tagion.tools.Basic; 9 import tagion.tools.toolsexception; 10 11 DARTIndex dartIndexDecode(const(HashNet) net, const(char[]) str) { 12 import tagion.hibon.HiBONtoText; 13 import misc = tagion.utils.Miscellaneous; 14 import std.base64; 15 import std.algorithm; 16 import std.array : split; 17 import std.traits; 18 import tagion.hibon.Document : mut; 19 import tagion.hibon.HiBONBase; 20 import tagion.hibon.HiBONFile : fread; 21 import tagion.hibon.HiBONJSON : NotSupported, typeMap; 22 23 verbose("dart-index %s", str); 24 25 if (isBase64Prefix(str)) { 26 return DARTIndex(Base64URL.decode(str[1 .. $]).idup); 27 } 28 else if (isHexPrefix(str)) { 29 return DARTIndex(misc.decode(str[hex_prefix.length .. $])); 30 } 31 else if (str.canFind(":")) { 32 33 const list = str.split(":"); 34 const name = list[0]; 35 if (list.length == 2) { 36 return net.dartKey(name, list[1].idup); 37 } 38 case_type: 39 switch (list[1]) { 40 static foreach (E; EnumMembers!Type) { 41 { 42 enum type_name = typeMap[E]; 43 static if (type_name != NotSupported) { 44 case type_name: 45 verbose("Htype %s -> %s", type_name, E); 46 static if (E == Type.BINARY) { 47 Buffer buf = list[2].decode; 48 verbose("Dtype %s name=%s value=%(%02x%)", Buffer.stringof, name, buf); 49 return net.dartKey(name, buf); 50 } 51 else static if (E == Type.DOCUMENT) { 52 const doc = list[2].fread; 53 verbose("Dtype %s name=%s value=\n%s", Document.stringof, name, doc.toPretty); 54 return net.dartKey(name, doc.mut); 55 } 56 else static if (E == Type.STRING) { 57 verbose("Dtype %s name=%s value=%s", string.stringof, name, list[2]); 58 return net.dartKey(name, list[2].idup); 59 } 60 else static if (E == Type.TIME) { 61 import std.datetime; 62 63 const val = SysTime.fromISOExtString(list[2]).stdTime; 64 verbose("Dtype %s name=%s value=%s", SysTime.stringof, name, val); 65 return net.dartKey(name, val); 66 } 67 else { 68 alias Value = ValueT!(false, void, void); 69 alias T = Unqual!(Value.TypeT!E); 70 import std.conv : to; 71 72 auto val = list[2].to!T; 73 verbose("Dtype %s name=%s value=%s", T.stringof, name, val); 74 return net.dartKey(name, val); 75 } 76 break case_type; 77 } 78 } 79 } 80 default: 81 check(0, format("DART search %s not supported expected name:Type:value or name:text", str)); 82 } 83 verbose("Dtype %s name=%s value=%s", string.stringof, name, list[2]); 84 85 return net.dartKey(name, list[1].idup); 86 } 87 88 return DARTIndex(misc.decode(str)); 89 } 90 91 immutable(Buffer) binaryHash(const(HashNet) net, scope const(ubyte[]) h1, scope const(ubyte[]) h2) 92 in { 93 assert(h1.length is 0 || h1.length is net.hashSize, 94 format("h1 is not a valid hash (length=%d should be 0 or %d", h1.length, net.hashSize)); 95 assert(h2.length is 0 || h2.length is net.hashSize, 96 format("h2 is not a valid hash (length=%d should be 0 or %d", h2.length, net.hashSize)); 97 } 98 out (result) { 99 if (h1.length is 0) { 100 assert(h2 == result); 101 } 102 else if (h2.length is 0) { 103 assert(h1 == result); 104 } 105 } 106 do { 107 assert(h1.length is 0 || h1.length is net.hashSize, 108 format("h1 is not a valid hash (length=%d should be 0 or %d", h1.length, net.hashSize)); 109 assert(h2.length is 0 || h2.length is net.hashSize, 110 format("h2 is not a valid hash (length=%d should be 0 or %d", h2.length, net.hashSize)); 111 if (h1.length is 0) { 112 return h2.idup; 113 } 114 if (h2.length is 0) { 115 return h1.idup; 116 } 117 return net.rawCalcHash(h1 ~ h2); 118 }