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