8 #include <boost/filesystem/fstream.hpp>
12 #include <qi/macro.hpp>
13 #include <qi/anymodule.hpp>
22 if (!localFilePath.exists())
24 std::stringstream message;
25 message <<
"File not found on qi::File open: " << localFilePath.str();
26 throw std::runtime_error(message.str());
31 _fileStream.open(localFilePath, std::ios::in | std::ios::binary);
43 Buffer
read(std::streamoff beginOffset, std::streamsize countBytesToRead)
override
45 if (
seek(beginOffset))
46 return read(countBytesToRead);
51 Buffer
read(std::streamsize countBytesToRead)
override
55 throw std::runtime_error(
"Tried to read too much data at once.");
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);
66 _readBuffer.resize(
static_cast<size_t>(byteCountToRead),
'\0');
68 const std::streamsize bytesRead =
_fileStream.gcount();
69 assert(bytesRead <= byteCountToRead);
70 output.write(
_readBuffer.data(),
static_cast<size_t>(bytesRead));
75 bool seek(std::streamoff offsetFromBegin)
override
79 if (offsetFromBegin >=
_size)
92 std::streamsize
size()
const override
113 Buffer
_read(std::streamoff beginOffset, std::streamsize countBytesToRead)
override
115 return read(beginOffset, countBytesToRead);
118 Buffer
_read(std::streamsize countBytesToRead)
override
120 return read(countBytesToRead);
123 bool _seek(std::streamoff offsetFromBegin)
override
125 return seek(offsetFromBegin);
142 throw std::runtime_error(
"Trying to manipulate a closed file access.");
148 ::qi::ObjectTypeBuilder<File> builder;
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);
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);
168 builder.registerType();
171 qi::detail::ForceProxyInclusion<File>().dummyCall();
172 qi::registerType(
typeid(
FileImpl), qi::typeOf<File>());
175 intptr_t offset =
reinterpret_cast<intptr_t
>(pptr)-
reinterpret_cast<intptr_t
>(ptr);
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");
188 return boost::make_shared<FileImpl>(localPath);