Gtk-WARNING gtktreestore.c:1047: Invalid column number 1 added to iter
[LibreOffice.git] / vcl / source / gdi / jobset.cxx
blob4ac341f47e59886b8b0b2847f1e15cf4c593dea1
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>
28 #define JOBSET_FILE364_SYSTEM (sal_uInt16(0xFFFF))
29 #define JOBSET_FILE605_SYSTEM (sal_uInt16(0xFFFE))
31 namespace {
33 // used only for compatibility with older versions,
34 // printer/driver name are truncated if too long,
35 // device name and port name are completely unused
36 struct ImplOldJobSetupData
38 char cPrinterName[64];
39 char cDeviceName[32];
40 char cPortName[32];
41 char cDriverName[32];
44 struct Impl364JobSetupData
46 SVBT16 nSize;
47 SVBT16 nSystem;
48 SVBT32 nDriverDataLen;
49 SVBT16 nOrientation;
50 SVBT16 nPaperBin;
51 SVBT16 nPaperFormat;
52 SVBT32 nPaperWidth;
53 SVBT32 nPaperHeight;
58 ImplJobSetup::ImplJobSetup()
60 mnSystem = 0;
61 meOrientation = Orientation::Portrait;
62 meDuplexMode = DuplexMode::Unknown;
63 mnPaperBin = 0;
64 mePaperFormat = PAPER_USER;
65 mnPaperWidth = 0;
66 mnPaperHeight = 0;
67 mnDriverDataLen = 0;
68 mbPapersizeFromSetup = false;
69 meSetupMode = PrinterSetupMode::DocumentGlobal;
72 ImplJobSetup::ImplJobSetup( const ImplJobSetup& rJobSetup ) :
73 mnSystem( rJobSetup.GetSystem() ),
74 maPrinterName( rJobSetup.GetPrinterName() ),
75 maDriver( rJobSetup.GetDriver() ),
76 meOrientation( rJobSetup.GetOrientation() ),
77 meDuplexMode( rJobSetup.GetDuplexMode() ),
78 mnPaperBin( rJobSetup.GetPaperBin() ),
79 mePaperFormat( rJobSetup.GetPaperFormat() ),
80 mnPaperWidth( rJobSetup.GetPaperWidth() ),
81 mnPaperHeight( rJobSetup.GetPaperHeight() ),
82 mnDriverDataLen( rJobSetup.GetDriverDataLen() ),
83 mpDriverData(),
84 mbPapersizeFromSetup( rJobSetup.GetPapersizeFromSetup() ),
85 meSetupMode( rJobSetup.GetPrinterSetupMode() ),
86 maValueMap( rJobSetup.GetValueMap() )
88 if ( rJobSetup.GetDriverData() )
90 mpDriverData.reset( new sal_uInt8[mnDriverDataLen] );
91 memcpy( mpDriverData.get(), rJobSetup.GetDriverData(), mnDriverDataLen );
93 else
94 mpDriverData = nullptr;
97 ImplJobSetup::~ImplJobSetup()
101 void ImplJobSetup::SetSystem(sal_uInt16 nSystem)
103 mnSystem = nSystem;
106 void ImplJobSetup::SetPrinterName(const OUString& rPrinterName)
108 maPrinterName = rPrinterName;
111 void ImplJobSetup::SetDriver(const OUString& rDriver)
113 maDriver = rDriver;
116 void ImplJobSetup::SetOrientation(Orientation eOrientation)
118 meOrientation = eOrientation;
121 void ImplJobSetup::SetDuplexMode(DuplexMode eDuplexMode)
123 meDuplexMode = eDuplexMode;
126 void ImplJobSetup::SetPaperBin(sal_uInt16 nPaperBin)
128 mnPaperBin = nPaperBin;
131 void ImplJobSetup::SetPaperFormat(Paper ePaperFormat)
133 mePaperFormat = ePaperFormat;
136 void ImplJobSetup::SetPaperWidth(tools::Long nPaperWidth)
138 mnPaperWidth = nPaperWidth;
141 void ImplJobSetup::SetPaperHeight(tools::Long nPaperHeight)
143 mnPaperHeight = nPaperHeight;
146 void ImplJobSetup::SetDriverData(std::unique_ptr<sal_uInt8[]> pDriverData, sal_uInt32 nDriverDataLen)
148 mpDriverData = std::move(pDriverData);
149 mnDriverDataLen = nDriverDataLen;
152 void ImplJobSetup::SetPapersizeFromSetup(bool bPapersizeFromSetup)
154 mbPapersizeFromSetup = bPapersizeFromSetup;
157 void ImplJobSetup::SetPrinterSetupMode(PrinterSetupMode eMode)
159 meSetupMode = eMode;
162 void ImplJobSetup::SetValueMap( const OUString& rKey, const OUString& rValue )
164 maValueMap [ rKey ] = rValue;
167 JobSetup& JobSetup::operator=( const JobSetup& ) = default;
169 JobSetup& JobSetup::operator=( JobSetup&& ) = default;
171 bool ImplJobSetup::operator==( const ImplJobSetup& rImplJobSetup ) const
173 return mnSystem == rImplJobSetup.mnSystem &&
174 maPrinterName == rImplJobSetup.maPrinterName &&
175 maDriver == rImplJobSetup.maDriver &&
176 meOrientation == rImplJobSetup.meOrientation &&
177 meDuplexMode == rImplJobSetup.meDuplexMode &&
178 mnPaperBin == rImplJobSetup.mnPaperBin &&
179 mePaperFormat == rImplJobSetup.mePaperFormat &&
180 mnPaperWidth == rImplJobSetup.mnPaperWidth &&
181 mnPaperHeight == rImplJobSetup.mnPaperHeight &&
182 mbPapersizeFromSetup == rImplJobSetup.mbPapersizeFromSetup &&
183 mnDriverDataLen == rImplJobSetup.mnDriverDataLen &&
184 maValueMap == rImplJobSetup.maValueMap &&
185 memcmp( mpDriverData.get(),
186 rImplJobSetup.mpDriverData.get(),
187 std::min(mnDriverDataLen, rImplJobSetup.mnDriverDataLen)) == 0;
190 namespace
192 JobSetup::ImplType& GetGlobalDefault()
194 static JobSetup::ImplType gDefault;
195 return gDefault;
199 JobSetup::JobSetup() : mpData(GetGlobalDefault())
203 JobSetup::JobSetup( const JobSetup& ) = default;
205 JobSetup::~JobSetup() = default;
207 bool JobSetup::operator==( const JobSetup& rJobSetup ) const
209 return mpData == rJobSetup.mpData;
212 const ImplJobSetup& JobSetup::ImplGetConstData() const
214 return *mpData;
217 ImplJobSetup& JobSetup::ImplGetData()
219 return *mpData;
222 OUString const & JobSetup::GetPrinterName() const
224 return mpData->GetPrinterName();
227 bool JobSetup::IsDefault() const
229 return mpData.same_object(GetGlobalDefault());
232 SvStream& ReadJobSetup( SvStream& rIStream, JobSetup& rJobSetup )
235 sal_uInt16 nLen = 0;
236 rIStream.ReadUInt16( nLen );
237 if (nLen <= 4)
238 return rIStream;
240 sal_uInt16 nSystem = 0;
241 rIStream.ReadUInt16( nSystem );
242 size_t nRead = nLen - sizeof(nLen) - sizeof(nSystem);
243 if (nRead > rIStream.remainingSize())
245 SAL_WARN("vcl", "Parsing error: " << rIStream.remainingSize() <<
246 " max possible entries, but " << nRead << " claimed, truncating");
247 return rIStream;
249 sal_uInt64 const nFirstPos = rIStream.Tell();
250 std::unique_ptr<char[]> pTempBuf(new char[nRead]);
251 nRead = rIStream.ReadBytes(pTempBuf.get(), nRead);
252 if (nRead >= sizeof(ImplOldJobSetupData))
254 ImplOldJobSetupData* pData = reinterpret_cast<ImplOldJobSetupData*>(pTempBuf.get());
256 rtl_TextEncoding aStreamEncoding = RTL_TEXTENCODING_UTF8;
257 if( nSystem == JOBSET_FILE364_SYSTEM )
258 aStreamEncoding = rIStream.GetStreamCharSet();
260 ImplJobSetup& rJobData = rJobSetup.ImplGetData();
262 // use (potentially truncated) printer/driver name from ImplOldJobSetupData as fallback,
263 // gets overwritten below if PRINTER_NAME/DRIVER_NAME keys are set
264 pData->cPrinterName[std::size(pData->cPrinterName) - 1] = 0;
265 rJobData.SetPrinterName( OStringToOUString(pData->cPrinterName, aStreamEncoding) );
266 pData->cDriverName[std::size(pData->cDriverName) - 1] = 0;
267 rJobData.SetDriver( OStringToOUString(pData->cDriverName, aStreamEncoding) );
269 // Are these our new JobSetup files?
270 if ( nSystem == JOBSET_FILE364_SYSTEM ||
271 nSystem == JOBSET_FILE605_SYSTEM )
273 if (nRead < sizeof(ImplOldJobSetupData) + sizeof(Impl364JobSetupData))
275 SAL_WARN("vcl", "Parsing error: " << sizeof(ImplOldJobSetupData) + sizeof(Impl364JobSetupData) <<
276 " required, but " << nRead << " available");
277 return rIStream;
280 Impl364JobSetupData* pOldJobData = reinterpret_cast<Impl364JobSetupData*>(pTempBuf.get() + sizeof( ImplOldJobSetupData ));
281 sal_uInt16 nOldJobDataSize = SVBT16ToUInt16( pOldJobData->nSize );
282 rJobData.SetSystem( SVBT16ToUInt16( pOldJobData->nSystem ) );
283 const sal_uInt32 nDriverDataLen = SVBT32ToUInt32( pOldJobData->nDriverDataLen );
284 rJobData.SetOrientation( static_cast<Orientation>(SVBT16ToUInt16( pOldJobData->nOrientation )) );
285 rJobData.SetDuplexMode( DuplexMode::Unknown );
286 rJobData.SetPaperBin( SVBT16ToUInt16( pOldJobData->nPaperBin ) );
287 sal_uInt16 nPaperFormat = SVBT16ToUInt16(pOldJobData->nPaperFormat);
288 if (nPaperFormat < NUM_PAPER_ENTRIES)
289 rJobData.SetPaperFormat(static_cast<Paper>(nPaperFormat));
290 else
292 SAL_WARN("vcl", "Parsing error: " << nPaperFormat <<
293 " paper format, but legal max is " << NUM_PAPER_ENTRIES);
295 rJobData.SetPaperWidth( static_cast<tools::Long>(SVBT32ToUInt32( pOldJobData->nPaperWidth )) );
296 rJobData.SetPaperHeight( static_cast<tools::Long>(SVBT32ToUInt32( pOldJobData->nPaperHeight )) );
297 if ( nDriverDataLen )
299 const char* pDriverData = reinterpret_cast<const char*>(pOldJobData) + nOldJobDataSize;
300 const char* pDriverDataEnd = pDriverData + nDriverDataLen;
301 if (pDriverDataEnd > pTempBuf.get() + nRead)
303 SAL_WARN("vcl", "corrupted job setup");
305 else
307 auto pNewDriverData = std::make_unique<sal_uInt8[]>( nDriverDataLen );
308 memcpy( pNewDriverData.get(), pDriverData, nDriverDataLen );
309 rJobData.SetDriverData( std::move(pNewDriverData), nDriverDataLen );
312 if( nSystem == JOBSET_FILE605_SYSTEM )
314 rIStream.Seek( nFirstPos + sizeof( ImplOldJobSetupData ) +
315 sizeof( Impl364JobSetupData ) + rJobData.GetDriverDataLen() );
316 while( rIStream.Tell() < nFirstPos + nRead )
318 OUString aKey = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStream, RTL_TEXTENCODING_UTF8);
319 OUString aValue = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStream, RTL_TEXTENCODING_UTF8);
320 if( aKey == "COMPAT_DUPLEX_MODE" )
322 if( aValue == "DuplexMode::Unknown" )
323 rJobData.SetDuplexMode( DuplexMode::Unknown );
324 else if( aValue == "DuplexMode::Off" )
325 rJobData.SetDuplexMode( DuplexMode::Off );
326 else if( aValue == "DuplexMode::ShortEdge" )
327 rJobData.SetDuplexMode( DuplexMode::ShortEdge );
328 else if( aValue == "DuplexMode::LongEdge" )
329 rJobData.SetDuplexMode( DuplexMode::LongEdge );
331 else if (aKey == u"PRINTER_NAME")
332 rJobData.SetPrinterName(aValue);
333 else if (aKey == u"DRIVER_NAME")
334 rJobData.SetDriver(aValue);
335 else
336 rJobData.SetValueMap(aKey, aValue);
338 SAL_WARN_IF( rIStream.Tell() != nFirstPos+nRead, "vcl", "corrupted job setup" );
339 // ensure correct stream position
340 rIStream.Seek(nFirstPos + nRead);
346 return rIStream;
349 SvStream& WriteJobSetup( SvStream& rOStream, const JobSetup& rJobSetup )
352 sal_uInt16 nLen = 0;
353 if ( rJobSetup.IsDefault() )
354 rOStream.WriteUInt16( nLen );
355 else
357 const ImplJobSetup& rJobData = rJobSetup.ImplGetConstData();
358 Impl364JobSetupData aOldJobData;
359 sal_uInt16 nOldJobDataSize = sizeof( aOldJobData );
360 ShortToSVBT16( nOldJobDataSize, aOldJobData.nSize );
361 ShortToSVBT16( rJobData.GetSystem(), aOldJobData.nSystem );
362 UInt32ToSVBT32( rJobData.GetDriverDataLen(), aOldJobData.nDriverDataLen );
363 ShortToSVBT16( static_cast<sal_uInt16>(rJobData.GetOrientation()), aOldJobData.nOrientation );
364 ShortToSVBT16( rJobData.GetPaperBin(), aOldJobData.nPaperBin );
365 ShortToSVBT16( static_cast<sal_uInt16>(rJobData.GetPaperFormat()), aOldJobData.nPaperFormat );
366 UInt32ToSVBT32( static_cast<sal_uInt32>(rJobData.GetPaperWidth()), aOldJobData.nPaperWidth );
367 UInt32ToSVBT32( static_cast<sal_uInt32>(rJobData.GetPaperHeight()), aOldJobData.nPaperHeight );
369 ImplOldJobSetupData aOldData = {};
370 OString aPrnByteName(OUStringToOString(rJobData.GetPrinterName(), RTL_TEXTENCODING_UTF8));
371 strncpy(aOldData.cPrinterName, aPrnByteName.getStr(), std::size(aOldData.cPrinterName) - 1);
372 OString aDriverByteName(OUStringToOString(rJobData.GetDriver(), RTL_TEXTENCODING_UTF8));
373 strncpy(aOldData.cDriverName, aDriverByteName.getStr(), std::size(aOldData.cDriverName) - 1);
374 int nPos = rOStream.Tell();
375 rOStream.WriteUInt16( 0 );
376 rOStream.WriteUInt16( JOBSET_FILE605_SYSTEM );
377 rOStream.WriteBytes( &aOldData, sizeof( aOldData ) );
378 rOStream.WriteBytes( &aOldJobData, nOldJobDataSize );
379 rOStream.WriteBytes( rJobData.GetDriverData(), rJobData.GetDriverDataLen() );
381 const std::unordered_map< OUString, OUString >& rValueMap(
382 rJobData.GetValueMap());
384 for (auto const& value : rValueMap)
386 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream, value.first, RTL_TEXTENCODING_UTF8);
387 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream, value.second, RTL_TEXTENCODING_UTF8);
389 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, "COMPAT_DUPLEX_MODE");
390 switch( rJobData.GetDuplexMode() )
392 case DuplexMode::Unknown:
393 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, "DuplexMode::Unknown");
394 break;
395 case DuplexMode::Off:
396 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, "DuplexMode::Off");
397 break;
398 case DuplexMode::ShortEdge:
399 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, "DuplexMode::ShortEdge");
400 break;
401 case DuplexMode::LongEdge:
402 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, "DuplexMode::LongEdge");
403 break;
405 // write printer, driver name in full, the ones in aOldData may be truncated
406 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream, u"PRINTER_NAME", RTL_TEXTENCODING_UTF8);
407 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream, rJobData.GetPrinterName(), RTL_TEXTENCODING_UTF8);
408 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream, u"DRIVER_NAME", RTL_TEXTENCODING_UTF8);
409 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream, rJobData.GetDriver(), RTL_TEXTENCODING_UTF8);
411 nLen = sal::static_int_cast<sal_uInt16>(rOStream.Tell() - nPos);
412 rOStream.Seek( nPos );
413 rOStream.WriteUInt16( nLen );
414 rOStream.Seek( nPos + nLen );
418 return rOStream;
421 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */