1 #pragma once 2 3 #include <inttypes.h> 4 #include <string.h> 5 #include <stdlib.h> 6 7 #include <scx/BufObj.h> 8 9 using namespace std; 10 using namespace scx; 11 12 //#pragma pack(push, 1) 13 14 namespace Protocol { 15 16 //==== Helper ==== 17 #define IsVaildEm(Em, v)\ 18 (v > Em::None && v < Em::Top) 19 20 //==== Header ==== 21 const char* const STR_MAGIC = "MOUS"; 22 23 namespace Group { 24 enum e 25 { 26 None = 0, 27 28 App, 29 Player, 30 Playlist, 31 32 Top 33 }; 34 } 35 typedef Group::e EmGroup; 36 37 struct Header 38 { 39 char group; 40 int32_t payloadSize; 41 HeaderHeader42 Header(char _group, int32_t _payloadSize): 43 group(_group), payloadSize(_payloadSize) 44 { 45 } 46 SizeHeader47 static int Size() 48 { 49 return 4 + sizeof(char) + sizeof(int32_t); 50 } 51 TotalSizeHeader52 int TotalSize() const 53 { 54 return Size() + payloadSize; 55 } 56 ReadHeader57 bool Read(char* buf) 58 { 59 if (::memcmp(STR_MAGIC, buf, 4) == 0) { 60 BufObj(buf+4) >> group >> payloadSize; 61 return IsVaildEm(Group, group); 62 } else { 63 group = Group::None; 64 payloadSize = -1; 65 return false; 66 } 67 } 68 WriteHeader69 void Write(char* buf) const 70 { 71 BufObj(buf).PutChars(STR_MAGIC, 4) << group << payloadSize; 72 } 73 }; 74 75 namespace Op { 76 77 //==== App ==== 78 namespace App { 79 enum e 80 { 81 None = 0, 82 83 // C:op(char) 84 StopService, 85 86 // S:op(char) count(int32_t) string(BufObj's string)..* 87 Suffixes, 88 89 Top 90 }; 91 } 92 typedef App::e EmApp; 93 94 //==== Player ==== 95 namespace Player { 96 enum e 97 { 98 None = 0, 99 100 // C:op(char) 101 // S:op(char) 102 Pause, 103 104 // C:op(char) direction(char -1/1) 105 // S:op(char) 106 Seek, 107 108 // C:op(char) change(char 0/-1/1) 109 // S:op(char) percent(char [0, 100]) 110 Volume, 111 112 // C:op(char) next(char 0/1) 113 // S:op(char) mode(string) 114 PlayMode, 115 116 // C:op(char) direction(char -1/1) 117 // S:op(char) has(char 0/1) 118 PlayNext, 119 120 // C:op(char) running(char 0/1) 121 // S:op(char) running(char 0/1) 122 Sync, 123 124 // S:op(char) item(MediaItem) sampleRate(int32_t) duration(uint64_t) 125 ItemInfo, 126 127 // S:op(char) ms(uint64_t) bitRate(int32_t) 128 ItemProgress, 129 130 // For instance: 131 // C(running=0) |Sync| >> S(running=1) 132 // C wait 133 // C(running=0=>1) << S(running=1) |ItemInfo|ItemProgress|Sync| 134 // C(running=1) |Sync| >> S(running=1) 135 // C wait 136 // C(running=1) << S(running=1) |ItemProgress|Sync| 137 // C(running=1) |Sync| >> S(running=0) 138 // C wait 139 // C(running=1=>0) << S(running=0) |Sync| 140 // 141 // Client should wait for Server's ItemSync before sending *next* ItemSync. 142 143 Top 144 }; 145 } 146 typedef Player::e EmPlayer; 147 148 //==== Playlist ==== 149 namespace Playlist { 150 enum e 151 { 152 None = 0, 153 154 // C:op(char) playlist(char) 155 // S:op(char) playlist(char) 156 Switch, 157 158 // C:op(char) playlist(char) item(int32_t) 159 // S:op(char) playlist(char) item(int32_t) 160 Select, 161 162 // C:op(char) playlist(char) pos(int32_t) 163 // S:op(char) playlist(char) ok(char 0/1) 164 Play, 165 166 // C:op(char) playlist(char) path(string) 167 // S:op(char) playlist(char) count(int32_t) item(MediaItem)..* 168 Append, 169 170 // C:op(char) playlist(char) pos(int32_t) 171 // S:op(char) playlist(char) pos(int32_t) 172 Remove, 173 174 // C:op(char) playlist(char) pos(int32_t) direct(char -1/1) 175 // S:op(char) playlist(char) pos(int32_t) direct(char -1/1) 176 Move, 177 178 // C:op(char) playlist(char) 179 // S:op(char) playlist(char) 180 Clear, 181 182 // C:op(char) playlist(char) 183 // S:{Append..*} 184 Sync, 185 186 // C:op(char) playlist1(char) pos1(int32_t) playlist2(char) pos2(int32_t) 187 // S:op(char) playlist1(char) pos2(int32_t) playlist2(char) pos2(int32_t) 188 //Move, 189 190 Top 191 }; 192 } 193 typedef Playlist::e EmPlaylist; 194 195 } 196 197 } 198 199 //#pragma pack(pop) 200 201