From a208d79c00dd24206b9370939eb69a63299376ba Mon Sep 17 00:00:00 2001 From: Jeongseok Lee Date: Sun, 17 Mar 2024 17:48:01 -0700 Subject: [PATCH] [v7] Move Resource to v7 --- dart/common/LocalResource.hpp | 45 +----- dart/common/Resource.hpp | 64 +-------- dart/dynamics/AssimpInputResourceAdaptor.cpp | 6 +- dart/v7/empty.cpp | 39 ++++++ dart/v7/empty.hpp | 41 ++++++ .../local_resource.cpp} | 131 +++++++++--------- dart/v7/local_resource.hpp | 84 +++++++++++ dart/{common/Resource.cpp => v7/resource.cpp} | 19 +-- dart/v7/resource.hpp | 93 +++++++++++++ .../test_LocalResourceRetriever.cpp | 18 +-- tests/unit/v7/test_local_resource.cpp | 105 ++++++++++++++ 11 files changed, 457 insertions(+), 188 deletions(-) create mode 100644 dart/v7/empty.cpp create mode 100644 dart/v7/empty.hpp rename dart/{common/LocalResource.cpp => v7/local_resource.cpp} (53%) create mode 100644 dart/v7/local_resource.hpp rename dart/{common/Resource.cpp => v7/resource.cpp} (84%) create mode 100644 dart/v7/resource.hpp create mode 100644 tests/unit/v7/test_local_resource.cpp diff --git a/dart/common/LocalResource.hpp b/dart/common/LocalResource.hpp index e8a3599c189ec..351ed7a6e3cb6 100644 --- a/dart/common/LocalResource.hpp +++ b/dart/common/LocalResource.hpp @@ -30,47 +30,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef DART_COMMON_LOCALRESOURCE_HPP_ -#define DART_COMMON_LOCALRESOURCE_HPP_ +#pragma once -#include -#include +#include -namespace dart { -namespace common { +namespace dart::common { -DART_DECLARE_CLASS_WITH_VIRTUAL_BASE_BEGIN -class LocalResource : public virtual Resource -{ -public: - explicit LocalResource(const std::string& _path); - virtual ~LocalResource(); +using LocalResource = v7::LocalResource; - LocalResource(const LocalResource& _other) = delete; - LocalResource& operator=(const LocalResource& _other) = delete; - - /// Returns true if the resource is open and in a valid state. - bool isGood() const; - - // Documentation inherited. - std::size_t getSize() override; - - // Documentation inherited. - std::size_t tell() override; - - // Documentation inherited. - bool seek(ptrdiff_t _origin, SeekType _mode) override; - - // Documentation inherited. - std::size_t read( - void* _buffer, std::size_t _size, std::size_t _count) override; - -private: - std::FILE* mFile; -}; -DART_DECLARE_CLASS_WITH_VIRTUAL_BASE_END - -} // namespace common -} // namespace dart - -#endif // ifndef DART_COMMON_LOCALRESOURCE_HPP_ +} // namespace dart::common diff --git a/dart/common/Resource.hpp b/dart/common/Resource.hpp index 12014c7ed6ca5..7bf25bb190f59 100644 --- a/dart/common/Resource.hpp +++ b/dart/common/Resource.hpp @@ -30,67 +30,13 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef DART_COMMON_RESOURCE_HPP_ -#define DART_COMMON_RESOURCE_HPP_ +#pragma once -#include -#include +#include -#include - -namespace dart { -namespace common { - -/// \brief Resource provides file-like access to a resource loaded from URI. -/// -/// It is expected that each \a ResourceRetriever will provide a concrete / -/// instantiation of the Resource class. This interface exposes an similar API -/// to that of the the standard C file manipulation functions. -class Resource -{ -public: - /// \brief Position to seek relative to. - enum SeekType - { - SEEKTYPE_CUR, ///< Current position. - SEEKTYPE_END, ///< End of file. - SEEKTYPE_SET ///< Begining of file. - }; - - virtual ~Resource() = default; - - /// \brief Return the size of the resource, in bytes. - virtual std::size_t getSize() = 0; - - /// \brief Return the current value of the position indicator. - /// \note This method has the same API as the standard ftell function. - virtual std::size_t tell() = 0; - - /// \brief Set the position indicator to a new position. - /// \param[in] _offset Offset, in bytes, relative to _origin. - /// \param[in] _origin Position used as the reference of _offset. - /// \note This method has the same API as the standard fseek function. - virtual bool seek(ptrdiff_t _offset, SeekType _origin) = 0; - - /// \brief Read _count element, each of size _size, into _buffer. - /// \param[out] _buffer Pointer to a block of memory with a size of at least - /// (_size * _count) bytes. - /// \param[in] _size Size, in bytes, of each element. - /// \param[in] _count Number of elements, each of _size bytes. - /// \note This method has the same API as the standard fread function. - virtual std::size_t read(void* _buffer, std::size_t _size, std::size_t _count) - = 0; - - /// Reads all data from this resource, and returns it as a string. - /// - /// \return The string retrieved from the resource. - /// \throw std::runtime_error when failed to read sucessfully. - virtual std::string readAll(); -}; +namespace dart::common { +using Resource = v7::Resource; using ResourcePtr = std::shared_ptr; -} // namespace common -} // namespace dart - -#endif // ifndef DART_COMMON_RESOURCE_HPP_ +} // namespace dart::common diff --git a/dart/dynamics/AssimpInputResourceAdaptor.cpp b/dart/dynamics/AssimpInputResourceAdaptor.cpp index 3256f9891880e..b0b21768982ec 100644 --- a/dart/dynamics/AssimpInputResourceAdaptor.cpp +++ b/dart/dynamics/AssimpInputResourceAdaptor.cpp @@ -141,15 +141,15 @@ aiReturn AssimpInputResourceAdaptor::Seek(std::size_t pOffset, aiOrigin pOrigin) Resource::SeekType origin; switch (pOrigin) { case aiOrigin_CUR: - origin = Resource::SEEKTYPE_CUR; + origin = Resource::SeekType::CUR; break; case aiOrigin_END: - origin = Resource::SEEKTYPE_END; + origin = Resource::SeekType::END; break; case aiOrigin_SET: - origin = Resource::SEEKTYPE_SET; + origin = Resource::SeekType::SET; break; default: diff --git a/dart/v7/empty.cpp b/dart/v7/empty.cpp new file mode 100644 index 0000000000000..ca8a30e379820 --- /dev/null +++ b/dart/v7/empty.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) The DART development contributors + * All rights reserved. + * + * The list of contributors can be found at: + * https://github.com/dartsim/dart/blob/main/LICENSE + * + * This file is provided under the following "BSD-style" License: + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "dart/v7/empty.hpp" + +namespace dart::v7 { + +// + +} // namespace dart::v7 diff --git a/dart/v7/empty.hpp b/dart/v7/empty.hpp new file mode 100644 index 0000000000000..82b6742c126a6 --- /dev/null +++ b/dart/v7/empty.hpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) The DART development contributors + * All rights reserved. + * + * The list of contributors can be found at: + * https://github.com/dartsim/dart/blob/main/LICENSE + * + * This file is provided under the following "BSD-style" License: + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include + +namespace dart::v7 { + +// + +} // namespace dart::v7 diff --git a/dart/common/LocalResource.cpp b/dart/v7/local_resource.cpp similarity index 53% rename from dart/common/LocalResource.cpp rename to dart/v7/local_resource.cpp index 71b3286ed3ea8..162d919742841 100644 --- a/dart/common/LocalResource.cpp +++ b/dart/v7/local_resource.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2024, The DART development contributors + * Copyright (c) The DART development contributors * All rights reserved. * * The list of contributors can be found at: @@ -30,74 +30,74 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "LocalResource.hpp" +#include "dart/v7/local_resource.hpp" -#include "dart/common/Console.hpp" +#include "dart/v7/logging.hpp" -#include #include #include -namespace dart { -namespace common { +namespace dart::v7 { -//============================================================================== LocalResource::LocalResource(const std::string& _path) : mFile(std::fopen(_path.c_str(), "rb")) { - if (!mFile) { - dtwarn << "[LocalResource::constructor] Failed opening file '" << _path - << "' for reading: " << std::strerror(errno) << "\n"; - } + DART_WARN_IF( + !mFile, + "[LocalResource::constructor] Failed opening file '{}' for reading: {}", + _path, + std::strerror(errno)); } -//============================================================================== LocalResource::~LocalResource() { - if (!mFile) + if (!mFile) { return; - - if (std::fclose(mFile) == EOF) { - dtwarn << "[LocalResource::destructor] Failed closing file: " - << std::strerror(errno) << "\n"; } + + DART_WARN_IF( + std::fclose(mFile) == EOF, + "[LocalResource::destructor] Failed closing file: {}", + std::strerror(errno)); } -//============================================================================== bool LocalResource::isGood() const { return !!mFile; } -//============================================================================== std::size_t LocalResource::getSize() { - if (!mFile) + if (!mFile) { return 0; + } const long offset = std::ftell(mFile); if (offset == -1L) { - dtwarn << "[LocalResource::getSize] Unable to compute file size: Failed" - " getting current offset: " - << std::strerror(errno) << "\n"; + DART_WARN( + "[LocalResource::getSize] Unable to compute file size: Failed getting " + "current offset: {}", + std::strerror(errno)); return 0; } // The SEEK_END option is not required by the C standard. However, it is // required by POSIX. if (std::fseek(mFile, 0, SEEK_END) || std::ferror(mFile)) { - dtwarn << "[LocalResource::getSize] Unable to compute file size: Failed" - " seeking to the end of the file: " - << std::strerror(errno) << "\n"; + DART_WARN( + "[LocalResource::getSize] Unable to compute file size: Failed seeking " + "to the end of the file: {}", + std::strerror(errno)); return 0; } const long size = std::ftell(mFile); if (size == -1L) { - dtwarn << "[LocalResource::getSize] Unable to compute file size: Failed" - " getting end of file offset: " - << std::strerror(errno) << "\n"; + DART_WARN( + "[LocalResource::getSize] Unable to compute file size: Failed getting " + "end of file offset: {}", + std::strerror(errno)); return 0; } // fopen, ftell, and fseek produce undefined behavior when called on @@ -106,40 +106,43 @@ std::size_t LocalResource::getSize() // // See here: http://stackoverflow.com/a/18193383/111426 else if (size == std::numeric_limits::max()) { - dtwarn << "[LocalResource::getSize] Unable to compute file size: Computed" - " file size of LONG_MAX. Is this a directory?\n"; + DART_WARN( + "[LocalResource::getSize] Unable to compute file size: Computed file " + "size of LONG_MAX. Is this a directory?"); return 0; } if (std::fseek(mFile, offset, SEEK_SET) || std::ferror(mFile)) { - dtwarn << "[LocalResource::getSize] Unable to compute file size: Failed" - " restoring offset: " - << std::strerror(errno) << "\n"; + DART_WARN( + "[LocalResource::getSize] Unable to compute file size: Failed " + "restoring offset: {}", + std::strerror(errno)); return 0; } return size; } -//============================================================================== std::size_t LocalResource::tell() { - if (!mFile) + if (!mFile) { return 0; + } const long offset = std::ftell(mFile); if (offset == -1L) { - dtwarn << "[LocalResource::tell] Failed getting current offset: " - << std::strerror(errno) << "\n"; - } - // fopen, ftell, and fseek produce undefined behavior when called on - // directories. ftell() on Linux libc returns LONG_MAX, unless you are in an - // NFS mount. - // - // See here: http://stackoverflow.com/a/18193383/111426 - else if (offset == std::numeric_limits::max()) { - dtwarn << "[LocalResource::tell] Failed getting current offset: ftell" - " returned LONG_MAX. Is this a directory?\n"; + DART_WARN( + "[LocalResource::tell] Failed getting current offset: {}", + std::strerror(errno)); + } else if (offset == std::numeric_limits::max()) { + // fopen, ftell, and fseek produce undefined behavior when called on + // directories. ftell() on Linux libc returns LONG_MAX, unless you are in an + // NFS mount. + // + // See here: http://stackoverflow.com/a/18193383/111426 + DART_WARN( + "[LocalResource::tell] Failed getting current offset: ftell returned " + "LONG_MAX. Is this a directory?"); return -1L; } @@ -147,52 +150,50 @@ std::size_t LocalResource::tell() return offset; } -//============================================================================== bool LocalResource::seek(ptrdiff_t _offset, SeekType _mode) { int origin; switch (_mode) { - case Resource::SEEKTYPE_CUR: + case Resource::SeekType::CUR: origin = SEEK_CUR; break; - case Resource::SEEKTYPE_END: + case Resource::SeekType::END: origin = SEEK_END; break; - case Resource::SEEKTYPE_SET: + case Resource::SeekType::SET: origin = SEEK_SET; break; default: - dtwarn << "[LocalResource::seek] Invalid origin. Expected" - " SEEKTYPE_CUR, SEEKTYPE_END, or SEEKTYPE_SET.\n"; + DART_WARN( + "[LocalResource::seek] Invalid origin. Expected SeekType::CUR, " + "SeekType::END, or SEEKTYPE_SET."); return false; } - if (!std::fseek(mFile, _offset, origin) && !std::ferror(mFile)) + if (!std::fseek(mFile, _offset, origin) && !std::ferror(mFile)) { return true; - else { - dtwarn << "[LocalResource::seek] Failed seeking: " << std::strerror(errno) - << "\n"; + } else { + DART_WARN("[LocalResource::seek] Failed seeking: {}", std::strerror(errno)); return false; } } -//============================================================================== std::size_t LocalResource::read( void* _buffer, std::size_t _size, std::size_t _count) { - if (!mFile) + if (!mFile) { return 0; + } const std::size_t result = std::fread(_buffer, _size, _count, mFile); - if (std::ferror(mFile)) { - dtwarn << "[LocalResource::read] Failed reading file: " - << std::strerror(errno) << "\n"; - } + DART_WARN_IF( + std::ferror(mFile), + "[LocalResource::read] Failed reading file: {}", + std::strerror(errno)); return result; } -} // namespace common -} // namespace dart +} // namespace dart::v7 diff --git a/dart/v7/local_resource.hpp b/dart/v7/local_resource.hpp new file mode 100644 index 0000000000000..7f66e336f8ff1 --- /dev/null +++ b/dart/v7/local_resource.hpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) The DART development contributors + * All rights reserved. + * + * The list of contributors can be found at: + * https://github.com/dartsim/dart/blob/main/LICENSE + * + * This file is provided under the following "BSD-style" License: + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include + +namespace dart::v7 { + +/// LocalResource provides file-like access to a resource loaded from a local +/// file path. +/// +/// LocalResource is a concrete implementation of the Resource class that is +/// used to access resources located on the local file system. It provides an +/// API similar to that of the standard C file manipulation functions, and can +/// be used to read, seek and retrieve the size of a file. +class LocalResource : public Resource +{ +public: + /// Constructs a LocalResource object with a given file path. + /// @param[in] path The file path of the resource. + explicit LocalResource(const std::string& _path); + + /// Destructs the LocalResource object, closing the resource if it is open. + ~LocalResource() override; + + /// Deleted copy constructor to prevent copying of LocalResource objects. + LocalResource(const LocalResource& other) = delete; + + /// Deleted assignment operator to prevent assignment of LocalResource + /// objects. + LocalResource& operator=(const LocalResource& other) = delete; + + /// Checks if the resource is open and in a valid state. + /// @return true if the resource is open and in a valid state, false + /// otherwise. + bool isGood() const; + + /// Returns the size of the resource in bytes. + std::size_t getSize() override; + + /// Returns the current position of the resource. + std::size_t tell() override; + + /// Sets the position of the resource to a new position. + bool seek(ptrdiff_t origin, SeekType mode) override; + + /// Reads data from the resource into a buffer. + std::size_t read(void* buffer, std::size_t size, std::size_t count) override; + +private: + std::FILE* mFile; +}; + +} // namespace dart::v7 diff --git a/dart/common/Resource.cpp b/dart/v7/resource.cpp similarity index 84% rename from dart/common/Resource.cpp rename to dart/v7/resource.cpp index 87ef00954d004..15017c0f6c3b4 100644 --- a/dart/common/Resource.cpp +++ b/dart/v7/resource.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2024, The DART development contributors + * Copyright (c) The DART development contributors * All rights reserved. * * The list of contributors can be found at: @@ -30,17 +30,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "dart/common/Resource.hpp" +#include "dart/v7/resource.hpp" -#include "dart/common/Console.hpp" +#include -#include -#include +namespace dart::v7 { -namespace dart { -namespace common { - -//============================================================================== std::string Resource::readAll() { std::string content; @@ -48,11 +43,11 @@ std::string Resource::readAll() const auto result = read(&content.front(), content.size(), 1); // Safe because std::string is guaranteed to be contiguous in C++11. - if (result != 1) + if (result != 1) { throw std::runtime_error("Failed reading data from a resource."); + } return content; } -} // namespace common -} // namespace dart +} // namespace dart::v7 diff --git a/dart/v7/resource.hpp b/dart/v7/resource.hpp new file mode 100644 index 0000000000000..5af1709089aa9 --- /dev/null +++ b/dart/v7/resource.hpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) The DART development contributors + * All rights reserved. + * + * The list of contributors can be found at: + * https://github.com/dartsim/dart/blob/main/LICENSE + * + * This file is provided under the following "BSD-style" License: + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include + +#include +#include + +#include + +namespace dart::v7 { + +/// Resource provides file-like access to a resource loaded from URI. +/// +/// It is expected that each @a ResourceRetriever will provide a concrete +/// instantiation of the Resource class. This interface exposes a similar API +/// to that of the standard C file manipulation functions. +class Resource +{ +public: + /// Position to seek relative to. + enum class SeekType + { + CUR, ///< Current position. + END, ///< End of file. + SET ///< Beginning of file. + }; + + virtual ~Resource() = default; + + /// Returns the size of the resource, in bytes. + virtual std::size_t getSize() = 0; + + /// Returns the current value of the position indicator. + /// @note This method has the same API as the standard ftell function. + virtual std::size_t tell() = 0; + + /// Sets the position indicator to a new position. + /// @param[in] offset Offset, in bytes, relative to origin. + /// @param[in] origin Position used as the reference of offset. + /// @note This method has the same API as the standard fseek function. + virtual bool seek(ptrdiff_t offset, SeekType origin) = 0; + + /// Reads count element, each of size size, into buffer. + /// @param[out] buffer Pointer to a block of memory with a size of at least + /// (size * count) bytes. + /// @param[in] size Size, in bytes, of each element. + /// @param[in] count Number of elements, each of size bytes. + /// @note This method has the same API as the standard fread function. + virtual std::size_t read(void* buffer, std::size_t size, std::size_t count) + = 0; + + /// Reads all data from this resource, and returns it as a string. + /// + /// @return The string retrieved from the resource. + /// @throw std::runtime_error when failed to read successfully. + virtual std::string readAll(); +}; + +using ResourcePtr = std::shared_ptr; + +} // namespace dart::v7 diff --git a/tests/integration/test_LocalResourceRetriever.cpp b/tests/integration/test_LocalResourceRetriever.cpp index 1907fbc865731..acae0db0a64e3 100644 --- a/tests/integration/test_LocalResourceRetriever.cpp +++ b/tests/integration/test_LocalResourceRetriever.cpp @@ -171,40 +171,40 @@ TEST(LocalResourceRetriever, retrieve_ResourceOperations) EXPECT_EQ(content.size(), resource->getSize()); // Relative seek. - ASSERT_TRUE(resource->seek(2, Resource::SEEKTYPE_CUR)); + ASSERT_TRUE(resource->seek(2, Resource::SeekType::CUR)); EXPECT_EQ(2u, resource->tell()); // Absolute seek. - ASSERT_TRUE(resource->seek(5, Resource::SEEKTYPE_SET)); + ASSERT_TRUE(resource->seek(5, Resource::SeekType::SET)); EXPECT_EQ(5u, resource->tell()); // Seek to the end of the file. - ASSERT_TRUE(resource->seek(0, Resource::SEEKTYPE_END)); + ASSERT_TRUE(resource->seek(0, Resource::SeekType::END)); EXPECT_EQ(content.size(), resource->tell()); - // TODO: SEEKTYPE_END should require negative input. - ASSERT_TRUE(resource->seek(-3, Resource::SEEKTYPE_END)); + // TODO: SeekType::END should require negative input. + ASSERT_TRUE(resource->seek(-3, Resource::SeekType::END)); EXPECT_EQ(content.size() - 3, resource->tell()); // Reading a block that's too large should do nothing. - ASSERT_TRUE(resource->seek(0, Resource::SEEKTYPE_SET)); + ASSERT_TRUE(resource->seek(0, Resource::SeekType::SET)); ASSERT_EQ(0u, resource->read(buffer.data(), content.size() + 1, 1)); // Reading should only return full blocks. buffer.assign(buffer.size(), '\0'); - ASSERT_TRUE(resource->seek(0, Resource::SEEKTYPE_SET)); + ASSERT_TRUE(resource->seek(0, Resource::SeekType::SET)); ASSERT_EQ(1u, resource->read(buffer.data(), 8, 1)); EXPECT_STREQ(content.substr(0, 8).c_str(), buffer.data()); // Reading multiple blocks buffer.assign(buffer.size(), '\0'); - ASSERT_TRUE(resource->seek(0, Resource::SEEKTYPE_SET)); + ASSERT_TRUE(resource->seek(0, Resource::SeekType::SET)); ASSERT_EQ(2u, resource->read(buffer.data(), 4, 2)); EXPECT_STREQ(content.substr(0, 8).c_str(), buffer.data()); // Reading the whole file at once. buffer.assign(buffer.size(), '\0'); - ASSERT_TRUE(resource->seek(0, Resource::SEEKTYPE_SET)); + ASSERT_TRUE(resource->seek(0, Resource::SeekType::SET)); ASSERT_EQ(1u, resource->read(buffer.data(), content.size(), 1)); EXPECT_STREQ(content.c_str(), buffer.data()); } diff --git a/tests/unit/v7/test_local_resource.cpp b/tests/unit/v7/test_local_resource.cpp new file mode 100644 index 0000000000000..973ff1a5cd8a8 --- /dev/null +++ b/tests/unit/v7/test_local_resource.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) The DART development contributors + * All rights reserved. + * + * The list of contributors can be found at: + * https://github.com/dartsim/dart/blob/main/LICENSE + * + * This file is provided under the following "BSD-style" License: + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "dart/v7/local_resource.hpp" + +#include + +#include + +using namespace dart; +using namespace v7; + +class LocalResourceTest : public ::testing::Test +{ +protected: + LocalResourceTest() + { + // Create a test file + std::ofstream testFile("test.txt"); + testFile << "This is a test file."; + testFile.close(); + } + + ~LocalResourceTest() + { + // Delete the test file + std::remove("test.txt"); + } +}; + +TEST_F(LocalResourceTest, TestGetSize) +{ + LocalResource res("test.txt"); + std::string data = res.readAll(); + std::size_t fileSize = data.size(); + EXPECT_EQ(fileSize, res.getSize()); +} + +TEST_F(LocalResourceTest, TestTell) +{ + LocalResource res("test.txt"); + res.seek(10, Resource::SeekType::SET); + std::size_t position = res.tell(); + EXPECT_EQ(position, 10); +} + +TEST_F(LocalResourceTest, TestSeek) +{ + LocalResource res("test.txt"); + res.seek(10, Resource::SeekType::SET); + std::size_t position = res.tell(); + EXPECT_EQ(position, 10); +} + +TEST_F(LocalResourceTest, TestRead) +{ + LocalResource res("test.txt"); + char buffer[100]; + std::size_t bytesRead = res.read(buffer, 1, 100); + EXPECT_EQ(bytesRead, res.getSize()); +} + +TEST_F(LocalResourceTest, TestReadAll) +{ + LocalResource res("test.txt"); + std::string data = res.readAll(); + EXPECT_EQ(data, "This is a test file."); +} + +TEST_F(LocalResourceTest, TestIsGood) +{ + LocalResource res("test.txt"); + EXPECT_TRUE(res.isGood()); + LocalResource res2("nonexistentfile.txt"); + EXPECT_FALSE(res2.isGood()); +} \ No newline at end of file