1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_xmlsecurity.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "resourcemanager.hxx"
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include <vcl/svapp.hxx>
34*cdf0e10cSrcweir #include <vcl/fixed.hxx>
35*cdf0e10cSrcweir #include <svtools/stdctrl.hxx>
36*cdf0e10cSrcweir #include <svl/solar.hrc>
37*cdf0e10cSrcweir #include <unotools/syslocale.hxx>
38*cdf0e10cSrcweir #include <rtl/ustring.h>
39*cdf0e10cSrcweir #include <rtl/ustrbuf.h>
40*cdf0e10cSrcweir #include <vector>
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir using ::rtl::OUString;
43*cdf0e10cSrcweir using namespace std;
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir namespace XmlSec
46*cdf0e10cSrcweir {
47*cdf0e10cSrcweir 	static ResMgr*			pResMgr = 0;
48*cdf0e10cSrcweir     static SvtSysLocale*    pSysLocale = 0;
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir 	ResMgr* GetResMgr( void )
51*cdf0e10cSrcweir 	{
52*cdf0e10cSrcweir 		if( !pResMgr )
53*cdf0e10cSrcweir 		{
54*cdf0e10cSrcweir 			ByteString	aName( "xmlsec" );
55*cdf0e10cSrcweir //    		pResMgr = ResMgr::CreateResMgr( aName.GetBuffer(), Application::GetSettings().GetUILanguage() );
56*cdf0e10cSrcweir //			LanguageType	aLang( LANGUAGE_ENGLISH_US );
57*cdf0e10cSrcweir //			pResMgr = ResMgr::CreateResMgr( aName.GetBuffer(), aLang );
58*cdf0e10cSrcweir // MT: Change to Locale
59*cdf0e10cSrcweir 			pResMgr = ResMgr::CreateResMgr( aName.GetBuffer() );
60*cdf0e10cSrcweir 		}
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir 	return pResMgr;
63*cdf0e10cSrcweir 	}
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir 	const LocaleDataWrapper&    GetLocaleData( void )
66*cdf0e10cSrcweir 	{
67*cdf0e10cSrcweir         if (!pSysLocale)
68*cdf0e10cSrcweir             pSysLocale = new SvtSysLocale;
69*cdf0e10cSrcweir         return pSysLocale->GetLocaleData();
70*cdf0e10cSrcweir 	}
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir 	DateTime GetDateTime( const ::com::sun::star::util::DateTime& _rDT )
73*cdf0e10cSrcweir 	{
74*cdf0e10cSrcweir 		return DateTime(
75*cdf0e10cSrcweir 			Date( _rDT.Day, _rDT.Month, _rDT.Year ),
76*cdf0e10cSrcweir 			Time( _rDT.Hours, _rDT.Minutes, _rDT.Seconds, _rDT.HundredthSeconds ) );
77*cdf0e10cSrcweir 	}
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir 	String GetDateTimeString( const ::com::sun::star::util::DateTime& _rDT )
80*cdf0e10cSrcweir 	{
81*cdf0e10cSrcweir         // --> PB 2004-10-12 #i20172# String with date and time information
82*cdf0e10cSrcweir         DateTime aDT( GetDateTime( _rDT ) );
83*cdf0e10cSrcweir         const LocaleDataWrapper& rLoDa = GetLocaleData();
84*cdf0e10cSrcweir         String sRet( rLoDa.getDate( aDT ) );
85*cdf0e10cSrcweir         sRet += ' ';
86*cdf0e10cSrcweir         sRet += rLoDa.getTime( aDT );
87*cdf0e10cSrcweir         return sRet;
88*cdf0e10cSrcweir 	}
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir 	String GetDateTimeString( const rtl::OUString& _rDate, const rtl::OUString& _rTime )
91*cdf0e10cSrcweir 	{
92*cdf0e10cSrcweir 		String sDay( _rDate, 6, 2 );
93*cdf0e10cSrcweir 		String sMonth( _rDate, 4, 2 );
94*cdf0e10cSrcweir 		String sYear( _rDate, 0, 4 );
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir 		String sHour( _rTime, 0, 2 );
97*cdf0e10cSrcweir 		String sMin( _rTime, 4, 2 );
98*cdf0e10cSrcweir 		String sSec( _rTime, 6, 2 );
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir 		Date aDate( (sal_uInt16)sDay.ToInt32(), (sal_uInt16) sMonth.ToInt32(), (sal_uInt16)sYear.ToInt32() );
102*cdf0e10cSrcweir 		Time aTime( sHour.ToInt32(), sMin.ToInt32(), sSec.ToInt32(), 0 );
103*cdf0e10cSrcweir         const LocaleDataWrapper& rLoDa = GetLocaleData();
104*cdf0e10cSrcweir 		String aStr( rLoDa.getDate( aDate ) );
105*cdf0e10cSrcweir 		aStr.AppendAscii( " " );
106*cdf0e10cSrcweir 		aStr += rLoDa.getTime( aTime );
107*cdf0e10cSrcweir 		return aStr;
108*cdf0e10cSrcweir 	}
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir 	String GetDateString( const ::com::sun::star::util::DateTime& _rDT )
111*cdf0e10cSrcweir 	{
112*cdf0e10cSrcweir 		return GetLocaleData().getDate( GetDateTime( _rDT ) );
113*cdf0e10cSrcweir 	}
114*cdf0e10cSrcweir 
115*cdf0e10cSrcweir     /*
116*cdf0e10cSrcweir         Creates two strings based on the distinguished name which are displayed in the
117*cdf0e10cSrcweir         certificate details view. The first string contains only the values of the attribute
118*cdf0e10cSrcweir         and valudes pairs, which are separated by commas. All escape characters ('"') are
119*cdf0e10cSrcweir         removed.
120*cdf0e10cSrcweir         The second string is for the details view at the bottom. It shows the attribute/value
121*cdf0e10cSrcweir         pairs on different lines. All escape characters ('"') are removed.
122*cdf0e10cSrcweir     */
123*cdf0e10cSrcweir     pair< OUString, OUString> GetDNForCertDetailsView( const OUString & rRawString)
124*cdf0e10cSrcweir     {
125*cdf0e10cSrcweir         vector< pair< OUString, OUString > > vecAttrValueOfDN = parseDN(rRawString);
126*cdf0e10cSrcweir         ::rtl::OUStringBuffer s1, s2;
127*cdf0e10cSrcweir         OUString sEqual(RTL_CONSTASCII_USTRINGPARAM(" = "));
128*cdf0e10cSrcweir         typedef vector< pair < OUString, OUString > >::const_iterator CIT;
129*cdf0e10cSrcweir         for (CIT i = vecAttrValueOfDN.begin(); i < vecAttrValueOfDN.end(); i ++)
130*cdf0e10cSrcweir         {
131*cdf0e10cSrcweir             if (i != vecAttrValueOfDN.begin())
132*cdf0e10cSrcweir             {
133*cdf0e10cSrcweir                 s1.append(static_cast<sal_Unicode>(','));
134*cdf0e10cSrcweir                 s2.append(static_cast<sal_Unicode>('\n'));
135*cdf0e10cSrcweir             }
136*cdf0e10cSrcweir             s1.append(i->second);
137*cdf0e10cSrcweir             s2.append(i->first);
138*cdf0e10cSrcweir             s2.append(sEqual);
139*cdf0e10cSrcweir             s2.append(i->second);
140*cdf0e10cSrcweir         }
141*cdf0e10cSrcweir         return make_pair(s1.makeStringAndClear(), s2.makeStringAndClear());
142*cdf0e10cSrcweir     }
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir /*
145*cdf0e10cSrcweir     Whenever the attribute value contains special characters, such as '"' or ',' (without '')
146*cdf0e10cSrcweir     then the value will be enclosed in double quotes by the respective Windows or NSS function
147*cdf0e10cSrcweir     which we use to retrieve, for example, the subject name. If double quotes appear in the value then
148*cdf0e10cSrcweir     they are escaped with a double quote. This function removes the escape characters.
149*cdf0e10cSrcweir */
150*cdf0e10cSrcweir #ifdef WNT
151*cdf0e10cSrcweir vector< pair< OUString, OUString> > parseDN(const OUString& rRawString)
152*cdf0e10cSrcweir {
153*cdf0e10cSrcweir         vector< pair<OUString, OUString> > retVal;
154*cdf0e10cSrcweir         bool bInEscape = false;
155*cdf0e10cSrcweir         bool bInValue = false;
156*cdf0e10cSrcweir         bool bInType = true;
157*cdf0e10cSrcweir         sal_Int32 nTypeNameStart = 0;
158*cdf0e10cSrcweir         OUString sType;
159*cdf0e10cSrcweir         ::rtl::OUStringBuffer sbufValue;
160*cdf0e10cSrcweir         sal_Int32 length = rRawString.getLength();
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir         for (sal_Int32 i = 0; i < length; i++)
163*cdf0e10cSrcweir         {
164*cdf0e10cSrcweir             sal_Unicode c = rRawString[i];
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir             if (c == '=')
167*cdf0e10cSrcweir             {
168*cdf0e10cSrcweir                 if (! bInValue)
169*cdf0e10cSrcweir                 {
170*cdf0e10cSrcweir                     sType = rRawString.copy(nTypeNameStart, i - nTypeNameStart);
171*cdf0e10cSrcweir                     sType = sType.trim();
172*cdf0e10cSrcweir                     bInType = false;
173*cdf0e10cSrcweir                 }
174*cdf0e10cSrcweir                 else
175*cdf0e10cSrcweir                 {
176*cdf0e10cSrcweir                     sbufValue.append(c);
177*cdf0e10cSrcweir                 }
178*cdf0e10cSrcweir             }
179*cdf0e10cSrcweir             else if (c == '"')
180*cdf0e10cSrcweir             {
181*cdf0e10cSrcweir                 if (!bInEscape)
182*cdf0e10cSrcweir                 {
183*cdf0e10cSrcweir                     //If this is the quote is the first of the couple which enclose the
184*cdf0e10cSrcweir                     //whole value, because the value contains special characters
185*cdf0e10cSrcweir                     //then we just drop it. That is, this character must be followed by
186*cdf0e10cSrcweir                     //a character which is not '"'.
187*cdf0e10cSrcweir                     if ( i + 1 < length && rRawString[i+1] == '"')
188*cdf0e10cSrcweir                         bInEscape = true;
189*cdf0e10cSrcweir                     else
190*cdf0e10cSrcweir                         bInValue = !bInValue; //value is enclosed in " "
191*cdf0e10cSrcweir                 }
192*cdf0e10cSrcweir                 else
193*cdf0e10cSrcweir                 {
194*cdf0e10cSrcweir                     //This quote is escaped by a preceding quote and therefore is
195*cdf0e10cSrcweir                     //part of the value
196*cdf0e10cSrcweir                     sbufValue.append(c);
197*cdf0e10cSrcweir                     bInEscape = false;
198*cdf0e10cSrcweir                 }
199*cdf0e10cSrcweir             }
200*cdf0e10cSrcweir             else if (c == ',' || c == '+')
201*cdf0e10cSrcweir             {
202*cdf0e10cSrcweir                 //The comma separate the attribute value pairs.
203*cdf0e10cSrcweir                 //If the comma is not part of a value (the value would then be enclosed in '"'),
204*cdf0e10cSrcweir                 //then we have reached the end of the value
205*cdf0e10cSrcweir                 if (!bInValue)
206*cdf0e10cSrcweir                 {
207*cdf0e10cSrcweir                     OSL_ASSERT(sType.getLength());
208*cdf0e10cSrcweir                     retVal.push_back(make_pair(sType, sbufValue.makeStringAndClear()));
209*cdf0e10cSrcweir                     sType = OUString();
210*cdf0e10cSrcweir                     //The next char is the start of the new type
211*cdf0e10cSrcweir                     nTypeNameStart = i + 1;
212*cdf0e10cSrcweir                     bInType = true;
213*cdf0e10cSrcweir                 }
214*cdf0e10cSrcweir                 else
215*cdf0e10cSrcweir                 {
216*cdf0e10cSrcweir                     //The whole string is enclosed because it contains special characters.
217*cdf0e10cSrcweir                     //The enclosing '"' are not part of certificate but will be added by
218*cdf0e10cSrcweir                     //the function (Windows or NSS) which retrieves DN
219*cdf0e10cSrcweir                     sbufValue.append(c);
220*cdf0e10cSrcweir                 }
221*cdf0e10cSrcweir             }
222*cdf0e10cSrcweir             else
223*cdf0e10cSrcweir             {
224*cdf0e10cSrcweir                 if (!bInType)
225*cdf0e10cSrcweir                     sbufValue.append(c);
226*cdf0e10cSrcweir             }
227*cdf0e10cSrcweir         }
228*cdf0e10cSrcweir         if (sbufValue.getLength())
229*cdf0e10cSrcweir         {
230*cdf0e10cSrcweir             OSL_ASSERT(sType.getLength());
231*cdf0e10cSrcweir             retVal.push_back(make_pair(sType, sbufValue.makeStringAndClear()));
232*cdf0e10cSrcweir         }
233*cdf0e10cSrcweir         return retVal;
234*cdf0e10cSrcweir     }
235*cdf0e10cSrcweir #else
236*cdf0e10cSrcweir vector< pair< OUString, OUString> > parseDN(const OUString& rRawString)
237*cdf0e10cSrcweir     {
238*cdf0e10cSrcweir         vector< pair<OUString, OUString> > retVal;
239*cdf0e10cSrcweir         //bInEscape == true means that the preceding character is an escape character
240*cdf0e10cSrcweir         bool bInEscape = false;
241*cdf0e10cSrcweir         bool bInValue = false;
242*cdf0e10cSrcweir         bool bInType = true;
243*cdf0e10cSrcweir         sal_Int32 nTypeNameStart = 0;
244*cdf0e10cSrcweir         OUString sType;
245*cdf0e10cSrcweir         ::rtl::OUStringBuffer sbufValue;
246*cdf0e10cSrcweir         sal_Int32 length = rRawString.getLength();
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir         for (sal_Int32 i = 0; i < length; i++)
249*cdf0e10cSrcweir         {
250*cdf0e10cSrcweir             sal_Unicode c = rRawString[i];
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir             if (c == '=')
253*cdf0e10cSrcweir             {
254*cdf0e10cSrcweir                 if (! bInValue)
255*cdf0e10cSrcweir                 {
256*cdf0e10cSrcweir                     sType = rRawString.copy(nTypeNameStart, i - nTypeNameStart);
257*cdf0e10cSrcweir                     sType = sType.trim();
258*cdf0e10cSrcweir                     bInType = false;
259*cdf0e10cSrcweir                 }
260*cdf0e10cSrcweir                 else
261*cdf0e10cSrcweir                 {
262*cdf0e10cSrcweir                     sbufValue.append(c);
263*cdf0e10cSrcweir                 }
264*cdf0e10cSrcweir             }
265*cdf0e10cSrcweir             else if (c == '\\')
266*cdf0e10cSrcweir             {
267*cdf0e10cSrcweir                 if (!bInEscape)
268*cdf0e10cSrcweir                 {
269*cdf0e10cSrcweir                     bInEscape = true;
270*cdf0e10cSrcweir                 }
271*cdf0e10cSrcweir                 else
272*cdf0e10cSrcweir                 { // bInEscape is true
273*cdf0e10cSrcweir                     sbufValue.append(c);
274*cdf0e10cSrcweir                     bInEscape = false;
275*cdf0e10cSrcweir                 }
276*cdf0e10cSrcweir             }
277*cdf0e10cSrcweir             else if (c == '"')
278*cdf0e10cSrcweir             {
279*cdf0e10cSrcweir                 //an unescaped '"' is either at the beginning or end of the value
280*cdf0e10cSrcweir                 if (!bInEscape)
281*cdf0e10cSrcweir                 {
282*cdf0e10cSrcweir                     if ( !bInValue)
283*cdf0e10cSrcweir                         bInValue = true;
284*cdf0e10cSrcweir                     else if (bInValue)
285*cdf0e10cSrcweir                         bInValue = false;
286*cdf0e10cSrcweir                 }
287*cdf0e10cSrcweir                 else
288*cdf0e10cSrcweir                 {
289*cdf0e10cSrcweir                     //This quote is escaped by a preceding quote and therefore is
290*cdf0e10cSrcweir                     //part of the value
291*cdf0e10cSrcweir                     sbufValue.append(c);
292*cdf0e10cSrcweir                     bInEscape = false;
293*cdf0e10cSrcweir                 }
294*cdf0e10cSrcweir             }
295*cdf0e10cSrcweir             else if (c == ',' || c == '+')
296*cdf0e10cSrcweir             {
297*cdf0e10cSrcweir                 //The comma separate the attribute value pairs.
298*cdf0e10cSrcweir                 //If the comma is not part of a value (the value would then be enclosed in '"'),
299*cdf0e10cSrcweir                 //then we have reached the end of the value
300*cdf0e10cSrcweir                 if (!bInValue)
301*cdf0e10cSrcweir                 {
302*cdf0e10cSrcweir                     OSL_ASSERT(sType.getLength());
303*cdf0e10cSrcweir                     retVal.push_back(make_pair(sType, sbufValue.makeStringAndClear()));
304*cdf0e10cSrcweir                     sType = OUString();
305*cdf0e10cSrcweir                     //The next char is the start of the new type
306*cdf0e10cSrcweir                     nTypeNameStart = i + 1;
307*cdf0e10cSrcweir                     bInType = true;
308*cdf0e10cSrcweir                 }
309*cdf0e10cSrcweir                 else
310*cdf0e10cSrcweir                 {
311*cdf0e10cSrcweir                     //The whole string is enclosed because it contains special characters.
312*cdf0e10cSrcweir                     //The enclosing '"' are not part of certificate but will be added by
313*cdf0e10cSrcweir                     //the function (Windows or NSS) which retrieves DN
314*cdf0e10cSrcweir                     sbufValue.append(c);
315*cdf0e10cSrcweir                 }
316*cdf0e10cSrcweir             }
317*cdf0e10cSrcweir             else
318*cdf0e10cSrcweir             {
319*cdf0e10cSrcweir                 if (!bInType)
320*cdf0e10cSrcweir                 {
321*cdf0e10cSrcweir                     sbufValue.append(c);
322*cdf0e10cSrcweir                     bInEscape = false;
323*cdf0e10cSrcweir                 }
324*cdf0e10cSrcweir             }
325*cdf0e10cSrcweir         }
326*cdf0e10cSrcweir         if (sbufValue.getLength())
327*cdf0e10cSrcweir         {
328*cdf0e10cSrcweir             OSL_ASSERT(sType.getLength());
329*cdf0e10cSrcweir             retVal.push_back(make_pair(sType, sbufValue.makeStringAndClear()));
330*cdf0e10cSrcweir         }
331*cdf0e10cSrcweir         return retVal;
332*cdf0e10cSrcweir     }
333*cdf0e10cSrcweir 
334*cdf0e10cSrcweir #endif
335*cdf0e10cSrcweir 
336*cdf0e10cSrcweir     String GetContentPart( const String& _rRawString )
337*cdf0e10cSrcweir     {
338*cdf0e10cSrcweir         char const * aIDs[] = { "CN", "OU", "O", "E", NULL };
339*cdf0e10cSrcweir         OUString retVal;
340*cdf0e10cSrcweir         int i = 0;
341*cdf0e10cSrcweir         vector< pair< OUString, OUString > > vecAttrValueOfDN = parseDN(_rRawString);
342*cdf0e10cSrcweir         while ( aIDs[i] )
343*cdf0e10cSrcweir         {
344*cdf0e10cSrcweir             OUString sPartId = OUString::createFromAscii( aIDs[i++] );
345*cdf0e10cSrcweir             typedef vector< pair < OUString, OUString > >::const_iterator CIT;
346*cdf0e10cSrcweir             for (CIT idn = vecAttrValueOfDN.begin(); idn != vecAttrValueOfDN.end(); idn++)
347*cdf0e10cSrcweir             {
348*cdf0e10cSrcweir                 if (idn->first.equals(sPartId))
349*cdf0e10cSrcweir                 {
350*cdf0e10cSrcweir                     retVal = idn->second;
351*cdf0e10cSrcweir                     break;
352*cdf0e10cSrcweir                 }
353*cdf0e10cSrcweir             }
354*cdf0e10cSrcweir             if (retVal.getLength())
355*cdf0e10cSrcweir                 break;
356*cdf0e10cSrcweir         }
357*cdf0e10cSrcweir         return retVal;
358*cdf0e10cSrcweir     }
359*cdf0e10cSrcweir 
360*cdf0e10cSrcweir 	String GetHexString( const ::com::sun::star::uno::Sequence< sal_Int8 >& _rSeq, const char* _pSep, sal_uInt16 _nLineBreak )
361*cdf0e10cSrcweir 	{
362*cdf0e10cSrcweir 		const sal_Int8*			pSerNumSeq = _rSeq.getConstArray();
363*cdf0e10cSrcweir 		int						nCnt = _rSeq.getLength();
364*cdf0e10cSrcweir 		String					aStr;
365*cdf0e10cSrcweir 		const char				pHexDigs[ 17 ] = "0123456789ABCDEF";
366*cdf0e10cSrcweir 		char					pBuffer[ 3 ] = "  ";
367*cdf0e10cSrcweir 		sal_uInt8					nNum;
368*cdf0e10cSrcweir 		sal_uInt16					nBreakStart = _nLineBreak? _nLineBreak : 1;
369*cdf0e10cSrcweir 		sal_uInt16					nBreak = nBreakStart;
370*cdf0e10cSrcweir 		for( int i = 0 ; i < nCnt ; ++i )
371*cdf0e10cSrcweir 		{
372*cdf0e10cSrcweir 			nNum = sal_uInt8( pSerNumSeq[ i ] );
373*cdf0e10cSrcweir 
374*cdf0e10cSrcweir 			//MM : exchange the buffer[0] and buffer[1], which make it consistent with Mozilla and Windows
375*cdf0e10cSrcweir 			pBuffer[ 1 ] = pHexDigs[ nNum & 0x0F ];
376*cdf0e10cSrcweir 			nNum >>= 4;
377*cdf0e10cSrcweir 			pBuffer[ 0 ] = pHexDigs[ nNum ];
378*cdf0e10cSrcweir 			aStr.AppendAscii( pBuffer );
379*cdf0e10cSrcweir 
380*cdf0e10cSrcweir 			--nBreak;
381*cdf0e10cSrcweir 			if( nBreak )
382*cdf0e10cSrcweir 				aStr.AppendAscii( _pSep );
383*cdf0e10cSrcweir 			else
384*cdf0e10cSrcweir 			{
385*cdf0e10cSrcweir 				nBreak = nBreakStart;
386*cdf0e10cSrcweir 				aStr.AppendAscii( "\n" );
387*cdf0e10cSrcweir 			}
388*cdf0e10cSrcweir 		}
389*cdf0e10cSrcweir 
390*cdf0e10cSrcweir 		return aStr;
391*cdf0e10cSrcweir 	}
392*cdf0e10cSrcweir 
393*cdf0e10cSrcweir 	long ShrinkToFitWidth( Control& _rCtrl, long _nOffs )
394*cdf0e10cSrcweir 	{
395*cdf0e10cSrcweir 		long	nWidth = _rCtrl.GetTextWidth( _rCtrl.GetText() );
396*cdf0e10cSrcweir 		Size	aSize( _rCtrl.GetSizePixel() );
397*cdf0e10cSrcweir 		nWidth += _nOffs;
398*cdf0e10cSrcweir 		aSize.Width() = nWidth;
399*cdf0e10cSrcweir 		_rCtrl.SetSizePixel( aSize );
400*cdf0e10cSrcweir 		return nWidth;
401*cdf0e10cSrcweir 	}
402*cdf0e10cSrcweir 
403*cdf0e10cSrcweir 	void AlignAfterImage( const FixedImage& _rImage, Control& _rCtrl, long _nXOffset )
404*cdf0e10cSrcweir 	{
405*cdf0e10cSrcweir 		Point	aPos( _rImage.GetPosPixel() );
406*cdf0e10cSrcweir 		Size	aSize( _rImage.GetSizePixel() );
407*cdf0e10cSrcweir 		long	n = aPos.X();
408*cdf0e10cSrcweir 		n += aSize.Width();
409*cdf0e10cSrcweir 		n += _nXOffset;
410*cdf0e10cSrcweir 		aPos.X() = n;
411*cdf0e10cSrcweir 		n = aPos.Y();
412*cdf0e10cSrcweir 		n += aSize.Height() / 2;					// y-position is in the middle of the image
413*cdf0e10cSrcweir 		n -= _rCtrl.GetSizePixel().Height() / 2;	// center Control
414*cdf0e10cSrcweir 		aPos.Y() = n;
415*cdf0e10cSrcweir 		_rCtrl.SetPosPixel( aPos );
416*cdf0e10cSrcweir 	}
417*cdf0e10cSrcweir 
418*cdf0e10cSrcweir 	void AlignAfterImage( const FixedImage& _rImage, FixedInfo& _rFI, long _nXOffset )
419*cdf0e10cSrcweir 	{
420*cdf0e10cSrcweir 		AlignAfterImage( _rImage, static_cast< Control& >( _rFI ), _nXOffset );
421*cdf0e10cSrcweir 		ShrinkToFitWidth( _rFI );
422*cdf0e10cSrcweir 	}
423*cdf0e10cSrcweir 
424*cdf0e10cSrcweir 	void AlignAndFitImageAndControl( FixedImage& _rImage, FixedInfo& _rFI, long _nXOffset )
425*cdf0e10cSrcweir 	{
426*cdf0e10cSrcweir 		_rImage.SetSizePixel( _rImage.GetImage().GetSizePixel() );
427*cdf0e10cSrcweir 		AlignAfterImage( _rImage, _rFI, _nXOffset );
428*cdf0e10cSrcweir 	}
429*cdf0e10cSrcweir }
430*cdf0e10cSrcweir 
431*cdf0e10cSrcweir 
432