Add a ResourceProxy class
The ResourceProxy class allows one to access real files or embedded
resources in a unified way. When using it, one can switch from one data
source to the other with minimal code changes, possibly even at runtime
(in which case there is obviously no code change at all).
Sample usage (from FlightGear for the globals->get_fg_root() bit):
simgear::ResourceProxy proxy(globals->get_fg_root(), "/FGData");
std::string s = proxy.getString("/some/path");
std::unique_ptr<std::istream> streamp = proxy.getIStream("/some/path");
The methods ResourceProxy::getString(const std::string& path) and
ResourceProxy::getIStream(const std::string& path) decide whether to use
embedded resources or real files depending on the boolean value passed
to ResourceProxy::setUseEmbeddedResources() (also available as an
optional parameter to the ResourceProxy constructor, defaulting to
true). It is often most convenient to set this boolean once and don't
worry about it anymore---it's stored inside the ResourceProxy object.
Otherwise, if you want to fetch resources some times from real files,
other times from embedded resources, you may use the following methods:
// Retrieve contents using embedded resources
std:string s = proxy.getString("/some/path", true);
std:string s = proxy.getStringDecideOnPrefix(":/some/path");
// Retrieve contents using real files
std:string s = proxy.getString("/some/path", false);
std:string s = proxy.getStringDecideOnPrefix("/some/path");
(alternatively, you could use several ResourceProxy objects with
different values for the constructor's third parameter)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
include (SimGearComponent)
|
||||
|
||||
set(HEADERS EmbeddedResource.hxx EmbeddedResourceManager.hxx)
|
||||
set(SOURCES EmbeddedResource.cxx EmbeddedResourceManager.cxx)
|
||||
set(HEADERS EmbeddedResource.hxx EmbeddedResourceManager.hxx ResourceProxy.hxx)
|
||||
set(SOURCES EmbeddedResource.cxx EmbeddedResourceManager.cxx ResourceProxy.cxx)
|
||||
|
||||
simgear_component(embedded_resources embedded_resources
|
||||
"${SOURCES}" "${HEADERS}")
|
||||
|
||||
247
simgear/embedded_resources/ResourceProxy.cxx
Normal file
247
simgear/embedded_resources/ResourceProxy.cxx
Normal file
@@ -0,0 +1,247 @@
|
||||
// -*- coding: utf-8 -*-
|
||||
//
|
||||
// ResourceProxy.cxx --- Unified access to real files or embedded resources
|
||||
// Copyright (C) 2017 Florent Rougon
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
// MA 02110-1301 USA.
|
||||
|
||||
#include <simgear_config.h>
|
||||
|
||||
#include <algorithm> // std::find()
|
||||
#include <ios> // std::streamsize
|
||||
#include <istream>
|
||||
#include <limits> // std::numeric_limits
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cstdlib> // std::size_t
|
||||
#include <cassert>
|
||||
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/misc/strutils.hxx>
|
||||
#include <simgear/io/iostreams/sgstream.hxx>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
#include "EmbeddedResourceManager.hxx"
|
||||
#include "ResourceProxy.hxx"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::shared_ptr;
|
||||
using std::unique_ptr;
|
||||
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
|
||||
ResourceProxy::ResourceProxy(const SGPath& realRoot, const string& virtualRoot,
|
||||
bool useEmbeddedResourcesByDefault)
|
||||
: _realRoot(realRoot),
|
||||
_virtualRoot(normalizeVirtualRoot(virtualRoot)),
|
||||
_useEmbeddedResourcesByDefault(useEmbeddedResourcesByDefault)
|
||||
{ }
|
||||
|
||||
SGPath
|
||||
ResourceProxy::getRealRoot() const
|
||||
{ return _realRoot; }
|
||||
|
||||
void
|
||||
ResourceProxy::setRealRoot(const SGPath& realRoot)
|
||||
{ _realRoot = realRoot; }
|
||||
|
||||
string
|
||||
ResourceProxy::getVirtualRoot() const
|
||||
{ return _virtualRoot; }
|
||||
|
||||
void
|
||||
ResourceProxy::setVirtualRoot(const string& virtualRoot)
|
||||
{ _virtualRoot = normalizeVirtualRoot(virtualRoot); }
|
||||
|
||||
bool
|
||||
ResourceProxy::getUseEmbeddedResources() const
|
||||
{ return _useEmbeddedResourcesByDefault; }
|
||||
|
||||
void
|
||||
ResourceProxy::setUseEmbeddedResources(bool useEmbeddedResources)
|
||||
{ _useEmbeddedResourcesByDefault = useEmbeddedResources; }
|
||||
|
||||
// Static method: normalize the 'virtualRoot' argument of the constructor
|
||||
//
|
||||
// The argument must start with a slash and mustn't contain any '.' or '..'
|
||||
// component. The return value never ends with a slash.
|
||||
string
|
||||
ResourceProxy::normalizeVirtualRoot(const string& path)
|
||||
{
|
||||
ResourceProxy::checkPath(__func__, path, false /* allowStartWithColon */);
|
||||
string res = path;
|
||||
|
||||
// Make sure 'res' doesn't end with a '/'.
|
||||
while (!res.empty() && res.back() == '/') {
|
||||
res.pop_back(); // This will ease path concatenation
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// Static method
|
||||
void
|
||||
ResourceProxy::checkPath(const string& callerMethod, const string& path,
|
||||
bool allowStartWithColon) {
|
||||
if (path.empty()) {
|
||||
throw sg_format_exception(
|
||||
"Invalid empty path for ResourceProxy::" + callerMethod + "(): '" +
|
||||
path + "'", path);
|
||||
} else if (allowStartWithColon &&
|
||||
!simgear::strutils::starts_with(path, ":/") && path[0] != '/') {
|
||||
throw sg_format_exception(
|
||||
"Invalid path for ResourceProxy::" + callerMethod + "(): it should "
|
||||
"start with either ':/' or '/'", path);
|
||||
} else if (!allowStartWithColon && path[0] != '/') {
|
||||
throw sg_format_exception(
|
||||
"Invalid path for ResourceProxy::" + callerMethod + "(): it should "
|
||||
"start with a slash ('/')", path);
|
||||
} else {
|
||||
const vector<string> components = simgear::strutils::split(path, "/");
|
||||
auto find = [&components](const string& s) -> bool {
|
||||
return (std::find(components.begin(), components.end(), s) !=
|
||||
components.end());
|
||||
};
|
||||
|
||||
if (find(".") || find("..")) {
|
||||
throw sg_format_exception(
|
||||
"Invalid path for ResourceProxy::" + callerMethod + "(): "
|
||||
"'.' and '..' components are not allowed", path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unique_ptr<std::istream>
|
||||
ResourceProxy::getIStream(const string& path, bool fromEmbeddedResource) const
|
||||
{
|
||||
ResourceProxy::checkPath(__func__, path, false /* allowStartWithColon */);
|
||||
assert(!path.empty() && path.front() == '/');
|
||||
|
||||
if (fromEmbeddedResource) {
|
||||
const auto& embeddedResMgr = simgear::EmbeddedResourceManager::instance();
|
||||
return embeddedResMgr->getIStream(
|
||||
_virtualRoot + path,
|
||||
""); // fetch the default-locale version of the resource
|
||||
} else {
|
||||
const SGPath sgPath = _realRoot / path.substr(std::size_t(1));
|
||||
return unique_ptr<std::istream>(new sg_ifstream(sgPath));
|
||||
}
|
||||
}
|
||||
|
||||
unique_ptr<std::istream>
|
||||
ResourceProxy::getIStream(const string& path) const
|
||||
{
|
||||
return getIStream(path, _useEmbeddedResourcesByDefault);
|
||||
}
|
||||
|
||||
unique_ptr<std::istream>
|
||||
ResourceProxy::getIStreamDecideOnPrefix(const string& path) const
|
||||
{
|
||||
ResourceProxy::checkPath(__func__, path, true /* allowStartWithColon */);
|
||||
|
||||
// 'path' is non-empty
|
||||
if (path.front() == '/') {
|
||||
return getIStream(path, false /* fromEmbeddedResource */);
|
||||
} else if (path.front() == ':') {
|
||||
assert(path.size() >= 2 && path[1] == '/');
|
||||
// Skip the leading ':'
|
||||
return getIStream(path.substr(std::size_t(1)),
|
||||
true /* fromEmbeddedResource */);
|
||||
} else {
|
||||
// The checkPath() call should make it impossible to reach this point.
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
ResourceProxy::getString(const string& path, bool fromEmbeddedResource) const
|
||||
{
|
||||
string result;
|
||||
|
||||
ResourceProxy::checkPath(__func__, path, false /* allowStartWithColon */);
|
||||
assert(!path.empty() && path.front() == '/');
|
||||
|
||||
if (fromEmbeddedResource) {
|
||||
const auto& embeddedResMgr = simgear::EmbeddedResourceManager::instance();
|
||||
// Fetch the default-locale version of the resource
|
||||
result = embeddedResMgr->getString(_virtualRoot + path, "");
|
||||
} else {
|
||||
const SGPath sgPath = _realRoot / path.substr(std::size_t(1));
|
||||
result.reserve(sgPath.sizeInBytes());
|
||||
const unique_ptr<std::istream> streamp = getIStream(path,
|
||||
fromEmbeddedResource);
|
||||
std::streamsize nbCharsRead;
|
||||
|
||||
// Allocate a buffer
|
||||
static constexpr std::size_t bufSize = 65536;
|
||||
static_assert(bufSize <= std::numeric_limits<std::streamsize>::max(),
|
||||
"Type std::streamsize is unexpectedly small");
|
||||
static_assert(bufSize <= std::numeric_limits<string::size_type>::max(),
|
||||
"Type std::string::size_type is unexpectedly small");
|
||||
unique_ptr<char[]> buf(new char[bufSize]);
|
||||
|
||||
do {
|
||||
streamp->read(buf.get(), bufSize);
|
||||
nbCharsRead = streamp->gcount();
|
||||
|
||||
if (nbCharsRead > 0) {
|
||||
result.append(buf.get(), nbCharsRead);
|
||||
}
|
||||
} while (*streamp);
|
||||
|
||||
// streamp->fail() would *not* indicate an error, due to the semantics
|
||||
// of std::istream::read().
|
||||
if (streamp->bad()) {
|
||||
throw sg_io_exception("Error reading from file", sg_location(path));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
string
|
||||
ResourceProxy::getString(const string& path) const
|
||||
{
|
||||
return getString(path, _useEmbeddedResourcesByDefault);
|
||||
}
|
||||
|
||||
string
|
||||
ResourceProxy::getStringDecideOnPrefix(const string& path) const
|
||||
{
|
||||
string result;
|
||||
|
||||
ResourceProxy::checkPath(__func__, path, true /* allowStartWithColon */);
|
||||
|
||||
// 'path' is non-empty
|
||||
if (path.front() == '/') {
|
||||
result = getString(path, false /* fromEmbeddedResource */);
|
||||
} else if (path.front() == ':') {
|
||||
assert(path.size() >= 2 && path[1] == '/');
|
||||
// Skip the leading ':'
|
||||
result = getString(path.substr(std::size_t(1)),
|
||||
true /* fromEmbeddedResource */);
|
||||
} else {
|
||||
// The checkPath() call should make it impossible to reach this point.
|
||||
std::abort();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // of namespace simgear
|
||||
152
simgear/embedded_resources/ResourceProxy.hxx
Normal file
152
simgear/embedded_resources/ResourceProxy.hxx
Normal file
@@ -0,0 +1,152 @@
|
||||
// -*- coding: utf-8 -*-
|
||||
//
|
||||
// ResourceProxy.hxx --- Unified access to real files or embedded resources
|
||||
// Copyright (C) 2017 Florent Rougon
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
// MA 02110-1301 USA.
|
||||
|
||||
#ifndef FG_RESOURCEPROXY_HXX
|
||||
#define FG_RESOURCEPROXY_HXX
|
||||
|
||||
#include <istream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
// The ResourceProxy class allows one to access real files or embedded
|
||||
// resources in a unified way. When using it, one can switch from one data
|
||||
// source to the other with minimal code changes, possibly even at runtime (in
|
||||
// which case there is obviously no code change at all).
|
||||
//
|
||||
// Sample usage of the ResourceProxy class (from FlightGear):
|
||||
//
|
||||
// simgear::ResourceProxy proxy(globals->get_fg_root(), "/FGData");
|
||||
// std::string s = proxy.getString("/some/path");
|
||||
// std::unique_ptr<std::istream> streamp = proxy.getIStream("/some/path");
|
||||
//
|
||||
// The methods ResourceProxy::getString(const std::string& path) and
|
||||
// ResourceProxy::getIStream(const std::string& path) decide whether to use
|
||||
// embedded resources or real files depending on the boolean value passed to
|
||||
// ResourceProxy::setUseEmbeddedResources() (also available as an optional
|
||||
// parameter to the ResourceProxy constructor, defaulting to true). It is
|
||||
// often most convenient to set this boolean once and then don't worry about
|
||||
// it anymore (it is stored inside ResourceProxy). Otherwise, if you want to
|
||||
// fetch resources some times from real files, other times from embedded
|
||||
// resources, you may use the following methods:
|
||||
//
|
||||
// // Retrieve contents using embedded resources
|
||||
// std:string s = proxy.getString("/some/path", true);
|
||||
// std:string s = proxy.getStringDecideOnPrefix(":/some/path");
|
||||
//
|
||||
// // Retrieve contents using real files
|
||||
// std:string s = proxy.getString("/some/path", false);
|
||||
// std:string s = proxy.getStringDecideOnPrefix("/some/path");
|
||||
//
|
||||
// You can do exactly the same with ResourceProxy::getIStream() and
|
||||
// ResourceProxy::getIStreamDecideOnPrefix(), except they return an
|
||||
// std::unique_ptr<std::istream> instead of an std::string.
|
||||
//
|
||||
// Given how the 'proxy' object was constructed above, each of these calls
|
||||
// will fetch data from either the real file $FG_ROOT/some/path or the
|
||||
// embedded resource whose virtual path is '/FGData/some/path' (more
|
||||
// precisely: the default-locale version of this resource).
|
||||
//
|
||||
// The 'path' argument of ResourceProxy's methods getString(), getIStream(),
|
||||
// getStringDecideOnPrefix() and getIStreamDecideOnPrefix() must:
|
||||
//
|
||||
// - use UTF-8 encoding;
|
||||
//
|
||||
// - start with:
|
||||
// * either '/' or ':/' for the 'DecideOnPrefix' variants;
|
||||
// * only '/' for the other methods.
|
||||
//
|
||||
// - have its components separated by slashes;
|
||||
//
|
||||
// - not contain any '.' or '..' component.
|
||||
//
|
||||
// For the 'DecideOnPrefix' variants:
|
||||
//
|
||||
// - if the path starts with a slash ('/'), a real file access is done;
|
||||
//
|
||||
// - if, on the other hand, it starts with ':/', ResourceProxy uses the
|
||||
// embedded resource whose virtual path is the specified path without its
|
||||
// leading ':' (more precisely: the default-locale version of this
|
||||
// resource).
|
||||
namespace simgear
|
||||
{
|
||||
|
||||
class ResourceProxy
|
||||
{
|
||||
public:
|
||||
// 'virtualRoot' must start with a '/', e.g: '/FGData'. Whether it ends
|
||||
// with a '/' doesn't make a difference.
|
||||
explicit ResourceProxy(const SGPath& realRoot,
|
||||
const std::string& virtualRoot,
|
||||
bool useEmbeddedResourcesByDefault = true);
|
||||
|
||||
// Getters and setters for the corresponding data members
|
||||
SGPath getRealRoot() const;
|
||||
void setRealRoot(const SGPath& realRoot);
|
||||
|
||||
std::string getVirtualRoot() const;
|
||||
void setVirtualRoot(const std::string& virtualRoot);
|
||||
|
||||
bool getUseEmbeddedResources() const;
|
||||
void setUseEmbeddedResources(bool useEmbeddedResources);
|
||||
|
||||
// Get an std::istream to read from a file or from an embedded resource.
|
||||
std::unique_ptr<std::istream>
|
||||
getIStream(const std::string& path, bool fromEmbeddedResource) const;
|
||||
|
||||
std::unique_ptr<std::istream>
|
||||
getIStream(const std::string& path) const;
|
||||
|
||||
std::unique_ptr<std::istream>
|
||||
getIStreamDecideOnPrefix(const std::string& path) const;
|
||||
|
||||
// Get a file or embedded resource contents as a string.
|
||||
std::string
|
||||
getString(const std::string& path, bool fromEmbeddedResource) const;
|
||||
|
||||
std::string
|
||||
getString(const std::string& path) const;
|
||||
|
||||
std::string
|
||||
getStringDecideOnPrefix(const std::string& path) const;
|
||||
|
||||
private:
|
||||
// Check that 'path' starts with either ':/' or '/', and doesn't contain any
|
||||
// '..' component ('path' may only start with ':/' if 'allowStartWithColon'
|
||||
// is true).
|
||||
static void
|
||||
checkPath(const std::string& callerMethod, const std::string& path,
|
||||
bool allowStartWithColon);
|
||||
|
||||
// Normalize the 'virtualRoot' argument of the constructor. The argument
|
||||
// must start with a '/' and mustn't contain any '.' or '..' component. The
|
||||
// return value never ends with a '/'.
|
||||
static std::string
|
||||
normalizeVirtualRoot(const std::string& path);
|
||||
|
||||
SGPath _realRoot;
|
||||
std::string _virtualRoot;
|
||||
bool _useEmbeddedResourcesByDefault;
|
||||
};
|
||||
|
||||
} // of namespace simgear
|
||||
|
||||
#endif // of FG_RESOURCEPROXY_HXX
|
||||
@@ -33,11 +33,14 @@
|
||||
#include <cstddef> // std::size_t
|
||||
|
||||
#include <simgear/misc/test_macros.hxx>
|
||||
#include <simgear/misc/sg_dir.hxx>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
#include <simgear/io/iostreams/CharArrayStream.hxx>
|
||||
#include <simgear/io/iostreams/sgstream.hxx>
|
||||
#include <simgear/io/iostreams/zlibstream.hxx>
|
||||
#include "EmbeddedResource.hxx"
|
||||
#include "EmbeddedResourceManager.hxx"
|
||||
#include "ResourceProxy.hxx"
|
||||
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
@@ -395,6 +398,102 @@ void test_getLocaleAndSelectLocale()
|
||||
}
|
||||
}
|
||||
|
||||
// Auxiliary function for test_ResourceProxy()
|
||||
void auxTest_ResourceProxy_getIStream(unique_ptr<std::istream> iStream,
|
||||
const string& contents)
|
||||
{
|
||||
cout << "Testing ResourceProxy::getIStream()" << endl;
|
||||
|
||||
iStream->exceptions(std::ios_base::badbit);
|
||||
static constexpr std::size_t bufSize = 65536;
|
||||
unique_ptr<char[]> buf(new char[bufSize]); // intermediate buffer
|
||||
string result;
|
||||
|
||||
do {
|
||||
iStream->read(buf.get(), bufSize);
|
||||
result.append(buf.get(), iStream->gcount());
|
||||
} while (*iStream); // iStream *points* to an std::istream
|
||||
|
||||
// 1) If set, badbit would have caused an exception to be raised (see above).
|
||||
// 2) failbit doesn't necessarily indicate an error here: it is set as soon
|
||||
// as the read() call can't provide the requested number of characters.
|
||||
SG_VERIFY(iStream->eof() && !iStream->bad());
|
||||
SG_CHECK_EQUAL(result, contents);
|
||||
}
|
||||
|
||||
void test_ResourceProxy()
|
||||
{
|
||||
cout << "Testing the ResourceProxy class" << endl;
|
||||
|
||||
// Initialize stuff we need and create two files containing the contents of
|
||||
// the default-locale version of two embedded resources: those with virtual
|
||||
// paths '/path/to/resource1' and '/path/to/resource2'.
|
||||
const auto& resMgr = EmbeddedResourceManager::instance();
|
||||
simgear::Dir tmpDir = simgear::Dir::tempDir("FlightGear");
|
||||
tmpDir.setRemoveOnDestroy();
|
||||
|
||||
const SGPath path1 = tmpDir.path() / "resource1";
|
||||
const SGPath path2 = tmpDir.path() / "resource2";
|
||||
|
||||
sg_ofstream out1(path1);
|
||||
sg_ofstream out2(path2);
|
||||
const string s1 = resMgr->getString("/path/to/resource1", "");
|
||||
// To make sure in these tests that we can tell whether something came from
|
||||
// a real file or from an embedded resource.
|
||||
const string rs1 = s1 + " from real file";
|
||||
const string rlipsum = lipsum + " from real file";
|
||||
|
||||
out1 << rs1;
|
||||
out1.close();
|
||||
if (!out1) {
|
||||
throw sg_io_exception("Error writing to file", sg_location(path1));
|
||||
}
|
||||
|
||||
out2 << rlipsum;
|
||||
out2.close();
|
||||
if (!out2) {
|
||||
throw sg_io_exception("Error writing to file", sg_location(path2));
|
||||
}
|
||||
|
||||
// 'proxy' defaults to using embedded resources
|
||||
const simgear::ResourceProxy proxy(tmpDir.path(),
|
||||
"/path/to",
|
||||
true /* useEmbeddedResourcesByDefault */);
|
||||
simgear::ResourceProxy rproxy(tmpDir.path(), "/path/to");
|
||||
// 'rproxy' defaults to using real files
|
||||
rproxy.setUseEmbeddedResources(false); // could be done from the ctor too
|
||||
|
||||
// Test ResourceProxy::getString()
|
||||
SG_CHECK_EQUAL(proxy.getStringDecideOnPrefix("/resource1"), rs1);
|
||||
SG_CHECK_EQUAL(proxy.getStringDecideOnPrefix(":/resource1"), s1);
|
||||
SG_CHECK_EQUAL(proxy.getString("/resource1", false), rs1);
|
||||
SG_CHECK_EQUAL(proxy.getString("/resource1", true), s1);
|
||||
SG_CHECK_EQUAL(proxy.getString("/resource1"), s1);
|
||||
SG_CHECK_EQUAL(rproxy.getString("/resource1"), rs1);
|
||||
|
||||
SG_CHECK_EQUAL(proxy.getStringDecideOnPrefix("/resource2"), rlipsum);
|
||||
SG_CHECK_EQUAL(proxy.getStringDecideOnPrefix(":/resource2"), lipsum);
|
||||
SG_CHECK_EQUAL(proxy.getString("/resource2", false), rlipsum);
|
||||
SG_CHECK_EQUAL(proxy.getString("/resource2", true), lipsum);
|
||||
SG_CHECK_EQUAL(proxy.getString("/resource2"), lipsum);
|
||||
SG_CHECK_EQUAL(rproxy.getString("/resource2"), rlipsum);
|
||||
|
||||
// Test ResourceProxy::getIStream()
|
||||
auxTest_ResourceProxy_getIStream(proxy.getIStreamDecideOnPrefix("/resource1"),
|
||||
rs1);
|
||||
auxTest_ResourceProxy_getIStream(proxy.getIStreamDecideOnPrefix(":/resource1"),
|
||||
s1);
|
||||
auxTest_ResourceProxy_getIStream(proxy.getIStream("/resource1"), s1);
|
||||
auxTest_ResourceProxy_getIStream(rproxy.getIStream("/resource1"), rs1);
|
||||
|
||||
auxTest_ResourceProxy_getIStream(proxy.getIStream("/resource2", false),
|
||||
rlipsum);
|
||||
auxTest_ResourceProxy_getIStream(proxy.getIStream("/resource2", true),
|
||||
lipsum);
|
||||
auxTest_ResourceProxy_getIStream(proxy.getIStream("/resource2"), lipsum);
|
||||
auxTest_ResourceProxy_getIStream(rproxy.getIStream("/resource2"), rlipsum);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Initialize the EmbeddedResourceManager instance, add a few resources
|
||||
@@ -407,6 +506,7 @@ int main(int argc, char **argv)
|
||||
test_addAlreadyExistingResource();
|
||||
test_localeDependencyOfResourceFetching();
|
||||
test_getLocaleAndSelectLocale();
|
||||
test_ResourceProxy();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user