1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.waarp.gateway.kernel.commonfile;
21
22 import io.netty.buffer.ByteBuf;
23 import io.netty.buffer.ByteBufAllocator;
24 import io.netty.buffer.Unpooled;
25 import io.netty.channel.ChannelHandlerContext;
26 import io.netty.handler.stream.ChunkedInput;
27 import org.waarp.common.command.exception.CommandAbstractException;
28 import org.waarp.common.exception.FileEndOfTransferException;
29 import org.waarp.common.exception.FileTransferException;
30 import org.waarp.common.file.DataBlock;
31 import org.waarp.common.file.FileInterface;
32 import org.waarp.gateway.kernel.exception.HttpIncorrectRetrieveException;
33
34
35
36
37 public class CommonFileChunkedInput implements ChunkedInput<ByteBuf> {
38
39 private final FileInterface document;
40
41 private boolean lastChunkAlready;
42
43 private long offset;
44
45
46
47
48
49
50 public CommonFileChunkedInput(final FileInterface document)
51 throws HttpIncorrectRetrieveException {
52 this.document = document;
53 try {
54 this.document.retrieve();
55 } catch (final CommandAbstractException e) {
56 throw new HttpIncorrectRetrieveException(e);
57 }
58 }
59
60 @Override
61 public final ByteBuf readChunk(final ChannelHandlerContext ctx)
62 throws Exception {
63 return readChunk(ByteBufAllocator.DEFAULT);
64 }
65
66 @Override
67 public final long length() {
68 try {
69 return document.length();
70 } catch (final CommandAbstractException e) {
71 return -1;
72 }
73 }
74
75 @Override
76 public final long progress() {
77 return offset;
78 }
79
80 @Override
81 public final boolean isEndOfInput() {
82 return lastChunkAlready;
83 }
84
85 @Override
86 public final void close() throws HttpIncorrectRetrieveException {
87 try {
88 if (document.isInReading()) {
89 document.abortFile();
90 }
91 } catch (final CommandAbstractException e) {
92 throw new HttpIncorrectRetrieveException(e);
93 }
94 lastChunkAlready = true;
95 }
96
97 @Override
98 public final ByteBuf readChunk(final ByteBufAllocator byteBufAllocator)
99 throws Exception {
100
101 final DataBlock block;
102 try {
103 block = document.readDataBlock();
104 } catch (final FileEndOfTransferException e) {
105 lastChunkAlready = true;
106 return Unpooled.EMPTY_BUFFER;
107 } catch (final FileTransferException e) {
108 throw new HttpIncorrectRetrieveException(e);
109 }
110 lastChunkAlready = block.isEOF();
111 offset += block.getByteCount();
112 final byte[] bytes = block.getByteBlock();
113 final ByteBuf buffer = byteBufAllocator.buffer(bytes.length, bytes.length);
114 buffer.writeBytes(bytes);
115 return buffer;
116 }
117 }