xref: /trunk/main/svl/source/misc/ownlist.cxx (revision 40df464e)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svl.hxx"
26 #include <ctype.h>
27 #include <stdio.h>
28 #include <com/sun/star/beans/PropertyValues.hpp>
29 
30 #include <svl/ownlist.hxx>
31 
32 using namespace com::sun::star;
33 
34 //=========================================================================
35 //============== SvCommandList ============================================
36 //=========================================================================
PRV_SV_IMPL_OWNER_LIST(SvCommandList,SvCommand)37 PRV_SV_IMPL_OWNER_LIST(SvCommandList,SvCommand)
38 
39 
40 static String parseString(const String & rCmd, sal_uInt16 * pIndex)
41 {
42 	String result;
43 
44 	if(rCmd.GetChar( *pIndex ) == '\"') {
45 		(*pIndex) ++;
46 
47 		sal_uInt16 begin = *pIndex;
48 
49 		while(*pIndex < rCmd.Len() && rCmd.GetChar((*pIndex) ++) != '\"') ;
50 
51 		result = String(rCmd.Copy(begin, *pIndex - begin - 1));
52 	}
53 
54 	return result;
55 }
56 
parseWord(const String & rCmd,sal_uInt16 * pIndex)57 static String parseWord(const String & rCmd, sal_uInt16 * pIndex)
58 {
59 	sal_uInt16 begin = *pIndex;
60 
61 	while(*pIndex < rCmd.Len() && !isspace(rCmd.GetChar(*pIndex)) && rCmd.GetChar(*pIndex) != '=')
62 		(*pIndex) ++;
63 
64 	return String(rCmd.Copy(begin, *pIndex - begin));
65 }
66 
eatSpace(const String & rCmd,sal_uInt16 * pIndex)67 static void eatSpace(const String & rCmd, sal_uInt16 * pIndex)
68 {
69 	while(*pIndex < rCmd.Len() && isspace(rCmd.GetChar(*pIndex)))
70 		(*pIndex) ++;
71 }
72 
73 
74 //=========================================================================
AppendCommands(const String & rCmd,sal_uInt16 * pEaten)75 sal_Bool SvCommandList::AppendCommands
76 (
77 	const String & rCmd,	/* Dieser Text wird in Kommandos umgesetzt */
78 	sal_uInt16 * pEaten			/* Anzahl der Zeichen, die gelesen wurden */
79 )
80 /*	[Beschreibung]
81 
82 	Es wird eine Text geparsed und die einzelnen Kommandos werden an
83 	die Liste angeh"angt.
84 
85 	[R"uckgabewert]
86 
87 	sal_Bool		sal_True, der Text wurde korrekt geparsed.
88 				sal_False, der Text wurde nicht korrekt geparsed.
89 */
90 {
91 	sal_uInt16 index = 0;
92 	while(index < rCmd.Len())
93 	{
94 
95 		eatSpace(rCmd, &index);
96 		String name = (rCmd.GetChar(index) == '\"') ? parseString(rCmd, &index) : parseWord(rCmd, &index);
97 
98 		eatSpace(rCmd, &index);
99 		String value;
100 		if(index < rCmd.Len() && rCmd.GetChar(index) == '=')
101 		{
102 			index ++;
103 
104 			eatSpace(rCmd, &index);
105 			value = (rCmd.GetChar(index) == '\"') ? parseString(rCmd, &index) : parseWord(rCmd, &index);
106 		}
107 
108 		SvCommand * pCmd = new SvCommand(name, value);
109 		aTypes.Insert(pCmd, LIST_APPEND);
110 	}
111 
112 	*pEaten = index;
113 
114 //  	sal_uInt16 nPos = 0;
115 //  	while( nPos < rCmd.Len() )
116 //  	{
117 //  		// ein Zeichen ? Dann faengt hier eine Option an
118 //    		if( isalpha( rCmd[nPos] ) )
119 //  		{
120 //  			String aValue;
121 //  			sal_uInt16 nStt = nPos;
122 //  			register char c;
123 
124 //  			while( nPos < rCmd.Len() &&
125 //  					( isalnum(c=rCmd[nPos]) || '-'==c || '.'==c ) )
126 //  				nPos++;
127 
128 //  			String aToken( rCmd.Copy( nStt, nPos-nStt ) );
129 
130 //  			while( nPos < rCmd.Len() &&
131 //  					( !String::IsPrintable( (c=rCmd[nPos]),
132 //  					RTL_TEXTENCODING_MS_1252 ) || isspace(c) ) )
133 //  				nPos++;
134 
135 //  			// hat die Option auch einen Wert?
136 //  			if( nPos!=rCmd.Len() && '='==c )
137 //  			{
138 //  				nPos++;
139 
140 //  				while( nPos < rCmd.Len() &&
141 //  					 	( !String::IsPrintable( (c=rCmd[nPos]),
142 //  						RTL_TEXTENCODING_MS_1252 ) || isspace(c) ) )
143 //  					nPos++;
144 
145 //  				if( nPos != rCmd.Len() )
146 //  				{
147 //  					sal_uInt16 nLen = 0;
148 //  					nStt = nPos;
149 //  					if( '"' == c )
150 //  					{
151 //  						nPos++; nStt++;
152 //  						while( nPos < rCmd.Len() &&
153 //  					    	 	'"' != rCmd[nPos] )
154 //  							nPos++, nLen++;
155 //  						if( nPos!=rCmd.Len() )
156 //  							nPos++;
157 //  					}
158 //  					else
159 //  						// hier sind wir etwas laxer als der
160 //  						// Standard und erlauben alles druckbare
161 //  						while( nPos < rCmd.Len() &&
162 //  		 				    	String::IsPrintable( (c=rCmd[nPos]),
163 //  								RTL_TEXTENCODING_MS_1252 ) &&
164 //  								!isspace( c ) )
165 //  							nPos++, nLen++;
166 
167 //  					if( nLen )
168 //  						aValue = rCmd( nStt, nLen );
169 //  				}
170 //  			}
171 
172 //  			SvCommand * pCmd = new SvCommand( aToken, aValue );
173 //  		    aTypes.Insert( pCmd, LIST_APPEND );
174 //  		}
175 //  		else
176 //  			// white space un unerwartete Zeichen ignorieren wie
177 //  			nPos++;
178 //  	}
179 //  	*pEaten = nPos;
180 	return sal_True;
181 }
182 
183 //=========================================================================
GetCommands() const184 String SvCommandList::GetCommands() const
185 /*	[Beschreibung]
186 
187 	Die Kommandos in der Liste werden als Text hintereinander, durch ein
188 	Leerzeichen getrennt geschrieben. Der Text muss nicht genauso
189 	aussehen wie der in <SvCommandList::AppendCommands()> "ubergebene.
190 
191 	[R"uckgabewert]
192 
193 	String		Die Kommandos werden zur"uckgegeben.
194 */
195 {
196 	String aRet;
197 	for( sal_uLong i = 0; i < aTypes.Count(); i++ )
198 	{
199 		if( i != 0 )
200 			aRet += ' ';
201 		SvCommand * pCmd = (SvCommand *)aTypes.GetObject( i );
202 		aRet += pCmd->GetCommand();
203 		if( pCmd->GetArgument().Len() )
204 		{
205 			aRet.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "=\"" ) );
206 			aRet += pCmd->GetArgument();
207 			aRet.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "\"" ) );
208 		}
209 	}
210 	return aRet;
211 }
212 
213 //=========================================================================
Append(const String & rCommand,const String & rArg)214 SvCommand & SvCommandList::Append
215 (
216 	const String & rCommand,	/* das Kommando	*/
217 	const String & rArg			/* dasArgument des Kommandos */
218 )
219 /*	[Beschreibung]
220 
221 	Es wird eine Objekt vom Typ SvCommand erzeugt und an die Liste
222 	angeh"angt.
223 
224 	[R"uckgabewert]
225 
226 	SvCommand &		Das erteugte Objekt wird zur"uckgegeben.
227 */
228 {
229 	SvCommand * pCmd = new SvCommand( rCommand, rArg );
230 	aTypes.Insert( pCmd, LIST_APPEND );
231 	return *pCmd;
232 }
233 
234 //=========================================================================
operator >>(SvStream & rStm,SvCommandList & rThis)235 SvStream & operator >>
236 (
237 	SvStream & rStm,     	/* Stream aus dem gelesen wird */
238 	SvCommandList & rThis	/* Die zu f"ullende Liste */
239 )
240 /*	[Beschreibung]
241 
242 	Die Liste mit ihren Elementen wird gelesen. Das Format ist:
243 	1. Anzahl der Elemente
244 	2. Alle Elemente
245 
246 	[R"uckgabewert]
247 
248 	SvStream &		Der "ubergebene Stream.
249 */
250 {
251 	sal_uInt32 nCount = 0;
252 	rStm >> nCount;
253 	if( !rStm.GetError() )
254 	{
255 		while( nCount-- )
256 		{
257 			SvCommand * pCmd = new SvCommand();
258 			rStm >> *pCmd;
259 			rThis.aTypes.Insert( pCmd, LIST_APPEND );
260 		}
261 	}
262 	return rStm;
263 }
264 
265 //=========================================================================
operator <<(SvStream & rStm,const SvCommandList & rThis)266 SvStream & operator <<
267 (
268 	SvStream & rStm,     		/* Stream in den geschrieben wird */
269 	const SvCommandList & rThis	/* Die zu schreibende Liste */
270 )
271 /*	[Beschreibung]
272 
273 	Die Liste mit ihren Elementen wir geschrieben. Das Format ist:
274 	1. Anzahl der Elemente
275 	2. Alle Elemente
276 
277 	[R"uckgabewert]
278 
279 	SvStream &		Der "ubergebene Stream.
280 */
281 {
282 	sal_uInt32 nCount = rThis.aTypes.Count();
283 	rStm << nCount;
284 
285 	for( sal_uInt32 i = 0; i < nCount; i++ )
286 	{
287 		SvCommand * pCmd = (SvCommand *)rThis.aTypes.GetObject( i );
288 		rStm << *pCmd;
289 	}
290 	return rStm;
291 }
292 
FillFromSequence(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> & aCommandSequence)293 sal_Bool SvCommandList::FillFromSequence( const com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue >& aCommandSequence )
294 {
295 	const sal_Int32 nCount = aCommandSequence.getLength();
296 	String aCommand, aArg;
297     ::rtl::OUString aApiArg;
298     for( sal_Int32 nIndex=0; nIndex<nCount; nIndex++ )
299 	{
300 		aCommand = aCommandSequence[nIndex].Name;
301 		if( !( aCommandSequence[nIndex].Value >>= aApiArg ) )
302 			return sal_False;
303 		aArg = aApiArg;
304         Append( aCommand, aArg );
305 	}
306 
307     return sal_True;
308 }
309 
FillSequence(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> & aCommandSequence)310 void SvCommandList::FillSequence( com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue >& aCommandSequence )
311 {
312     const sal_Int32 nCount = Count();
313 	aCommandSequence.realloc( nCount );
314 	for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
315 	{
316         const SvCommand& rCommand = (*this)[ nIndex ];
317 		aCommandSequence[nIndex].Name = rCommand.GetCommand();
318 		aCommandSequence[nIndex].Handle = -1;
319         aCommandSequence[nIndex].Value = uno::makeAny( ::rtl::OUString( rCommand.GetArgument() ) );
320         aCommandSequence[nIndex].State = beans::PropertyState_DIRECT_VALUE;
321 	}
322 }
323 
324