Kaydet (Commit) c36daa01 authored tarafından Stephan Bergmann's avatar Stephan Bergmann

Introduce INetContentType::scan

...for use in <https://gerrit.libreoffice.org/#/c/8737/> "new methodINetURLObject::getData()
for data urls."

Change-Id: Id381d7c328153fbea44c0efb80532b2961c6c2b7
üst 92ad689b
...@@ -253,8 +253,9 @@ public: ...@@ -253,8 +253,9 @@ public:
/** Parse the body of an RFC 2045 Content-Type header field. /** Parse the body of an RFC 2045 Content-Type header field.
@param rMediaType The body of the Content-Type header field. It must @param pBegin The range (that must be valid) from non-null pBegin,
be of the form 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)) token "/" token *(";" token "=" (token / quoted-string))
...@@ -263,21 +264,28 @@ public: ...@@ -263,21 +264,28 @@ public:
should be US-ASCII, but any Unicode values in the range U+0080..U+FFFF should be US-ASCII, but any Unicode values in the range U+0080..U+FFFF
are interpretet 'as appropriate.' are interpretet 'as appropriate.'
@param rType Returns the type (the first of the above tokens), in US- @param pType If not null, returns the type (the first of the above
ASCII encoding and converted to lower case.
@param rSubType Returns the sub type (the second of the above
tokens), in US-ASCII encoding and converted to lower case. 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 INetContentTypeParameters (the attributes are in US-ASCII encoding and
converted to lower case, the values are in Unicode encoding). If converted to lower case, the values are in Unicode encoding). If
null, only the syntax of the parameters is checked, but they are not null, only the syntax of the parameters is checked, but they are not
returned. returned.
@return True if the syntax of the field body is correct. If false is @return Null if the syntax of the field body is incorrect (i.e., does
returned, none of the output parameters will be modified! 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, static bool parse(OUString const & rMediaType, OUString & rType,
OUString & rSubType, OUString & rSubType,
INetContentTypeParameterList * pParameters = 0); INetContentTypeParameterList * pParameters = 0);
......
# -*- 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:
...@@ -32,6 +32,7 @@ $(eval $(call gb_Module_add_l10n_targets,svl,\ ...@@ -32,6 +32,7 @@ $(eval $(call gb_Module_add_l10n_targets,svl,\
$(eval $(call gb_Module_add_check_targets,svl,\ $(eval $(call gb_Module_add_check_targets,svl,\
CppunitTest_svl_lngmisc \ CppunitTest_svl_lngmisc \
CppunitTest_svl_qa_cppunit \ CppunitTest_svl_qa_cppunit \
CppunitTest_svl_inetcontenttype \
CppunitTest_svl_items \ CppunitTest_svl_items \
)) ))
......
/* -*- 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: */
...@@ -779,46 +779,66 @@ bool INetContentTypes::GetExtensionFromURL(OUString const & rURL, ...@@ -779,46 +779,66 @@ bool INetContentTypes::GetExtensionFromURL(OUString const & rURL,
} }
// static // static
bool INetContentTypes::parse(OUString const & rMediaType, sal_Unicode const * INetContentTypes::scan(
OUString & rType, OUString & rSubType, sal_Unicode const * pBegin, sal_Unicode const * pEnd, OUString * pType,
INetContentTypeParameterList * pParameters) OUString * pSubType, INetContentTypeParameterList * pParameters)
{ {
sal_Unicode const * p = rMediaType.getStr(); sal_Unicode const * p = INetMIME::skipLinearWhiteSpaceComment(pBegin, pEnd);
sal_Unicode const * pEnd = p + rMediaType.getLength(); sal_Unicode const * pTypeBegin = p;
p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd);
sal_Unicode const * pToken = p;
bool bDowncase = false;
while (p != pEnd && INetMIME::isTokenChar(*p)) while (p != pEnd && INetMIME::isTokenChar(*p))
{ {
bDowncase = bDowncase || rtl::isAsciiUpperCase(*p);
++p; ++p;
} }
if (p == pToken) if (p == pTypeBegin)
return false; return 0;
rType = OUString(pToken, p - pToken); sal_Unicode const * pTypeEnd = p;
if (bDowncase)
rType= rType.toAsciiLowerCase();
p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd);
if (p == pEnd || *p++ != '/') if (p == pEnd || *p++ != '/')
return false; return 0;
p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd);
pToken = p; sal_Unicode const * pSubTypeBegin = p;
bDowncase = false;
while (p != pEnd && INetMIME::isTokenChar(*p)) while (p != pEnd && INetMIME::isTokenChar(*p))
{ {
bDowncase = bDowncase || rtl::isAsciiUpperCase(*p);
++p; ++p;
} }
if (p == pToken) if (p == pSubTypeBegin)
return false; return 0;
rSubType = OUString(pToken, p - pToken); sal_Unicode const * pSubTypeEnd = p;
if (bDowncase)
rSubType = rSubType.toAsciiLowerCase(); if (pType != 0)
{
*pType = OUString(pTypeBegin, pTypeEnd - pTypeBegin).toAsciiLowerCase();
}
if (pSubType != 0)
{
*pSubType = OUString(pSubTypeBegin, pSubTypeEnd - pSubTypeBegin)
.toAsciiLowerCase();
}
return INetMIME::scanParameters(p, pEnd, pParameters) == pEnd; 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: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment