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