bump product version to 5.0.4.1
[LibreOffice.git] / ucb / source / ucp / webdav-neon / LinkSequence.cxx
bloba365e080be619ac599604c0f1372bd757905c2c7
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>
33 #include "LinkSequence.hxx"
35 using namespace webdav_ucp;
36 using namespace com::sun::star;
40 struct LinkSequenceParseContext
42 ucb::Link * pLink;
43 bool hasSource;
44 bool hasDestination;
46 LinkSequenceParseContext()
47 : pLink( 0 ), hasSource( false ), hasDestination( false ) {}
48 ~LinkSequenceParseContext() { delete pLink; }
51 #define STATE_TOP (1)
53 #define STATE_LINK (STATE_TOP)
54 #define STATE_DST (STATE_TOP + 1)
55 #define STATE_SRC (STATE_TOP + 2)
58 extern "C" int LinkSequence_startelement_callback(
59 void *,
60 int parent,
61 const char * /*nspace*/,
62 const char *name,
63 const char ** )
65 if ( name != 0 )
67 switch ( parent )
69 case NE_XML_STATEROOT:
70 if ( strcmp( name, "link" ) == 0 )
71 return STATE_LINK;
72 break;
74 case STATE_LINK:
75 if ( strcmp( name, "dst" ) == 0 )
76 return STATE_DST;
77 else if ( strcmp( name, "src" ) == 0 )
78 return STATE_SRC;
79 break;
82 return NE_XML_DECLINE;
86 extern "C" int LinkSequence_chardata_callback(
87 void *userdata,
88 int state,
89 const char *buf,
90 size_t len )
92 LinkSequenceParseContext * pCtx
93 = static_cast< LinkSequenceParseContext * >( userdata );
94 if ( !pCtx->pLink )
95 pCtx->pLink = new ucb::Link;
97 switch ( state )
99 case STATE_DST:
100 pCtx->pLink->Destination
101 = OUString( buf, len, RTL_TEXTENCODING_ASCII_US );
102 pCtx->hasDestination = true;
103 break;
105 case STATE_SRC:
106 pCtx->pLink->Source
107 = OUString( buf, len, RTL_TEXTENCODING_ASCII_US );
108 pCtx->hasSource = true;
109 break;
111 return 0; // zero to continue, non-zero to abort parsing
115 extern "C" int LinkSequence_endelement_callback(
116 void *userdata,
117 int state,
118 const char *,
119 const char * )
121 LinkSequenceParseContext * pCtx
122 = static_cast< LinkSequenceParseContext * >( userdata );
123 if ( !pCtx->pLink )
124 pCtx->pLink = new ucb::Link;
126 switch ( state )
128 case STATE_LINK:
129 if ( !pCtx->hasDestination || !pCtx->hasSource )
130 return 1; // abort
131 break;
133 return 0; // zero to continue, non-zero to abort parsing
137 // static
138 bool LinkSequence::createFromXML( const OString & rInData,
139 uno::Sequence< ucb::Link > & rOutData )
141 const sal_Int32 TOKEN_LENGTH = 7; // </link>
142 bool success = true;
144 // rInData may contain multiple <link>...</link> tags.
145 sal_Int32 nCount = 0;
146 sal_Int32 nStart = 0;
147 sal_Int32 nEnd = rInData.indexOf( "</link>" );
148 while ( nEnd > -1 )
150 ne_xml_parser * parser = ne_xml_create();
151 if ( !parser )
153 success = false;
154 break;
157 LinkSequenceParseContext aCtx;
158 ne_xml_push_handler( parser,
159 LinkSequence_startelement_callback,
160 LinkSequence_chardata_callback,
161 LinkSequence_endelement_callback,
162 &aCtx );
164 ne_xml_parse( parser,
165 rInData.getStr() + nStart,
166 nEnd - nStart + TOKEN_LENGTH );
168 success = !ne_xml_failed( parser );
170 ne_xml_destroy( parser );
172 if ( !success )
173 break;
175 if ( aCtx.pLink )
177 nCount++;
178 if ( nCount > rOutData.getLength() )
179 rOutData.realloc( rOutData.getLength() + 1 );
181 rOutData[ nCount - 1 ] = *aCtx.pLink;
184 nStart = nEnd + TOKEN_LENGTH;
185 nEnd = rInData.indexOf( "</link>", nStart );
188 return success;
192 // static
193 bool LinkSequence::toXML( const uno::Sequence< ucb::Link > & rInData,
194 OUString & rOutData )
196 // <link><src>value</src><dst>value</dst></link><link><src>....
198 sal_Int32 nCount = rInData.getLength();
199 if ( nCount )
201 OUString aPre( "<link><src>" );
202 OUString aMid( "</src><dst>" );
203 OUString aEnd( "</dst></link>" );
205 for ( sal_Int32 n = 0; n < nCount; ++n )
207 rOutData += aPre;
208 rOutData += rInData[ n ].Source;
209 rOutData += aMid;
210 rOutData += rInData[ n ].Destination;
211 rOutData += aEnd;
213 return true;
215 return false;
218 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */