1 /*
2  * This File is part of Davix, The IO library for HTTP based protocols
3  * Copyright (C) CERN 2013
4  * Author: Adrien Devresse <adrien.devresse@cern.ch>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20 */
21 
22 #pragma once
23 #ifndef DAVIX_IOBUFFMAP_HPP
24 #define DAVIX_IOBUFFMAP_HPP
25 
26 #include <davix_internal.hpp>
27 #include <fileops/fileutils.hpp>
28 #include <fileops/httpiochain.hpp>
29 
30 
31 
32 namespace Davix {
33 
34 //
35 // Internal POSIX like to HTTP RW operation mapper
36 // provides facilities for caching
37 //
38 
39 
40 
41 /// RW operation mapped to pure HTTP ops
42 class HttpIO : public HttpIOChain{
43 public:
44     HttpIO();
45     virtual ~HttpIO();
46 
47 
48     // read to dynamically allocated buffer
49     virtual dav_ssize_t readFull(IOChainContext & iocontext, std::vector<char> & buffer);
50 
51 
52     // position independant read operation,
53     // similar to pread except that does not need open() before
54     virtual dav_ssize_t pread(IOChainContext & iocontext, void* buf, dav_size_t count, dav_off_t offset);
55 
56     // read to fd
57     virtual dav_ssize_t readToFd(IOChainContext & iocontext, int fd, dav_size_t size);
58 
59     virtual dav_ssize_t writeFromCb(IOChainContext &iocontext, const DataProviderFun &func, dav_size_t size);
60 
61     // position independant write operation,
62     // similar to pwrite do not need open() before
63     virtual dav_ssize_t writeFromFd(IOChainContext & iocontext, int fd, dav_size_t size);
64 
65 private:
66 
67 
68     HttpIO(const HttpIO & );
69     HttpIO & operator=(const HttpIO & );
70 
71 
72 };
73 
74 
75 struct IOBufferLocalFile;
76 
77 ///
78 /// RW operation with buffering support and POSIX like interface
79 class HttpIOBuffer : public HttpIOChain{
80 public:
81     HttpIOBuffer();
82     virtual ~HttpIOBuffer();
83 
84     // open the file associated with the davix IOBuffMap
85     // do a simple check if the file exist and try to anticipate the next ops
86     virtual bool open(IOChainContext & iocontext, int flags);
87 
88     //
89     virtual dav_ssize_t read(IOChainContext & iocontext, void* buf, dav_size_t count);
90 
91 
92     // give information on the future operation for prefecting
93     virtual void prefetchInfo(IOChainContext & iocontext, off_t offset, dav_size_t size_read, advise_t adv);
94 
95     //
96     virtual dav_ssize_t write(IOChainContext & iocontext, const void* buf, dav_size_t count);
97 
98     //
99     virtual dav_off_t lseek(IOChainContext & iocontext, dav_off_t offset, int flags);
100 
101     //
102     virtual void resetIO(IOChainContext & iocontext);
103 
104 
105     void commitLocal(IOChainContext & iocontext);
106 
107 protected:
108 
109     dav_size_t _file_size;
110     bool _file_exist;
111     dav_off_t _pos;
112     bool _opened;
113     advise_t _last_advise;
114 
115     // locker
116     std::recursive_mutex _rwlock;
117     // write cache
118     std::unique_ptr<IOBufferLocalFile> _local;
119 
120     dav_off_t _read_pos; //curent read file offset
121     bool _read_endfile;
122     HttpRequest * _read_req;
123 
124 private:
125 
isAdviseFullRead()126     inline bool isAdviseFullRead(){
127         return (_last_advise == AdviseAuto || _last_advise == AdviseSequential);
128     }
129 
130     dav_ssize_t readInternal(IOChainContext & iocontext, void *buffer, dav_size_t size_read);
131 
132     HttpIOBuffer(const HttpIOBuffer & );
133     HttpIOBuffer & operator=(const HttpIOBuffer & );
134 };
135 
136 // create a single-ton filestream for cache from
137 int get_valid_cache_file(FILE** stream, DavixError** err);
138 
139 
140 dav_ssize_t read_segment_request(HttpRequest* req, void* buffer, dav_size_t size_read, DavixError**err);
141 
142 
143 } // namespace Davix
144 
145 #endif // DAVIX_IOBUFFMAP_HPP
146