1 module hunt.http.codec.http.encode.PriorityGenerator;
2 
3 import hunt.http.codec.http.frame.Flags;
4 import hunt.http.codec.http.frame.Frame;
5 import hunt.http.codec.http.frame.FrameType;
6 import hunt.http.codec.http.frame.PriorityFrame;
7 
8 import hunt.http.codec.http.encode.FrameGenerator;
9 import hunt.http.codec.http.encode.HeaderGenerator;
10 
11 import hunt.collection;
12 import hunt.Exceptions;
13 
14 import std.conv;
15 
16 
17 /**
18 */
19 class PriorityGenerator :FrameGenerator {
20     this(HeaderGenerator headerGenerator) {
21         super(headerGenerator);
22     }
23 
24     override
25     List!(ByteBuffer) generate(Frame frame) {
26         PriorityFrame priorityFrame = cast(PriorityFrame) frame;
27         return Collections.singletonList(generatePriority(
28                 priorityFrame.getStreamId(),
29                 priorityFrame.getParentStreamId(),
30                 priorityFrame.getWeight(),
31                 priorityFrame.isExclusive()));
32     }
33 
34     ByteBuffer generatePriority(int streamId, int parentStreamId, int weight, bool exclusive) {
35         ByteBuffer header = generateHeader(FrameType.PRIORITY, PriorityFrame.PRIORITY_LENGTH, Flags.NONE, streamId);
36         generatePriorityBody(header, streamId, parentStreamId, weight, exclusive);
37         BufferUtils.flipToFlush(header, 0);
38         return header;
39     }
40 
41     void generatePriorityBody(ByteBuffer header, int streamId, int parentStreamId, int weight,
42                                      bool exclusive) {
43         if (streamId < 0)
44             throw new IllegalArgumentException("Invalid stream id: " ~ streamId.to!string());
45         if (parentStreamId < 0)
46             throw new IllegalArgumentException("Invalid parent stream id: " ~ parentStreamId.to!string());
47         if (parentStreamId == streamId)
48             throw new IllegalArgumentException("Stream " ~ streamId.to!string() ~ " cannot depend on stream " ~ parentStreamId.to!string());
49         if (weight < 1 || weight > 256)
50             throw new IllegalArgumentException("Invalid weight: " ~ weight.to!string());
51 
52         if (exclusive)
53             parentStreamId |= 0x80_00_00_00;
54         header.put!int(parentStreamId);
55         header.put(cast(byte) (weight - 1));
56     }
57 }