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