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 <sal/config.h>
25 #include <osl/diagnose.h>
26 #include "FilterContainer.hxx"
30 #if !defined WIN32_LEAN_AND_MEAN
31 # define WIN32_LEAN_AND_MEAN
35 CFilterContainer::CFilterContainer( sal_Int32 initSize
) :
36 m_vFilters( initSize
),
37 m_bIterInitialized( false )
41 // add a name/filter pair
43 bool CFilterContainer::addFilter(
44 const OUString
& aName
, const OUString
& aFilter
, bool bAllowDuplicates
)
46 // check if the filter is already in the container
49 if ( !bAllowDuplicates
)
51 pos
= getFilterTagPos( aName
);
52 if ( pos
< 0 ) // if not there, append
54 m_vFilters
.push_back( std::make_pair( aName
, aFilter
) );
55 m_bIterInitialized
= false;
60 m_vFilters
.push_back( std::make_pair( aName
, aFilter
) );
61 m_bIterInitialized
= false;
68 // Precondition: the container is not empty
69 // there is a filter identified by the given name
71 bool CFilterContainer::delFilter( const OUString
& aName
)
73 OSL_ASSERT( !m_vFilters
.empty() );
75 sal_Int32 pos
= getFilterTagPos( aName
);
78 m_vFilters
.erase( m_vFilters
.begin() + pos
);
79 m_bIterInitialized
= false;
85 // return the number of filters currently in the container
87 sal_Int32
CFilterContainer::numFilter( )
89 return m_vFilters
.size( );
94 void CFilterContainer::empty()
99 // get a filter by name
100 // Precondition: the container is not empty
101 // there is a filter identified by the name
103 bool CFilterContainer::getFilterByName(const OUString
& aName
, OUString
& theFilter
) const
105 OSL_PRECOND( !m_vFilters
.empty() , "Empty filter container" );
106 return getFilterByIndex(getFilterTagPos(aName
), theFilter
);
109 bool CFilterContainer::getFilterByIndex(sal_Int32 aIndex
, OUString
& theFilter
) const
115 theFilter
= m_vFilters
.at(aIndex
).second
;
117 catch (std::out_of_range
&)
119 OSL_FAIL("Filter index out of range");
126 bool CFilterContainer::getFilterNameByIndex(sal_Int32 aIndex
, OUString
& theName
) const
132 theName
= m_vFilters
.at(aIndex
).first
;
134 catch( std::out_of_range
& )
136 OSL_FAIL( "Filter index out of range" );
143 sal_Int32
CFilterContainer::getFilterPos( const OUString
& aName
) const
145 return getFilterTagPos( aName
);
148 // returns the index of the filter identified by name
150 sal_Int32
CFilterContainer::getFilterTagPos( const OUString
& aName
) const
152 if ( !m_vFilters
.empty() )
154 FILTER_VECTOR_T::const_iterator iter
= std::find_if(m_vFilters
.begin(), m_vFilters
.end(),
155 [&aName
](const FILTER_ENTRY_T
& rFilter
) { return rFilter
.first
.equalsIgnoreAsciiCase(aName
); });
156 if (iter
!= m_vFilters
.end())
157 return std::distance(m_vFilters
.begin(), iter
);
163 // starts enumerating the filter in the container
165 void CFilterContainer::beginEnumFilter( )
167 m_iter
= m_vFilters
.begin( );
168 m_bIterInitialized
= true;
171 // returns true if another filter has been retrieved
173 bool CFilterContainer::getNextFilter( FILTER_ENTRY_T
& nextFilterEntry
)
175 OSL_ASSERT( m_bIterInitialized
);
177 bool bRet
= ( m_iter
!= m_vFilters
.end( ) );
180 nextFilterEntry
= *m_iter
++;
182 m_bIterInitialized
= false;
187 void CFilterContainer::setCurrentFilter( const OUString
& aName
)
189 m_sCurrentFilter
= aName
;
192 OUString
CFilterContainer::getCurrentFilter() const
194 return m_sCurrentFilter
;
197 // calculates the length of a '\0' separated filter, that means
198 // length of the name + '\0' + length of the filter string +
201 static sal_uInt32
getLengthFilter( CFilterContainer::FILTER_ENTRY_T aFilterEntry
)
204 aFilterEntry
.first
.getLength( ) + 1 +
205 aFilterEntry
.second
.getLength( ) + 1 );
208 // calculates the length of all filters currently in the container
210 static sal_uInt32
getTotalFilterLength( CFilterContainer
& aFilterContainer
)
212 CFilterContainer::FILTER_ENTRY_T nextFilter
;
214 aFilterContainer
.beginEnumFilter( );
216 sal_uInt32 totalLength
= 0;
217 while( aFilterContainer
.getNextFilter( nextFilter
) )
218 totalLength
+= getLengthFilter( nextFilter
);
220 return ( totalLength
> 0 ) ? totalLength
+ 1 : totalLength
;
224 void wcsmemcpy( sal_Unicode
* pDest
, const sal_Unicode
* pSrc
, sal_uInt32 nLength
)
226 memcpy( pDest
, pSrc
, nLength
* sizeof( sal_Unicode
) );
229 // a helper trivial helper function to create a filter buffer in the
230 // format the Win32 API requires,
231 // e.g. "Text\0*.txt\0Doc\0*.doc;*xls\0\0"
233 OUString
makeWinFilterBuffer( CFilterContainer
& aFilterContainer
)
235 // calculate the required buffer size
236 sal_uInt32 reqBuffSize
= getTotalFilterLength( aFilterContainer
);
238 // return if there are no filters
242 auto pBuff
= std::make_unique
<sal_Unicode
[]>(reqBuffSize
);
244 // initialize the buffer with 0
245 ZeroMemory( pBuff
.get(), sizeof( sal_Unicode
) * reqBuffSize
);
247 OUString winFilterBuff
;
248 CFilterContainer::FILTER_ENTRY_T nextFilter
;
249 sal_uInt32 memPos
= 0;
251 aFilterContainer
.beginEnumFilter( );
253 while( aFilterContainer
.getNextFilter( nextFilter
) )
256 pBuff
.get() + memPos
,
257 nextFilter
.first
.getStr( ),
258 nextFilter
.first
.getLength( ) );
260 memPos
+= nextFilter
.first
.getLength( ) + 1;
263 pBuff
.get() + memPos
,
264 nextFilter
.second
.getStr( ),
265 nextFilter
.second
.getLength( ) );
267 memPos
+= nextFilter
.second
.getLength( ) + 1 ;
270 winFilterBuff
= OUString( pBuff
.get(), reqBuffSize
);
272 return winFilterBuff
;
275 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */