diff options
| author | Martin Owens <doctormo@gmail.com> | 2014-02-20 16:37:22 +0000 |
|---|---|---|
| committer | Martin Owens <doctormo@gmail.com> | 2014-02-20 16:37:22 +0000 |
| commit | 048e27577b22844eaaab36d1884a511092e6ddf7 (patch) | |
| tree | 659d26168e2df8b064f83d7aa9755ca804f7e004 /src | |
| parent | Fix for SPSwitch updates. (diff) | |
| download | inkscape-048e27577b22844eaaab36d1884a511092e6ddf7.tar.gz inkscape-048e27577b22844eaaab36d1884a511092e6ddf7.zip | |
Add test for URI and help with data uris.
(bzr r13045)
Diffstat (limited to 'src')
| -rw-r--r-- | src/uri-test.h | 90 | ||||
| -rw-r--r-- | src/uri.cpp | 50 | ||||
| -rw-r--r-- | src/uri.h | 2 |
3 files changed, 138 insertions, 4 deletions
diff --git a/src/uri-test.h b/src/uri-test.h new file mode 100644 index 000000000..2a4cdab46 --- /dev/null +++ b/src/uri-test.h @@ -0,0 +1,90 @@ + +#ifndef SEEN_URI_TEST_H +#define SEEN_URI_TEST_H +/* + * Test uri.h + * + * Written to aid with refactoring the uri handling to support fullPath + * and data URIs and also cover code which wasn't before tested. + * + * Copyright 2014 (c) BasisTech Boston + * + */ +#include <cxxtest/TestSuite.h> + +#include "uri.h" + +using Inkscape::URI; + +class URITest : public CxxTest::TestSuite +{ +public: + void stringTest( std::string result, std::string expected ) + { + if ( !result.empty() && !expected.empty() ) { + TS_ASSERT_EQUALS( result, expected ); + } else if ( result.empty() && !expected.empty() ) { + TS_FAIL( std::string("Expected (") + expected + "), found null" ); + } else if ( !result.empty() && expected.empty() ) { + TS_FAIL( std::string("Expected null, found (") + result + ")" ); + } + } + + std::string ValueOrEmpty(const char* s) { + return s == NULL ? std::string() : s; + } + + void toStringTest( std::string uri, std::string expected ) { + stringTest( URI(uri.c_str()).toString(), expected ); + } + void pathTest( std::string uri, std::string expected ) { + stringTest( ValueOrEmpty(URI(uri.c_str()).getPath()), expected ); + } + + void testToString() + { + char const* cases[][2] = { + { "foo", "foo" }, + { "#foo", "#foo" }, + { "blah.svg#h", "blah.svg#h" }, + //{ "data:data", "data:data" }, + }; + + for ( size_t i = 0; i < G_N_ELEMENTS(cases); i++ ) { + toStringTest( std::string(cases[i][0]), std::string(cases[i][1]) ); + } + } + + void testPath() + { + char const* cases[][2] = { + { "foo.svg", "foo.svg" }, + { "foo.svg#bar", "foo.svg" }, + { "#bar", NULL }, + { "data:data", NULL }, + }; + + for ( size_t i = 0; i < G_N_ELEMENTS(cases); i++ ) { + pathTest( ValueOrEmpty(cases[i][0]), ValueOrEmpty(cases[i][1]) ); + } + } + void testFullPath() { + std::ofstream fhl("/tmp/cxxtest-uri.svg", std::ofstream::out); + stringTest( URI("cxxtest-uri.svg").getFullPath("/tmp"), std::string("/tmp/cxxtest-uri.svg") ); + stringTest( URI("cxxtest-uri.svg").getFullPath("/usr/../tmp"), std::string("/tmp/cxxtest-uri.svg") ); + } + +}; + +#endif // SEEN_URI_TEST_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/uri.cpp b/src/uri.cpp index 89f6f33e4..a48aa8274 100644 --- a/src/uri.cpp +++ b/src/uri.cpp @@ -11,6 +11,8 @@ #include <glib.h> #include "uri.h" #include <string> +#include <cstring> +#include <iostream> // XXX #include <glibmm/ustring.h> #include <glibmm/miscutils.h> @@ -26,6 +28,10 @@ URI::URI(gchar const *preformed) throw(BadURIException) { if (!preformed) { throw MalformedURIException(); } + if( strncmp(preformed, "data:", 5)==0 ) { + parseDataUri( preformed + 5 ); + preformed = ""; // g_free? + } uri = xmlParseURI(preformed); if (!uri) { throw MalformedURIException(); @@ -135,6 +141,38 @@ gchar *URI::to_native_filename(gchar const* uri) throw(BadURIException) filename = tmp.toNativeFilename(); return filename; } + +/* + * Parse data:... uris so we can access their data transparently. + * otherwise data: is considered a malformed protocol like http: + * and two // as appended and the data is stored in the path of the uri. + */ +bool URI::parseDataUri(const char *uri) { + + int len = (strchr(uri, ',') - uri) * sizeof(char); + + const char *data; + std::string head; + if (len > 0) { + head = std::string(uri, len); + data = uri + len; + } else { + head = "text/plain"; + data = uri; + } + + //bool base64 = false; + std::cout << "Header: " << head << "\n"; + std::cout << "Data: " << data << "\n"; + /*while(uri < data) { + if (strncmp(uri,"base64",6) == 0) + base64 = true; + if (strncmp(uri,"image/", + data = strchr(uri, ';'); + }*/ + return true; +} + /* * Returns the absolute path to an existing file referenced in this URI, * if the uri is data, the path is empty or the file doesn't exist, then @@ -149,12 +187,16 @@ const std::string URI::getFullPath(std::string const base) const { if(!base.empty() && !path.empty() && path[0] != '/') { path = Glib::build_filename(base, path); } - // Check the existance of the file - if(! g_file_test(path.c_str(), G_FILE_TEST_EXISTS) - || g_file_test(path.c_str(), G_FILE_TEST_IS_DIR) ) { + // Normalise path, this only works if all parts of the path exist + char *output = realpath(path.c_str(), NULL); + if(output == NULL) { + path.clear(); + } else // Re-check the existance of the file (make damn sure) + if(! g_file_test(output, G_FILE_TEST_EXISTS) + || g_file_test(output, G_FILE_TEST_IS_DIR) ) { path.clear(); } - return path; + return std::string( output ); } @@ -121,6 +121,8 @@ public: URI &operator=(URI const &uri); private: + bool parseDataUri(const char *uri); + class Impl { public: static Impl *create(xmlURIPtr uri); |
