@@ -39,11 +39,11 @@ class MessageWithHeader extends AbstractReferenceCounted implements FileRegion {
39
39
private final long bodyLength ;
40
40
private int totalBytesTransferred ;
41
41
42
- MessageWithHeader (ByteBuf header , int headerLength , Object body , long bodyLength ) {
42
+ MessageWithHeader (ByteBuf header , Object body , long bodyLength ) {
43
43
Preconditions .checkArgument (body instanceof ByteBuf || body instanceof FileRegion ,
44
44
"Body must be a ByteBuf or a FileRegion." );
45
45
this .header = header ;
46
- this .headerLength = headerLength ;
46
+ this .headerLength = header . readableBytes () ;
47
47
this .body = body ;
48
48
this .bodyLength = bodyLength ;
49
49
}
@@ -65,22 +65,26 @@ public long transfered() {
65
65
66
66
@ Override
67
67
public long transferTo (WritableByteChannel target , long position ) throws IOException {
68
- Preconditions .checkArgument (position >= 0 && position < count () , "Invalid position." );
68
+ Preconditions .checkArgument (position == totalBytesTransferred , "Invalid position." );
69
69
long written = 0 ;
70
70
71
71
if (position < headerLength ) {
72
- written += copyByteBuf (header , target , position );
72
+ written += copyByteBuf (header , target );
73
73
if (header .readableBytes () > 0 ) {
74
74
totalBytesTransferred += written ;
75
75
return written ;
76
76
}
77
77
}
78
78
79
79
if (body instanceof FileRegion ) {
80
+ // Adjust the position. If the write is happening as part of the same call where the header
81
+ // (or some part of it) is written, `position` will be less than the header size, so we want
82
+ // to start from position 0 in the FileRegion object. Otherwise, we start from the position
83
+ // requested by the caller.
80
84
long bodyPos = position > headerLength ? position - headerLength : 0 ;
81
85
written += ((FileRegion )body ).transferTo (target , bodyPos );
82
86
} else if (body instanceof ByteBuf ) {
83
- written += copyByteBuf ((ByteBuf ) body , target , position );
87
+ written += copyByteBuf ((ByteBuf ) body , target );
84
88
}
85
89
86
90
totalBytesTransferred += written ;
@@ -93,12 +97,7 @@ protected void deallocate() {
93
97
ReferenceCountUtil .release (body );
94
98
}
95
99
96
- private int copyByteBuf (ByteBuf buf , WritableByteChannel target , long position )
97
- throws IOException {
98
-
99
- if (position > totalBytesTransferred ) {
100
- buf .skipBytes (Ints .checkedCast (position - totalBytesTransferred ));
101
- }
100
+ private int copyByteBuf (ByteBuf buf , WritableByteChannel target ) throws IOException {
102
101
int written = target .write (buf .nioBuffer ());
103
102
buf .skipBytes (written );
104
103
return written ;
0 commit comments