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 }