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