/* -*- 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/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include "DAVProperties.hxx"
#include <rtl/ustrbuf.hxx>
#include <o3tl/string_view.hxx>
#include <string.h>
using namespace http_dav_ucp;
// static
void DAVProperties::createSerfPropName( ::std::u16string_view const rFullName,
SerfPropName & rName )
{
if (o3tl::starts_with(rFullName, u"DAV:"))
{
rName.nspace = "DAV:";
rName.name
= strdup( OUStringToOString(
rFullName.substr(RTL_CONSTASCII_LENGTH("DAV:")),
RTL_TEXTENCODING_UTF8 ).getStr() );
}
else if (o3tl::starts_with(rFullName, u"http://apache.org/dav/props/"))
{
rName.nspace = "http://apache.org/dav/props/";
rName.name
= strdup( OUStringToOString(
rFullName.substr(
RTL_CONSTASCII_LENGTH(
"http://apache.org/dav/props/" ) ),
RTL_TEXTENCODING_UTF8 ).getStr() );
}
else if (o3tl::starts_with(rFullName, u"http://ucb.openoffice.org/dav/props/"))
{
rName.nspace = "http://ucb.openoffice.org/dav/props/";
rName.name
= strdup( OUStringToOString(
rFullName.substr(
RTL_CONSTASCII_LENGTH(
"http://ucb.openoffice.org/dav/props/" ) ),
RTL_TEXTENCODING_UTF8 ).getStr() );
}
else if (o3tl::starts_with(rFullName, u"<prop:"))
{
// Support for 3rd party namespaces/props
OString aFullName
= OUStringToOString( rFullName, RTL_TEXTENCODING_UTF8 );
// Format: <prop:the_propname xmlns:prop="the_namespace">
sal_Int32 nStart = RTL_CONSTASCII_LENGTH( "<prop:" );
sal_Int32 nLen = aFullName.indexOf( ' ' ) - nStart;
rName.name = strdup( aFullName.copy( nStart, nLen ).getStr() );
nStart = aFullName.indexOf( '=', nStart + nLen ) + 2; // after ="
nLen = aFullName.getLength() - RTL_CONSTASCII_LENGTH( "\">" ) - nStart;
rName.nspace = strdup( aFullName.copy( nStart, nLen ).getStr() );
}
else
{
// this must not be a URI - WebDAVResponseParser must have converted it
// to the "<prop:" form above
assert(rFullName.find(':') == ::std::u16string_view::npos);
// Add our namespace to our own properties.
rName.nspace = "http://ucb.openoffice.org/dav/props/";
rName.name
= strdup( OUStringToOString( rFullName,
RTL_TEXTENCODING_UTF8 ).getStr() );
}
}
// static
void DAVProperties::createUCBPropName( const char * nspace,
const char * name,
OUString & rFullName )
{
OUString aNameSpace
= OStringToOUString( nspace, RTL_TEXTENCODING_UTF8 );
OUString aName
= OStringToOUString( name, RTL_TEXTENCODING_UTF8 );
if ( !aNameSpace.getLength() )
{
// Some servers send XML without proper namespaces. Assume "DAV:"
// in this case, if name is a well-known dav property name.
// Although this is not 100% correct, it solves many problems.
if (o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::RESOURCETYPE).substr(4)) ||
o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::SUPPORTEDLOCK).substr(4)) ||
o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::LOCKDISCOVERY).substr(4)) ||
o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::CREATIONDATE).substr(4)) ||
o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::DISPLAYNAME).substr(4)) ||
o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::GETCONTENTLANGUAGE).substr(4)) ||
o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::GETCONTENTLENGTH).substr(4)) ||
o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::GETCONTENTTYPE).substr(4)) ||
o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::GETETAG).substr(4)) ||
o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::GETLASTMODIFIED).substr(4)))
{
aNameSpace = "DAV:";
}
}
// Note: Concatenating strings BEFORE comparing against known namespaces
// is important. See RFC 2815 ( 23.4.2 Meaning of Qualified Names ).
rFullName = aNameSpace;
rFullName += aName;
if ( rFullName.startsWith( "DAV:" ) )
{
// Okay, Just concat strings.
}
else if ( rFullName.startsWith( "http://apache.org/dav/props/" ) )
{
// Okay, Just concat strings.
}
else if ( rFullName.startsWith( "http://ucb.openoffice.org/dav/props/" ) )
{
// Remove namespace from our own properties.
rFullName = rFullName.copy(
RTL_CONSTASCII_LENGTH(
"http://ucb.openoffice.org/dav/props/" ) );
}
else
{
// Create property name that encodes, namespace and name ( XML ).
rFullName = "<prop:";
rFullName += aName;
rFullName += " xmlns:prop=\"";
rFullName += aNameSpace;
rFullName += "\">";
}
}
// static
bool DAVProperties::isUCBDeadProperty( const SerfPropName & rName )
{
return ( rName.nspace &&
( rtl_str_compareIgnoreAsciiCase(
rName.nspace, "http://ucb.openoffice.org/dav/props/" )
== 0 ) );
}
bool DAVProperties::isUCBSpecialProperty(std::u16string_view rFullName, OUString& rParsedName)
{
size_t nLen = rFullName.size();
if ( nLen <= 0 ||
!o3tl::starts_with(rFullName, u"<prop:" ) ||
!o3tl::starts_with(rFullName, u"\">" ) )
return false;
sal_Int32 nStart = RTL_CONSTASCII_LENGTH( "<prop:" );
size_t nEnd = rFullName.find( ' ', nStart );
if ( nEnd == std::u16string_view::npos )
return false;
std::u16string_view sPropName = rFullName.substr( nStart, nEnd - nStart );
if ( sPropName.empty() )
return false;
// TODO skip whitespaces?
++nEnd;
if ( !o3tl::starts_with(rFullName.substr(nEnd), u"xmlns:prop=\"" ) )
return false;
nStart = nEnd + RTL_CONSTASCII_LENGTH( "xmlns:prop=\"" );
nEnd = rFullName.find( '"', nStart );
if ( nEnd != nLen - RTL_CONSTASCII_LENGTH( "\">" ) )
return false;
std::u16string_view sNamesp = rFullName.substr( nStart, nEnd - nStart );
nLen = sNamesp.size();
if ( !nLen )
return false;
OUStringBuffer aBuff( sNamesp );
if ( sNamesp[nLen - 1] != '/' )
aBuff.append( '/' );
aBuff.append( sPropName );
rParsedName = aBuff.makeStringAndClear();
return rParsedName.getLength();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V530 The return value of function 'append' is required to be utilized.
↑ V530 The return value of function 'append' is required to be utilized.