1 // Written in the D programming language. 2 3 /** 4 A type for representing the name object of the 9P / Styx protocol. 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.protobj.nwname; 12 13 private { 14 import std.conv : to; 15 import std.path : buildPath; 16 import std..string : format; 17 18 import styx2000.lowlevel.endianness; 19 import styx2000.lowlevel.vls; 20 21 import styx2000.protobj.styxobject; 22 } 23 24 /** 25 A class that provides a type for the Nwname field in some Styx messages. Inherits methods from the StyxObject class. 26 See_Also: 27 https://web.archive.org/web/20201029184954/https://powerman.name/Inferno/man/5/0intro.html 28 */ 29 class Nwname : StyxObject 30 { 31 protected { 32 string[] _nwname; 33 34 ubyte[] _representation; 35 } 36 37 private { 38 // update names list 39 void updateNames() 40 { 41 if (_nwname.length == 0) 42 { 43 // ???? 44 // if empty walk then nwname = 1, wname = [0, 0] (in inferno) 45 // in plan9 is [0, 0] 46 _representation = [0, 0]; 47 } 48 else 49 { 50 _representation = toLEBytes!ushort( 51 cast(ushort) _nwname.length 52 ); 53 foreach (e; _nwname) 54 { 55 _representation ~= VariableLengthSequence.pack(cast(ubyte[]) e); 56 } 57 } 58 } 59 } 60 61 /** 62 A constructor that creates an object of the Nwname class with the given parameter in the form of string's array. 63 If called without parameters, then the default parameter is empty string's array. 64 Params: 65 nwname = Full file path as string's array. 66 67 Typical usage: 68 ---- 69 Nwname nwname = new Nwname([`test`]); 70 ---- 71 */ 72 this(string[] nwname = []) 73 { 74 _nwname = nwname; 75 _representation = []; 76 updateNames; 77 } 78 79 /// Set name to Nwname objects as string's array 80 void setName(string[] nwname...) 81 { 82 _nwname = nwname; 83 _representation = []; 84 updateNames; 85 } 86 87 /// Number of names in path 88 ushort countOfNames() 89 { 90 return fromLEBytes!ushort(_representation[0..2]); 91 } 92 93 /// Get all names in path as string's array 94 string[] getName() 95 { 96 return _nwname; 97 } 98 99 /// An alias that allows you to call a getter method without accessing the base Name class 100 alias getNwname = getName; 101 /// An alias that allows you to call a setter method without accessing the base Name class 102 alias setNwname = setName; 103 104 /// Pack to bytes array 105 ubyte[] pack() 106 { 107 return _representation; 108 } 109 110 /// Unpack from bytes array 111 void unpack(ubyte[] bytes...) 112 { 113 _representation = bytes; 114 _nwname = []; 115 ushort length = fromLEBytes!ushort(bytes[0..2]); 116 auto vlsPosition = 2; 117 118 foreach (_; 0..length) 119 { 120 string n = cast(string) VariableLengthSequence.unpack( 121 bytes[vlsPosition..$] 122 ); 123 _nwname ~= n; 124 vlsPosition += n.length + 2; 125 } 126 } 127 128 /// Convenient string representation of an object for printing 129 override string toString() 130 { 131 return format( 132 `Nwname(nwname=%d, wmname="%s")`, 133 fromLEBytes!ushort(_representation[0..2]), 134 buildPath(_nwname) 135 ); 136 } 137 138 /// An alias for easier packing into a byte array without having to manually call the pack() method 139 alias pack this; 140 }