1 module hunt.http.codec.websocket.frame.Frame;
2 
3 import hunt.container.ByteBuffer;
4 import hunt.lang.exception;
5 import std.conv;
6 
7 alias FrameType = Frame.Type;
8 
9 /**
10  * An immutable websocket frame.
11  */
12 interface Frame {
13     enum Type : byte {
14         CONTINUATION = 0x00,
15         TEXT = 0x01,
16         BINARY = 0x02,
17         CLOSE = 0x08,
18         PING = 0x09,
19         PONG = 0x0A
20     }
21 
22     byte[] getMask();
23 
24     byte getOpCode();
25 
26     ByteBuffer getPayload();
27 
28     /**
29      * The original payload length ({@link ByteBuffer#remaining()})
30      *
31      * @return the original payload length ({@link ByteBuffer#remaining()})
32      */
33     int getPayloadLength();
34 
35     Type getType();
36 
37     bool hasPayload();
38 
39     bool isFin();
40 
41     bool isMasked();
42 
43     bool isRsv1();
44 
45     bool isRsv2();
46 
47     bool isRsv3();
48 }
49 
50 import std.traits;
51 
52 class FrameTypeHelper {
53     
54         static FrameType from(byte op) {
55             foreach (FrameType type ; EnumMembers!(FrameType)) {
56                 if (cast(byte)type == op) 
57                     return type;
58             }
59             throw new IllegalArgumentException("OpCode " ~ to!string(op) ~ 
60                 " is not a valid Frame.Type");
61         }
62 
63         static bool isControl(FrameType type) {
64             return type >= FrameType.CLOSE;
65         }
66 
67         bool isData(FrameType type) {
68             return (type == FrameType.TEXT) || (type == FrameType.BINARY);
69         }
70 
71         bool isContinuation(FrameType type) {
72             return type == FrameType.CONTINUATION;
73         }
74 
75 }