0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
FileDevice.h
Go to the documentation of this file.
1 /* -*- c++ -*-
2  * Copyright (C) 2007-2015 Hypertable, Inc.
3  *
4  * This file is part of Hypertable.
5  *
6  * Hypertable is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 3
9  * of the License, or any later version.
10  *
11  * Hypertable 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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA.
20  */
21 
22 #ifndef FsBroker_Lib_FileDevice_h
23 #define FsBroker_Lib_FileDevice_h
24 
25 #include <Common/Compat.h>
26 
27 #include "Client.h"
28 
29 #include <Common/StringExt.h>
30 #include <Common/StaticBuffer.h>
31 #include <Common/Error.h>
32 
33 #include <boost/cstdint.hpp> // intmax_t.
34 #include <boost/iostreams/categories.hpp> // tags.
35 #include <boost/iostreams/detail/ios.hpp> // openmode, seekdir, int types.
36 #include <boost/shared_ptr.hpp>
37 
38 namespace Hypertable {
39 namespace FsBroker {
40 namespace Lib {
41 
42  using namespace boost::iostreams;
43  using namespace std;
44 
47 
48  /*
49  * These classes are intended to be Dfs equivalent of boost::iostreams::basic_file,
50  * boost::iostreams::basic_file_source, boost::iostreams::basic_file_sink
51  */
52 
53  // Forward declarations
54  class FileSource;
55  class FileSink;
56 
57  namespace {
58  const uint32_t READAHEAD_BUFFER_SIZE = 1024*1024;
59  const uint32_t OUTSTANDING_READS = 2;
60  }
61 
62  class FileDevice {
63  public:
64  friend class FileSource;
65  friend class FileSink;
66 
67  typedef char char_type;
68  struct category : public device_tag, public closable_tag
69  {};
70  // Ctor
71  FileDevice(ClientPtr &client, const String &filename,
72  bool accurate_length = true,
73  BOOST_IOS::openmode mode = BOOST_IOS::in);
74  // Dtor
75  virtual ~FileDevice() { }
76 
77  // open
78  virtual void open(ClientPtr &client, const String &filename,
79  bool accurate_length = true,
80  BOOST_IOS::openmode mode = BOOST_IOS::in);
81  virtual bool is_open() const;
82 
83  // read
84  virtual streamsize read(char_type* dst, size_t amount);
85  virtual size_t bytes_read();
86  virtual size_t length();
87 
88  // write
89  virtual size_t write(const char_type *src, size_t amount);
90  virtual size_t bytes_written();
91 
92  // close
93  virtual void close();
94 
95  private:
96  struct impl {
97  impl(ClientPtr &client, const String &filename,
98  bool accurate_length, BOOST_IOS::openmode mode)
99  : m_client(client), m_filename(filename), m_open(false),
100  m_bytes_read(0), m_bytes_written(0), m_length(0)
101  {
102  // if file is opened for output then create if it doesn't exist
103  if (mode & BOOST_IOS::in) {
104  if (!m_client->exists(filename))
106  m_length = m_client->length(filename, accurate_length);
107  m_fd = m_client->open_buffered(filename, Filesystem::OPEN_FLAG_DIRECTIO,
108  READAHEAD_BUFFER_SIZE, OUTSTANDING_READS);
109  }
110  else if (mode & BOOST_IOS::out) {
111  m_fd = m_client->create(filename, Filesystem::OPEN_FLAG_OVERWRITE, -1 , -1, -1);
112  }
113  m_open = true;
114  }
115 
116  ~impl() {
117  close();
118  }
119 
120  void close() {
121  if (m_open) {
122  m_client->close(m_fd);
123  m_bytes_read = m_bytes_written = 0;
124  m_open = false;
125  }
126  }
127 
128  streamsize read(char_type *dst, size_t amount) {
129  if (amount + m_bytes_read > m_length)
130  amount = m_length - m_bytes_read;
131  if (amount > 0 ) {
132  size_t bytes_read = m_client->read(m_fd, (void *)dst, amount);
133  m_bytes_read += bytes_read;
134  return bytes_read;
135  }
136  else {
137  return -1;
138  }
139  }
140 
141  size_t bytes_read() {
142  return m_bytes_read;
143  }
144 
145  size_t length() {
146  return m_length;
147  }
148 
149  size_t write(const char_type *dst, size_t amount) {
150  StaticBuffer write_buffer((void *)dst, amount, false);
151  size_t bytes_written = m_client->append(m_fd, write_buffer);
152  m_bytes_written += bytes_written;
153  return bytes_written;
154  }
155 
156  size_t bytes_written() {
157  return m_bytes_written;
158  }
159 
162  int m_fd;
163  bool m_open;
164  size_t m_bytes_read;
166  size_t m_length;
167  };
168 
169  boost::shared_ptr<impl> pimpl_;
170  };
171 
172  class FileSource : private FileDevice {
173  public:
174  typedef char char_type;
175  struct category : source_tag, closable_tag
176  {};
177 
178  using FileDevice::is_open;
179  using FileDevice::close;
180  using FileDevice::read;
182  using FileDevice::length;
183 
185  : FileDevice(client, filename, BOOST_IOS::in)
186  {}
187  virtual ~FileSource() { }
188 
189  virtual void open(ClientPtr &client, const String &filename,
190  bool accurate_length = true,
191  BOOST_IOS::openmode mode = BOOST_IOS::in) {
192  FileDevice::open(client, filename, accurate_length, mode);
193  }
194  };
195 
196  class FileSink : private FileDevice {
197  public:
198  typedef char char_type;
199  struct category : sink_tag, closable_tag
200  {};
201 
202  using FileDevice::is_open;
203  using FileDevice::close;
204  using FileDevice::write;
206 
208  : FileDevice(client, filename, false, BOOST_IOS::out)
209  {}
210  virtual ~FileSink() { }
211 
212  virtual void open(ClientPtr &client, const String &filename,
213  bool accurate_length = false,
214  BOOST_IOS::openmode mode = BOOST_IOS::out) {
215  FileDevice::open(client, filename, accurate_length, mode);
216  }
217  };
218 
220 
221 }}}
222 
223 #endif // FsBroker_Lib_FileDevice_h
224 
225 
A memory buffer of static size.
Definition: StaticBuffer.h:45
FileSink(ClientPtr &client, const String &filename)
Definition: FileDevice.h:207
static String filename
Definition: Config.cc:48
std::string String
A String is simply a typedef to std::string.
Definition: String.h:44
STL namespace.
streamsize read(char_type *dst, size_t amount)
Definition: FileDevice.h:128
impl(ClientPtr &client, const String &filename, bool accurate_length, BOOST_IOS::openmode mode)
Definition: FileDevice.h:97
std::shared_ptr< Client > ClientPtr
Smart pointer to Client.
Definition: Client.h:233
size_t write(const char_type *dst, size_t amount)
Definition: FileDevice.h:149
Compatibility Macros for C/C++.
FileSource(ClientPtr &client, const String &filename)
Definition: FileDevice.h:184
virtual streamsize read(char_type *dst, size_t amount)
Definition: FileDevice.cc:47
A memory buffer of static size.
virtual size_t write(const char_type *src, size_t amount)
Definition: FileDevice.cc:62
Hypertable definitions
virtual void open(ClientPtr &client, const String &filename, bool accurate_length=true, BOOST_IOS::openmode mode=BOOST_IOS::in)
Definition: FileDevice.cc:36
virtual void open(ClientPtr &client, const String &filename, bool accurate_length=false, BOOST_IOS::openmode mode=BOOST_IOS::out)
Definition: FileDevice.h:212
boost::shared_ptr< impl > pimpl_
Definition: FileDevice.h:169
virtual void open(ClientPtr &client, const String &filename, bool accurate_length=true, BOOST_IOS::openmode mode=BOOST_IOS::in)
Definition: FileDevice.h:189
String extensions and helpers: sets, maps, append operators etc.
Error codes, Exception handling, error logging.
#define HT_THROW(_code_, _msg_)
Definition: Error.h:478
Declarations for Client.