LibreOffice Module ucb (master) 1
DAVProperties.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include "DAVProperties.hxx"
21#include <rtl/ustrbuf.hxx>
22#include <o3tl/string_view.hxx>
23#include <string.h>
24
25using namespace http_dav_ucp;
26
27
28// static
29void DAVProperties::createSerfPropName( ::std::u16string_view const rFullName,
30 SerfPropName & rName )
31{
32 if (o3tl::starts_with(rFullName, u"DAV:"))
33 {
34 rName.nspace = "DAV:";
35 rName.name
36 = strdup( OUStringToOString(
37 rFullName.substr(RTL_CONSTASCII_LENGTH("DAV:")),
38 RTL_TEXTENCODING_UTF8 ).getStr() );
39 }
40 else if (o3tl::starts_with(rFullName, u"http://apache.org/dav/props/"))
41 {
42 rName.nspace = "http://apache.org/dav/props/";
43 rName.name
44 = strdup( OUStringToOString(
45 rFullName.substr(
46 RTL_CONSTASCII_LENGTH(
47 "http://apache.org/dav/props/" ) ),
48 RTL_TEXTENCODING_UTF8 ).getStr() );
49 }
50 else if (o3tl::starts_with(rFullName, u"http://ucb.openoffice.org/dav/props/"))
51 {
52 rName.nspace = "http://ucb.openoffice.org/dav/props/";
53 rName.name
54 = strdup( OUStringToOString(
55 rFullName.substr(
56 RTL_CONSTASCII_LENGTH(
57 "http://ucb.openoffice.org/dav/props/" ) ),
58 RTL_TEXTENCODING_UTF8 ).getStr() );
59 }
60 else if (o3tl::starts_with(rFullName, u"<prop:"))
61 {
62 // Support for 3rd party namespaces/props
63
64 OString aFullName
65 = OUStringToOString( rFullName, RTL_TEXTENCODING_UTF8 );
66
67 // Format: <prop:the_propname xmlns:prop="the_namespace">
68
69 sal_Int32 nStart = RTL_CONSTASCII_LENGTH( "<prop:" );
70 sal_Int32 nLen = aFullName.indexOf( ' ' ) - nStart;
71 rName.name = strdup( aFullName.copy( nStart, nLen ).getStr() );
72
73 nStart = aFullName.indexOf( '=', nStart + nLen ) + 2; // after ="
74 nLen = aFullName.getLength() - RTL_CONSTASCII_LENGTH( "\">" ) - nStart;
75 rName.nspace = strdup( aFullName.copy( nStart, nLen ).getStr() );
76 }
77 else
78 {
79 // this must not be a URI - WebDAVResponseParser must have converted it
80 // to the "<prop:" form above
81 assert(rFullName.find(':') == ::std::u16string_view::npos);
82 // Add our namespace to our own properties.
83 rName.nspace = "http://ucb.openoffice.org/dav/props/";
84 rName.name
85 = strdup( OUStringToOString( rFullName,
86 RTL_TEXTENCODING_UTF8 ).getStr() );
87 }
88}
89
90
91// static
92void DAVProperties::createUCBPropName( const char * nspace,
93 const char * name,
94 OUString & rFullName )
95{
96 OUString aNameSpace
97 = OStringToOUString( nspace, RTL_TEXTENCODING_UTF8 );
98 OUString aName
99 = OStringToOUString( name, RTL_TEXTENCODING_UTF8 );
100
101 if ( !aNameSpace.getLength() )
102 {
103 // Some servers send XML without proper namespaces. Assume "DAV:"
104 // in this case, if name is a well-known dav property name.
105 // Although this is not 100% correct, it solves many problems.
106
107 if (o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::RESOURCETYPE).substr(4)) ||
108 o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::SUPPORTEDLOCK).substr(4)) ||
109 o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::LOCKDISCOVERY).substr(4)) ||
110 o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::CREATIONDATE).substr(4)) ||
111 o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::DISPLAYNAME).substr(4)) ||
113 o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::GETCONTENTLENGTH).substr(4)) ||
114 o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::GETCONTENTTYPE).substr(4)) ||
115 o3tl::equalsIgnoreAsciiCase(aName, std::u16string_view(DAVProperties::GETETAG).substr(4)) ||
117 {
118 aNameSpace = "DAV:";
119 }
120 }
121
122 // Note: Concatenating strings BEFORE comparing against known namespaces
123 // is important. See RFC 2815 ( 23.4.2 Meaning of Qualified Names ).
124 rFullName = aNameSpace;
125 rFullName += aName;
126
127 if ( rFullName.startsWith( "DAV:" ) )
128 {
129 // Okay, Just concat strings.
130 }
131 else if ( rFullName.startsWith( "http://apache.org/dav/props/" ) )
132 {
133 // Okay, Just concat strings.
134 }
135 else if ( rFullName.startsWith( "http://ucb.openoffice.org/dav/props/" ) )
136 {
137 // Remove namespace from our own properties.
138 rFullName = rFullName.copy(
139 RTL_CONSTASCII_LENGTH(
140 "http://ucb.openoffice.org/dav/props/" ) );
141 }
142 else
143 {
144 // Create property name that encodes, namespace and name ( XML ).
145 rFullName = "<prop:";
146 rFullName += aName;
147 rFullName += " xmlns:prop=\"";
148 rFullName += aNameSpace;
149 rFullName += "\">";
150 }
151}
152
153
154// static
156{
157 return ( rName.nspace &&
158 ( rtl_str_compareIgnoreAsciiCase(
159 rName.nspace, "http://ucb.openoffice.org/dav/props/" )
160 == 0 ) );
161}
162
163bool DAVProperties::isUCBSpecialProperty(std::u16string_view rFullName, OUString& rParsedName)
164{
165 size_t nLen = rFullName.size();
166 if ( nLen <= 0 ||
167 !o3tl::starts_with(rFullName, u"<prop:" ) ||
168 !o3tl::starts_with(rFullName, u"\">" ) )
169 return false;
170
171 sal_Int32 nStart = RTL_CONSTASCII_LENGTH( "<prop:" );
172 size_t nEnd = rFullName.find( ' ', nStart );
173 if ( nEnd == std::u16string_view::npos )
174 return false;
175
176 std::u16string_view sPropName = rFullName.substr( nStart, nEnd - nStart );
177 if ( sPropName.empty() )
178 return false;
179
180 // TODO skip whitespaces?
181 ++nEnd;
182 if ( !o3tl::starts_with(rFullName.substr(nEnd), u"xmlns:prop=\"" ) )
183 return false;
184
185 nStart = nEnd + RTL_CONSTASCII_LENGTH( "xmlns:prop=\"" );
186 nEnd = rFullName.find( '"', nStart );
187 if ( nEnd != nLen - RTL_CONSTASCII_LENGTH( "\">" ) )
188 return false;
189
190 std::u16string_view sNamesp = rFullName.substr( nStart, nEnd - nStart );
191 nLen = sNamesp.size();
192 if ( !nLen )
193 return false;
194
195 OUStringBuffer aBuff( sNamesp );
196 if ( sNamesp[nLen - 1] != '/' )
197 aBuff.append( '/' );
198 aBuff.append( sPropName );
199 rParsedName = aBuff.makeStringAndClear();
200
201 return rParsedName.getLength();
202}
203
204/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
float u
const char * name
OUString aName
bool equalsIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2)
constexpr bool starts_with(std::basic_string_view< charT, traits > sv, std::basic_string_view< charT, traits > x) noexcept
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
static void createUCBPropName(const char *nspace, const char *name, OUString &rFullName)
static constexpr OUStringLiteral GETCONTENTTYPE
static constexpr OUStringLiteral SUPPORTEDLOCK
static constexpr OUStringLiteral CREATIONDATE
static bool isUCBDeadProperty(const SerfPropName &rName)
static constexpr OUStringLiteral DISPLAYNAME
static constexpr OUStringLiteral GETETAG
static bool isUCBSpecialProperty(std::u16string_view rFullName, OUString &rParsedName)
static constexpr OUStringLiteral LOCKDISCOVERY
static constexpr OUStringLiteral RESOURCETYPE
static constexpr OUStringLiteral GETCONTENTLENGTH
static constexpr OUStringLiteral GETLASTMODIFIED
static constexpr OUStringLiteral GETCONTENTLANGUAGE