LibreOffice Module vcl (master)  1
jobset.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
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 
28 #define JOBSET_FILE364_SYSTEM (sal_uInt16(0xFFFF))
29 #define JOBSET_FILE605_SYSTEM (sal_uInt16(0xFFFE))
30 
31 namespace {
32 
33 struct ImplOldJobSetupData
34 {
35  char cPrinterName[64];
36  char cDeviceName[32];
37  char cPortName[32];
38  char cDriverName[32];
39 };
40 
41 struct Impl364JobSetupData
42 {
43  SVBT16 nSize;
44  SVBT16 nSystem;
45  SVBT32 nDriverDataLen;
46  SVBT16 nOrientation;
47  SVBT16 nPaperBin;
48  SVBT16 nPaperFormat;
49  SVBT32 nPaperWidth;
50  SVBT32 nPaperHeight;
51 };
52 
53 }
54 
56 {
57  mnSystem = 0;
60  mnPaperBin = 0;
62  mnPaperWidth = 0;
63  mnPaperHeight = 0;
64  mnDriverDataLen = 0;
65  mpDriverData = nullptr;
66  mbPapersizeFromSetup = false;
68 }
69 
71  mnSystem( rJobSetup.GetSystem() ),
72  maPrinterName( rJobSetup.GetPrinterName() ),
73  maDriver( rJobSetup.GetDriver() ),
74  meOrientation( rJobSetup.GetOrientation() ),
75  meDuplexMode( rJobSetup.GetDuplexMode() ),
76  mnPaperBin( rJobSetup.GetPaperBin() ),
77  mePaperFormat( rJobSetup.GetPaperFormat() ),
78  mnPaperWidth( rJobSetup.GetPaperWidth() ),
79  mnPaperHeight( rJobSetup.GetPaperHeight() ),
80  mnDriverDataLen( rJobSetup.GetDriverDataLen() ),
81  mbPapersizeFromSetup( rJobSetup.GetPapersizeFromSetup() ),
82  meSetupMode( rJobSetup.GetPrinterSetupMode() ),
83  maValueMap( rJobSetup.GetValueMap() )
84  {
85  if ( rJobSetup.GetDriverData() )
86  {
87  mpDriverData = static_cast<sal_uInt8*>(std::malloc( mnDriverDataLen ));
88  memcpy( mpDriverData, rJobSetup.GetDriverData(), mnDriverDataLen );
89  }
90  else
91  mpDriverData = nullptr;
92 }
93 
95 {
96  std::free( mpDriverData );
97 }
98 
99 void ImplJobSetup::SetSystem(sal_uInt16 nSystem)
100 {
101  mnSystem = nSystem;
102 }
103 
104 void ImplJobSetup::SetPrinterName(const OUString& rPrinterName)
105 {
106  maPrinterName = rPrinterName;
107 }
108 
109 void ImplJobSetup::SetDriver(const OUString& rDriver)
110 {
111  maDriver = rDriver;
112 }
113 
115 {
116  meOrientation = eOrientation;
117 }
118 
120 {
121  meDuplexMode = eDuplexMode;
122 }
123 
124 void ImplJobSetup::SetPaperBin(sal_uInt16 nPaperBin)
125 {
126  mnPaperBin = nPaperBin;
127 }
128 
130 {
131  mePaperFormat = ePaperFormat;
132 }
133 
135 {
136  mnPaperWidth = nPaperWidth;
137 }
138 
140 {
141  mnPaperHeight = nPaperHeight;
142 }
143 
144 void ImplJobSetup::SetDriverDataLen(sal_uInt32 nDriverDataLen)
145 {
146  mnDriverDataLen = nDriverDataLen;
147 }
148 
150 {
151  mpDriverData = pDriverData;
152 }
153 
154 void ImplJobSetup::SetPapersizeFromSetup(bool bPapersizeFromSetup)
155 {
156  mbPapersizeFromSetup = bPapersizeFromSetup;
157 }
158 
160 {
161  meSetupMode = eMode;
162 }
163 
164 void ImplJobSetup::SetValueMap( const OUString& rKey, const OUString& rValue )
165 {
166  maValueMap [ rKey ] = rValue;
167 }
168 
169 JobSetup& JobSetup::operator=( const JobSetup& ) = default;
170 
171 JobSetup& JobSetup::operator=( JobSetup&& ) = default;
172 
173 bool ImplJobSetup::operator==( const ImplJobSetup& rImplJobSetup ) const
174 {
175  return mnSystem == rImplJobSetup.mnSystem &&
176  maPrinterName == rImplJobSetup.maPrinterName &&
177  maDriver == rImplJobSetup.maDriver &&
178  meOrientation == rImplJobSetup.meOrientation &&
179  meDuplexMode == rImplJobSetup.meDuplexMode &&
180  mnPaperBin == rImplJobSetup.mnPaperBin &&
181  mePaperFormat == rImplJobSetup.mePaperFormat &&
182  mnPaperWidth == rImplJobSetup.mnPaperWidth &&
183  mnPaperHeight == rImplJobSetup.mnPaperHeight &&
184  mbPapersizeFromSetup == rImplJobSetup.mbPapersizeFromSetup &&
185  mnDriverDataLen == rImplJobSetup.mnDriverDataLen &&
186  maValueMap == rImplJobSetup.maValueMap &&
187  memcmp( mpDriverData, rImplJobSetup.mpDriverData, mnDriverDataLen ) == 0;
188 }
189 
190 namespace
191 {
192  JobSetup::ImplType& GetGlobalDefault()
193  {
194  static JobSetup::ImplType gDefault;
195  return gDefault;
196  }
197 }
198 
199 JobSetup::JobSetup() : mpData(GetGlobalDefault())
200 {
201 }
202 
203 JobSetup::JobSetup( const JobSetup& ) = default;
204 
205 JobSetup::~JobSetup() = default;
206 
207 bool JobSetup::operator==( const JobSetup& rJobSetup ) const
208 {
209  return mpData == rJobSetup.mpData;
210 }
211 
213 {
214  return *mpData;
215 }
216 
218 {
219  return *mpData;
220 }
221 
222 OUString const & JobSetup::GetPrinterName() const
223 {
224  return mpData->GetPrinterName();
225 }
226 
228 {
229  return mpData.same_object(GetGlobalDefault());
230 }
231 
232 SvStream& ReadJobSetup( SvStream& rIStream, JobSetup& rJobSetup )
233 {
234  {
235  sal_uInt16 nLen = 0;
236  rIStream.ReadUInt16( nLen );
237  if (nLen <= 4)
238  return rIStream;
239 
240  sal_uInt16 nSystem = 0;
241  rIStream.ReadUInt16( nSystem );
242  size_t nRead = nLen - sizeof(nLen) - sizeof(nSystem);
243  if (nRead > rIStream.remainingSize())
244  {
245  SAL_WARN("vcl", "Parsing error: " << rIStream.remainingSize() <<
246  " max possible entries, but " << nRead << " claimed, truncating");
247  return rIStream;
248  }
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))
253  {
254  ImplOldJobSetupData* pData = reinterpret_cast<ImplOldJobSetupData*>(pTempBuf.get());
255 
256  rtl_TextEncoding aStreamEncoding = RTL_TEXTENCODING_UTF8;
257  if( nSystem == JOBSET_FILE364_SYSTEM )
258  aStreamEncoding = rIStream.GetStreamCharSet();
259 
260  ImplJobSetup& rJobData = rJobSetup.ImplGetData();
261 
262  pData->cPrinterName[SAL_N_ELEMENTS(pData->cPrinterName) - 1] = 0;
263  rJobData.SetPrinterName( OStringToOUString(pData->cPrinterName, aStreamEncoding) );
264  pData->cDriverName[SAL_N_ELEMENTS(pData->cDriverName) - 1] = 0;
265  rJobData.SetDriver( OStringToOUString(pData->cDriverName, aStreamEncoding) );
266 
267  // Are these our new JobSetup files?
268  if ( nSystem == JOBSET_FILE364_SYSTEM ||
269  nSystem == JOBSET_FILE605_SYSTEM )
270  {
271  if (nRead < sizeof(ImplOldJobSetupData) + sizeof(Impl364JobSetupData))
272  {
273  SAL_WARN("vcl", "Parsing error: " << sizeof(ImplOldJobSetupData) + sizeof(Impl364JobSetupData) <<
274  " required, but " << nRead << " available");
275  return rIStream;
276  }
277 
278  Impl364JobSetupData* pOldJobData = reinterpret_cast<Impl364JobSetupData*>(pTempBuf.get() + sizeof( ImplOldJobSetupData ));
279  sal_uInt16 nOldJobDataSize = SVBT16ToUInt16( pOldJobData->nSize );
280  rJobData.SetSystem( SVBT16ToUInt16( pOldJobData->nSystem ) );
281  rJobData.SetDriverDataLen( SVBT32ToUInt32( pOldJobData->nDriverDataLen ) );
282  rJobData.SetOrientation( static_cast<Orientation>(SVBT16ToUInt16( pOldJobData->nOrientation )) );
284  rJobData.SetPaperBin( SVBT16ToUInt16( pOldJobData->nPaperBin ) );
285  sal_uInt16 nPaperFormat = SVBT16ToUInt16(pOldJobData->nPaperFormat);
286  if (nPaperFormat < NUM_PAPER_ENTRIES)
287  rJobData.SetPaperFormat(static_cast<Paper>(nPaperFormat));
288  else
289  {
290  SAL_WARN("vcl", "Parsing error: " << nPaperFormat <<
291  " paper format, but legal max is " << NUM_PAPER_ENTRIES);
292  }
293  rJobData.SetPaperWidth( static_cast<tools::Long>(SVBT32ToUInt32( pOldJobData->nPaperWidth )) );
294  rJobData.SetPaperHeight( static_cast<tools::Long>(SVBT32ToUInt32( pOldJobData->nPaperHeight )) );
295  if ( rJobData.GetDriverDataLen() )
296  {
297  const char* pDriverData = reinterpret_cast<const char*>(pOldJobData) + nOldJobDataSize;
298  const char* pDriverDataEnd = pDriverData + rJobData.GetDriverDataLen();
299  if (pDriverDataEnd > pTempBuf.get() + nRead)
300  {
301  SAL_WARN("vcl", "corrupted job setup");
302  }
303  else
304  {
305  sal_uInt8* pNewDriverData = static_cast<sal_uInt8*>(
306  std::malloc( rJobData.GetDriverDataLen() ));
307  memcpy( pNewDriverData, pDriverData, rJobData.GetDriverDataLen() );
308  rJobData.SetDriverData( pNewDriverData );
309  }
310  }
311  if( nSystem == JOBSET_FILE605_SYSTEM )
312  {
313  rIStream.Seek( nFirstPos + sizeof( ImplOldJobSetupData ) +
314  sizeof( Impl364JobSetupData ) + rJobData.GetDriverDataLen() );
315  while( rIStream.Tell() < nFirstPos + nRead )
316  {
317  OUString aKey = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStream, RTL_TEXTENCODING_UTF8);
318  OUString aValue = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStream, RTL_TEXTENCODING_UTF8);
319  if( aKey == "COMPAT_DUPLEX_MODE" )
320  {
321  if( aValue == "DuplexMode::Unknown" )
323  else if( aValue == "DuplexMode::Off" )
324  rJobData.SetDuplexMode( DuplexMode::Off );
325  else if( aValue == "DuplexMode::ShortEdge" )
327  else if( aValue == "DuplexMode::LongEdge" )
329  }
330  else
331  rJobData.SetValueMap(aKey, aValue);
332  }
333  SAL_WARN_IF( rIStream.Tell() != nFirstPos+nRead, "vcl", "corrupted job setup" );
334  // ensure correct stream position
335  rIStream.Seek(nFirstPos + nRead);
336  }
337  }
338  }
339  }
340 
341  return rIStream;
342 }
343 
344 SvStream& WriteJobSetup( SvStream& rOStream, const JobSetup& rJobSetup )
345 {
346  {
347  sal_uInt16 nLen = 0;
348  if ( rJobSetup.IsDefault() )
349  rOStream.WriteUInt16( nLen );
350  else
351  {
352  const ImplJobSetup& rJobData = rJobSetup.ImplGetConstData();
353  Impl364JobSetupData aOldJobData;
354  sal_uInt16 nOldJobDataSize = sizeof( aOldJobData );
355  ShortToSVBT16( nOldJobDataSize, aOldJobData.nSize );
356  ShortToSVBT16( rJobData.GetSystem(), aOldJobData.nSystem );
357  UInt32ToSVBT32( rJobData.GetDriverDataLen(), aOldJobData.nDriverDataLen );
358  ShortToSVBT16( static_cast<sal_uInt16>(rJobData.GetOrientation()), aOldJobData.nOrientation );
359  ShortToSVBT16( rJobData.GetPaperBin(), aOldJobData.nPaperBin );
360  ShortToSVBT16( static_cast<sal_uInt16>(rJobData.GetPaperFormat()), aOldJobData.nPaperFormat );
361  UInt32ToSVBT32( static_cast<sal_uLong>(rJobData.GetPaperWidth()), aOldJobData.nPaperWidth );
362  UInt32ToSVBT32( static_cast<sal_uLong>(rJobData.GetPaperHeight()), aOldJobData.nPaperHeight );
363 
364  ImplOldJobSetupData aOldData = {};
365  OString aPrnByteName(OUStringToOString(rJobData.GetPrinterName(), RTL_TEXTENCODING_UTF8));
366  strncpy(aOldData.cPrinterName, aPrnByteName.getStr(), SAL_N_ELEMENTS(aOldData.cPrinterName) - 1);
367  OString aDriverByteName(OUStringToOString(rJobData.GetDriver(), RTL_TEXTENCODING_UTF8));
368  strncpy(aOldData.cDriverName, aDriverByteName.getStr(), SAL_N_ELEMENTS(aOldData.cDriverName) - 1);
369  int nPos = rOStream.Tell();
370  rOStream.WriteUInt16( 0 );
372  rOStream.WriteBytes( &aOldData, sizeof( aOldData ) );
373  rOStream.WriteBytes( &aOldJobData, nOldJobDataSize );
374  rOStream.WriteBytes( rJobData.GetDriverData(), rJobData.GetDriverDataLen() );
375 
376  const std::unordered_map< OUString, OUString >& rValueMap(
377  rJobData.GetValueMap());
378 
379  for (auto const& value : rValueMap)
380  {
381  write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream, value.first, RTL_TEXTENCODING_UTF8);
382  write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream, value.second, RTL_TEXTENCODING_UTF8);
383  }
384  write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, "COMPAT_DUPLEX_MODE");
385  switch( rJobData.GetDuplexMode() )
386  {
387  case DuplexMode::Unknown:
388  write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, "DuplexMode::Unknown");
389  break;
390  case DuplexMode::Off:
391  write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, "DuplexMode::Off");
392  break;
394  write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, "DuplexMode::ShortEdge");
395  break;
397  write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, "DuplexMode::LongEdge");
398  break;
399  }
400  nLen = sal::static_int_cast<sal_uInt16>(rOStream.Tell() - nPos);
401  rOStream.Seek( nPos );
402  rOStream.WriteUInt16( nLen );
403  rOStream.Seek( nPos + nLen );
404  }
405  }
406 
407  return rOStream;
408 }
409 
410 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt32 mnDriverDataLen
Definition: jobset.h:46
void SetPrinterSetupMode(PrinterSetupMode eMode)
Definition: jobset.cxx:159
OUString maDriver
Definition: jobset.h:39
sal_uInt8 SVBT16[2]
SvStream & WriteUInt16(sal_uInt16 nUInt16)
sal_uInt16 mnSystem
Definition: jobset.h:37
SvStream & WriteJobSetup(SvStream &rOStream, const JobSetup &rJobSetup)
Definition: jobset.cxx:344
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
bool operator==(const ImplJobSetup &rImplJobSetup) const
Definition: jobset.cxx:173
std::unique_ptr< ContentProperties > pData
void SetValueMap(const OUString &rKey, const OUString &rValue)
Definition: jobset.cxx:164
long Long
sal_uInt64 Seek(sal_uInt64 nPos)
~ImplJobSetup()
Definition: jobset.cxx:94
PrinterSetupMode
Definition: prntypes.hxx:85
const OUString & GetDriver() const
Definition: jobset.h:67
JobSetup()
Definition: jobset.cxx:199
sal_uInt8 SVBT32[4]
SAL_DLLPRIVATE const ImplJobSetup & ImplGetConstData() const
Definition: jobset.cxx:212
void SetDriverDataLen(sal_uInt32 nDriverDataLen)
Definition: jobset.cxx:144
DuplexMode GetDuplexMode() const
Definition: jobset.h:73
DuplexMode
Definition: prntypes.hxx:28
void SetPaperHeight(tools::Long nHeight)
Definition: jobset.cxx:139
std::size_t write_uInt16_lenPrefixed_uInt8s_FromOUString(SvStream &rStrm, std::u16string_view rStr, rtl_TextEncoding eEnc)
void SetSystem(sal_uInt16 nSystem)
Definition: jobset.cxx:99
void SetDuplexMode(DuplexMode eDuplexMode)
Definition: jobset.cxx:119
Orientation meOrientation
Definition: jobset.h:40
void SetDriverData(sal_uInt8 *pDriverData)
Definition: jobset.cxx:149
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
SAL_DLLPRIVATE ImplJobSetup & ImplGetData()
Definition: jobset.cxx:217
sal_uInt64 remainingSize()
ImplJobSetup()
Definition: jobset.cxx:55
#define SAL_N_ELEMENTS(arr)
void SetPaperWidth(tools::Long nWidth)
Definition: jobset.cxx:134
OUString read_uInt16_lenPrefixed_uInt8s_ToOUString(SvStream &rStrm, rtl_TextEncoding eEnc)
void SetOrientation(Orientation eOrientation)
Definition: jobset.cxx:114
const OUString & GetPrinterName() const
Definition: jobset.h:64
PrinterSetupMode meSetupMode
Definition: jobset.h:50
bool same_object(const cow_wrapper &rOther) const
const sal_uInt8 * GetDriverData() const
Definition: jobset.h:91
std::size_t WriteBytes(const void *pData, std::size_t nSize)
sal_uInt16 GetSystem() const
Definition: jobset.h:61
void SetPapersizeFromSetup(bool bPapersizeFromSetup)
Definition: jobset.cxx:154
sal_uInt8 * mpDriverData
Definition: jobset.h:47
Paper
Orientation GetOrientation() const
Definition: jobset.h:70
std::unordered_map< OUString, OUString > maValueMap
Definition: jobset.h:52
Paper mePaperFormat
Definition: jobset.h:43
std::size_t write_uInt16_lenPrefixed_uInt8s_FromOString(SvStream &rStrm, std::string_view rStr)
std::size_t ReadBytes(void *pData, std::size_t nSize)
sal_uInt16 GetPaperBin() const
Definition: jobset.h:76
PAPER_USER
OUString const & GetPrinterName() const
Definition: jobset.cxx:222
void SetPaperBin(sal_uInt16 nPaperBin)
Definition: jobset.cxx:124
#define SAL_WARN_IF(condition, area, stream)
unsigned char sal_uInt8
tools::Long mnPaperWidth
Definition: jobset.h:44
tools::Long GetPaperWidth() const
Definition: jobset.h:82
sal_uInt32 GetDriverDataLen() const
Definition: jobset.h:88
rtl_TextEncoding GetStreamCharSet() const
tools::Long mnPaperHeight
Definition: jobset.h:45
Orientation
Definition: prntypes.hxx:31
void SetPrinterName(const OUString &rPrinterName)
Definition: jobset.cxx:104
sal_uInt64 Tell() const
Any value
ImplType mpData
Definition: jobset.hxx:58
Paper GetPaperFormat() const
Definition: jobset.h:79
bool operator==(const JobSetup &rJobSetup) const
Definition: jobset.cxx:207
void SetDriver(const OUString &rDriver)
Definition: jobset.cxx:109
tools::Long GetPaperHeight() const
Definition: jobset.h:85
sal_uInt16 mnPaperBin
Definition: jobset.h:42
SvStream & ReadJobSetup(SvStream &rIStream, JobSetup &rJobSetup)
Definition: jobset.cxx:232
#define SAL_WARN(area, stream)
void SetPaperFormat(Paper ePaperFormat)
Definition: jobset.cxx:129
JobSetup & operator=(const JobSetup &rJob)
#define NUM_PAPER_ENTRIES
DuplexMode meDuplexMode
Definition: jobset.h:41
#define JOBSET_FILE364_SYSTEM
Definition: jobset.cxx:28
bool IsDefault() const
Definition: jobset.cxx:227
sal_uInt16 nPos
#define JOBSET_FILE605_SYSTEM
Definition: jobset.cxx:29
const std::unordered_map< OUString, OUString > & GetValueMap() const
Definition: jobset.h:100
bool mbPapersizeFromSetup
Definition: jobset.h:48
OUString maPrinterName
Definition: jobset.h:38