1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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];
39 struct Impl364JobSetupData
43 SVBT32 nDriverDataLen
;
51 ImplJobSetup::ImplJobSetup()
54 meOrientation
= Orientation::Portrait
;
55 meDuplexMode
= DuplexMode::Unknown
;
57 mePaperFormat
= PAPER_USER
;
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
);
85 mpDriverData
= nullptr;
88 ImplJobSetup::~ImplJobSetup()
90 rtl_freeMemory( mpDriverData
);
93 void ImplJobSetup::SetSystem(sal_uInt16 nSystem
)
98 void ImplJobSetup::SetPrinterName(const OUString
& rPrinterName
)
100 maPrinterName
= rPrinterName
;
103 void ImplJobSetup::SetDriver(const OUString
& 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
;
164 JobSetup
& JobSetup::operator=( JobSetup
&& rJobSetup
)
166 mpData
= std::move(rJobSetup
.mpData
);
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;
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
214 ImplJobSetup
& JobSetup::ImplGetData()
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
)
233 rIStream
.ReadUInt16( nLen
);
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");
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");
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
);
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
);
325 SvStream
& WriteJobSetup( SvStream
& rOStream
, const JobSetup
& rJobSetup
)
329 if ( rJobSetup
.IsDefault() )
330 rOStream
.WriteUInt16( nLen
);
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");
375 case DuplexMode::Off
:
376 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream
, "DuplexMode::Off");
378 case DuplexMode::ShortEdge
:
379 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream
, "DuplexMode::ShortEdge");
381 case DuplexMode::LongEdge
:
382 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream
, "DuplexMode::LongEdge");
385 nLen
= sal::static_int_cast
<sal_uInt16
>(rOStream
.Tell() - nPos
);
386 rOStream
.Seek( nPos
);
387 rOStream
.WriteUInt16( nLen
);
388 rOStream
.Seek( nPos
+ nLen
);
395 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */