fileimpl.cpp
Go to the documentation of this file.
1 /*
2 ** Copyright (C) 2012 Aldebaran Robotics
3 ** See COPYING for the license
4 */
5 
6 #include <qicore/file.hpp>
7 
8 #include <boost/filesystem/fstream.hpp>
9 #include <algorithm>
10 #include <vector>
11 
12 #include <qi/macro.hpp>
13 #include <qi/anymodule.hpp>
14 
15 namespace qi
16 {
17 class FileImpl : public File
18 {
19 public:
20  explicit FileImpl(const Path& localFilePath)
21  {
22  if (!localFilePath.exists())
23  {
24  std::stringstream message;
25  message << "File not found on qi::File open: " << localFilePath.str();
26  throw std::runtime_error(message.str());
27  }
28 
30 
31  _fileStream.open(localFilePath, std::ios::in | std::ios::binary);
32  if (_fileStream.is_open())
33  {
34  _fileStream.seekg(0, _fileStream.end);
35  _size = _fileStream.tellg();
36  _fileStream.seekg(0, _fileStream.beg);
37  assert(_fileStream.tellg() == std::streamoff(0));
38  }
39  }
40 
41  ~FileImpl() = default;
42 
43  Buffer read(std::streamoff beginOffset, std::streamsize countBytesToRead) override
44  {
45  if (seek(beginOffset))
46  return read(countBytesToRead);
47  else
48  return {};
49  }
50 
51  Buffer read(std::streamsize countBytesToRead) override
52  {
54  if (countBytesToRead > MAX_READ_SIZE)
55  throw std::runtime_error("Tried to read too much data at once.");
56 
57  Buffer output;
58 
59  assert(_fileStream.is_open());
60  const std::streamoff initialCursorPos = static_cast<std::streamoff>(_fileStream.tellg());
61  const std::streamoff targetEnd = std::min(initialCursorPos + countBytesToRead, static_cast<std::streamoff>(_size));
62  const std::streamsize distanceToTargetEnd = targetEnd - initialCursorPos;
63  const std::streamsize byteCountToRead = std::min(static_cast<std::streamsize>(MAX_READ_SIZE), distanceToTargetEnd);
64  assert(byteCountToRead <= MAX_READ_SIZE);
65 
66  _readBuffer.resize(static_cast<size_t>(byteCountToRead), '\0');
67  _fileStream.read(_readBuffer.data(), byteCountToRead);
68  const std::streamsize bytesRead = _fileStream.gcount();
69  assert(bytesRead <= byteCountToRead);
70  output.write(_readBuffer.data(), static_cast<size_t>(bytesRead));
71 
72  return output;
73  }
74 
75  bool seek(std::streamoff offsetFromBegin) override
76  {
78 
79  if (offsetFromBegin >= _size)
80  return false;
81 
82  _fileStream.seekg(offsetFromBegin);
83  return true;
84  }
85 
86  void close() override
87  {
88  _fileStream.close();
89  _size = 0;
90  }
91 
92  std::streamsize size() const override
93  {
94  return _size;
95  }
96 
97  bool isOpen() const override
98  {
99  return _fileStream.is_open();
100  }
101 
102  bool isRemote() const override
103  {
104  return false;
105  }
106 
108  {
109  return _progressNotifier;
110  }
111 
112  // Deprecated members:
113  Buffer _read(std::streamoff beginOffset, std::streamsize countBytesToRead) override
114  {
115  return read(beginOffset, countBytesToRead);
116  }
117 
118  Buffer _read(std::streamsize countBytesToRead) override
119  {
120  return read(countBytesToRead);
121  }
122 
123  bool _seek(std::streamoff offsetFromBegin) override
124  {
125  return seek(offsetFromBegin);
126  }
127 
128  void _close() override
129  {
130  return close();
131  }
132 
133 private:
134  boost::filesystem::ifstream _fileStream;
135  std::vector<char> _readBuffer;
136  std::streamsize _size;
138 
140  {
141  if (!_fileStream.is_open())
142  throw std::runtime_error("Trying to manipulate a closed file access.");
143  }
144 };
145 
147 {
148  ::qi::ObjectTypeBuilder<File> builder;
149 
150  QI_OBJECT_BUILDER_ADVERTISE_OVERLOAD(builder, File, read, Buffer,(std::streamoff, std::streamsize));
151  QI_OBJECT_BUILDER_ADVERTISE_OVERLOAD(builder, File, read, Buffer, (std::streamsize));
152  QI_OBJECT_BUILDER_ADVERTISE(builder, File, seek);
153  QI_OBJECT_BUILDER_ADVERTISE(builder, File, close);
154  QI_OBJECT_BUILDER_ADVERTISE(builder, File, size);
155  QI_OBJECT_BUILDER_ADVERTISE(builder, File, isOpen);
156  QI_OBJECT_BUILDER_ADVERTISE(builder, File, isRemote);
157  QI_OBJECT_BUILDER_ADVERTISE(builder, File, operationProgress);
158 
159  // Deprecated members:
160 QI_WARNING_PUSH()
161 QI_WARNING_DISABLE(4996, deprecated-declarations)
162  QI_OBJECT_BUILDER_ADVERTISE_OVERLOAD(builder, File, _read, Buffer, (std::streamoff, std::streamsize));
163  QI_OBJECT_BUILDER_ADVERTISE_OVERLOAD(builder, File, _read, Buffer, (std::streamsize));
164  QI_OBJECT_BUILDER_ADVERTISE(builder, File, _seek);
165  QI_OBJECT_BUILDER_ADVERTISE(builder, File, _close);
166 QI_WARNING_POP()
167 
168  builder.registerType();
169 
170  {
171  qi::detail::ForceProxyInclusion<File>().dummyCall();
172  qi::registerType(typeid(FileImpl), qi::typeOf<File>());
173  FileImpl* ptr = static_cast<FileImpl*>(reinterpret_cast<void*>(0x10000));
174  File* pptr = ptr;
175  intptr_t offset = reinterpret_cast<intptr_t>(pptr)-reinterpret_cast<intptr_t>(ptr);
176  if (offset)
177  {
178  qiLogError("qitype.register") << "non-zero offset for implementation FileImpl of File,"
179  "call will fail at runtime";
180  throw std::runtime_error("non-zero offset between implementation and interface");
181  }
182  }
183 
184 }
185 
186 FilePtr openLocalFile(const qi::Path& localPath)
187 {
188  return boost::make_shared<FileImpl>(localPath);
189 }
190 
191 void registerFileCreation(qi::ModuleBuilder& mb)
192 {
193  mb.advertiseMethod("openLocalFile", &openLocalFile);
194 }
195 }
qi::ProgressNotifierPtr
qi::Object< ProgressNotifier > ProgressNotifierPtr
Pointer to a ProgressNotifier with shared/remote semantic.
Definition: file.hpp:114
qi::FileImpl::_read
Buffer _read(std::streamsize countBytesToRead) override
Definition: fileimpl.cpp:118
qi::FileImpl::_size
std::streamsize _size
Definition: fileimpl.cpp:136
qi::FileImpl::_fileStream
boost::filesystem::ifstream _fileStream
Definition: fileimpl.cpp:134
qi::FileImpl
Definition: fileimpl.cpp:17
file.hpp
qi::FileImpl::_seek
bool _seek(std::streamoff offsetFromBegin) override
Definition: fileimpl.cpp:123
qi::FileImpl::_progressNotifier
ProgressNotifierPtr _progressNotifier
Definition: fileimpl.cpp:137
qi::FileImpl::requireOpenFile
void requireOpenFile()
Definition: fileimpl.cpp:139
qi::FileImpl::isOpen
bool isOpen() const override
Definition: fileimpl.cpp:97
qi::FileImpl::FileImpl
FileImpl(const Path &localFilePath)
Definition: fileimpl.cpp:20
qi::registerFileCreation
void registerFileCreation(qi::ModuleBuilder &mb)
Definition: fileimpl.cpp:191
qi::FileImpl::close
void close() override
Definition: fileimpl.cpp:86
qi::File::MAX_READ_SIZE
static const std::streamsize MAX_READ_SIZE
Maximum count of bytes that you can read by reading functions call.
Definition: file.hpp:156
qi::File
Definition: file.hpp:127
qi::FileImpl::_close
void _close() override
Definition: fileimpl.cpp:128
qi::FileImpl::operationProgress
ProgressNotifierPtr operationProgress() const override
Definition: fileimpl.cpp:107
qi::FileImpl::~FileImpl
~FileImpl()=default
qi
Definition: file.hpp:21
qi::createProgressNotifier
QICORE_API ProgressNotifierPtr createProgressNotifier(Future< void > operationFuture={})
Definition: progressnotifier.cpp:160
qi::FileImpl::size
std::streamsize size() const override
Definition: fileimpl.cpp:92
qi::_qiregisterFile
void _qiregisterFile()
Definition: fileimpl.cpp:146
qi::FileImpl::_readBuffer
std::vector< char > _readBuffer
Definition: fileimpl.cpp:135
qi::openLocalFile
QICORE_API FilePtr openLocalFile(const qi::Path &localPath)
Definition: fileimpl.cpp:186
qi::FileImpl::read
Buffer read(std::streamoff beginOffset, std::streamsize countBytesToRead) override
Definition: fileimpl.cpp:43
qi::FileImpl::seek
bool seek(std::streamoff offsetFromBegin) override
Definition: fileimpl.cpp:75
qi::FileImpl::isRemote
bool isRemote() const override
Definition: fileimpl.cpp:102
qi::FileImpl::_read
Buffer _read(std::streamoff beginOffset, std::streamsize countBytesToRead) override
Definition: fileimpl.cpp:113
qi::FileImpl::read
Buffer read(std::streamsize countBytesToRead) override
Definition: fileimpl.cpp:51
qi::FilePtr
qi::Object< File > FilePtr
Pointer to a file with shared/remote semantic.
Definition: file.hpp:213


naoqi_libqicore
Author(s): Aldebaran
autogenerated on Wed Sep 14 2022 02:22:41