1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
27 #include <boost/scoped_array.hpp>
29 #define JOBSET_FILE364_SYSTEM ((sal_uInt16)0xFFFF)
30 #define JOBSET_FILE605_SYSTEM ((sal_uInt16)0xFFFE)
32 struct ImplOldJobSetupData
34 char cPrinterName
[64];
40 struct Impl364JobSetupData
44 SVBT32 nDriverDataLen
;
52 ImplJobSetup::ImplJobSetup()
56 meOrientation
= ORIENTATION_PORTRAIT
;
57 meDuplexMode
= DUPLEX_UNKNOWN
;
59 mePaperFormat
= PAPER_USER
;
64 mbPapersizeFromSetup
= false;
67 ImplJobSetup::ImplJobSetup( const ImplJobSetup
& rJobSetup
) :
68 maPrinterName( rJobSetup
.maPrinterName
),
69 maDriver( rJobSetup
.maDriver
)
72 mnSystem
= rJobSetup
.mnSystem
;
73 meOrientation
= rJobSetup
.meOrientation
;
74 meDuplexMode
= rJobSetup
.meDuplexMode
;
75 mnPaperBin
= rJobSetup
.mnPaperBin
;
76 mePaperFormat
= rJobSetup
.mePaperFormat
;
77 mnPaperWidth
= rJobSetup
.mnPaperWidth
;
78 mnPaperHeight
= rJobSetup
.mnPaperHeight
;
79 mnDriverDataLen
= rJobSetup
.mnDriverDataLen
;
80 if ( rJobSetup
.mpDriverData
)
82 mpDriverData
= static_cast<sal_uInt8
*>(rtl_allocateMemory( mnDriverDataLen
));
83 memcpy( mpDriverData
, rJobSetup
.mpDriverData
, mnDriverDataLen
);
87 mbPapersizeFromSetup
= rJobSetup
.mbPapersizeFromSetup
;
88 maValueMap
= rJobSetup
.maValueMap
;
91 ImplJobSetup::~ImplJobSetup()
93 rtl_freeMemory( mpDriverData
);
96 ImplJobSetup
* JobSetup::ImplGetData()
99 mpData
= new ImplJobSetup
;
100 else if ( mpData
->mnRefCount
!= 1 )
102 mpData
->mnRefCount
--;
103 mpData
= new ImplJobSetup( *mpData
);
109 ImplJobSetup
* JobSetup::ImplGetConstData()
112 mpData
= new ImplJobSetup
;
116 const ImplJobSetup
* JobSetup::ImplGetConstData() const
119 const_cast<JobSetup
*>(this)->mpData
= new ImplJobSetup
;
129 JobSetup::JobSetup( const JobSetup
& rJobSetup
)
131 DBG_ASSERT( !rJobSetup
.mpData
|| (rJobSetup
.mpData
->mnRefCount
< 0xFFFE), "JobSetup: RefCount overflow" );
133 mpData
= rJobSetup
.mpData
;
135 mpData
->mnRefCount
++;
138 JobSetup::~JobSetup()
143 if ( mpData
->mnRefCount
== 1 )
146 mpData
->mnRefCount
--;
150 OUString
JobSetup::GetPrinterName() const
153 return mpData
->maPrinterName
;
158 OUString
JobSetup::GetDriverName() const
161 return mpData
->maDriver
;
166 JobSetup
& JobSetup::operator=( const JobSetup
& rJobSetup
)
168 DBG_ASSERT( !rJobSetup
.mpData
|| (rJobSetup
.mpData
->mnRefCount
) < 0xFFFE, "JobSetup: RefCount overflow" );
170 // Increment refcount first, so that we can assign to ourselves
171 if ( rJobSetup
.mpData
)
172 rJobSetup
.mpData
->mnRefCount
++;
174 // If it's not static ImpData and the last reference, delete it, else
175 // decrement refcount
178 if ( mpData
->mnRefCount
== 1 )
181 mpData
->mnRefCount
--;
184 mpData
= rJobSetup
.mpData
;
189 bool JobSetup::operator==( const JobSetup
& rJobSetup
) const
192 if ( mpData
== rJobSetup
.mpData
)
195 if ( !mpData
|| !rJobSetup
.mpData
)
198 ImplJobSetup
* pData1
= mpData
;
199 ImplJobSetup
* pData2
= rJobSetup
.mpData
;
200 if ( (pData1
->mnSystem
== pData2
->mnSystem
) &&
201 (pData1
->maPrinterName
== pData2
->maPrinterName
) &&
202 (pData1
->maDriver
== pData2
->maDriver
) &&
203 (pData1
->meOrientation
== pData2
->meOrientation
) &&
204 (pData1
->meDuplexMode
== pData2
->meDuplexMode
) &&
205 (pData1
->mnPaperBin
== pData2
->mnPaperBin
) &&
206 (pData1
->mePaperFormat
== pData2
->mePaperFormat
) &&
207 (pData1
->mnPaperWidth
== pData2
->mnPaperWidth
) &&
208 (pData1
->mnPaperHeight
== pData2
->mnPaperHeight
) &&
209 (pData1
->mnDriverDataLen
== pData2
->mnDriverDataLen
) &&
210 (memcmp( pData1
->mpDriverData
, pData2
->mpDriverData
, pData1
->mnDriverDataLen
) == 0) &&
211 (pData1
->maValueMap
== pData2
->maValueMap
)
218 SvStream
& ReadJobSetup( SvStream
& rIStream
, JobSetup
& rJobSetup
)
220 DBG_ASSERTWARNING( rIStream
.GetVersion(), "JobSetup::>> - Solar-Version not set on rOStream" );
224 rIStream
.ReadUInt16( nLen
);
228 sal_uInt16 nSystem
= 0;
229 rIStream
.ReadUInt16( nSystem
);
230 const size_t nRead
= nLen
- sizeof(nLen
) - sizeof(nSystem
);
231 if (nRead
> rIStream
.remainingSize())
233 SAL_WARN("vcl", "Parsing error: " << rIStream
.remainingSize() <<
234 " max possible entries, but " << nRead
<< " claimed, truncating");
237 sal_Size nFirstPos
= rIStream
.Tell();
238 boost::scoped_array
<char> pTempBuf(new char[nRead
]);
239 rIStream
.Read(pTempBuf
.get(), nRead
);
240 if (nRead
>= sizeof(ImplOldJobSetupData
))
242 ImplOldJobSetupData
* pData
= reinterpret_cast<ImplOldJobSetupData
*>(pTempBuf
.get());
243 if ( rJobSetup
.mpData
)
245 if ( rJobSetup
.mpData
->mnRefCount
== 1 )
246 delete rJobSetup
.mpData
;
248 rJobSetup
.mpData
->mnRefCount
--;
251 rtl_TextEncoding aStreamEncoding
= RTL_TEXTENCODING_UTF8
;
252 if( nSystem
== JOBSET_FILE364_SYSTEM
)
253 aStreamEncoding
= rIStream
.GetStreamCharSet();
255 rJobSetup
.mpData
= new ImplJobSetup
;
256 ImplJobSetup
* pJobData
= rJobSetup
.mpData
;
257 pJobData
->maPrinterName
= OStringToOUString(pData
->cPrinterName
, aStreamEncoding
);
258 pJobData
->maDriver
= OStringToOUString(pData
->cDriverName
, aStreamEncoding
);
260 // Are these our new JobSetup files?
261 if ( nSystem
== JOBSET_FILE364_SYSTEM
||
262 nSystem
== JOBSET_FILE605_SYSTEM
)
264 Impl364JobSetupData
* pOldJobData
= reinterpret_cast<Impl364JobSetupData
*>(pTempBuf
.get() + sizeof( ImplOldJobSetupData
));
265 sal_uInt16 nOldJobDataSize
= SVBT16ToShort( pOldJobData
->nSize
);
266 pJobData
->mnSystem
= SVBT16ToShort( pOldJobData
->nSystem
);
267 pJobData
->mnDriverDataLen
= SVBT32ToUInt32( pOldJobData
->nDriverDataLen
);
268 pJobData
->meOrientation
= (Orientation
)SVBT16ToShort( pOldJobData
->nOrientation
);
269 pJobData
->meDuplexMode
= DUPLEX_UNKNOWN
;
270 pJobData
->mnPaperBin
= SVBT16ToShort( pOldJobData
->nPaperBin
);
271 pJobData
->mePaperFormat
= (Paper
)SVBT16ToShort( pOldJobData
->nPaperFormat
);
272 pJobData
->mnPaperWidth
= (long)SVBT32ToUInt32( pOldJobData
->nPaperWidth
);
273 pJobData
->mnPaperHeight
= (long)SVBT32ToUInt32( pOldJobData
->nPaperHeight
);
274 if ( pJobData
->mnDriverDataLen
)
276 sal_uInt8
* pDriverData
= reinterpret_cast<sal_uInt8
*>(pOldJobData
) + nOldJobDataSize
;
277 pJobData
->mpDriverData
= static_cast<sal_uInt8
*>(rtl_allocateMemory( pJobData
->mnDriverDataLen
));
278 memcpy( pJobData
->mpDriverData
, pDriverData
, pJobData
->mnDriverDataLen
);
280 if( nSystem
== JOBSET_FILE605_SYSTEM
)
282 rIStream
.Seek( nFirstPos
+ sizeof( ImplOldJobSetupData
) + sizeof( Impl364JobSetupData
) + pJobData
->mnDriverDataLen
);
283 while( rIStream
.Tell() < nFirstPos
+ nRead
)
285 OUString aKey
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStream
, RTL_TEXTENCODING_UTF8
);
286 OUString aValue
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStream
, RTL_TEXTENCODING_UTF8
);
287 if( aKey
== "COMPAT_DUPLEX_MODE" )
289 if( aValue
== "DUPLEX_UNKNOWN" )
290 pJobData
->meDuplexMode
= DUPLEX_UNKNOWN
;
291 else if( aValue
== "DUPLEX_OFF" )
292 pJobData
->meDuplexMode
= DUPLEX_OFF
;
293 else if( aValue
== "DUPLEX_SHORTEDGE" )
294 pJobData
->meDuplexMode
= DUPLEX_SHORTEDGE
;
295 else if( aValue
== "DUPLEX_LONGEDGE" )
296 pJobData
->meDuplexMode
= DUPLEX_LONGEDGE
;
299 pJobData
->maValueMap
[ aKey
] = aValue
;
301 DBG_ASSERT( rIStream
.Tell() == nFirstPos
+nRead
, "corrupted job setup" );
302 // ensure correct stream position
303 rIStream
.Seek(nFirstPos
+ nRead
);
312 SvStream
& WriteJobSetup( SvStream
& rOStream
, const JobSetup
& rJobSetup
)
314 DBG_ASSERTWARNING( rOStream
.GetVersion(), "JobSetup::<< - Solar-Version not set on rOStream" );
316 // We do not have a new FileFormat at this point in time
317 // #define JOBSET_FILEFORMAT2 3780
318 // if ( rOStream.GetVersion() < JOBSET_FILEFORMAT2 )
321 if ( !rJobSetup
.mpData
)
322 rOStream
.WriteUInt16( nLen
);
325 sal_uInt16 nSystem
= JOBSET_FILE605_SYSTEM
;
327 const ImplJobSetup
* pJobData
= rJobSetup
.ImplGetConstData();
328 Impl364JobSetupData aOldJobData
;
329 sal_uInt16 nOldJobDataSize
= sizeof( aOldJobData
);
330 ShortToSVBT16( nOldJobDataSize
, aOldJobData
.nSize
);
331 ShortToSVBT16( pJobData
->mnSystem
, aOldJobData
.nSystem
);
332 UInt32ToSVBT32( pJobData
->mnDriverDataLen
, aOldJobData
.nDriverDataLen
);
333 ShortToSVBT16( (sal_uInt16
)(pJobData
->meOrientation
), aOldJobData
.nOrientation
);
334 ShortToSVBT16( pJobData
->mnPaperBin
, aOldJobData
.nPaperBin
);
335 ShortToSVBT16( (sal_uInt16
)(pJobData
->mePaperFormat
), aOldJobData
.nPaperFormat
);
336 UInt32ToSVBT32( (sal_uLong
)(pJobData
->mnPaperWidth
), aOldJobData
.nPaperWidth
);
337 UInt32ToSVBT32( (sal_uLong
)(pJobData
->mnPaperHeight
), aOldJobData
.nPaperHeight
);
339 ImplOldJobSetupData aOldData
;
340 memset( &aOldData
, 0, sizeof( aOldData
) );
341 OString
aPrnByteName(OUStringToOString(rJobSetup
.GetPrinterName(), RTL_TEXTENCODING_UTF8
));
342 strncpy( aOldData
.cPrinterName
, aPrnByteName
.getStr(), 63 );
343 OString
aDriverByteName(OUStringToOString(rJobSetup
.GetDriverName(), RTL_TEXTENCODING_UTF8
));
344 strncpy( aOldData
.cDriverName
, aDriverByteName
.getStr(), 31 );
345 // nLen = sizeof( aOldData ) + 4 + nOldJobDataSize + pJobData->mnDriverDataLen;
346 int nPos
= rOStream
.Tell();
347 rOStream
.WriteUInt16( nLen
);
348 rOStream
.WriteUInt16( nSystem
);
349 rOStream
.Write( &aOldData
, sizeof( aOldData
) );
350 rOStream
.Write( &aOldJobData
, nOldJobDataSize
);
351 rOStream
.Write( pJobData
->mpDriverData
, pJobData
->mnDriverDataLen
);
352 std::unordered_map
< OUString
, OUString
, OUStringHash
>::const_iterator it
;
353 for( it
= pJobData
->maValueMap
.begin(); it
!= pJobData
->maValueMap
.end(); ++it
)
355 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream
, it
->first
, RTL_TEXTENCODING_UTF8
);
356 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream
, it
->second
, RTL_TEXTENCODING_UTF8
);
358 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream
, "COMPAT_DUPLEX_MODE");
359 switch( pJobData
->meDuplexMode
)
362 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream
, "DUPLEX_UNKNOWN");
365 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream
, "DUPLEX_OFF");
367 case DUPLEX_SHORTEDGE
:
368 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream
, "DUPLEX_SHORTEDGE");
370 case DUPLEX_LONGEDGE
:
371 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream
, "DUPLEX_LONGEDGE");
374 nLen
= sal::static_int_cast
<sal_uInt16
>(rOStream
.Tell() - nPos
);
375 rOStream
.Seek( nPos
);
376 rOStream
.WriteUInt16( nLen
);
377 rOStream
.Seek( nPos
+ nLen
);
384 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */