Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : #include <tools/debug.hxx>
22 : #include <tools/stream.hxx>
23 : #include <tools/string.hxx>
24 : #include <rtl/alloc.h>
25 : #include <vcl/jobset.hxx>
26 :
27 : #include <jobset.h>
28 :
29 : DBG_NAME( JobSetup )
30 :
31 : #define JOBSET_FILE364_SYSTEM ((sal_uInt16)0xFFFF)
32 : #define JOBSET_FILE605_SYSTEM ((sal_uInt16)0xFFFE)
33 :
34 : struct ImplOldJobSetupData
35 : {
36 : char cPrinterName[64];
37 : char cDeviceName[32];
38 : char cPortName[32];
39 : char cDriverName[32];
40 : };
41 :
42 : struct Impl364JobSetupData
43 : {
44 : SVBT16 nSize;
45 : SVBT16 nSystem;
46 : SVBT32 nDriverDataLen;
47 : SVBT16 nOrientation;
48 : SVBT16 nPaperBin;
49 : SVBT16 nPaperFormat;
50 : SVBT32 nPaperWidth;
51 : SVBT32 nPaperHeight;
52 : };
53 :
54 151 : ImplJobSetup::ImplJobSetup()
55 : {
56 151 : mnRefCount = 1;
57 151 : mnSystem = 0;
58 151 : meOrientation = ORIENTATION_PORTRAIT;
59 151 : meDuplexMode = DUPLEX_UNKNOWN;
60 151 : mnPaperBin = 0;
61 151 : mePaperFormat = PAPER_USER;
62 151 : mnPaperWidth = 0;
63 151 : mnPaperHeight = 0;
64 151 : mnDriverDataLen = 0;
65 151 : mpDriverData = NULL;
66 151 : }
67 :
68 3 : ImplJobSetup::ImplJobSetup( const ImplJobSetup& rJobSetup ) :
69 : maPrinterName( rJobSetup.maPrinterName ),
70 3 : maDriver( rJobSetup.maDriver )
71 : {
72 3 : mnRefCount = 1;
73 3 : mnSystem = rJobSetup.mnSystem;
74 3 : meOrientation = rJobSetup.meOrientation;
75 3 : meDuplexMode = rJobSetup.meDuplexMode;
76 3 : mnPaperBin = rJobSetup.mnPaperBin;
77 3 : mePaperFormat = rJobSetup.mePaperFormat;
78 3 : mnPaperWidth = rJobSetup.mnPaperWidth;
79 3 : mnPaperHeight = rJobSetup.mnPaperHeight;
80 3 : mnDriverDataLen = rJobSetup.mnDriverDataLen;
81 3 : if ( rJobSetup.mpDriverData )
82 : {
83 3 : mpDriverData = (sal_uInt8*)rtl_allocateMemory( mnDriverDataLen );
84 3 : memcpy( mpDriverData, rJobSetup.mpDriverData, mnDriverDataLen );
85 : }
86 : else
87 0 : mpDriverData = NULL;
88 3 : maValueMap = rJobSetup.maValueMap;
89 3 : }
90 :
91 298 : ImplJobSetup::~ImplJobSetup()
92 : {
93 149 : rtl_freeMemory( mpDriverData );
94 149 : }
95 :
96 160 : ImplJobSetup* JobSetup::ImplGetData()
97 : {
98 160 : if ( !mpData )
99 77 : mpData = new ImplJobSetup;
100 83 : else if ( mpData->mnRefCount != 1 )
101 : {
102 3 : mpData->mnRefCount--;
103 3 : mpData = new ImplJobSetup( *mpData );
104 : }
105 :
106 160 : return mpData;
107 : }
108 :
109 160 : ImplJobSetup* JobSetup::ImplGetConstData()
110 : {
111 160 : if ( !mpData )
112 0 : mpData = new ImplJobSetup;
113 160 : return mpData;
114 : }
115 :
116 64 : const ImplJobSetup* JobSetup::ImplGetConstData() const
117 : {
118 64 : if ( !mpData )
119 30 : ((JobSetup*)this)->mpData = new ImplJobSetup;
120 64 : return mpData;
121 : }
122 :
123 3151 : JobSetup::JobSetup()
124 : {
125 : DBG_CTOR( JobSetup, NULL );
126 :
127 3151 : mpData = NULL;
128 3151 : }
129 :
130 3 : JobSetup::JobSetup( const JobSetup& rJobSetup )
131 : {
132 : DBG_CTOR( JobSetup, NULL );
133 : DBG_CHKOBJ( &rJobSetup, JobSetup, NULL );
134 : DBG_ASSERT( !rJobSetup.mpData || (rJobSetup.mpData->mnRefCount < 0xFFFE), "JobSetup: RefCount overflow" );
135 :
136 3 : mpData = rJobSetup.mpData;
137 3 : if ( mpData )
138 3 : mpData->mnRefCount++;
139 3 : }
140 :
141 3130 : JobSetup::~JobSetup()
142 : {
143 : DBG_DTOR( JobSetup, NULL );
144 :
145 3130 : if ( mpData )
146 : {
147 149 : if ( mpData->mnRefCount == 1 )
148 146 : delete mpData;
149 : else
150 3 : mpData->mnRefCount--;
151 : }
152 3130 : }
153 :
154 107 : OUString JobSetup::GetPrinterName() const
155 : {
156 107 : if ( mpData )
157 92 : return mpData->maPrinterName;
158 : else
159 15 : return OUString();
160 : }
161 :
162 4 : OUString JobSetup::GetDriverName() const
163 : {
164 4 : if ( mpData )
165 4 : return mpData->maDriver;
166 : else
167 0 : return OUString();
168 : }
169 :
170 0 : void JobSetup::SetValue( const OUString& rKey, const OUString& rValue )
171 : {
172 0 : if( ! mpData )
173 0 : mpData = new ImplJobSetup();
174 :
175 0 : mpData->maValueMap[ rKey ] = rValue;
176 0 : }
177 :
178 3 : JobSetup& JobSetup::operator=( const JobSetup& rJobSetup )
179 : {
180 : DBG_CHKTHIS( JobSetup, NULL );
181 : DBG_CHKOBJ( &rJobSetup, JobSetup, NULL );
182 : DBG_ASSERT( !rJobSetup.mpData || (rJobSetup.mpData->mnRefCount) < 0xFFFE, "JobSetup: RefCount overflow" );
183 :
184 : // Increment refcount first, so that we can assign to ourselves
185 3 : if ( rJobSetup.mpData )
186 3 : rJobSetup.mpData->mnRefCount++;
187 :
188 : // If it's not static ImpData and the last reference, delete it, else
189 : // decrement refcount
190 3 : if ( mpData )
191 : {
192 3 : if ( mpData->mnRefCount == 1 )
193 3 : delete mpData;
194 : else
195 0 : mpData->mnRefCount--;
196 : }
197 :
198 3 : mpData = rJobSetup.mpData;
199 :
200 3 : return *this;
201 : }
202 :
203 0 : sal_Bool JobSetup::operator==( const JobSetup& rJobSetup ) const
204 : {
205 : DBG_CHKTHIS( JobSetup, NULL );
206 : DBG_CHKOBJ( &rJobSetup, JobSetup, NULL );
207 :
208 0 : if ( mpData == rJobSetup.mpData )
209 0 : return sal_True;
210 :
211 0 : if ( !mpData || !rJobSetup.mpData )
212 0 : return sal_False;
213 :
214 0 : ImplJobSetup* pData1 = mpData;
215 0 : ImplJobSetup* pData2 = rJobSetup.mpData;
216 0 : if ( (pData1->mnSystem == pData2->mnSystem) &&
217 0 : (pData1->maPrinterName == pData2->maPrinterName) &&
218 0 : (pData1->maDriver == pData2->maDriver) &&
219 0 : (pData1->meOrientation == pData2->meOrientation) &&
220 0 : (pData1->meDuplexMode == pData2->meDuplexMode) &&
221 0 : (pData1->mnPaperBin == pData2->mnPaperBin) &&
222 0 : (pData1->mePaperFormat == pData2->mePaperFormat) &&
223 0 : (pData1->mnPaperWidth == pData2->mnPaperWidth) &&
224 0 : (pData1->mnPaperHeight == pData2->mnPaperHeight) &&
225 0 : (pData1->mnDriverDataLen == pData2->mnDriverDataLen) &&
226 0 : (memcmp( pData1->mpDriverData, pData2->mpDriverData, pData1->mnDriverDataLen ) == 0) &&
227 0 : (pData1->maValueMap == pData2->maValueMap)
228 : )
229 0 : return sal_True;
230 :
231 0 : return sal_False;
232 : }
233 :
234 44 : SvStream& operator>>( SvStream& rIStream, JobSetup& rJobSetup )
235 : {
236 : DBG_ASSERTWARNING( rIStream.GetVersion(), "JobSetup::>> - Solar-Version not set on rOStream" );
237 :
238 : {
239 44 : sal_Size nFirstPos = rIStream.Tell();
240 :
241 44 : sal_uInt16 nLen = 0;
242 44 : rIStream >> nLen;
243 44 : if ( !nLen )
244 0 : return rIStream;
245 :
246 44 : sal_uInt16 nSystem = 0;
247 44 : rIStream >> nSystem;
248 :
249 44 : char* pTempBuf = new char[nLen];
250 44 : rIStream.Read( pTempBuf, nLen - sizeof( nLen ) - sizeof( nSystem ) );
251 44 : if ( nLen >= sizeof(ImplOldJobSetupData)+4 )
252 : {
253 44 : ImplOldJobSetupData* pData = (ImplOldJobSetupData*)pTempBuf;
254 44 : if ( rJobSetup.mpData )
255 : {
256 0 : if ( rJobSetup.mpData->mnRefCount == 1 )
257 0 : delete rJobSetup.mpData;
258 : else
259 0 : rJobSetup.mpData->mnRefCount--;
260 : }
261 :
262 44 : rtl_TextEncoding aStreamEncoding = RTL_TEXTENCODING_UTF8;
263 44 : if( nSystem == JOBSET_FILE364_SYSTEM )
264 0 : aStreamEncoding = rIStream.GetStreamCharSet();
265 :
266 44 : rJobSetup.mpData = new ImplJobSetup;
267 44 : ImplJobSetup* pJobData = rJobSetup.mpData;
268 44 : pJobData->maPrinterName = OStringToOUString(pData->cPrinterName, aStreamEncoding);
269 44 : pJobData->maDriver = OStringToOUString(pData->cDriverName, aStreamEncoding);
270 :
271 : // Are these our new JobSetup files?
272 88 : if ( nSystem == JOBSET_FILE364_SYSTEM ||
273 44 : nSystem == JOBSET_FILE605_SYSTEM )
274 : {
275 44 : Impl364JobSetupData* pOldJobData = (Impl364JobSetupData*)(pTempBuf + sizeof( ImplOldJobSetupData ));
276 44 : sal_uInt16 nOldJobDataSize = SVBT16ToShort( pOldJobData->nSize );
277 44 : pJobData->mnSystem = SVBT16ToShort( pOldJobData->nSystem );
278 44 : pJobData->mnDriverDataLen = SVBT32ToUInt32( pOldJobData->nDriverDataLen );
279 44 : pJobData->meOrientation = (Orientation)SVBT16ToShort( pOldJobData->nOrientation );
280 44 : pJobData->meDuplexMode = DUPLEX_UNKNOWN;
281 44 : pJobData->mnPaperBin = SVBT16ToShort( pOldJobData->nPaperBin );
282 44 : pJobData->mePaperFormat = (Paper)SVBT16ToShort( pOldJobData->nPaperFormat );
283 44 : pJobData->mnPaperWidth = (long)SVBT32ToUInt32( pOldJobData->nPaperWidth );
284 44 : pJobData->mnPaperHeight = (long)SVBT32ToUInt32( pOldJobData->nPaperHeight );
285 44 : if ( pJobData->mnDriverDataLen )
286 : {
287 40 : sal_uInt8* pDriverData = ((sal_uInt8*)pOldJobData) + nOldJobDataSize;
288 40 : pJobData->mpDriverData = (sal_uInt8*)rtl_allocateMemory( pJobData->mnDriverDataLen );
289 40 : memcpy( pJobData->mpDriverData, pDriverData, pJobData->mnDriverDataLen );
290 : }
291 44 : if( nSystem == JOBSET_FILE605_SYSTEM )
292 : {
293 44 : rIStream.Seek( nFirstPos + sizeof( ImplOldJobSetupData ) + 4 + sizeof( Impl364JobSetupData ) + pJobData->mnDriverDataLen );
294 128 : while( rIStream.Tell() < nFirstPos + nLen )
295 : {
296 40 : String aKey = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(rIStream, RTL_TEXTENCODING_UTF8);
297 80 : String aValue = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(rIStream, RTL_TEXTENCODING_UTF8);
298 40 : if( aKey.EqualsAscii( "COMPAT_DUPLEX_MODE" ) )
299 : {
300 37 : if( aValue.EqualsAscii( "DUPLEX_UNKNOWN" ) )
301 9 : pJobData->meDuplexMode = DUPLEX_UNKNOWN;
302 28 : else if( aValue.EqualsAscii( "DUPLEX_OFF" ) )
303 28 : pJobData->meDuplexMode = DUPLEX_OFF;
304 0 : else if( aValue.EqualsAscii( "DUPLEX_SHORTEDGE" ) )
305 0 : pJobData->meDuplexMode = DUPLEX_SHORTEDGE;
306 0 : else if( aValue.EqualsAscii( "DUPLEX_LONGEDGE" ) )
307 0 : pJobData->meDuplexMode = DUPLEX_LONGEDGE;
308 : }
309 : else
310 3 : pJobData->maValueMap[ aKey ] = aValue;
311 40 : }
312 : DBG_ASSERT( rIStream.Tell() == nFirstPos+nLen, "corrupted job setup" );
313 : // ensure correct stream position
314 44 : rIStream.Seek( nFirstPos + nLen );
315 : }
316 : }
317 : }
318 44 : delete[] pTempBuf;
319 : }
320 :
321 44 : return rIStream;
322 : }
323 :
324 4 : SvStream& operator<<( SvStream& rOStream, const JobSetup& rJobSetup )
325 : {
326 : DBG_ASSERTWARNING( rOStream.GetVersion(), "JobSetup::<< - Solar-Version not set on rOStream" );
327 :
328 : // We do not have a new FileFormat at this point in time
329 : // #define JOBSET_FILEFORMAT2 3780
330 : // if ( rOStream.GetVersion() < JOBSET_FILEFORMAT2 )
331 : {
332 4 : sal_uInt16 nLen = 0;
333 4 : if ( !rJobSetup.mpData )
334 0 : rOStream << nLen;
335 : else
336 : {
337 4 : sal_uInt16 nSystem = JOBSET_FILE605_SYSTEM;
338 :
339 4 : const ImplJobSetup* pJobData = rJobSetup.ImplGetConstData();
340 : Impl364JobSetupData aOldJobData;
341 4 : sal_uInt16 nOldJobDataSize = sizeof( aOldJobData );
342 4 : ShortToSVBT16( nOldJobDataSize, aOldJobData.nSize );
343 4 : ShortToSVBT16( pJobData->mnSystem, aOldJobData.nSystem );
344 4 : UInt32ToSVBT32( pJobData->mnDriverDataLen, aOldJobData.nDriverDataLen );
345 4 : ShortToSVBT16( (sal_uInt16)(pJobData->meOrientation), aOldJobData.nOrientation );
346 4 : ShortToSVBT16( pJobData->mnPaperBin, aOldJobData.nPaperBin );
347 4 : ShortToSVBT16( (sal_uInt16)(pJobData->mePaperFormat), aOldJobData.nPaperFormat );
348 4 : UInt32ToSVBT32( (sal_uLong)(pJobData->mnPaperWidth), aOldJobData.nPaperWidth );
349 4 : UInt32ToSVBT32( (sal_uLong)(pJobData->mnPaperHeight), aOldJobData.nPaperHeight );
350 :
351 : ImplOldJobSetupData aOldData;
352 4 : memset( &aOldData, 0, sizeof( aOldData ) );
353 4 : OString aPrnByteName(OUStringToOString(rJobSetup.GetPrinterName(), RTL_TEXTENCODING_UTF8));
354 4 : strncpy( aOldData.cPrinterName, aPrnByteName.getStr(), 63 );
355 8 : OString aDriverByteName(OUStringToOString(rJobSetup.GetDriverName(), RTL_TEXTENCODING_UTF8));
356 4 : strncpy( aOldData.cDriverName, aDriverByteName.getStr(), 31 );
357 : // nLen = sizeof( aOldData ) + 4 + nOldJobDataSize + pJobData->mnDriverDataLen;
358 4 : int nPos = rOStream.Tell();
359 4 : rOStream << nLen;
360 4 : rOStream << nSystem;
361 4 : rOStream.Write( (char*)&aOldData, sizeof( aOldData ) );
362 4 : rOStream.Write( (char*)&aOldJobData, nOldJobDataSize );
363 4 : rOStream.Write( (char*)pJobData->mpDriverData, pJobData->mnDriverDataLen );
364 4 : ::boost::unordered_map< OUString, OUString, OUStringHash >::const_iterator it;
365 4 : for( it = pJobData->maValueMap.begin(); it != pJobData->maValueMap.end(); ++it )
366 : {
367 0 : write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(rOStream, it->first, RTL_TEXTENCODING_UTF8);
368 0 : write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(rOStream, it->second, RTL_TEXTENCODING_UTF8);
369 : }
370 4 : write_lenPrefixed_uInt8s_FromOString<sal_uInt16>(rOStream, "COMPAT_DUPLEX_MODE");
371 4 : switch( pJobData->meDuplexMode )
372 : {
373 : case DUPLEX_UNKNOWN:
374 4 : write_lenPrefixed_uInt8s_FromOString<sal_uInt16>(rOStream, "DUPLEX_UNKNOWN");
375 4 : break;
376 : case DUPLEX_OFF:
377 0 : write_lenPrefixed_uInt8s_FromOString<sal_uInt16>(rOStream, "DUPLEX_OFF");
378 0 : break;
379 : case DUPLEX_SHORTEDGE:
380 0 : write_lenPrefixed_uInt8s_FromOString<sal_uInt16>(rOStream, "DUPLEX_SHORTEDGE");
381 0 : break;
382 : case DUPLEX_LONGEDGE:
383 0 : write_lenPrefixed_uInt8s_FromOString<sal_uInt16>(rOStream, "DUPLEX_LONGEDGE");
384 0 : break;
385 : }
386 4 : nLen = sal::static_int_cast<sal_uInt16>(rOStream.Tell() - nPos);
387 4 : rOStream.Seek( nPos );
388 4 : rOStream << nLen;
389 8 : rOStream.Seek( nPos + nLen );
390 : }
391 : }
392 :
393 4 : return rOStream;
394 : }
395 :
396 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|