diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
commit | 940b4d1848e8c70ab7642901a68594e8016caffc (patch) | |
tree | eb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /ucb/source/ucp/webdav-neon/LockEntrySequence.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip |
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ucb/source/ucp/webdav-neon/LockEntrySequence.cxx')
-rw-r--r-- | ucb/source/ucp/webdav-neon/LockEntrySequence.cxx | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/ucb/source/ucp/webdav-neon/LockEntrySequence.cxx b/ucb/source/ucp/webdav-neon/LockEntrySequence.cxx new file mode 100644 index 000000000..61be4420c --- /dev/null +++ b/ucb/source/ucp/webdav-neon/LockEntrySequence.cxx @@ -0,0 +1,246 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <config_lgpl.h> +#include <string.h> +#include <ne_xml.h> +#include "LockEntrySequence.hxx" +#include <memory> + +using namespace webdav_ucp; +using namespace com::sun::star; + +namespace { + +struct LockEntrySequenceParseContext +{ + std::unique_ptr<ucb::LockEntry> pEntry; + bool hasScope; + bool hasType; + + LockEntrySequenceParseContext() + : hasScope( false ), hasType( false ) {} +}; + +} + +#define STATE_TOP (1) + +#define STATE_LOCKENTRY (STATE_TOP) +#define STATE_LOCKSCOPE (STATE_TOP + 1) +#define STATE_EXCLUSIVE (STATE_TOP + 2) +#define STATE_SHARED (STATE_TOP + 3) +#define STATE_LOCKTYPE (STATE_TOP + 4) +#define STATE_WRITE (STATE_TOP + 5) + + +extern "C" { + +static int LockEntrySequence_startelement_callback( + void *, + int parent, + const char * /*nspace*/, + const char *name, + const char ** ) +{ + if ( name != nullptr ) + { + switch ( parent ) + { + case NE_XML_STATEROOT: + if ( strcmp( name, "lockentry" ) == 0 ) + return STATE_LOCKENTRY; + break; + + case STATE_LOCKENTRY: + if ( strcmp( name, "lockscope" ) == 0 ) + return STATE_LOCKSCOPE; + else if ( strcmp( name, "locktype" ) == 0 ) + return STATE_LOCKTYPE; + +#define IIS_BUGS_WORKAROUND + +#ifdef IIS_BUGS_WORKAROUND + /* IIS (6) returns XML violating RFC 4918 + for DAV:supportedlock property value. + + <lockentry> + <write></write> + <shared></shared> + </lockentry> + <lockentry> + <write></write> + <exclusive></exclusive> + </lockentry> + + Bother... + */ + else if ( strcmp( name, "exclusive" ) == 0 ) + return STATE_EXCLUSIVE; + else if ( strcmp( name, "shared" ) == 0 ) + return STATE_SHARED; + else if ( strcmp( name, "write" ) == 0 ) + return STATE_WRITE; +#endif + break; + + case STATE_LOCKSCOPE: + if ( strcmp( name, "exclusive" ) == 0 ) + return STATE_EXCLUSIVE; + else if ( strcmp( name, "shared" ) == 0 ) + return STATE_SHARED; + break; + + case STATE_LOCKTYPE: + if ( strcmp( name, "write" ) == 0 ) + return STATE_WRITE; + break; + } + } + return NE_XML_DECLINE; +} + + +static int LockEntrySequence_chardata_callback( + void *, + int, + const char *, + size_t ) +{ + return 0; // zero to continue, non-zero to abort parsing +} + + +static int LockEntrySequence_endelement_callback( + void *userdata, + int state, + const char *, + const char * ) +{ + LockEntrySequenceParseContext * pCtx + = static_cast< LockEntrySequenceParseContext * >( userdata ); + if ( !pCtx->pEntry ) + pCtx->pEntry.reset( new ucb::LockEntry ); + + switch ( state ) + { + case STATE_EXCLUSIVE: + pCtx->pEntry->Scope = ucb::LockScope_EXCLUSIVE; + pCtx->hasScope = true; + break; + + case STATE_SHARED: + pCtx->pEntry->Scope = ucb::LockScope_SHARED; + pCtx->hasScope = true; + break; + + case STATE_WRITE: + pCtx->pEntry->Type = ucb::LockType_WRITE; + pCtx->hasType = true; + break; + + case STATE_LOCKSCOPE: + if ( !pCtx->hasScope ) + return 1; // abort + break; + + case STATE_LOCKTYPE: + if ( !pCtx->hasType ) + return 1; // abort + break; + + case STATE_LOCKENTRY: + if ( !pCtx->hasType || !pCtx->hasScope ) + return 1; // abort + break; + + default: + break; + } + return 0; // zero to continue, non-zero to abort parsing +} + +} + +// static +bool LockEntrySequence::createFromXML( const OString & rInData, + uno::Sequence< + ucb::LockEntry > & rOutData ) +{ + const sal_Int32 TOKEN_LENGTH = 12; // </lockentry> + bool success = true; + + // rInData may contain multiple <lockentry>...</lockentry> tags. + sal_Int32 nCount = 0; + sal_Int32 nStart = 0; + sal_Int32 nEnd = rInData.indexOf( "</lockentry>" ); + while ( nEnd > -1 ) + { + ne_xml_parser * parser = ne_xml_create(); + if ( !parser ) + { + success = false; + break; + } + + LockEntrySequenceParseContext aCtx; + ne_xml_push_handler( parser, + LockEntrySequence_startelement_callback, + LockEntrySequence_chardata_callback, + LockEntrySequence_endelement_callback, + &aCtx ); + + ne_xml_parse( parser, + rInData.getStr() + nStart, + nEnd - nStart + TOKEN_LENGTH ); + + success = !ne_xml_failed( parser ); + + ne_xml_destroy( parser ); + + if ( !success ) + break; + + if ( aCtx.pEntry ) + { + nCount++; + if ( nCount > rOutData.getLength() ) + rOutData.realloc( rOutData.getLength() + 2 ); + + rOutData[ nCount - 1 ] = *aCtx.pEntry; + } + + nStart = nEnd + TOKEN_LENGTH; + nEnd = rInData.indexOf( "</lockentry>", nStart ); + } + + rOutData.realloc( nCount ); + return success; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |