1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <UnxCommandThread.hxx>
21 #include <UnxNotifyThread.hxx>
23 #include <rtl/ustring.hxx>
24 #include <rtl/ustrbuf.hxx>
30 using namespace ::com::sun::star
;
34 ::std::list
< OUString
> tokenize( const OUString
&rCommand
)
36 ::std::list
< OUString
> aList
;
37 OUStringBuffer
aBuffer( 1024 );
39 const sal_Unicode
*pUnicode
= rCommand
.getStr();
40 const sal_Unicode
*pEnd
= pUnicode
+ rCommand
.getLength();
43 for ( ; pUnicode
!= pEnd
; ++pUnicode
)
45 if ( *pUnicode
== '\\' )
48 if ( pUnicode
!= pEnd
)
50 if ( *pUnicode
== 'n' )
51 aBuffer
.appendAscii( "\n", 1 );
53 aBuffer
.append( *pUnicode
);
56 else if ( *pUnicode
== '"' )
58 else if ( *pUnicode
== ' ' && !bQuoted
)
59 aList
.push_back( aBuffer
.makeStringAndClear() );
61 aBuffer
.append( *pUnicode
);
63 aList
.push_back( aBuffer
.makeStringAndClear() );
70 // UnxFilePickerCommandThread
72 UnxFilePickerCommandThread::UnxFilePickerCommandThread( UnxFilePickerNotifyThread
*pNotifyThread
, int nReadFD
)
73 : m_pNotifyThread( pNotifyThread
),
78 UnxFilePickerCommandThread::~UnxFilePickerCommandThread()
82 bool SAL_CALL
UnxFilePickerCommandThread::result()
84 ::osl::MutexGuard
aGuard( m_aMutex
);
89 OUString SAL_CALL
UnxFilePickerCommandThread::getCurrentFilter()
91 ::osl::MutexGuard
aGuard( m_aMutex
);
93 return m_aGetCurrentFilter
;
96 OUString SAL_CALL
UnxFilePickerCommandThread::getDirectory()
98 ::osl::MutexGuard
aGuard( m_aMutex
);
100 return m_aGetDirectory
;
103 uno::Sequence
< OUString
> SAL_CALL
UnxFilePickerCommandThread::getFiles()
105 ::osl::MutexGuard
aGuard( m_aMutex
);
107 sal_Int32 nSize
= m_aGetFiles
.size();
108 uno::Sequence
< OUString
> aFiles( ( nSize
> 1 )? nSize
+ 1: nSize
);
111 aFiles
[0] = m_aGetFiles
.front();
112 else if ( nSize
> 1 )
114 // First entry in the sequence must be the dirname, the others are the
115 // filenames, so we have to rearrange the list...
117 OUString aFront
= m_aGetFiles
.front();
118 sal_Int32 nLastSlash
= aFront
.lastIndexOf( '/' );
120 aFiles
[0] = ( nLastSlash
>= 0 )? aFront
.copy( 0, nLastSlash
): OUString();
124 for ( ::std::list
< OUString
>::const_iterator it
= m_aGetFiles
.begin();
125 it
!= m_aGetFiles
.end(); ++it
, ++nIdx
)
127 sal_Int32 nLength
= (*it
).getLength() - nLastSlash
;
128 aFiles
[nIdx
] = ( nLength
>= 0 )? (*it
).copy( nLastSlash
, nLength
): OUString();
135 uno::Any SAL_CALL
UnxFilePickerCommandThread::getValue()
137 ::osl::MutexGuard
aGuard( m_aMutex
);
142 void SAL_CALL
UnxFilePickerCommandThread::run()
144 osl_setThreadName("UnxFilePickerCommandThread");
149 sal_Int32 nBufferSize
= 1024; // 1 is for testing, 1024 for real use
150 sal_Char
*pBuffer
= new sal_Char
[nBufferSize
];
151 sal_Char
*pBufferEnd
= pBuffer
+ nBufferSize
;
153 sal_Char
*pWhereToRead
= pBuffer
;
154 sal_Char
*pEntryBegin
= pBuffer
;
155 sal_Int32 nBytesRead
= 0;
156 bool bShouldExit
= false;
157 while ( !bShouldExit
&& ( nBytesRead
= read( m_nReadFD
, pWhereToRead
, pBufferEnd
- pWhereToRead
) ) > 0 )
159 bool bFoundNL
= false;
160 sal_Char
*pWhereToReadEnd
= pWhereToRead
+ nBytesRead
;
161 sal_Char
*pEntryEnd
= pWhereToRead
;
163 for ( ; pEntryEnd
< pWhereToReadEnd
&& *pEntryEnd
!= '\n'; ++pEntryEnd
)
166 if ( pEntryEnd
< pWhereToReadEnd
)
171 if ( strcmp( pEntryBegin
, "exited" ) == 0 )
174 handleCommand( OUString( pEntryBegin
, pEntryEnd
- pEntryBegin
, RTL_TEXTENCODING_UTF8
)/*, bQuit*/ );
176 pEntryBegin
= pEntryEnd
+ 1;
178 } while ( pEntryEnd
< pWhereToReadEnd
);
182 if ( pEntryBegin
< pBufferEnd
)
183 memmove( pBuffer
, pEntryBegin
, pWhereToReadEnd
- pEntryBegin
);
187 // enlarge the buffer size
189 sal_Char
*pNewBuffer
= new sal_Char
[nBufferSize
];
190 if ( pEntryBegin
< pBufferEnd
)
191 memcpy( pNewBuffer
, pEntryBegin
, pWhereToReadEnd
- pEntryBegin
);
194 pBuffer
= pNewBuffer
;
195 pBufferEnd
= pBuffer
+ nBufferSize
;
198 pWhereToRead
= pBuffer
+ ( pWhereToReadEnd
- pEntryBegin
);
199 pEntryBegin
= pBuffer
;
203 void SAL_CALL
UnxFilePickerCommandThread::handleCommand( const OUString
&rCommand
)
205 ::osl::MutexGuard
aGuard( m_aMutex
);
207 #if OSL_DEBUG_LEVEL > 0
208 ::std::cerr
<< "UnxFilePicker received: \"" <<
209 OUStringToOString( rCommand
, RTL_TEXTENCODING_ASCII_US
).getStr() << "\"" << ::std::endl
;
212 ::std::list
< OUString
> aList
= tokenize( rCommand
);
217 OUString aCommandName
= aList
.front();
220 if ( aCommandName
== "accept" )
223 m_aExecCondition
.set();
225 else if ( aCommandName
== "reject" )
228 m_aExecCondition
.set();
230 else if ( aCommandName
== "fileSelectionChanged" )
232 if ( m_pNotifyThread
)
233 m_pNotifyThread
->fileSelectionChanged();
235 else if ( aCommandName
== "files" )
238 m_aGetFilesCondition
.set();
240 else if ( aCommandName
== "value" )
243 if ( !aList
.empty() )
245 aType
= aList
.front();
249 if ( aType
== "bool" )
251 bool bValue
= !aList
.empty() && aList
.front().equalsIgnoreAsciiCase("true");
253 m_aGetValue
<<= bValue
;
254 m_aGetValueCondition
.set();
256 else if ( aType
== "int" )
258 sal_Int32 nValue
= 0;
259 if ( !aList
.empty() )
260 nValue
= aList
.front().toInt32();
262 m_aGetValue
<<= nValue
;
263 m_aGetValueCondition
.set();
265 else if ( aType
== "string" )
268 if ( !aList
.empty() )
269 aValue
= aList
.front();
271 m_aGetValue
<<= aValue
;
272 m_aGetValueCondition
.set();
274 else if ( aType
== "stringList" )
276 uno::Sequence
< OUString
> aSequence( aList
.size() );
278 for ( ::std::list
< OUString
>::const_iterator it
= aList
.begin(); it
!= aList
.end(); ++it
, ++nIdx
)
279 aSequence
[nIdx
] = (*it
);
281 m_aGetValue
<<= aSequence
;
282 m_aGetValueCondition
.set();
286 m_aGetValue
= uno::Any();
287 m_aGetValueCondition
.set();
290 else if ( aCommandName
== "currentFilter" )
292 m_aGetCurrentFilter
= aList
.empty()? OUString(): aList
.front();
293 m_aGetCurrentFilterCondition
.set();
295 else if ( aCommandName
== "currentDirectory" )
297 m_aGetDirectory
= aList
.empty()? OUString(): aList
.front();
298 m_aGetDirectoryCondition
.set();
302 #if OSL_DEBUG_LEVEL > 0
303 ::std::cerr
<< "Unrecognized command: "
304 << OUStringToOString( aCommandName
, RTL_TEXTENCODING_ASCII_US
).getStr() << "\"" << ::std::endl
;
309 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */