xref: /aoo41x/main/vcl/source/gdi/jobset.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 
31 #include <tools/debug.hxx>
32 #include <tools/stream.hxx>
33 
34 #include <rtl/alloc.h>
35 
36 #include <vcl/jobset.hxx>
37 
38 #include <jobset.h>
39 
40 // =======================================================================
41 
42 DBG_NAME( JobSetup )
43 
44 #define JOBSET_FILEFORMAT2		3780
45 #define JOBSET_FILE364_SYSTEM	((sal_uInt16)0xFFFF)
46 #define JOBSET_FILE605_SYSTEM	((sal_uInt16)0xFFFE)
47 
48 struct ImplOldJobSetupData
49 {
50 	char	cPrinterName[64];
51 	char	cDeviceName[32];
52 	char	cPortName[32];
53 	char	cDriverName[32];
54 };
55 
56 struct Impl364JobSetupData
57 {
58 	SVBT16	nSize;
59 	SVBT16	nSystem;
60 	SVBT32	nDriverDataLen;
61 	SVBT16	nOrientation;
62 	SVBT16	nPaperBin;
63 	SVBT16	nPaperFormat;
64 	SVBT32	nPaperWidth;
65 	SVBT32	nPaperHeight;
66 };
67 
68 // =======================================================================
69 
70 ImplJobSetup::ImplJobSetup()
71 {
72 	mnRefCount			= 1;
73 	mnSystem			= 0;
74 	meOrientation		= ORIENTATION_PORTRAIT;
75     meDuplexMode        = DUPLEX_UNKNOWN;
76 	mnPaperBin			= 0;
77 	mePaperFormat		= PAPER_USER;
78 	mnPaperWidth		= 0;
79 	mnPaperHeight		= 0;
80 	mnDriverDataLen 	= 0;
81 	mpDriverData		= NULL;
82 }
83 
84 // -----------------------------------------------------------------------
85 
86 ImplJobSetup::ImplJobSetup( const ImplJobSetup& rJobSetup ) :
87 	maPrinterName( rJobSetup.maPrinterName ),
88 	maDriver( rJobSetup.maDriver )
89 {
90 	mnRefCount			= 1;
91 	mnSystem			= rJobSetup.mnSystem;
92 	meOrientation		= rJobSetup.meOrientation;
93     meDuplexMode        = rJobSetup.meDuplexMode;
94 	mnPaperBin			= rJobSetup.mnPaperBin;
95 	mePaperFormat		= rJobSetup.mePaperFormat;
96 	mnPaperWidth		= rJobSetup.mnPaperWidth;
97 	mnPaperHeight		= rJobSetup.mnPaperHeight;
98 	mnDriverDataLen 	= rJobSetup.mnDriverDataLen;
99 	if ( rJobSetup.mpDriverData )
100 	{
101 		mpDriverData = (sal_uInt8*)rtl_allocateMemory( mnDriverDataLen );
102 		memcpy( mpDriverData, rJobSetup.mpDriverData, mnDriverDataLen );
103 	}
104 	else
105 		mpDriverData = NULL;
106 	maValueMap 			= rJobSetup.maValueMap;
107 }
108 
109 // -----------------------------------------------------------------------
110 
111 ImplJobSetup::~ImplJobSetup()
112 {
113 	rtl_freeMemory( mpDriverData );
114 }
115 
116 // =======================================================================
117 
118 ImplJobSetup* JobSetup::ImplGetData()
119 {
120 	if ( !mpData )
121 		mpData = new ImplJobSetup;
122 	else if ( mpData->mnRefCount != 1 )
123 	{
124 		mpData->mnRefCount--;
125 		mpData = new ImplJobSetup( *mpData );
126 	}
127 
128 	return mpData;
129 }
130 
131 // -----------------------------------------------------------------------
132 
133 ImplJobSetup* JobSetup::ImplGetConstData()
134 {
135 	if ( !mpData )
136 		mpData = new ImplJobSetup;
137 	return mpData;
138 }
139 
140 // -----------------------------------------------------------------------
141 
142 const ImplJobSetup* JobSetup::ImplGetConstData() const
143 {
144 	if ( !mpData )
145 		((JobSetup*)this)->mpData = new ImplJobSetup;
146 	return mpData;
147 }
148 
149 // =======================================================================
150 
151 JobSetup::JobSetup()
152 {
153 	DBG_CTOR( JobSetup, NULL );
154 
155 	mpData = NULL;
156 }
157 
158 // -----------------------------------------------------------------------
159 
160 JobSetup::JobSetup( const JobSetup& rJobSetup )
161 {
162 	DBG_CTOR( JobSetup, NULL );
163 	DBG_CHKOBJ( &rJobSetup, JobSetup, NULL );
164 	DBG_ASSERT( !rJobSetup.mpData || (rJobSetup.mpData->mnRefCount < 0xFFFE), "JobSetup: RefCount overflow" );
165 
166 	mpData = rJobSetup.mpData;
167 	if ( mpData )
168 		mpData->mnRefCount++;
169 }
170 
171 // -----------------------------------------------------------------------
172 
173 JobSetup::~JobSetup()
174 {
175 	DBG_DTOR( JobSetup, NULL );
176 
177 	if ( mpData )
178 	{
179 		if ( mpData->mnRefCount == 1 )
180 			delete mpData;
181 		else
182 			mpData->mnRefCount--;
183 	}
184 }
185 
186 // -----------------------------------------------------------------------
187 
188 XubString JobSetup::GetPrinterName() const
189 {
190 	if ( mpData )
191 		return mpData->maPrinterName;
192 	else
193 	{
194 		XubString aName;
195 		return aName;
196 	}
197 }
198 
199 // -----------------------------------------------------------------------
200 
201 XubString JobSetup::GetDriverName() const
202 {
203 	if ( mpData )
204 		return mpData->maDriver;
205 	else
206 	{
207 		XubString aDriver;
208 		return aDriver;
209 	}
210 }
211 
212 // -----------------------------------------------------------------------
213 
214 String JobSetup::GetValue( const String& rKey ) const
215 {
216 	if( mpData )
217 	{
218 		::std::hash_map< ::rtl::OUString, ::rtl::OUString, ::rtl::OUStringHash >::const_iterator it;
219 		it = mpData->maValueMap.find( rKey );
220 		return it != mpData->maValueMap.end() ? String( it->second ) : String();
221 	}
222 	return String();
223 }
224 
225 // -----------------------------------------------------------------------
226 
227 void JobSetup::SetValue( const String& rKey, const String& rValue )
228 {
229 	if( ! mpData )
230 		mpData = new ImplJobSetup();
231 
232 	mpData->maValueMap[ rKey ] = rValue;
233 }
234 
235 // -----------------------------------------------------------------------
236 
237 JobSetup& JobSetup::operator=( const JobSetup& rJobSetup )
238 {
239 	DBG_CHKTHIS( JobSetup, NULL );
240 	DBG_CHKOBJ( &rJobSetup, JobSetup, NULL );
241 	DBG_ASSERT( !rJobSetup.mpData || (rJobSetup.mpData->mnRefCount) < 0xFFFE, "JobSetup: RefCount overflow" );
242 
243 	// Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
244 	if ( rJobSetup.mpData )
245 		rJobSetup.mpData->mnRefCount++;
246 
247 	// Wenn es keine statischen ImpDaten sind, dann loeschen, wenn es
248 	// die letzte Referenz ist, sonst Referenzcounter decrementieren
249 	if ( mpData )
250 	{
251 		if ( mpData->mnRefCount == 1 )
252 			delete mpData;
253 		else
254 			mpData->mnRefCount--;
255 	}
256 
257 	mpData = rJobSetup.mpData;
258 
259 	return *this;
260 }
261 
262 // -----------------------------------------------------------------------
263 
264 sal_Bool JobSetup::operator==( const JobSetup& rJobSetup ) const
265 {
266 	DBG_CHKTHIS( JobSetup, NULL );
267 	DBG_CHKOBJ( &rJobSetup, JobSetup, NULL );
268 
269 	if ( mpData == rJobSetup.mpData )
270 		return sal_True;
271 
272 	if ( !mpData || !rJobSetup.mpData )
273 		return sal_False;
274 
275 	ImplJobSetup* pData1 = mpData;
276 	ImplJobSetup* pData2 = rJobSetup.mpData;
277 	if ( (pData1->mnSystem			== pData2->mnSystem)				&&
278 		 (pData1->maPrinterName 	== pData2->maPrinterName)			&&
279 		 (pData1->maDriver			== pData2->maDriver)				&&
280 		 (pData1->meOrientation 	== pData2->meOrientation)			&&
281 		 (pData1->meDuplexMode      == pData2->meDuplexMode)			&&
282 		 (pData1->mnPaperBin		== pData2->mnPaperBin)				&&
283 		 (pData1->mePaperFormat 	== pData2->mePaperFormat)			&&
284 		 (pData1->mnPaperWidth		== pData2->mnPaperWidth)			&&
285 		 (pData1->mnPaperHeight 	== pData2->mnPaperHeight)			&&
286 		 (pData1->mnDriverDataLen	== pData2->mnDriverDataLen) 		&&
287 		 (memcmp( pData1->mpDriverData, pData2->mpDriverData, pData1->mnDriverDataLen ) == 0)															&&
288 		 (pData1->maValueMap		== pData2->maValueMap)
289 		 )
290 		return sal_True;
291 
292 	return sal_False;
293 }
294 
295 // -----------------------------------------------------------------------
296 
297 SvStream& operator>>( SvStream& rIStream, JobSetup& rJobSetup )
298 {
299 	DBG_ASSERTWARNING( rIStream.GetVersion(), "JobSetup::>> - Solar-Version not set on rOStream" );
300 
301 	// Zur Zeit haben wir noch kein neues FileFormat
302 //	  if ( rIStream.GetVersion() < JOBSET_FILEFORMAT2 )
303 	{
304 		sal_Size nFirstPos = rIStream.Tell();
305 
306 		sal_uInt16 nLen = 0;
307 		rIStream >> nLen;
308 		if ( !nLen )
309 			return rIStream;
310 
311 		sal_uInt16 nSystem = 0;
312 		rIStream >> nSystem;
313 
314 		char* pTempBuf = new char[nLen];
315 		rIStream.Read( pTempBuf,  nLen - sizeof( nLen ) - sizeof( nSystem ) );
316 		if ( nLen >= sizeof(ImplOldJobSetupData)+4 )
317 		{
318 			ImplOldJobSetupData* pData = (ImplOldJobSetupData*)pTempBuf;
319 			if ( rJobSetup.mpData )
320 			{
321 				if ( rJobSetup.mpData->mnRefCount == 1 )
322 					delete rJobSetup.mpData;
323 				else
324 					rJobSetup.mpData->mnRefCount--;
325 			}
326 
327             rtl_TextEncoding aStreamEncoding = RTL_TEXTENCODING_UTF8;
328             if( nSystem == JOBSET_FILE364_SYSTEM )
329                 aStreamEncoding = rIStream.GetStreamCharSet();
330 
331 			rJobSetup.mpData = new ImplJobSetup;
332 			ImplJobSetup* pJobData = rJobSetup.mpData;
333 			pJobData->maPrinterName = UniString( pData->cPrinterName, aStreamEncoding );
334 			pJobData->maDriver		= UniString( pData->cDriverName, aStreamEncoding );
335 
336 			// Sind es unsere neuen JobSetup-Daten?
337 			if ( nSystem == JOBSET_FILE364_SYSTEM ||
338 				 nSystem == JOBSET_FILE605_SYSTEM )
339 			{
340 				Impl364JobSetupData* pOldJobData	= (Impl364JobSetupData*)(pTempBuf + sizeof( ImplOldJobSetupData ));
341 				sal_uInt16 nOldJobDataSize				= SVBT16ToShort( pOldJobData->nSize );
342 				pJobData->mnSystem					= SVBT16ToShort( pOldJobData->nSystem );
343 				pJobData->mnDriverDataLen			= SVBT32ToUInt32( pOldJobData->nDriverDataLen );
344 				pJobData->meOrientation 			= (Orientation)SVBT16ToShort( pOldJobData->nOrientation );
345                 pJobData->meDuplexMode              = DUPLEX_UNKNOWN;
346 				pJobData->mnPaperBin				= SVBT16ToShort( pOldJobData->nPaperBin );
347 				pJobData->mePaperFormat 			= (Paper)SVBT16ToShort( pOldJobData->nPaperFormat );
348 				pJobData->mnPaperWidth				= (long)SVBT32ToUInt32( pOldJobData->nPaperWidth );
349 				pJobData->mnPaperHeight 			= (long)SVBT32ToUInt32( pOldJobData->nPaperHeight );
350 				if ( pJobData->mnDriverDataLen )
351 				{
352 					sal_uInt8* pDriverData = ((sal_uInt8*)pOldJobData) + nOldJobDataSize;
353 					pJobData->mpDriverData = (sal_uInt8*)rtl_allocateMemory( pJobData->mnDriverDataLen );
354 					memcpy( pJobData->mpDriverData, pDriverData, pJobData->mnDriverDataLen );
355 				}
356 				if( nSystem == JOBSET_FILE605_SYSTEM )
357 				{
358 					rIStream.Seek( nFirstPos + sizeof( ImplOldJobSetupData ) + 4 + sizeof( Impl364JobSetupData ) + pJobData->mnDriverDataLen );
359 					while( rIStream.Tell() < nFirstPos + nLen )
360 					{
361 						String aKey, aValue;
362 						rIStream.ReadByteString( aKey, RTL_TEXTENCODING_UTF8 );
363 						rIStream.ReadByteString( aValue, RTL_TEXTENCODING_UTF8 );
364                         if( aKey.EqualsAscii( "COMPAT_DUPLEX_MODE" ) )
365                         {
366                             if( aValue.EqualsAscii( "DUPLEX_UNKNOWN" ) )
367                                 pJobData->meDuplexMode = DUPLEX_UNKNOWN;
368                             else if( aValue.EqualsAscii( "DUPLEX_OFF" ) )
369                                 pJobData->meDuplexMode = DUPLEX_OFF;
370                             else if( aValue.EqualsAscii( "DUPLEX_SHORTEDGE" ) )
371                                 pJobData->meDuplexMode = DUPLEX_SHORTEDGE;
372                             else if( aValue.EqualsAscii( "DUPLEX_LONGEDGE" ) )
373                                 pJobData->meDuplexMode = DUPLEX_LONGEDGE;
374                         }
375                         else
376                             pJobData->maValueMap[ aKey ] = aValue;
377 					}
378 					DBG_ASSERT( rIStream.Tell() == nFirstPos+nLen, "corrupted job setup" );
379 					// ensure correct stream position
380 					rIStream.Seek( nFirstPos + nLen );
381 				}
382 			}
383 		}
384 		delete[] pTempBuf;
385 	}
386 /*
387 	else
388 	{
389 	}
390 */
391 
392 	return rIStream;
393 }
394 
395 // -----------------------------------------------------------------------
396 
397 SvStream& operator<<( SvStream& rOStream, const JobSetup& rJobSetup )
398 {
399 	DBG_ASSERTWARNING( rOStream.GetVersion(), "JobSetup::<< - Solar-Version not set on rOStream" );
400 
401 	// Zur Zeit haben wir noch kein neues FileFormat
402 //	  if ( rOStream.GetVersion() < JOBSET_FILEFORMAT2 )
403 	{
404 		sal_uInt16 nLen = 0;
405 		if ( !rJobSetup.mpData )
406 			rOStream << nLen;
407 		else
408 		{
409 			sal_uInt16 nSystem = JOBSET_FILE605_SYSTEM;
410 
411 			const ImplJobSetup* pJobData = rJobSetup.ImplGetConstData();
412 			Impl364JobSetupData aOldJobData;
413 			sal_uInt16				nOldJobDataSize = sizeof( aOldJobData );
414 			ShortToSVBT16( nOldJobDataSize, aOldJobData.nSize );
415 			ShortToSVBT16( pJobData->mnSystem, aOldJobData.nSystem );
416 			UInt32ToSVBT32( pJobData->mnDriverDataLen, aOldJobData.nDriverDataLen );
417 			ShortToSVBT16( (sal_uInt16)(pJobData->meOrientation), aOldJobData.nOrientation );
418 			ShortToSVBT16( pJobData->mnPaperBin, aOldJobData.nPaperBin );
419 			ShortToSVBT16( (sal_uInt16)(pJobData->mePaperFormat), aOldJobData.nPaperFormat );
420 			UInt32ToSVBT32( (sal_uLong)(pJobData->mnPaperWidth), aOldJobData.nPaperWidth );
421 			UInt32ToSVBT32( (sal_uLong)(pJobData->mnPaperHeight), aOldJobData.nPaperHeight );
422 
423 			ImplOldJobSetupData aOldData;
424 			memset( &aOldData, 0, sizeof( aOldData ) );
425 			ByteString aPrnByteName( rJobSetup.GetPrinterName(), RTL_TEXTENCODING_UTF8 );
426 			strncpy( aOldData.cPrinterName, aPrnByteName.GetBuffer(), 63 );
427 			ByteString aDriverByteName( rJobSetup.GetDriverName(), RTL_TEXTENCODING_UTF8 );
428 			strncpy( aOldData.cDriverName, aDriverByteName.GetBuffer(), 31 );
429 //			nLen = sizeof( aOldData ) + 4 + nOldJobDataSize + pJobData->mnDriverDataLen;
430 			int nPos = rOStream.Tell();
431 			rOStream << nLen;
432 			rOStream << nSystem;
433 			rOStream.Write( (char*)&aOldData, sizeof( aOldData ) );
434 			rOStream.Write( (char*)&aOldJobData, nOldJobDataSize );
435 			rOStream.Write( (char*)pJobData->mpDriverData, pJobData->mnDriverDataLen );
436 			::std::hash_map< ::rtl::OUString, ::rtl::OUString, ::rtl::OUStringHash >::const_iterator it;
437 			for( it = pJobData->maValueMap.begin(); it != pJobData->maValueMap.end(); ++it )
438 			{
439 				rOStream.WriteByteString( it->first, RTL_TEXTENCODING_UTF8 );
440 				rOStream.WriteByteString( it->second, RTL_TEXTENCODING_UTF8 );
441 			}
442             rOStream.WriteByteString( "COMPAT_DUPLEX_MODE" ) ;
443             switch( pJobData->meDuplexMode )
444             {
445             case DUPLEX_UNKNOWN: rOStream.WriteByteString( "DUPLEX_UNKNOWN" );break;
446             case DUPLEX_OFF: rOStream.WriteByteString( "DUPLEX_OFF" );break;
447             case DUPLEX_SHORTEDGE: rOStream.WriteByteString( "DUPLEX_SHORTEDGE" );break;
448             case DUPLEX_LONGEDGE: rOStream.WriteByteString( "DUPLEX_LONGEDGE" );break;
449             }
450 			nLen = sal::static_int_cast<sal_uInt16>(rOStream.Tell() - nPos);
451 			rOStream.Seek( nPos );
452 			rOStream << nLen;
453 			rOStream.Seek( nPos + nLen );
454 		}
455 	}
456 /*
457 	else
458 	{
459 	}
460 */
461 
462 	return rOStream;
463 }
464