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