1 module hunt.http.codec.http.encode.DataGenerator; 2 3 import hunt.http.codec.http.encode.HeaderGenerator; 4 5 import hunt.http.codec.http.frame.DataFrame; 6 import hunt.http.codec.http.frame.Flags; 7 import hunt.http.codec.http.frame.Frame; 8 import hunt.http.codec.http.frame.FrameType; 9 10 import hunt.collection; 11 import hunt.Exceptions; 12 13 import std.algorithm; 14 import std.conv; 15 import std.typecons; 16 17 18 /** 19 */ 20 class DataGenerator { 21 private HeaderGenerator headerGenerator; 22 23 this(HeaderGenerator headerGenerator) { 24 this.headerGenerator = headerGenerator; 25 } 26 27 Tuple!(int, List!(ByteBuffer)) generate(DataFrame frame, int maxLength) { 28 return generateData(frame.getStreamId(), frame.getData(), frame.isEndStream(), maxLength); 29 } 30 31 Tuple!(int, List!(ByteBuffer)) generateData(int streamId, ByteBuffer data, bool last, int maxLength) { 32 if (streamId < 0) 33 throw new IllegalArgumentException("Invalid stream id: " ~ streamId.to!string); 34 35 List!ByteBuffer list = new LinkedList!(ByteBuffer)(); 36 37 int dataLength = data.remaining(); 38 int maxFrameSize = headerGenerator.getMaxFrameSize(); 39 int length = std.algorithm.min(dataLength, std.algorithm.min(maxFrameSize, maxLength)); 40 if (length == dataLength) { 41 generateFrame(streamId, data, last, list); 42 } else { 43 int limit = data.limit(); 44 int newLimit = data.position() + length; 45 data.limit(newLimit); 46 ByteBuffer slice = data.slice(); 47 data.position(newLimit); 48 data.limit(limit); 49 generateFrame(streamId, slice, false, list); 50 } 51 return tuple(length + Frame.HEADER_LENGTH, list); 52 } 53 54 private void generateFrame(int streamId, ByteBuffer data, bool last, List!ByteBuffer list) { 55 int length = data.remaining(); 56 57 int flags = Flags.NONE; 58 if (last) 59 flags |= Flags.END_STREAM; 60 61 ByteBuffer header = headerGenerator.generate(FrameType.DATA, Frame.HEADER_LENGTH + length, length, flags, 62 streamId); 63 64 BufferUtils.flipToFlush(header, 0); 65 list.add(header); 66 67 if (data.remaining() > 0) 68 list.add(data); 69 } 70 71 }