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/ustring.hxx>
21 #include <sal/log.hxx>
22 #include <tools/solar.h>
23 #include <tools/stream.hxx>
24 #include <vcl/jobset.hxx>
27 #include <rtl/instance.hxx>
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()
55 meOrientation
= Orientation::Portrait
;
56 meDuplexMode
= DuplexMode::Unknown
;
58 mePaperFormat
= PAPER_USER
;
62 mpDriverData
= nullptr;
63 mbPapersizeFromSetup
= false;
64 meSetupMode
= PrinterSetupMode::DocumentGlobal
;
67 ImplJobSetup::ImplJobSetup( const ImplJobSetup
& rJobSetup
) :
68 mnSystem( rJobSetup
.GetSystem() ),
69 maPrinterName( rJobSetup
.GetPrinterName() ),
70 maDriver( rJobSetup
.GetDriver() ),
71 meOrientation( rJobSetup
.GetOrientation() ),
72 meDuplexMode( rJobSetup
.GetDuplexMode() ),
73 mnPaperBin( rJobSetup
.GetPaperBin() ),
74 mePaperFormat( rJobSetup
.GetPaperFormat() ),
75 mnPaperWidth( rJobSetup
.GetPaperWidth() ),
76 mnPaperHeight( rJobSetup
.GetPaperHeight() ),
77 mnDriverDataLen( rJobSetup
.GetDriverDataLen() ),
78 mbPapersizeFromSetup( rJobSetup
.GetPapersizeFromSetup() ),
79 meSetupMode( rJobSetup
.GetPrinterSetupMode() ),
80 maValueMap( rJobSetup
.GetValueMap() )
82 if ( rJobSetup
.GetDriverData() )
84 mpDriverData
= static_cast<sal_uInt8
*>(std::malloc( mnDriverDataLen
));
85 memcpy( mpDriverData
, rJobSetup
.GetDriverData(), mnDriverDataLen
);
88 mpDriverData
= nullptr;
91 ImplJobSetup::~ImplJobSetup()
93 std::free( mpDriverData
);
96 void ImplJobSetup::SetSystem(sal_uInt16 nSystem
)
101 void ImplJobSetup::SetPrinterName(const OUString
& rPrinterName
)
103 maPrinterName
= rPrinterName
;
106 void ImplJobSetup::SetDriver(const OUString
& rDriver
)
111 void ImplJobSetup::SetOrientation(Orientation eOrientation
)
113 meOrientation
= eOrientation
;
116 void ImplJobSetup::SetDuplexMode(DuplexMode eDuplexMode
)
118 meDuplexMode
= eDuplexMode
;
121 void ImplJobSetup::SetPaperBin(sal_uInt16 nPaperBin
)
123 mnPaperBin
= nPaperBin
;
126 void ImplJobSetup::SetPaperFormat(Paper ePaperFormat
)
128 mePaperFormat
= ePaperFormat
;
131 void ImplJobSetup::SetPaperWidth(long nPaperWidth
)
133 mnPaperWidth
= nPaperWidth
;
136 void ImplJobSetup::SetPaperHeight(long nPaperHeight
)
138 mnPaperHeight
= nPaperHeight
;
141 void ImplJobSetup::SetDriverDataLen(sal_uInt32 nDriverDataLen
)
143 mnDriverDataLen
= nDriverDataLen
;
146 void ImplJobSetup::SetDriverData(sal_uInt8
* pDriverData
)
148 mpDriverData
= pDriverData
;
151 void ImplJobSetup::SetPapersizeFromSetup(bool bPapersizeFromSetup
)
153 mbPapersizeFromSetup
= bPapersizeFromSetup
;
156 void ImplJobSetup::SetPrinterSetupMode(PrinterSetupMode eMode
)
161 void ImplJobSetup::SetValueMap( const OUString
& rKey
, const OUString
& rValue
)
163 maValueMap
[ rKey
] = rValue
;
166 JobSetup
& JobSetup::operator=( const JobSetup
& ) = default;
168 JobSetup
& JobSetup::operator=( JobSetup
&& ) = default;
170 bool ImplJobSetup::operator==( const ImplJobSetup
& rImplJobSetup
) const
172 return mnSystem
== rImplJobSetup
.mnSystem
&&
173 maPrinterName
== rImplJobSetup
.maPrinterName
&&
174 maDriver
== rImplJobSetup
.maDriver
&&
175 meOrientation
== rImplJobSetup
.meOrientation
&&
176 meDuplexMode
== rImplJobSetup
.meDuplexMode
&&
177 mnPaperBin
== rImplJobSetup
.mnPaperBin
&&
178 mePaperFormat
== rImplJobSetup
.mePaperFormat
&&
179 mnPaperWidth
== rImplJobSetup
.mnPaperWidth
&&
180 mnPaperHeight
== rImplJobSetup
.mnPaperHeight
&&
181 mbPapersizeFromSetup
== rImplJobSetup
.mbPapersizeFromSetup
&&
182 mnDriverDataLen
== rImplJobSetup
.mnDriverDataLen
&&
183 maValueMap
== rImplJobSetup
.maValueMap
&&
184 memcmp( mpDriverData
, rImplJobSetup
.mpDriverData
, mnDriverDataLen
) == 0;
189 struct theGlobalDefault
:
190 public rtl::Static
< JobSetup::ImplType
, theGlobalDefault
> {};
193 JobSetup::JobSetup() : mpData(theGlobalDefault::get())
197 JobSetup::JobSetup( const JobSetup
& ) = default;
199 JobSetup::~JobSetup() = default;
201 bool JobSetup::operator==( const JobSetup
& rJobSetup
) const
203 return mpData
== rJobSetup
.mpData
;
206 const ImplJobSetup
& JobSetup::ImplGetConstData() const
211 ImplJobSetup
& JobSetup::ImplGetData()
216 OUString
const & JobSetup::GetPrinterName() const
218 return mpData
->GetPrinterName();
221 bool JobSetup::IsDefault() const
223 return mpData
.same_object(theGlobalDefault::get());
226 SvStream
& ReadJobSetup( SvStream
& rIStream
, JobSetup
& rJobSetup
)
230 rIStream
.ReadUInt16( nLen
);
234 sal_uInt16 nSystem
= 0;
235 rIStream
.ReadUInt16( nSystem
);
236 size_t nRead
= nLen
- sizeof(nLen
) - sizeof(nSystem
);
237 if (nRead
> rIStream
.remainingSize())
239 SAL_WARN("vcl", "Parsing error: " << rIStream
.remainingSize() <<
240 " max possible entries, but " << nRead
<< " claimed, truncating");
243 sal_uInt64
const nFirstPos
= rIStream
.Tell();
244 std::unique_ptr
<char[]> pTempBuf(new char[nRead
]);
245 nRead
= rIStream
.ReadBytes(pTempBuf
.get(), nRead
);
246 if (nRead
>= sizeof(ImplOldJobSetupData
))
248 ImplOldJobSetupData
* pData
= reinterpret_cast<ImplOldJobSetupData
*>(pTempBuf
.get());
250 rtl_TextEncoding aStreamEncoding
= RTL_TEXTENCODING_UTF8
;
251 if( nSystem
== JOBSET_FILE364_SYSTEM
)
252 aStreamEncoding
= rIStream
.GetStreamCharSet();
254 ImplJobSetup
& rJobData
= rJobSetup
.ImplGetData();
256 pData
->cPrinterName
[SAL_N_ELEMENTS(pData
->cPrinterName
) - 1] = 0;
257 rJobData
.SetPrinterName( OStringToOUString(pData
->cPrinterName
, aStreamEncoding
) );
258 pData
->cDriverName
[SAL_N_ELEMENTS(pData
->cDriverName
) - 1] = 0;
259 rJobData
.SetDriver( OStringToOUString(pData
->cDriverName
, aStreamEncoding
) );
261 // Are these our new JobSetup files?
262 if ( nSystem
== JOBSET_FILE364_SYSTEM
||
263 nSystem
== JOBSET_FILE605_SYSTEM
)
265 Impl364JobSetupData
* pOldJobData
= reinterpret_cast<Impl364JobSetupData
*>(pTempBuf
.get() + sizeof( ImplOldJobSetupData
));
266 sal_uInt16 nOldJobDataSize
= SVBT16ToUInt16( pOldJobData
->nSize
);
267 rJobData
.SetSystem( SVBT16ToUInt16( pOldJobData
->nSystem
) );
268 rJobData
.SetDriverDataLen( SVBT32ToUInt32( pOldJobData
->nDriverDataLen
) );
269 rJobData
.SetOrientation( static_cast<Orientation
>(SVBT16ToUInt16( pOldJobData
->nOrientation
)) );
270 rJobData
.SetDuplexMode( DuplexMode::Unknown
);
271 rJobData
.SetPaperBin( SVBT16ToUInt16( pOldJobData
->nPaperBin
) );
272 rJobData
.SetPaperFormat( static_cast<Paper
>(SVBT16ToUInt16( pOldJobData
->nPaperFormat
)) );
273 rJobData
.SetPaperWidth( static_cast<long>(SVBT32ToUInt32( pOldJobData
->nPaperWidth
)) );
274 rJobData
.SetPaperHeight( static_cast<long>(SVBT32ToUInt32( pOldJobData
->nPaperHeight
)) );
275 if ( rJobData
.GetDriverDataLen() )
277 const char* pDriverData
= reinterpret_cast<const char*>(pOldJobData
) + nOldJobDataSize
;
278 const char* pDriverDataEnd
= pDriverData
+ rJobData
.GetDriverDataLen();
279 if (pDriverDataEnd
> pTempBuf
.get() + nRead
)
281 SAL_WARN("vcl", "corrupted job setup");
285 sal_uInt8
* pNewDriverData
= static_cast<sal_uInt8
*>(
286 std::malloc( rJobData
.GetDriverDataLen() ));
287 memcpy( pNewDriverData
, pDriverData
, rJobData
.GetDriverDataLen() );
288 rJobData
.SetDriverData( pNewDriverData
);
291 if( nSystem
== JOBSET_FILE605_SYSTEM
)
293 rIStream
.Seek( nFirstPos
+ sizeof( ImplOldJobSetupData
) +
294 sizeof( Impl364JobSetupData
) + rJobData
.GetDriverDataLen() );
295 while( rIStream
.Tell() < nFirstPos
+ nRead
)
297 OUString aKey
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStream
, RTL_TEXTENCODING_UTF8
);
298 OUString aValue
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStream
, RTL_TEXTENCODING_UTF8
);
299 if( aKey
== "COMPAT_DUPLEX_MODE" )
301 if( aValue
== "DuplexMode::Unknown" )
302 rJobData
.SetDuplexMode( DuplexMode::Unknown
);
303 else if( aValue
== "DuplexMode::Off" )
304 rJobData
.SetDuplexMode( DuplexMode::Off
);
305 else if( aValue
== "DuplexMode::ShortEdge" )
306 rJobData
.SetDuplexMode( DuplexMode::ShortEdge
);
307 else if( aValue
== "DuplexMode::LongEdge" )
308 rJobData
.SetDuplexMode( DuplexMode::LongEdge
);
311 rJobData
.SetValueMap(aKey
, aValue
);
313 SAL_WARN_IF( rIStream
.Tell() != nFirstPos
+nRead
, "vcl", "corrupted job setup" );
314 // ensure correct stream position
315 rIStream
.Seek(nFirstPos
+ nRead
);
324 SvStream
& WriteJobSetup( SvStream
& rOStream
, const JobSetup
& rJobSetup
)
328 if ( rJobSetup
.IsDefault() )
329 rOStream
.WriteUInt16( nLen
);
332 const ImplJobSetup
& rJobData
= rJobSetup
.ImplGetConstData();
333 Impl364JobSetupData aOldJobData
;
334 sal_uInt16 nOldJobDataSize
= sizeof( aOldJobData
);
335 ShortToSVBT16( nOldJobDataSize
, aOldJobData
.nSize
);
336 ShortToSVBT16( rJobData
.GetSystem(), aOldJobData
.nSystem
);
337 UInt32ToSVBT32( rJobData
.GetDriverDataLen(), aOldJobData
.nDriverDataLen
);
338 ShortToSVBT16( static_cast<sal_uInt16
>(rJobData
.GetOrientation()), aOldJobData
.nOrientation
);
339 ShortToSVBT16( rJobData
.GetPaperBin(), aOldJobData
.nPaperBin
);
340 ShortToSVBT16( static_cast<sal_uInt16
>(rJobData
.GetPaperFormat()), aOldJobData
.nPaperFormat
);
341 UInt32ToSVBT32( static_cast<sal_uLong
>(rJobData
.GetPaperWidth()), aOldJobData
.nPaperWidth
);
342 UInt32ToSVBT32( static_cast<sal_uLong
>(rJobData
.GetPaperHeight()), aOldJobData
.nPaperHeight
);
344 ImplOldJobSetupData aOldData
= {};
345 OString
aPrnByteName(OUStringToOString(rJobData
.GetPrinterName(), RTL_TEXTENCODING_UTF8
));
346 strncpy(aOldData
.cPrinterName
, aPrnByteName
.getStr(), SAL_N_ELEMENTS(aOldData
.cPrinterName
) - 1);
347 OString
aDriverByteName(OUStringToOString(rJobData
.GetDriver(), RTL_TEXTENCODING_UTF8
));
348 strncpy(aOldData
.cDriverName
, aDriverByteName
.getStr(), SAL_N_ELEMENTS(aOldData
.cDriverName
) - 1);
349 int nPos
= rOStream
.Tell();
350 rOStream
.WriteUInt16( 0 );
351 rOStream
.WriteUInt16( JOBSET_FILE605_SYSTEM
);
352 rOStream
.WriteBytes( &aOldData
, sizeof( aOldData
) );
353 rOStream
.WriteBytes( &aOldJobData
, nOldJobDataSize
);
354 rOStream
.WriteBytes( rJobData
.GetDriverData(), rJobData
.GetDriverDataLen() );
356 const std::unordered_map
< OUString
, OUString
>& rValueMap(
357 rJobData
.GetValueMap());
359 for (auto const& value
: rValueMap
)
361 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream
, value
.first
, RTL_TEXTENCODING_UTF8
);
362 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream
, value
.second
, RTL_TEXTENCODING_UTF8
);
364 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream
, "COMPAT_DUPLEX_MODE");
365 switch( rJobData
.GetDuplexMode() )
367 case DuplexMode::Unknown
:
368 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream
, "DuplexMode::Unknown");
370 case DuplexMode::Off
:
371 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream
, "DuplexMode::Off");
373 case DuplexMode::ShortEdge
:
374 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream
, "DuplexMode::ShortEdge");
376 case DuplexMode::LongEdge
:
377 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream
, "DuplexMode::LongEdge");
380 nLen
= sal::static_int_cast
<sal_uInt16
>(rOStream
.Tell() - nPos
);
381 rOStream
.Seek( nPos
);
382 rOStream
.WriteUInt16( nLen
);
383 rOStream
.Seek( nPos
+ nLen
);
390 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */