Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / vcl / source / gdi / jobset.cxx
blob57c02b95b5572aceb97c300a9ac69b34dd7c3832
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/alloc.h>
21 #include <rtl/ustring.hxx>
22 #include <tools/stream.hxx>
23 #include <vcl/jobset.hxx>
24 #include <jobset.h>
25 #include <memory>
26 #include <rtl/instance.hxx>
28 #define JOBSET_FILE364_SYSTEM ((sal_uInt16)0xFFFF)
29 #define JOBSET_FILE605_SYSTEM ((sal_uInt16)0xFFFE)
31 struct ImplOldJobSetupData
33 char cPrinterName[64];
34 char cDeviceName[32];
35 char cPortName[32];
36 char cDriverName[32];
39 struct Impl364JobSetupData
41 SVBT16 nSize;
42 SVBT16 nSystem;
43 SVBT32 nDriverDataLen;
44 SVBT16 nOrientation;
45 SVBT16 nPaperBin;
46 SVBT16 nPaperFormat;
47 SVBT32 nPaperWidth;
48 SVBT32 nPaperHeight;
51 ImplJobSetup::ImplJobSetup()
53 mnSystem = 0;
54 meOrientation = Orientation::Portrait;
55 meDuplexMode = DuplexMode::Unknown;
56 mnPaperBin = 0;
57 mePaperFormat = PAPER_USER;
58 mnPaperWidth = 0;
59 mnPaperHeight = 0;
60 mnDriverDataLen = 0;
61 mpDriverData = nullptr;
62 mbPapersizeFromSetup = false;
65 ImplJobSetup::ImplJobSetup( const ImplJobSetup& rJobSetup ) :
66 mnSystem( rJobSetup.GetSystem() ),
67 maPrinterName( rJobSetup.GetPrinterName() ),
68 maDriver( rJobSetup.GetDriver() ),
69 meOrientation( rJobSetup.GetOrientation() ),
70 meDuplexMode( rJobSetup.GetDuplexMode() ),
71 mnPaperBin( rJobSetup.GetPaperBin() ),
72 mePaperFormat( rJobSetup.GetPaperFormat() ),
73 mnPaperWidth( rJobSetup.GetPaperWidth() ),
74 mnPaperHeight( rJobSetup.GetPaperHeight() ),
75 mnDriverDataLen( rJobSetup.GetDriverDataLen() ),
76 mbPapersizeFromSetup( rJobSetup.GetPapersizeFromSetup() ),
77 maValueMap( rJobSetup.GetValueMap() )
79 if ( rJobSetup.GetDriverData() )
81 mpDriverData = static_cast<sal_uInt8*>(rtl_allocateMemory( mnDriverDataLen ));
82 memcpy( mpDriverData, rJobSetup.GetDriverData(), mnDriverDataLen );
84 else
85 mpDriverData = nullptr;
88 ImplJobSetup::~ImplJobSetup()
90 rtl_freeMemory( mpDriverData );
93 void ImplJobSetup::SetSystem(sal_uInt16 nSystem)
95 mnSystem = nSystem;
98 void ImplJobSetup::SetPrinterName(const OUString& rPrinterName)
100 maPrinterName = rPrinterName;
103 void ImplJobSetup::SetDriver(const OUString& rDriver)
105 maDriver = rDriver;
108 void ImplJobSetup::SetOrientation(Orientation eOrientation)
110 meOrientation = eOrientation;
113 void ImplJobSetup::SetDuplexMode(DuplexMode eDuplexMode)
115 meDuplexMode = eDuplexMode;
118 void ImplJobSetup::SetPaperBin(sal_uInt16 nPaperBin)
120 mnPaperBin = nPaperBin;
123 void ImplJobSetup::SetPaperFormat(Paper ePaperFormat)
125 mePaperFormat = ePaperFormat;
128 void ImplJobSetup::SetPaperWidth(long nPaperWidth)
130 mnPaperWidth = nPaperWidth;
133 void ImplJobSetup::SetPaperHeight(long nPaperHeight)
135 mnPaperHeight = nPaperHeight;
138 void ImplJobSetup::SetDriverDataLen(sal_uInt32 nDriverDataLen)
140 mnDriverDataLen = nDriverDataLen;
143 void ImplJobSetup::SetDriverData(sal_uInt8* pDriverData)
145 mpDriverData = pDriverData;
148 void ImplJobSetup::SetPapersizeFromSetup(bool bPapersizeFromSetup)
150 mbPapersizeFromSetup = bPapersizeFromSetup;
153 void ImplJobSetup::SetValueMap( const OUString& rKey, const OUString& rValue )
155 maValueMap [ rKey ] = rValue;
158 JobSetup& JobSetup::operator=( const JobSetup& rJobSetup )
160 mpData = rJobSetup.mpData;
161 return *this;
164 JobSetup& JobSetup::operator=( JobSetup&& rJobSetup )
166 mpData = std::move(rJobSetup.mpData);
167 return *this;
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 mnDriverDataLen == rImplJobSetup.mnDriverDataLen &&
182 maValueMap == rImplJobSetup.maValueMap &&
183 memcmp( mpDriverData, rImplJobSetup.mpDriverData, mnDriverDataLen ) == 0;
186 namespace
188 struct theGlobalDefault :
189 public rtl::Static< JobSetup::ImplType, theGlobalDefault > {};
192 JobSetup::JobSetup() : mpData(theGlobalDefault::get())
196 JobSetup::JobSetup( const JobSetup& rJobSetup ) : mpData(rJobSetup.mpData)
200 JobSetup::~JobSetup()
204 bool JobSetup::operator==( const JobSetup& rJobSetup ) const
206 return mpData == rJobSetup.mpData;
209 const ImplJobSetup& JobSetup::ImplGetConstData() const
211 return *mpData;
214 ImplJobSetup& JobSetup::ImplGetData()
216 return *mpData;
219 OUString JobSetup::GetPrinterName() const
221 return mpData->GetPrinterName();
224 bool JobSetup::IsDefault() const
226 return mpData.same_object(theGlobalDefault::get());
229 SvStream& ReadJobSetup( SvStream& rIStream, JobSetup& rJobSetup )
232 sal_uInt16 nLen = 0;
233 rIStream.ReadUInt16( nLen );
234 if (nLen <= 4)
235 return rIStream;
237 sal_uInt16 nSystem = 0;
238 rIStream.ReadUInt16( nSystem );
239 size_t nRead = nLen - sizeof(nLen) - sizeof(nSystem);
240 if (nRead > rIStream.remainingSize())
242 SAL_WARN("vcl", "Parsing error: " << rIStream.remainingSize() <<
243 " max possible entries, but " << nRead << " claimed, truncating");
244 return rIStream;
246 sal_uInt64 const nFirstPos = rIStream.Tell();
247 std::unique_ptr<char[]> pTempBuf(new char[nRead]);
248 nRead = rIStream.ReadBytes(pTempBuf.get(), nRead);
249 if (nRead >= sizeof(ImplOldJobSetupData))
251 ImplOldJobSetupData* pData = reinterpret_cast<ImplOldJobSetupData*>(pTempBuf.get());
253 rtl_TextEncoding aStreamEncoding = RTL_TEXTENCODING_UTF8;
254 if( nSystem == JOBSET_FILE364_SYSTEM )
255 aStreamEncoding = rIStream.GetStreamCharSet();
257 ImplJobSetup& rJobData = rJobSetup.ImplGetData();
259 rJobData.SetPrinterName( OStringToOUString(pData->cPrinterName, aStreamEncoding) );
260 rJobData.SetDriver( OStringToOUString(pData->cDriverName, aStreamEncoding) );
262 // Are these our new JobSetup files?
263 if ( nSystem == JOBSET_FILE364_SYSTEM ||
264 nSystem == JOBSET_FILE605_SYSTEM )
266 Impl364JobSetupData* pOldJobData = reinterpret_cast<Impl364JobSetupData*>(pTempBuf.get() + sizeof( ImplOldJobSetupData ));
267 sal_uInt16 nOldJobDataSize = SVBT16ToShort( pOldJobData->nSize );
268 rJobData.SetSystem( SVBT16ToShort( pOldJobData->nSystem ) );
269 rJobData.SetDriverDataLen( SVBT32ToUInt32( pOldJobData->nDriverDataLen ) );
270 rJobData.SetOrientation( (Orientation)SVBT16ToShort( pOldJobData->nOrientation ) );
271 rJobData.SetDuplexMode( DuplexMode::Unknown );
272 rJobData.SetPaperBin( SVBT16ToShort( pOldJobData->nPaperBin ) );
273 rJobData.SetPaperFormat( (Paper)SVBT16ToShort( pOldJobData->nPaperFormat ) );
274 rJobData.SetPaperWidth( (long)SVBT32ToUInt32( pOldJobData->nPaperWidth ) );
275 rJobData.SetPaperHeight( (long)SVBT32ToUInt32( pOldJobData->nPaperHeight ) );
276 if ( rJobData.GetDriverDataLen() )
278 const char* pDriverData = reinterpret_cast<const char*>(pOldJobData) + nOldJobDataSize;
279 const char* pDriverDataEnd = pDriverData + rJobData.GetDriverDataLen();
280 if (pDriverDataEnd > pTempBuf.get() + nRead)
282 SAL_WARN("vcl", "corrupted job setup");
284 else
286 sal_uInt8* pNewDriverData = static_cast<sal_uInt8*>(
287 rtl_allocateMemory( rJobData.GetDriverDataLen() ));
288 memcpy( pNewDriverData, pDriverData, rJobData.GetDriverDataLen() );
289 rJobData.SetDriverData( pNewDriverData );
292 if( nSystem == JOBSET_FILE605_SYSTEM )
294 rIStream.Seek( nFirstPos + sizeof( ImplOldJobSetupData ) +
295 sizeof( Impl364JobSetupData ) + rJobData.GetDriverDataLen() );
296 while( rIStream.Tell() < nFirstPos + nRead )
298 OUString aKey = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStream, RTL_TEXTENCODING_UTF8);
299 OUString aValue = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStream, RTL_TEXTENCODING_UTF8);
300 if( aKey == "COMPAT_DUPLEX_MODE" )
302 if( aValue == "DuplexMode::Unknown" )
303 rJobData.SetDuplexMode( DuplexMode::Unknown );
304 else if( aValue == "DuplexMode::Off" )
305 rJobData.SetDuplexMode( DuplexMode::Off );
306 else if( aValue == "DuplexMode::ShortEdge" )
307 rJobData.SetDuplexMode( DuplexMode::ShortEdge );
308 else if( aValue == "DuplexMode::LongEdge" )
309 rJobData.SetDuplexMode( DuplexMode::LongEdge );
311 else
312 rJobData.SetValueMap(aKey, aValue);
314 SAL_WARN_IF( rIStream.Tell() != nFirstPos+nRead, "vcl", "corrupted job setup" );
315 // ensure correct stream position
316 rIStream.Seek(nFirstPos + nRead);
322 return rIStream;
325 SvStream& WriteJobSetup( SvStream& rOStream, const JobSetup& rJobSetup )
328 sal_uInt16 nLen = 0;
329 if ( rJobSetup.IsDefault() )
330 rOStream.WriteUInt16( nLen );
331 else
333 sal_uInt16 nSystem = JOBSET_FILE605_SYSTEM;
335 const ImplJobSetup& rJobData = rJobSetup.ImplGetConstData();
336 Impl364JobSetupData aOldJobData;
337 sal_uInt16 nOldJobDataSize = sizeof( aOldJobData );
338 ShortToSVBT16( nOldJobDataSize, aOldJobData.nSize );
339 ShortToSVBT16( rJobData.GetSystem(), aOldJobData.nSystem );
340 UInt32ToSVBT32( rJobData.GetDriverDataLen(), aOldJobData.nDriverDataLen );
341 ShortToSVBT16( (sal_uInt16)(rJobData.GetOrientation()), aOldJobData.nOrientation );
342 ShortToSVBT16( rJobData.GetPaperBin(), aOldJobData.nPaperBin );
343 ShortToSVBT16( (sal_uInt16)(rJobData.GetPaperFormat()), aOldJobData.nPaperFormat );
344 UInt32ToSVBT32( (sal_uLong)(rJobData.GetPaperWidth()), aOldJobData.nPaperWidth );
345 UInt32ToSVBT32( (sal_uLong)(rJobData.GetPaperHeight()), aOldJobData.nPaperHeight );
347 ImplOldJobSetupData aOldData;
348 memset( &aOldData, 0, sizeof( aOldData ) );
349 OString aPrnByteName(OUStringToOString(rJobData.GetPrinterName(), RTL_TEXTENCODING_UTF8));
350 strncpy( aOldData.cPrinterName, aPrnByteName.getStr(), 63 );
351 OString aDriverByteName(OUStringToOString(rJobData.GetDriver(), RTL_TEXTENCODING_UTF8));
352 strncpy( aOldData.cDriverName, aDriverByteName.getStr(), 31 );
353 int nPos = rOStream.Tell();
354 rOStream.WriteUInt16( 0 );
355 rOStream.WriteUInt16( nSystem );
356 rOStream.WriteBytes( &aOldData, sizeof( aOldData ) );
357 rOStream.WriteBytes( &aOldJobData, nOldJobDataSize );
358 rOStream.WriteBytes( rJobData.GetDriverData(), rJobData.GetDriverDataLen() );
360 std::unordered_map< OUString, OUString, OUStringHash >::const_iterator it;
361 const std::unordered_map< OUString, OUString, OUStringHash >& rValueMap(
362 rJobData.GetValueMap());
364 for( it = rValueMap.begin(); it != rValueMap.end(); ++it )
366 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream, it->first, RTL_TEXTENCODING_UTF8);
367 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream, it->second, RTL_TEXTENCODING_UTF8);
369 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, "COMPAT_DUPLEX_MODE");
370 switch( rJobData.GetDuplexMode() )
372 case DuplexMode::Unknown:
373 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, "DuplexMode::Unknown");
374 break;
375 case DuplexMode::Off:
376 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, "DuplexMode::Off");
377 break;
378 case DuplexMode::ShortEdge:
379 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, "DuplexMode::ShortEdge");
380 break;
381 case DuplexMode::LongEdge:
382 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, "DuplexMode::LongEdge");
383 break;
385 nLen = sal::static_int_cast<sal_uInt16>(rOStream.Tell() - nPos);
386 rOStream.Seek( nPos );
387 rOStream.WriteUInt16( nLen );
388 rOStream.Seek( nPos + nLen );
392 return rOStream;
395 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */