1+ #include < trantor/net/inner/BufferNode.h>
2+ namespace trantor
3+ {
4+ static const size_t kMaxSendFileBufferSize = 16 * 1024 ;
5+ class FileBufferNode : public BufferNode
6+ {
7+ public:
8+ FileBufferNode (FILE *fp, long long offset, size_t length)
9+ : sendFp_(fp), fileBytesToSend_(length)
10+ {
11+ assert (fp);
12+ _fseeki64 (sendFp_, offset, SEEK_SET);
13+ }
14+
15+ bool isFile () const override
16+ {
17+ return true ;
18+ }
19+
20+ void getData (const char *&data, size_t &len) override
21+ {
22+ if (msgBuffer_.readableBytes () == 0 )
23+ {
24+ msgBuffer_.ensureWritableBytes (kMaxSendFileBufferSize <
25+ fileBytesToSend_
26+ ? kMaxSendFileBufferSize
27+ : fileBytesToSend_);
28+ auto n = fread (msgBuffer_.beginWrite (),
29+ 1 ,
30+ msgBuffer_.writableBytes (),
31+ sendFp_);
32+ if (n > 0 )
33+ {
34+ msgBuffer_.hasWritten (n);
35+ }
36+ else
37+ {
38+ LOG_SYSERR << " FileBufferNode::getData()" ;
39+ }
40+ }
41+ data = msgBuffer_.peek ();
42+ len = msgBuffer_.readableBytes ();
43+ }
44+ void retrieve (size_t len) override
45+ {
46+ msgBuffer_.retrieve (len);
47+ fileBytesToSend_ -= len;
48+ }
49+ size_t remainingBytes () const override
50+ {
51+ if (isDone_)
52+ return 0 ;
53+ return fileBytesToSend_;
54+ }
55+ ~FileBufferNode () override
56+ {
57+ if (sendFp_)
58+ {
59+ fclose (sendFp_);
60+ }
61+ }
62+ int getFd () const override
63+ {
64+ LOG_ERROR << " getFd() is not supported on Windows" ;
65+ return 0 ;
66+ }
67+
68+ private:
69+ FILE *sendFp_{nullptr };
70+ long long offset_{0 };
71+
72+ ssize_t fileBytesToSend_{0 };
73+
74+ MsgBuffer msgBuffer_;
75+ };
76+ BufferNodePtr BufferNode::newFileBufferNode (FILE *fp,
77+ long long offset,
78+ size_t length)
79+ {
80+ return std::make_shared<FileBufferNode>(fp, offset, length);
81+ }
82+ } // namespace trantor
0 commit comments