1 // Written in the D programming language. 2 3 /** 4 This module contains a set of various useful functions for more convenient work with 9P /Styx messages. 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.styxmessage; 12 13 private { 14 import styx2000.protoconst; 15 16 import styx2000.protobj; 17 } 18 19 /// Convenient alias 20 alias StyxMessage = StyxObject[]; 21 22 /// StyxMessage is client message ? 23 bool isTmessage(StyxMessage msg) 24 { 25 bool isMessage = false; 26 Type type = cast(Type) msg[1]; 27 28 if (type !is null) 29 { 30 with (STYX_MESSAGE_TYPE) 31 { 32 switch(type.getType) 33 { 34 // version 35 case T_VERSION: 36 isMessage = true; 37 break; 38 // auth 39 case T_AUTH: 40 isMessage = true; 41 break; 42 // flush 43 case T_FLUSH: 44 isMessage = true; 45 break; 46 // attach 47 case T_ATTACH: 48 isMessage = true; 49 break; 50 // walk 51 case T_WALK: 52 isMessage = true; 53 break; 54 case T_OPEN: 55 isMessage = true; 56 break; 57 // create 58 case T_CREATE: 59 isMessage = true; 60 break; 61 // read 62 case T_READ: 63 isMessage = true; 64 break; 65 // write 66 case T_WRITE: 67 isMessage = true; 68 break; 69 // clunk 70 case T_CLUNK: 71 isMessage = true; 72 break; 73 // remove 74 case T_REMOVE: 75 isMessage = true; 76 break; 77 // stat 78 case T_STAT: 79 isMessage = true; 80 break; 81 // wstat 82 case T_WSTAT: 83 isMessage = true; 84 break; 85 default: 86 break; 87 } 88 } 89 } 90 91 return isMessage; 92 } 93 94 /// StyxMessage is server message ? 95 bool isRmessage(StyxMessage msg) 96 { 97 bool isMessage = false; 98 Type type = cast(Type) msg[1]; 99 100 if (type !is null) 101 { 102 with (STYX_MESSAGE_TYPE) 103 { 104 switch(type.getType) 105 { 106 // version 107 case R_VERSION: 108 isMessage = true; 109 break; 110 // auth 111 case R_AUTH: 112 isMessage = true; 113 break; 114 // flush 115 case R_FLUSH: 116 isMessage = true; 117 break; 118 // attach 119 case R_ATTACH: 120 isMessage = true; 121 break; 122 // walk 123 case R_WALK: 124 isMessage = true; 125 break; 126 case R_OPEN: 127 isMessage = true; 128 break; 129 // create 130 case R_CREATE: 131 isMessage = true; 132 break; 133 // read 134 case R_READ: 135 isMessage = true; 136 break; 137 // write 138 case R_WRITE: 139 isMessage = true; 140 break; 141 // clunk 142 case R_CLUNK: 143 isMessage = true; 144 break; 145 // remove 146 case R_REMOVE: 147 isMessage = true; 148 break; 149 // stat 150 case R_STAT: 151 isMessage = true; 152 break; 153 // wstat 154 case R_WSTAT: 155 isMessage = true; 156 break; 157 // error 158 case R_ERROR: 159 isMessage = true; 160 break; 161 default: 162 break; 163 } 164 } 165 } 166 167 return isMessage; 168 } 169 170 /// StyxMessage is error message ? 171 bool isErrorMessage(StyxMessage msg) 172 { 173 bool isMessage = false; 174 Type type = cast(Type) msg[1]; 175 176 if (type !is null) 177 { 178 if (type.getType == STYX_MESSAGE_TYPE.R_ERROR) 179 { 180 isMessage = true; 181 } 182 } 183 184 return isMessage; 185 } 186 187 /// Create base header for 9P / Styx messages 188 auto createHeader(uint size = 0, STYX_MESSAGE_TYPE type = STYX_MESSAGE_TYPE.R_ERROR, ushort tag = STYX_NOTAG) 189 { 190 return cast(StyxMessage) [ 191 new Size(size), 192 new Type(type), 193 new Tag(tag) 194 ]; 195 } 196 197 /// Create version message from client 198 auto createTmsgVersion(ushort tag = STYX_NOTAG, uint maximalSize = 8192, string vers = STYX_VERSION) 199 { 200 return createHeader(0, STYX_MESSAGE_TYPE.T_VERSION, tag) ~ cast(StyxMessage) [ 201 new Msize(maximalSize), 202 new Version(vers) 203 ]; 204 } 205 206 /// Create version message from server 207 auto createRmsgVersion(ushort tag = STYX_NOTAG, uint maximalSize = 8192, string vers = STYX_VERSION) 208 { 209 return createHeader(0, STYX_MESSAGE_TYPE.R_VERSION, tag) ~ cast(StyxMessage) [ 210 new Msize(maximalSize), 211 new Version(vers) 212 ]; 213 } 214 215 /// Create error message from server (for client this type of message does not exists) 216 auto createRmsgError(ushort tag = STYX_NOTAG, string ename = "") 217 { 218 return createHeader(0, STYX_MESSAGE_TYPE.R_ERROR, tag) ~ cast(StyxMessage) [ 219 new Ename(ename) 220 ]; 221 } 222 223 /// Create clunk message from client 224 auto createTmsgClunk(ushort tag = STYX_NOTAG, uint fid = STYX_NOFID) 225 { 226 return createHeader(0, STYX_MESSAGE_TYPE.T_CLUNK, tag) ~ cast(StyxMessage) [ 227 new Fid(fid) 228 ]; 229 } 230 231 /// Create clunk message from server 232 auto createRmsgClunk(ushort tag = STYX_NOTAG) 233 { 234 return createHeader(0, STYX_MESSAGE_TYPE.R_CLUNK, tag); 235 } 236 237 /// Create flush message from client 238 auto createTmsgFlush(ushort tag = STYX_NOTAG, ushort oldTag = STYX_NOTAG) 239 { 240 return createHeader(0, STYX_MESSAGE_TYPE.T_FLUSH, tag) ~ cast(StyxMessage) [ 241 new OldTag(oldTag) 242 ]; 243 } 244 245 /// Create flush message from server 246 auto createRmsgFlush(ushort tag = STYX_NOTAG) 247 { 248 return createHeader(0, STYX_MESSAGE_TYPE.R_FLUSH, tag); 249 }