1 module grpc.core.utils; 2 import interop.headers; 3 import interop.functors; 4 import grpc.logger; 5 import std.experimental.allocator : theAllocator, makeArray, dispose; 6 public import core.time; 7 8 auto slice_to_string(grpc_slice slice) @nogc { 9 return slice_to_type!string(slice); 10 } 11 12 auto ref slice_to_type(T)(grpc_slice _slice) @nogc 13 if(__traits(isPOD, T) && __traits(compiles, cast(T)[0x01, 0x02])) { 14 struct Slice { 15 grpc_slice slice; 16 17 T data() { 18 return cast(T)GRPC_SLICE_START_PTR(slice)[0..GRPC_SLICE_LENGTH(slice)]; 19 } 20 21 alias data this; 22 23 ~this() { 24 grpc_slice_unref(slice); 25 } 26 } 27 28 if (GRPC_SLICE_LENGTH(_slice) != 0) { 29 grpc_slice slice = grpc_slice_copy(_slice); 30 grpc_slice_ref(slice); 31 return Slice(slice); 32 } 33 34 return Slice(); 35 } 36 37 auto byte_buffer_to_string(grpc_byte_buffer* bytebuf) { 38 return byte_buffer_to_type!string(bytebuf); 39 } 40 41 auto byte_buffer_to_type(T)(grpc_byte_buffer* bytebuf) { 42 grpc_byte_buffer_reader reader; 43 grpc_byte_buffer_reader_init(&reader, bytebuf); 44 grpc_slice slices = grpc_byte_buffer_reader_readall(&reader); 45 grpc_byte_buffer_reader_destroy(&reader); 46 auto val = slice_to_type!T(slices); 47 return val; 48 } 49 50 /* ensure that you unref after this.. don't want to keep a slice around too long */ 51 52 grpc_slice string_to_slice(string _string) { 53 import std.string : toStringz; 54 grpc_slice slice = grpc_slice_from_copied_string(_string.toStringz); 55 return slice; 56 } 57 58 grpc_slice type_to_slice(T)(T type) { 59 grpc_slice slice = grpc_slice_from_copied_buffer(cast(const(char*))type.ptr, type.length); 60 return slice; 61 } 62 63 gpr_timespec durtotimespec(Duration time) @nogc nothrow { 64 gpr_timespec t = gpr_time_from_nanos(time.split!"nsecs"().nsecs, GPR_TIMESPAN); 65 return t; 66 } 67 68 Duration timespectodur(gpr_timespec time) @nogc nothrow { 69 return gpr_time_to_millis(gpr_time_sub(time, gpr_now(time.clock_type))).msecs; 70 } 71 72 import core.memory : GC; 73 void doNotMoveObject(void* ptr, size_t len) @trusted nothrow { 74 GC.addRange(ptr, len); 75 GC.setAttr(cast(void*)ptr, GC.BlkAttr.NO_MOVE); 76 GC.addRoot(ptr); 77 } 78 79 void okToMoveObject(void* ptr) @trusted nothrow { 80 GC.removeRoot(ptr); 81 GC.clrAttr(cast(void*)ptr, GC.BlkAttr.NO_MOVE); 82 GC.removeRange(ptr); 83 } 84 85 import grpc.core.tag : Tag; 86 bool callOverDeadline(Tag* _tag) { 87 if (_tag.ctx.details.deadline == -1.seconds) { 88 DEBUG!"call has NO deadline"; 89 return false; 90 } else { 91 DEBUG!"%s vs %s"(MonoTime.currTime - _tag.ctx.timestamp, _tag.ctx.details.deadline); 92 } 93 94 if (MonoTime.currTime - _tag.ctx.timestamp > _tag.ctx.details.deadline) { 95 DEBUG!"reached deadline, cannot go further"; 96 return true; 97 } 98 return false; 99 } 100