Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / vcl / source / gdi / jobset.cxx
blobb1ca8e3f80f7a97f1ce67e03e787460c87cd2b63
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
25 #include <jobset.h>
26 #include <memory>
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];
35 char cDeviceName[32];
36 char cPortName[32];
37 char cDriverName[32];
40 struct Impl364JobSetupData
42 SVBT16 nSize;
43 SVBT16 nSystem;
44 SVBT32 nDriverDataLen;
45 SVBT16 nOrientation;
46 SVBT16 nPaperBin;
47 SVBT16 nPaperFormat;
48 SVBT32 nPaperWidth;
49 SVBT32 nPaperHeight;
52 ImplJobSetup::ImplJobSetup()
54 mnSystem = 0;
55 meOrientation = Orientation::Portrait;
56 meDuplexMode = DuplexMode::Unknown;
57 mnPaperBin = 0;
58 mePaperFormat = PAPER_USER;
59 mnPaperWidth = 0;
60 mnPaperHeight = 0;
61 mnDriverDataLen = 0;
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 );
87 else
88 mpDriverData = nullptr;
91 ImplJobSetup::~ImplJobSetup()
93 std::free( mpDriverData );
96 void ImplJobSetup::SetSystem(sal_uInt16 nSystem)
98 mnSystem = nSystem;
101 void ImplJobSetup::SetPrinterName(const OUString& rPrinterName)
103 maPrinterName = rPrinterName;
106 void ImplJobSetup::SetDriver(const OUString& rDriver)
108 maDriver = 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)
158 meSetupMode = 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;
187 namespace
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
208 return *mpData;
211 ImplJobSetup& JobSetup::ImplGetData()
213 return *mpData;
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 )
229 sal_uInt16 nLen = 0;
230 rIStream.ReadUInt16( nLen );
231 if (nLen <= 4)
232 return rIStream;
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");
241 return rIStream;
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");
283 else
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 );
310 else
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);
321 return rIStream;
324 SvStream& WriteJobSetup( SvStream& rOStream, const JobSetup& rJobSetup )
327 sal_uInt16 nLen = 0;
328 if ( rJobSetup.IsDefault() )
329 rOStream.WriteUInt16( nLen );
330 else
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");
369 break;
370 case DuplexMode::Off:
371 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, "DuplexMode::Off");
372 break;
373 case DuplexMode::ShortEdge:
374 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, "DuplexMode::ShortEdge");
375 break;
376 case DuplexMode::LongEdge:
377 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, "DuplexMode::LongEdge");
378 break;
380 nLen = sal::static_int_cast<sal_uInt16>(rOStream.Tell() - nPos);
381 rOStream.Seek( nPos );
382 rOStream.WriteUInt16( nLen );
383 rOStream.Seek( nPos + nLen );
387 return rOStream;
390 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */