1 // Written in the D programming language. 2 3 /** 4 This module contains a set of various functions for work with 9P / Styx messages as ranges. 5 6 Copyright: LightHouse Software, 2021 7 License: $(HTTP https://github.com/aquaratixc/ESL-License, Experimental Software License 1.0). 8 Authors: Oleg Bakharev, 9 Ilya Pertsev 10 */ 11 module styx2000.extrautil.msgranges; 12 13 private { 14 import std.algorithm : map; 15 import std.conv : to; 16 import std.string : replace; 17 18 import styx2000.lowlevel.endianness : fromLEBytes; 19 import styx2000.protobj.styxobject : StyxObject; 20 import styx2000.protomsg : decode; 21 } 22 23 private { 24 /// Raw byte range 25 struct ByteMessageRange 26 { 27 private { 28 ubyte[] _bytes; 29 ubyte[] _message; 30 uint _size; 31 } 32 33 /// Load into range byte array for processing (assume that byte array contains messages as bytes) 34 this(ubyte[] bytes...) 35 { 36 _bytes = bytes; 37 } 38 39 bool empty() @property { 40 bool isEmpty; 41 // if range contains valid message size marker 42 if (_bytes.length > 4) 43 { 44 // message marker 45 _size = fromLEBytes!uint(_bytes[0..4]); 46 // if rest's length greather than real length 47 if (_size > _bytes.length) 48 { 49 isEmpty = true; 50 } 51 } 52 else 53 { 54 isEmpty = true; 55 } 56 return isEmpty; 57 } 58 59 /// Front of range 60 ubyte[] front() { 61 _message = _bytes[0.._size]; 62 return _message; 63 } 64 65 /// Proccess current message 66 void popFront() 67 { 68 _bytes = _bytes[_size..$]; 69 } 70 } 71 } 72 73 /// Create message range (in byte form) from bytes 74 auto byRawMessage(ubyte[] bytes...) 75 { 76 return ByteMessageRange(bytes); 77 } 78 79 /// Create StyxObject range from bytes 80 auto byStyxMessage(ubyte[] bytes...) 81 { 82 return bytes.byRawMessage.map!decode; 83 } 84 85 /// Create string representation for entire StyxObject array 86 auto toTextObject(StyxObject[] msg) 87 { 88 return msg 89 .to!string 90 .replace(`[`, `{`) 91 .replace(`]`, `}`); 92 } 93 94 /// Create string representation range from bytes 95 auto byTextMessage(ubyte[] bytes...) 96 { 97 return bytes.byStyxMessage.map!toTextObject; 98 }