1*40df464eSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*40df464eSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*40df464eSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*40df464eSAndrew Rist * distributed with this work for additional information 6*40df464eSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*40df464eSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*40df464eSAndrew Rist * "License"); you may not use this file except in compliance 9*40df464eSAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*40df464eSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*40df464eSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*40df464eSAndrew Rist * software distributed under the License is distributed on an 15*40df464eSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*40df464eSAndrew Rist * KIND, either express or implied. See the License for the 17*40df464eSAndrew Rist * specific language governing permissions and limitations 18*40df464eSAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*40df464eSAndrew Rist *************************************************************/ 21*40df464eSAndrew Rist 22*40df464eSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_svl.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "sal/config.h" 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include <cstddef> 30cdf0e10cSrcweir 31cdf0e10cSrcweir #include "com/sun/star/lang/Locale.hpp" 32cdf0e10cSrcweir #include "com/sun/star/lang/XComponent.hpp" 33cdf0e10cSrcweir #include "com/sun/star/lang/XMultiComponentFactory.hpp" 34cdf0e10cSrcweir #include "com/sun/star/lang/XMultiServiceFactory.hpp" 35cdf0e10cSrcweir #include "com/sun/star/ucb/Command.hpp" 36cdf0e10cSrcweir #include "com/sun/star/ucb/CommandAbortedException.hpp" 37cdf0e10cSrcweir #include "com/sun/star/ucb/IllegalIdentifierException.hpp" 38cdf0e10cSrcweir #include "com/sun/star/ucb/XCommandProcessor.hpp" 39cdf0e10cSrcweir #include "com/sun/star/ucb/XContent.hpp" 40cdf0e10cSrcweir #include "com/sun/star/ucb/XContentIdentifier.hpp" 41cdf0e10cSrcweir #include "com/sun/star/ucb/XContentProvider.hpp" 42cdf0e10cSrcweir #include "com/sun/star/ucb/XContentProviderManager.hpp" 43cdf0e10cSrcweir #include "com/sun/star/uno/Any.hxx" 44cdf0e10cSrcweir #include "com/sun/star/uno/Exception.hpp" 45cdf0e10cSrcweir #include "com/sun/star/uno/Reference.hxx" 46cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp" 47cdf0e10cSrcweir #include "com/sun/star/uno/Sequence.hxx" 48cdf0e10cSrcweir #include "com/sun/star/uno/XComponentContext.hpp" 49cdf0e10cSrcweir #include "com/sun/star/uri/XUriReference.hpp" 50cdf0e10cSrcweir #include "cppuhelper/bootstrap.hxx" 51cdf0e10cSrcweir #include "cppuhelper/implbase1.hxx" 52cdf0e10cSrcweir #include "cppuhelper/implbase2.hxx" 53cdf0e10cSrcweir #include "testshl/simpleheader.hxx" 54cdf0e10cSrcweir #include "osl/diagnose.h" 55cdf0e10cSrcweir #include "rtl/strbuf.hxx" 56cdf0e10cSrcweir #include "rtl/string.h" 57cdf0e10cSrcweir #include "rtl/string.hxx" 58cdf0e10cSrcweir #include "rtl/textenc.h" 59cdf0e10cSrcweir #include "rtl/ustring.h" 60cdf0e10cSrcweir #include "rtl/ustring.hxx" 61cdf0e10cSrcweir #include "sal/types.h" 62cdf0e10cSrcweir #include "tools/solar.h" 63cdf0e10cSrcweir #include "unotools/charclass.hxx" 64cdf0e10cSrcweir 65cdf0e10cSrcweir #include "urihelper.hxx" 66cdf0e10cSrcweir 67cdf0e10cSrcweir // This test needs a UNO component context that supports various services (the 68cdf0e10cSrcweir // UCB, an UriReferenceFactory, ...), so it is best executed within an OOo 69cdf0e10cSrcweir // installation. 70cdf0e10cSrcweir 71cdf0e10cSrcweir namespace com { namespace sun { namespace star { namespace ucb { 72cdf0e10cSrcweir class XCommandEnvironment; 73cdf0e10cSrcweir class XContentEventListener; 74cdf0e10cSrcweir } } } } 75cdf0e10cSrcweir 76cdf0e10cSrcweir namespace { 77cdf0e10cSrcweir 78cdf0e10cSrcweir namespace css = com::sun::star; 79cdf0e10cSrcweir 80cdf0e10cSrcweir // This class only implements that subset of functionality of a proper 81cdf0e10cSrcweir // css::ucb::Content that is known to be needed here: 82cdf0e10cSrcweir class Content: 83cdf0e10cSrcweir public cppu::WeakImplHelper2< 84cdf0e10cSrcweir css::ucb::XContent, css::ucb::XCommandProcessor > 85cdf0e10cSrcweir { 86cdf0e10cSrcweir public: 87cdf0e10cSrcweir explicit Content( 88cdf0e10cSrcweir css::uno::Reference< css::ucb::XContentIdentifier > const & identifier); 89cdf0e10cSrcweir 90cdf0e10cSrcweir virtual css::uno::Reference< css::ucb::XContentIdentifier > SAL_CALL 91cdf0e10cSrcweir getIdentifier() throw (css::uno::RuntimeException) { 92cdf0e10cSrcweir return m_identifier; 93cdf0e10cSrcweir } 94cdf0e10cSrcweir 95cdf0e10cSrcweir virtual rtl::OUString SAL_CALL getContentType() 96cdf0e10cSrcweir throw (css::uno::RuntimeException) 97cdf0e10cSrcweir { 98cdf0e10cSrcweir return rtl::OUString(); 99cdf0e10cSrcweir } 100cdf0e10cSrcweir 101cdf0e10cSrcweir virtual void SAL_CALL addContentEventListener( 102cdf0e10cSrcweir css::uno::Reference< css::ucb::XContentEventListener > const &) 103cdf0e10cSrcweir throw (css::uno::RuntimeException) 104cdf0e10cSrcweir {} 105cdf0e10cSrcweir 106cdf0e10cSrcweir virtual void SAL_CALL removeContentEventListener( 107cdf0e10cSrcweir css::uno::Reference< css::ucb::XContentEventListener > const &) 108cdf0e10cSrcweir throw (css::uno::RuntimeException) 109cdf0e10cSrcweir {} 110cdf0e10cSrcweir 111cdf0e10cSrcweir virtual sal_Int32 SAL_CALL createCommandIdentifier() 112cdf0e10cSrcweir throw (css::uno::RuntimeException) 113cdf0e10cSrcweir { 114cdf0e10cSrcweir return 0; 115cdf0e10cSrcweir } 116cdf0e10cSrcweir 117cdf0e10cSrcweir virtual css::uno::Any SAL_CALL execute( 118cdf0e10cSrcweir css::ucb::Command const & command, sal_Int32 commandId, 119cdf0e10cSrcweir css::uno::Reference< css::ucb::XCommandEnvironment > const &) 120cdf0e10cSrcweir throw ( 121cdf0e10cSrcweir css::uno::Exception, css::ucb::CommandAbortedException, 122cdf0e10cSrcweir css::uno::RuntimeException); 123cdf0e10cSrcweir 124cdf0e10cSrcweir virtual void SAL_CALL abort(sal_Int32) throw (css::uno::RuntimeException) {} 125cdf0e10cSrcweir 126cdf0e10cSrcweir private: 127cdf0e10cSrcweir static char const m_prefix[]; 128cdf0e10cSrcweir 129cdf0e10cSrcweir css::uno::Reference< css::ucb::XContentIdentifier > m_identifier; 130cdf0e10cSrcweir }; 131cdf0e10cSrcweir 132cdf0e10cSrcweir char const Content::m_prefix[] = "test:"; 133cdf0e10cSrcweir 134cdf0e10cSrcweir Content::Content( 135cdf0e10cSrcweir css::uno::Reference< css::ucb::XContentIdentifier > const & identifier): 136cdf0e10cSrcweir m_identifier(identifier) 137cdf0e10cSrcweir { 138cdf0e10cSrcweir OSL_ASSERT(m_identifier.is()); 139cdf0e10cSrcweir rtl::OUString uri(m_identifier->getContentIdentifier()); 140cdf0e10cSrcweir if (!uri.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM(m_prefix)) 141cdf0e10cSrcweir || uri.indexOf('#', RTL_CONSTASCII_LENGTH(m_prefix)) != -1) 142cdf0e10cSrcweir { 143cdf0e10cSrcweir throw css::ucb::IllegalIdentifierException(); 144cdf0e10cSrcweir } 145cdf0e10cSrcweir } 146cdf0e10cSrcweir 147cdf0e10cSrcweir css::uno::Any Content::execute( 148cdf0e10cSrcweir css::ucb::Command const & command, sal_Int32, 149cdf0e10cSrcweir css::uno::Reference< css::ucb::XCommandEnvironment > const &) 150cdf0e10cSrcweir throw ( 151cdf0e10cSrcweir css::uno::Exception, css::ucb::CommandAbortedException, 152cdf0e10cSrcweir css::uno::RuntimeException) 153cdf0e10cSrcweir { 154cdf0e10cSrcweir if (!command.Name.equalsAsciiL( 155cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM("getCasePreservingURL"))) 156cdf0e10cSrcweir { 157cdf0e10cSrcweir throw css::uno::RuntimeException(); 158cdf0e10cSrcweir } 159cdf0e10cSrcweir // If any non-empty segment starts with anything but '0', '1', or '2', fail; 160cdf0e10cSrcweir // otherwise, if the last non-empty segment starts with '1', add a final 161cdf0e10cSrcweir // slash, and if the last non-empty segment starts with '2', remove a final 162cdf0e10cSrcweir // slash (if any); also, turn the given uri into all-lowercase: 163cdf0e10cSrcweir rtl::OUString uri(m_identifier->getContentIdentifier()); 164cdf0e10cSrcweir sal_Unicode c = '0'; 165cdf0e10cSrcweir for (sal_Int32 i = RTL_CONSTASCII_LENGTH(m_prefix); i != -1;) { 166cdf0e10cSrcweir rtl::OUString seg(uri.getToken(0, '/', i)); 167cdf0e10cSrcweir if (seg.getLength() > 0) { 168cdf0e10cSrcweir c = seg[0]; 169cdf0e10cSrcweir if (c < '0' || c > '2') { 170cdf0e10cSrcweir throw css::uno::Exception(); 171cdf0e10cSrcweir } 172cdf0e10cSrcweir } 173cdf0e10cSrcweir } 174cdf0e10cSrcweir switch (c) { 175cdf0e10cSrcweir case '1': 176cdf0e10cSrcweir uri += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")); 177cdf0e10cSrcweir break; 178cdf0e10cSrcweir case '2': 179cdf0e10cSrcweir if (uri.getLength() > 0 && uri[uri.getLength() - 1] == '/') { 180cdf0e10cSrcweir uri = uri.copy(0, uri.getLength() -1); 181cdf0e10cSrcweir } 182cdf0e10cSrcweir break; 183cdf0e10cSrcweir } 184cdf0e10cSrcweir return css::uno::makeAny(uri.toAsciiLowerCase()); 185cdf0e10cSrcweir } 186cdf0e10cSrcweir 187cdf0e10cSrcweir class Provider: public cppu::WeakImplHelper1< css::ucb::XContentProvider > { 188cdf0e10cSrcweir public: 189cdf0e10cSrcweir virtual css::uno::Reference< css::ucb::XContent > SAL_CALL queryContent( 190cdf0e10cSrcweir css::uno::Reference< css::ucb::XContentIdentifier > const & identifier) 191cdf0e10cSrcweir throw (css::ucb::IllegalIdentifierException, css::uno::RuntimeException) 192cdf0e10cSrcweir { 193cdf0e10cSrcweir return new Content(identifier); 194cdf0e10cSrcweir } 195cdf0e10cSrcweir 196cdf0e10cSrcweir virtual sal_Int32 SAL_CALL compareContentIds( 197cdf0e10cSrcweir css::uno::Reference< css::ucb::XContentIdentifier > const & id1, 198cdf0e10cSrcweir css::uno::Reference< css::ucb::XContentIdentifier > const & id2) 199cdf0e10cSrcweir throw (css::uno::RuntimeException) 200cdf0e10cSrcweir { 201cdf0e10cSrcweir OSL_ASSERT(id1.is() && id2.is()); 202cdf0e10cSrcweir return 203cdf0e10cSrcweir id1->getContentIdentifier().compareTo(id2->getContentIdentifier()); 204cdf0e10cSrcweir } 205cdf0e10cSrcweir }; 206cdf0e10cSrcweir 207cdf0e10cSrcweir class Test: public CppUnit::TestFixture { 208cdf0e10cSrcweir public: 209cdf0e10cSrcweir virtual void setUp(); 210cdf0e10cSrcweir 211cdf0e10cSrcweir void finish(); 212cdf0e10cSrcweir 213cdf0e10cSrcweir void testNormalizedMakeRelative(); 214cdf0e10cSrcweir 215cdf0e10cSrcweir void testFindFirstURLInText(); 216cdf0e10cSrcweir 217cdf0e10cSrcweir CPPUNIT_TEST_SUITE(Test); 218cdf0e10cSrcweir CPPUNIT_TEST(testNormalizedMakeRelative); 219cdf0e10cSrcweir CPPUNIT_TEST(testFindFirstURLInText); 220cdf0e10cSrcweir CPPUNIT_TEST(finish); 221cdf0e10cSrcweir CPPUNIT_TEST_SUITE_END(); 222cdf0e10cSrcweir 223cdf0e10cSrcweir private: 224cdf0e10cSrcweir static css::uno::Reference< css::uno::XComponentContext > m_context; 225cdf0e10cSrcweir }; 226cdf0e10cSrcweir 227cdf0e10cSrcweir void Test::setUp() { 228cdf0e10cSrcweir // For whatever reason, on W32 it does not work to create/destroy a fresh 229cdf0e10cSrcweir // component context for each test in Test::setUp/tearDown; therefore, a 230cdf0e10cSrcweir // single component context is used for all tests and destroyed in the last 231cdf0e10cSrcweir // pseudo-test "finish": 232cdf0e10cSrcweir if (!m_context.is()) { 233cdf0e10cSrcweir m_context = cppu::defaultBootstrap_InitialComponentContext(); 234cdf0e10cSrcweir } 235cdf0e10cSrcweir } 236cdf0e10cSrcweir 237cdf0e10cSrcweir void Test::finish() { 238cdf0e10cSrcweir css::uno::Reference< css::lang::XComponent >( 239cdf0e10cSrcweir m_context, css::uno::UNO_QUERY_THROW)->dispose(); 240cdf0e10cSrcweir } 241cdf0e10cSrcweir 242cdf0e10cSrcweir void Test::testNormalizedMakeRelative() { 243cdf0e10cSrcweir css::uno::Sequence< css::uno::Any > args(2); 244cdf0e10cSrcweir args[0] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Local")); 245cdf0e10cSrcweir args[1] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Office")); 246cdf0e10cSrcweir css::uno::Reference< css::ucb::XContentProviderManager >( 247cdf0e10cSrcweir (css::uno::Reference< css::lang::XMultiComponentFactory >( 248cdf0e10cSrcweir m_context->getServiceManager(), css::uno::UNO_QUERY_THROW)-> 249cdf0e10cSrcweir createInstanceWithArgumentsAndContext( 250cdf0e10cSrcweir rtl::OUString( 251cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM( 252cdf0e10cSrcweir "com.sun.star.ucb.UniversalContentBroker")), 253cdf0e10cSrcweir args, m_context)), 254cdf0e10cSrcweir css::uno::UNO_QUERY_THROW)->registerContentProvider( 255cdf0e10cSrcweir new Provider, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("test")), 256cdf0e10cSrcweir true); 257cdf0e10cSrcweir struct Test { 258cdf0e10cSrcweir char const * base; 259cdf0e10cSrcweir char const * absolute; 260cdf0e10cSrcweir char const * relative; 261cdf0e10cSrcweir }; 262cdf0e10cSrcweir static Test const tests[] = { 263cdf0e10cSrcweir { "hierarchical:/", "mailto:def@a.b.c.", "mailto:def@a.b.c." }, 264cdf0e10cSrcweir { "hierarchical:/", "a/b/c", "a/b/c" }, 265cdf0e10cSrcweir { "hierarchical:/a", "hierarchical:/a/b/c?d#e", "/a/b/c?d#e" }, 266cdf0e10cSrcweir { "hierarchical:/a/", "hierarchical:/a/b/c?d#e", "b/c?d#e" }, 267cdf0e10cSrcweir { "test:/0/0/a", "test:/0/b", "../b" }, 268cdf0e10cSrcweir { "test:/1/1/a", "test:/1/b", "../b" }, 269cdf0e10cSrcweir { "test:/2/2//a", "test:/2/b", "../../b" }, 270cdf0e10cSrcweir { "test:/0a/b", "test:/0A/c#f", "c#f" }, 271cdf0e10cSrcweir { "file:///usr/bin/nonex1/nonex2", 272cdf0e10cSrcweir "file:///usr/bin/nonex1/nonex3/nonex4", "nonex3/nonex4" }, 273cdf0e10cSrcweir { "file:///usr/bin/nonex1/nonex2#fragmentA", 274cdf0e10cSrcweir "file:///usr/bin/nonex1/nonex3/nonex4#fragmentB", 275cdf0e10cSrcweir "nonex3/nonex4#fragmentB" }, 276cdf0e10cSrcweir { "file:///usr/nonex1/nonex2", "file:///usr/nonex3", "../nonex3" }, 277cdf0e10cSrcweir { "file:///c:/windows/nonex1", "file:///c:/nonex2", "../nonex2" }, 278cdf0e10cSrcweir #if defined WNT 279cdf0e10cSrcweir { "file:///c:/nonex1/nonex2", "file:///C:/nonex1/nonex3/nonex4", 280cdf0e10cSrcweir "nonex3/nonex4" } 281cdf0e10cSrcweir #endif 282cdf0e10cSrcweir }; 283cdf0e10cSrcweir for (std::size_t i = 0; i < sizeof tests / sizeof tests[0]; ++i) { 284cdf0e10cSrcweir css::uno::Reference< css::uri::XUriReference > ref( 285cdf0e10cSrcweir URIHelper::normalizedMakeRelative( 286cdf0e10cSrcweir m_context, rtl::OUString::createFromAscii(tests[i].base), 287cdf0e10cSrcweir rtl::OUString::createFromAscii(tests[i].absolute))); 288cdf0e10cSrcweir bool ok = tests[i].relative == 0 289cdf0e10cSrcweir ? !ref.is() 290cdf0e10cSrcweir : ref.is() && ref->getUriReference().equalsAscii(tests[i].relative); 291cdf0e10cSrcweir rtl::OString msg; 292cdf0e10cSrcweir if (!ok) { 293cdf0e10cSrcweir rtl::OStringBuffer buf; 294cdf0e10cSrcweir buf.append('<'); 295cdf0e10cSrcweir buf.append(tests[i].base); 296cdf0e10cSrcweir buf.append(RTL_CONSTASCII_STRINGPARAM(">, <")); 297cdf0e10cSrcweir buf.append(tests[i].absolute); 298cdf0e10cSrcweir buf.append(RTL_CONSTASCII_STRINGPARAM(">: ")); 299cdf0e10cSrcweir if (ref.is()) { 300cdf0e10cSrcweir buf.append('<'); 301cdf0e10cSrcweir buf.append( 302cdf0e10cSrcweir rtl::OUStringToOString( 303cdf0e10cSrcweir ref->getUriReference(), RTL_TEXTENCODING_UTF8)); 304cdf0e10cSrcweir buf.append('>'); 305cdf0e10cSrcweir } else { 306cdf0e10cSrcweir buf.append(RTL_CONSTASCII_STRINGPARAM("none")); 307cdf0e10cSrcweir } 308cdf0e10cSrcweir buf.append(RTL_CONSTASCII_STRINGPARAM(" instead of ")); 309cdf0e10cSrcweir if (tests[i].relative == 0) { 310cdf0e10cSrcweir buf.append(RTL_CONSTASCII_STRINGPARAM("none")); 311cdf0e10cSrcweir } else { 312cdf0e10cSrcweir buf.append('<'); 313cdf0e10cSrcweir buf.append(tests[i].relative); 314cdf0e10cSrcweir buf.append('>'); 315cdf0e10cSrcweir } 316cdf0e10cSrcweir msg = buf.makeStringAndClear(); 317cdf0e10cSrcweir } 318cdf0e10cSrcweir CPPUNIT_ASSERT_MESSAGE(msg.getStr(), ok); 319cdf0e10cSrcweir } 320cdf0e10cSrcweir } 321cdf0e10cSrcweir 322cdf0e10cSrcweir void Test::testFindFirstURLInText() { 323cdf0e10cSrcweir struct Test { 324cdf0e10cSrcweir char const * input; 325cdf0e10cSrcweir char const * result; 326cdf0e10cSrcweir xub_StrLen begin; 327cdf0e10cSrcweir xub_StrLen end; 328cdf0e10cSrcweir }; 329cdf0e10cSrcweir static Test const tests[] = { 330cdf0e10cSrcweir { "...ftp://bla.bla.bla/blubber/...", 331cdf0e10cSrcweir "ftp://bla.bla.bla/blubber/", 3, 29 }, 332cdf0e10cSrcweir { "..\\ftp://bla.bla.bla/blubber/...", 0, 0, 0 }, 333cdf0e10cSrcweir { "..\\ftp:\\\\bla.bla.bla\\blubber/...", 334cdf0e10cSrcweir "file://bla.bla.bla/blubber%2F", 7, 29 }, 335cdf0e10cSrcweir { "http://sun.com", "http://sun.com/", 0, 14 }, 336cdf0e10cSrcweir { "http://sun.com/", "http://sun.com/", 0, 15 }, 337cdf0e10cSrcweir { "http://www.xerox.com@www.pcworld.com/go/3990332.htm", 0, 0, 0 }, 338cdf0e10cSrcweir { "ftp://www.xerox.com@www.pcworld.com/go/3990332.htm", 339cdf0e10cSrcweir "ftp://www.xerox.com@www.pcworld.com/go/3990332.htm", 0, 50 }, 340cdf0e10cSrcweir { "Version.1.2.3", 0, 0, 0 }, 341cdf0e10cSrcweir { "Version:1.2.3", 0, 0, 0 }, 342cdf0e10cSrcweir { "a.b.c", 0, 0, 0 }, 343cdf0e10cSrcweir { "file:///a|...", "file:///a:", 0, 10 }, 344cdf0e10cSrcweir { "file:///a||...", "file:///a%7C%7C", 0, 11 }, 345cdf0e10cSrcweir { "file:///a|/bc#...", "file:///a:/bc", 0, 13 }, 346cdf0e10cSrcweir { "file:///a|/bc#de...", "file:///a:/bc#de", 0, 16 }, 347cdf0e10cSrcweir { "abc.def.ghi,ftp.xxx.yyy/zzz...", "ftp://ftp.xxx.yyy/zzz", 12, 27 }, 348cdf0e10cSrcweir { "abc.def.ghi,Ftp.xxx.yyy/zzz...", "ftp://Ftp.xxx.yyy/zzz", 12, 27 }, 349cdf0e10cSrcweir { "abc.def.ghi,www.xxx.yyy...", "http://www.xxx.yyy/", 12, 23 }, 350cdf0e10cSrcweir { "abc.def.ghi,wwww.xxx.yyy...", 0, 0, 0 }, 351cdf0e10cSrcweir { "abc.def.ghi,wWW.xxx.yyy...", "http://wWW.xxx.yyy/", 12, 23 }, 352cdf0e10cSrcweir { "Bla {mailto.me@abc.def.g.h.i}...", 353cdf0e10cSrcweir "mailto:%7Bmailto.me@abc.def.g.h.i", 4, 28 }, 354cdf0e10cSrcweir { "abc@def@ghi", 0, 0, 0 }, 355cdf0e10cSrcweir { "lala@sun.com", "mailto:lala@sun.com", 0, 12 }, 356cdf0e10cSrcweir { "1lala@sun.com", "mailto:1lala@sun.com", 0, 13 }, 357cdf0e10cSrcweir { "aaa_bbb@xxx.yy", "mailto:aaa_bbb@xxx.yy", 0, 14 }, 358cdf0e10cSrcweir { "{a:\\bla/bla/bla...}", "file:///a:/bla/bla/bla", 1, 15 }, 359cdf0e10cSrcweir { "#b:/c/d#e#f#", "file:///b:/c/d", 1, 7 }, 360cdf0e10cSrcweir { "a:/", "file:///a:/", 0, 3 }, 361cdf0e10cSrcweir { ".component:", 0, 0, 0 }, 362cdf0e10cSrcweir { ".uno:", 0, 0, 0 }, 363cdf0e10cSrcweir { "cid:", 0, 0, 0 }, 364cdf0e10cSrcweir { "data:", 0, 0, 0 }, 365cdf0e10cSrcweir { "db:", 0, 0, 0 }, 366cdf0e10cSrcweir { "file:", 0, 0, 0 }, 367cdf0e10cSrcweir { "ftp:", 0, 0, 0 }, 368cdf0e10cSrcweir { "http:", 0, 0, 0 }, 369cdf0e10cSrcweir { "https:", 0, 0, 0 }, 370cdf0e10cSrcweir { "imap:", 0, 0, 0 }, 371cdf0e10cSrcweir { "javascript:", 0, 0, 0 }, 372cdf0e10cSrcweir { "ldap:", 0, 0, 0 }, 373cdf0e10cSrcweir { "macro:", 0, 0, 0 }, 374cdf0e10cSrcweir { "mailto:", 0, 0, 0 }, 375cdf0e10cSrcweir { "news:", 0, 0, 0 }, 376cdf0e10cSrcweir { "out:", 0, 0, 0 }, 377cdf0e10cSrcweir { "pop3:", 0, 0, 0 }, 378cdf0e10cSrcweir { "private:", 0, 0, 0 }, 379cdf0e10cSrcweir { "slot:", 0, 0, 0 }, 380cdf0e10cSrcweir { "staroffice.component:", 0, 0, 0 }, 381cdf0e10cSrcweir { "staroffice.db:", 0, 0, 0 }, 382cdf0e10cSrcweir { "staroffice.factory:", 0, 0, 0 }, 383cdf0e10cSrcweir { "staroffice.helpid:", 0, 0, 0 }, 384cdf0e10cSrcweir { "staroffice.java:", 0, 0, 0 }, 385cdf0e10cSrcweir { "staroffice.macro:", 0, 0, 0 }, 386cdf0e10cSrcweir { "staroffice.out:", 0, 0, 0 }, 387cdf0e10cSrcweir { "staroffice.pop3:", 0, 0, 0 }, 388cdf0e10cSrcweir { "staroffice.private:", 0, 0, 0 }, 389cdf0e10cSrcweir { "staroffice.searchfolder:", 0, 0, 0 }, 390cdf0e10cSrcweir { "staroffice.slot:", 0, 0, 0 }, 391cdf0e10cSrcweir { "staroffice.trashcan:", 0, 0, 0 }, 392cdf0e10cSrcweir { "staroffice.uno:", 0, 0, 0 }, 393cdf0e10cSrcweir { "staroffice.vim:", 0, 0, 0 }, 394cdf0e10cSrcweir { "staroffice:", 0, 0, 0 }, 395cdf0e10cSrcweir { "vim:", 0, 0, 0 }, 396cdf0e10cSrcweir { "vnd.sun.star.cmd:", 0, 0, 0 }, 397cdf0e10cSrcweir { "vnd.sun.star.help:", 0, 0, 0 }, 398cdf0e10cSrcweir { "vnd.sun.star.hier:", 0, 0, 0 }, 399cdf0e10cSrcweir { "vnd.sun.star.odma:", 0, 0, 0 }, 400cdf0e10cSrcweir { "vnd.sun.star.pkg:", 0, 0, 0 }, 401cdf0e10cSrcweir { "vnd.sun.star.script:", 0, 0, 0 }, 402cdf0e10cSrcweir { "vnd.sun.star.webdav:", 0, 0, 0 }, 403cdf0e10cSrcweir { "vnd.sun.star.wfs:", 0, 0, 0 }, 404cdf0e10cSrcweir { "generic:path", 0, 0, 0 }, 405cdf0e10cSrcweir { "wfs:", 0, 0, 0 } 406cdf0e10cSrcweir }; 407cdf0e10cSrcweir CharClass charClass( 408cdf0e10cSrcweir css::uno::Reference< css::lang::XMultiServiceFactory >( 409cdf0e10cSrcweir m_context->getServiceManager(), css::uno::UNO_QUERY_THROW), 410cdf0e10cSrcweir com::sun::star::lang::Locale( 411cdf0e10cSrcweir rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en")), 412cdf0e10cSrcweir rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("US")), rtl::OUString())); 413cdf0e10cSrcweir for (std::size_t i = 0; i < sizeof tests / sizeof tests[0]; ++i) { 414cdf0e10cSrcweir rtl::OUString input(rtl::OUString::createFromAscii(tests[i].input)); 415cdf0e10cSrcweir xub_StrLen begin = 0; 416cdf0e10cSrcweir xub_StrLen end = static_cast< xub_StrLen >(input.getLength()); 417cdf0e10cSrcweir rtl::OUString result( 418cdf0e10cSrcweir URIHelper::FindFirstURLInText(input, begin, end, charClass)); 419cdf0e10cSrcweir bool ok = tests[i].result == 0 420cdf0e10cSrcweir ? (result.getLength() == 0 && begin == input.getLength() 421cdf0e10cSrcweir && end == input.getLength()) 422cdf0e10cSrcweir : (result.equalsAscii(tests[i].result) && begin == tests[i].begin 423cdf0e10cSrcweir && end == tests[i].end); 424cdf0e10cSrcweir rtl::OString msg; 425cdf0e10cSrcweir if (!ok) { 426cdf0e10cSrcweir rtl::OStringBuffer buf; 427cdf0e10cSrcweir buf.append('"'); 428cdf0e10cSrcweir buf.append(tests[i].input); 429cdf0e10cSrcweir buf.append(RTL_CONSTASCII_STRINGPARAM("\" -> ")); 430cdf0e10cSrcweir buf.append(tests[i].result == 0 ? "none" : tests[i].result); 431cdf0e10cSrcweir buf.append(RTL_CONSTASCII_STRINGPARAM(" (")); 432cdf0e10cSrcweir buf.append(static_cast< sal_Int32 >(tests[i].begin)); 433cdf0e10cSrcweir buf.append(RTL_CONSTASCII_STRINGPARAM(", ")); 434cdf0e10cSrcweir buf.append(static_cast< sal_Int32 >(tests[i].end)); 435cdf0e10cSrcweir buf.append(')'); 436cdf0e10cSrcweir buf.append(RTL_CONSTASCII_STRINGPARAM(" != ")); 437cdf0e10cSrcweir buf.append(rtl::OUStringToOString(result, RTL_TEXTENCODING_UTF8)); 438cdf0e10cSrcweir buf.append(RTL_CONSTASCII_STRINGPARAM(" (")); 439cdf0e10cSrcweir buf.append(static_cast< sal_Int32 >(begin)); 440cdf0e10cSrcweir buf.append(RTL_CONSTASCII_STRINGPARAM(", ")); 441cdf0e10cSrcweir buf.append(static_cast< sal_Int32 >(end)); 442cdf0e10cSrcweir buf.append(')'); 443cdf0e10cSrcweir msg = buf.makeStringAndClear(); 444cdf0e10cSrcweir } 445cdf0e10cSrcweir CPPUNIT_ASSERT_MESSAGE(msg.getStr(), ok); 446cdf0e10cSrcweir } 447cdf0e10cSrcweir } 448cdf0e10cSrcweir 449cdf0e10cSrcweir css::uno::Reference< css::uno::XComponentContext > Test::m_context; 450cdf0e10cSrcweir 451cdf0e10cSrcweir CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(Test, "alltests"); 452cdf0e10cSrcweir 453cdf0e10cSrcweir } 454cdf0e10cSrcweir 455cdf0e10cSrcweir NOADDITIONAL; 456