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 //========================================================================= 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 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 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 //========================================================================= 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 //========================================================================= 184 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 //========================================================================= 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 //========================================================================= 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 //========================================================================= 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 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 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