bump product version to 5.0.4.1
[LibreOffice.git] / ucb / source / ucp / webdav-neon / LockEntrySequence.cxx
blob22a2d5b07388fe2f4d11186d9ccb4a33e8bae3bb
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <config_lgpl.h>
30 #include <string.h>
31 #include <ne_xml.h>
32 #include "LockEntrySequence.hxx"
34 using namespace webdav_ucp;
35 using namespace com::sun::star;
39 struct LockEntrySequenceParseContext
41 ucb::LockEntry * pEntry;
42 bool hasScope;
43 bool hasType;
45 LockEntrySequenceParseContext()
46 : pEntry( 0 ), hasScope( false ), hasType( false ) {}
47 ~LockEntrySequenceParseContext() { delete pEntry; }
50 #define STATE_TOP (1)
52 #define STATE_LOCKENTRY (STATE_TOP)
53 #define STATE_LOCKSCOPE (STATE_TOP + 1)
54 #define STATE_EXCLUSIVE (STATE_TOP + 2)
55 #define STATE_SHARED (STATE_TOP + 3)
56 #define STATE_LOCKTYPE (STATE_TOP + 4)
57 #define STATE_WRITE (STATE_TOP + 5)
60 extern "C" int LockEntrySequence_startelement_callback(
61 void *,
62 int parent,
63 const char * /*nspace*/,
64 const char *name,
65 const char ** )
67 if ( name != 0 )
69 switch ( parent )
71 case NE_XML_STATEROOT:
72 if ( strcmp( name, "lockentry" ) == 0 )
73 return STATE_LOCKENTRY;
74 break;
76 case STATE_LOCKENTRY:
77 if ( strcmp( name, "lockscope" ) == 0 )
78 return STATE_LOCKSCOPE;
79 else if ( strcmp( name, "locktype" ) == 0 )
80 return STATE_LOCKTYPE;
82 #define IIS_BUGS_WORKAROUND
84 #ifdef IIS_BUGS_WORKAROUND
85 /* IIS (6) returns XML violating RFC 4918
86 for DAV:supportedlock property value.
88 <lockentry>
89 <write></write>
90 <shared></shared>
91 </lockentry>
92 <lockentry>
93 <write></write>
94 <exclusive></exclusive>
95 </lockentry>
97 Bother...
99 else if ( strcmp( name, "exclusive" ) == 0 )
100 return STATE_EXCLUSIVE;
101 else if ( strcmp( name, "shared" ) == 0 )
102 return STATE_SHARED;
103 else if ( strcmp( name, "write" ) == 0 )
104 return STATE_WRITE;
105 #endif
106 break;
108 case STATE_LOCKSCOPE:
109 if ( strcmp( name, "exclusive" ) == 0 )
110 return STATE_EXCLUSIVE;
111 else if ( strcmp( name, "shared" ) == 0 )
112 return STATE_SHARED;
113 break;
115 case STATE_LOCKTYPE:
116 if ( strcmp( name, "write" ) == 0 )
117 return STATE_WRITE;
118 break;
121 return NE_XML_DECLINE;
125 extern "C" int LockEntrySequence_chardata_callback(
126 void *,
127 int,
128 const char *,
129 size_t )
131 return 0; // zero to continue, non-zero to abort parsing
135 extern "C" int LockEntrySequence_endelement_callback(
136 void *userdata,
137 int state,
138 const char *,
139 const char * )
141 LockEntrySequenceParseContext * pCtx
142 = static_cast< LockEntrySequenceParseContext * >( userdata );
143 if ( !pCtx->pEntry )
144 pCtx->pEntry = new ucb::LockEntry;
146 switch ( state )
148 case STATE_EXCLUSIVE:
149 pCtx->pEntry->Scope = ucb::LockScope_EXCLUSIVE;
150 pCtx->hasScope = true;
151 break;
153 case STATE_SHARED:
154 pCtx->pEntry->Scope = ucb::LockScope_SHARED;
155 pCtx->hasScope = true;
156 break;
158 case STATE_WRITE:
159 pCtx->pEntry->Type = ucb::LockType_WRITE;
160 pCtx->hasType = true;
161 break;
163 case STATE_LOCKSCOPE:
164 if ( !pCtx->hasScope )
165 return 1; // abort
166 break;
168 case STATE_LOCKTYPE:
169 if ( !pCtx->hasType )
170 return 1; // abort
171 break;
173 case STATE_LOCKENTRY:
174 if ( !pCtx->hasType || !pCtx->hasScope )
175 return 1; // abort
176 break;
178 default:
179 break;
181 return 0; // zero to continue, non-zero to abort parsing
185 // static
186 bool LockEntrySequence::createFromXML( const OString & rInData,
187 uno::Sequence<
188 ucb::LockEntry > & rOutData )
190 const sal_Int32 TOKEN_LENGTH = 12; // </lockentry>
191 bool success = true;
193 // rInData may contain multiple <lockentry>...</lockentry> tags.
194 sal_Int32 nCount = 0;
195 sal_Int32 nStart = 0;
196 sal_Int32 nEnd = rInData.indexOf( "</lockentry>" );
197 while ( nEnd > -1 )
199 ne_xml_parser * parser = ne_xml_create();
200 if ( !parser )
202 success = false;
203 break;
206 LockEntrySequenceParseContext aCtx;
207 ne_xml_push_handler( parser,
208 LockEntrySequence_startelement_callback,
209 LockEntrySequence_chardata_callback,
210 LockEntrySequence_endelement_callback,
211 &aCtx );
213 ne_xml_parse( parser,
214 rInData.getStr() + nStart,
215 nEnd - nStart + TOKEN_LENGTH );
217 success = !ne_xml_failed( parser );
219 ne_xml_destroy( parser );
221 if ( !success )
222 break;
224 if ( aCtx.pEntry )
226 nCount++;
227 if ( nCount > rOutData.getLength() )
228 rOutData.realloc( rOutData.getLength() + 2 );
230 rOutData[ nCount - 1 ] = *aCtx.pEntry;
233 nStart = nEnd + TOKEN_LENGTH;
234 nEnd = rInData.indexOf( "</lockentry>", nStart );
237 rOutData.realloc( nCount );
238 return success;
241 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */