summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2014-03-27 18:05:51 +0100
committerStephan Bergmann <sbergman@redhat.com>2014-03-27 18:06:27 +0100
commitc36daa01f444ebad799c1cc7a106f1b4bb3c3d12 (patch)
treedf0326a5b76d4b69b5661a57b64f5c6dd5314523
parent92ad689bcb3ad16bd35302e6ff4ee45b872c05a0 (diff)
Introduce INetContentType::scan
...for use in <https://gerrit.libreoffice.org/#/c/8737/> "new methodINetURLObject::getData() for data urls." Change-Id: Id381d7c328153fbea44c0efb80532b2961c6c2b7
-rw-r--r--include/svl/inettype.hxx26
-rw-r--r--svl/CppunitTest_svl_inetcontenttype.mk30
-rw-r--r--svl/Module_svl.mk1
-rw-r--r--svl/qa/unit/test_INetContentType.cxx92
-rw-r--r--svl/source/misc/inettype.cxx70
5 files changed, 185 insertions, 34 deletions
diff --git a/include/svl/inettype.hxx b/include/svl/inettype.hxx
index a69572b00222..b09261eb0dcd 100644
--- a/include/svl/inettype.hxx
+++ b/include/svl/inettype.hxx
@@ -253,8 +253,9 @@ public:
/** Parse the body of an RFC 2045 Content-Type header field.
- @param rMediaType The body of the Content-Type header field. It must
- be of the form
+ @param pBegin The range (that must be valid) from non-null pBegin,
+ inclusive. to non-null pEnd, exclusive, forms the body of the
+ Content-Type header field. It must be of the form
token "/" token *(";" token "=" (token / quoted-string))
@@ -263,21 +264,28 @@ public:
should be US-ASCII, but any Unicode values in the range U+0080..U+FFFF
are interpretet 'as appropriate.'
- @param rType Returns the type (the first of the above tokens), in US-
- ASCII encoding and converted to lower case.
-
- @param rSubType Returns the sub type (the second of the above
+ @param pType If not null, returns the type (the first of the above
tokens), in US-ASCII encoding and converted to lower case.
- @param rParameters If not null, returns the parameters as a list of
+ @param pSubType If not null, returns the sub-type (the second of the
+ above tokens), in US-ASCII encoding and converted to lower case.
+
+ @param pParameters If not null, returns the parameters as a list of
INetContentTypeParameters (the attributes are in US-ASCII encoding and
converted to lower case, the values are in Unicode encoding). If
null, only the syntax of the parameters is checked, but they are not
returned.
- @return True if the syntax of the field body is correct. If false is
- returned, none of the output parameters will be modified!
+ @return Null if the syntax of the field body is incorrect (i.e., does
+ not start with type and sub-type tokens). Otherwise, a pointer past the
+ longest valid input prefix. If null is returned, none of the output
+ parameters will be modified.
*/
+ static sal_Unicode const * scan(
+ sal_Unicode const *pBegin, sal_Unicode const * pEnd,
+ OUString * pType = 0, OUString * pSubType = 0,
+ INetContentTypeParameterList * pParameters = 0);
+
static bool parse(OUString const & rMediaType, OUString & rType,
OUString & rSubType,
INetContentTypeParameterList * pParameters = 0);
diff --git a/svl/CppunitTest_svl_inetcontenttype.mk b/svl/CppunitTest_svl_inetcontenttype.mk
new file mode 100644
index 000000000000..30cd296c0ae0
--- /dev/null
+++ b/svl/CppunitTest_svl_inetcontenttype.mk
@@ -0,0 +1,30 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_CppunitTest_CppunitTest,svl_inetcontenttype))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,svl_inetcontenttype, \
+ svl/qa/unit/test_INetContentType \
+))
+
+$(eval $(call gb_CppunitTest_use_api,svl_inetcontenttype, \
+ udkapi \
+))
+
+$(eval $(call gb_CppunitTest_use_externals,svl_inetcontenttype, \
+ boost_headers \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,svl_inetcontenttype, \
+ sal \
+ svl \
+ tl \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/svl/Module_svl.mk b/svl/Module_svl.mk
index 2e5e6a06dae3..f52c7a4bfb72 100644
--- a/svl/Module_svl.mk
+++ b/svl/Module_svl.mk
@@ -32,6 +32,7 @@ $(eval $(call gb_Module_add_l10n_targets,svl,\
$(eval $(call gb_Module_add_check_targets,svl,\
CppunitTest_svl_lngmisc \
CppunitTest_svl_qa_cppunit \
+ CppunitTest_svl_inetcontenttype \
CppunitTest_svl_items \
))
diff --git a/svl/qa/unit/test_INetContentType.cxx b/svl/qa/unit/test_INetContentType.cxx
new file mode 100644
index 000000000000..a2ce362a10a0
--- /dev/null
+++ b/svl/qa/unit/test_INetContentType.cxx
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+
+#include <cstring>
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/TestSuite.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+#include <rtl/ustring.hxx>
+#include <svl/inettype.hxx>
+#include <tools/inetmime.hxx>
+
+namespace {
+
+class Test: public CppUnit::TestFixture {
+public:
+ void testBad();
+
+ void testFull();
+
+ void testFollow();
+
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(testBad);
+ CPPUNIT_TEST(testFull);
+ CPPUNIT_TEST(testFollow);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void Test::testBad() {
+ OUString in("foo=bar");
+ CPPUNIT_ASSERT_EQUAL(
+ static_cast<sal_Unicode const *>(0),
+ INetContentTypes::scan(in.getStr(), in.getStr() + in.getLength()));
+ OUString t;
+ OUString s;
+ INetContentTypeParameterList ps;
+ CPPUNIT_ASSERT(!INetContentTypes::parse(in, t, s, &ps));
+ CPPUNIT_ASSERT(t.isEmpty());
+ CPPUNIT_ASSERT(s.isEmpty());
+ CPPUNIT_ASSERT_EQUAL(
+ static_cast<INetContentTypeParameter const *>(0), ps.find("foo"));
+}
+
+void Test::testFull() {
+ OUString in("foo/bar;baz=boz");
+ CPPUNIT_ASSERT_EQUAL(
+ in.getStr() + in.getLength(),
+ INetContentTypes::scan(in.getStr(), in.getStr() + in.getLength()));
+ OUString t;
+ OUString s;
+ INetContentTypeParameterList ps;
+ CPPUNIT_ASSERT(INetContentTypes::parse(in, t, s, &ps));
+ CPPUNIT_ASSERT_EQUAL(OUString("foo"), t);
+ CPPUNIT_ASSERT_EQUAL(OUString("bar"), s);
+ INetContentTypeParameter const * p = ps.find("baz");
+ CPPUNIT_ASSERT(p != 0);
+ CPPUNIT_ASSERT_EQUAL(OUString("boz"), p->m_sValue);
+}
+
+void Test::testFollow() {
+ OUString in("foo/bar;baz=boz;base64,");
+ CPPUNIT_ASSERT_EQUAL(
+ in.getStr() + std::strlen("foo/bar;baz=boz"),
+ INetContentTypes::scan(in.getStr(), in.getStr() + in.getLength()));
+ OUString t;
+ OUString s;
+ INetContentTypeParameterList ps;
+ CPPUNIT_ASSERT(!INetContentTypes::parse(in, t, s));
+ CPPUNIT_ASSERT(t.isEmpty());
+ CPPUNIT_ASSERT(s.isEmpty());
+ CPPUNIT_ASSERT_EQUAL(
+ static_cast<INetContentTypeParameter const *>(0), ps.find("baz"));
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/misc/inettype.cxx b/svl/source/misc/inettype.cxx
index 310d5088efd5..bfd812e3da15 100644
--- a/svl/source/misc/inettype.cxx
+++ b/svl/source/misc/inettype.cxx
@@ -779,46 +779,66 @@ bool INetContentTypes::GetExtensionFromURL(OUString const & rURL,
}
// static
-bool INetContentTypes::parse(OUString const & rMediaType,
- OUString & rType, OUString & rSubType,
- INetContentTypeParameterList * pParameters)
+sal_Unicode const * INetContentTypes::scan(
+ sal_Unicode const * pBegin, sal_Unicode const * pEnd, OUString * pType,
+ OUString * pSubType, INetContentTypeParameterList * pParameters)
{
- sal_Unicode const * p = rMediaType.getStr();
- sal_Unicode const * pEnd = p + rMediaType.getLength();
-
- p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd);
- sal_Unicode const * pToken = p;
- bool bDowncase = false;
+ sal_Unicode const * p = INetMIME::skipLinearWhiteSpaceComment(pBegin, pEnd);
+ sal_Unicode const * pTypeBegin = p;
while (p != pEnd && INetMIME::isTokenChar(*p))
{
- bDowncase = bDowncase || rtl::isAsciiUpperCase(*p);
++p;
}
- if (p == pToken)
- return false;
- rType = OUString(pToken, p - pToken);
- if (bDowncase)
- rType= rType.toAsciiLowerCase();
+ if (p == pTypeBegin)
+ return 0;
+ sal_Unicode const * pTypeEnd = p;
p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd);
if (p == pEnd || *p++ != '/')
- return false;
+ return 0;
p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd);
- pToken = p;
- bDowncase = false;
+ sal_Unicode const * pSubTypeBegin = p;
while (p != pEnd && INetMIME::isTokenChar(*p))
{
- bDowncase = bDowncase || rtl::isAsciiUpperCase(*p);
++p;
}
- if (p == pToken)
- return false;
- rSubType = OUString(pToken, p - pToken);
- if (bDowncase)
- rSubType = rSubType.toAsciiLowerCase();
+ if (p == pSubTypeBegin)
+ return 0;
+ sal_Unicode const * pSubTypeEnd = p;
- return INetMIME::scanParameters(p, pEnd, pParameters) == pEnd;
+ if (pType != 0)
+ {
+ *pType = OUString(pTypeBegin, pTypeEnd - pTypeBegin).toAsciiLowerCase();
+ }
+ if (pSubType != 0)
+ {
+ *pSubType = OUString(pSubTypeBegin, pSubTypeEnd - pSubTypeBegin)
+ .toAsciiLowerCase();
+ }
+
+ return INetMIME::scanParameters(p, pEnd, pParameters);
+}
+
+bool INetContentTypes::parse(
+ OUString const & rMediaType, OUString & rType, OUString & rSubType,
+ INetContentTypeParameterList * pParameters)
+{
+ sal_Unicode const * b = rMediaType.getStr();
+ sal_Unicode const * e = b + rMediaType.getLength();
+ OUString t;
+ OUString s;
+ INetContentTypeParameterList p;
+ if (scan(b, e, &t, &s, pParameters == 0 ? 0 : &p) == e) {
+ rType = t;
+ rSubType = s;
+ if (pParameters != 0) {
+ *pParameters = p;
+ }
+ return true;
+ } else {
+ return false;
+ }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */