1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_vcl.hxx" 30 31 #include <tools/debug.hxx> 32 #include <tools/stream.hxx> 33 34 #include <rtl/alloc.h> 35 36 #include <vcl/jobset.hxx> 37 38 #include <jobset.h> 39 40 // ======================================================================= 41 42 DBG_NAME( JobSetup ) 43 44 #define JOBSET_FILEFORMAT2 3780 45 #define JOBSET_FILE364_SYSTEM ((sal_uInt16)0xFFFF) 46 #define JOBSET_FILE605_SYSTEM ((sal_uInt16)0xFFFE) 47 48 struct ImplOldJobSetupData 49 { 50 char cPrinterName[64]; 51 char cDeviceName[32]; 52 char cPortName[32]; 53 char cDriverName[32]; 54 }; 55 56 struct Impl364JobSetupData 57 { 58 SVBT16 nSize; 59 SVBT16 nSystem; 60 SVBT32 nDriverDataLen; 61 SVBT16 nOrientation; 62 SVBT16 nPaperBin; 63 SVBT16 nPaperFormat; 64 SVBT32 nPaperWidth; 65 SVBT32 nPaperHeight; 66 }; 67 68 // ======================================================================= 69 70 ImplJobSetup::ImplJobSetup() 71 { 72 mnRefCount = 1; 73 mnSystem = 0; 74 meOrientation = ORIENTATION_PORTRAIT; 75 meDuplexMode = DUPLEX_UNKNOWN; 76 mnPaperBin = 0; 77 mePaperFormat = PAPER_USER; 78 mnPaperWidth = 0; 79 mnPaperHeight = 0; 80 mnDriverDataLen = 0; 81 mpDriverData = NULL; 82 } 83 84 // ----------------------------------------------------------------------- 85 86 ImplJobSetup::ImplJobSetup( const ImplJobSetup& rJobSetup ) : 87 maPrinterName( rJobSetup.maPrinterName ), 88 maDriver( rJobSetup.maDriver ) 89 { 90 mnRefCount = 1; 91 mnSystem = rJobSetup.mnSystem; 92 meOrientation = rJobSetup.meOrientation; 93 meDuplexMode = rJobSetup.meDuplexMode; 94 mnPaperBin = rJobSetup.mnPaperBin; 95 mePaperFormat = rJobSetup.mePaperFormat; 96 mnPaperWidth = rJobSetup.mnPaperWidth; 97 mnPaperHeight = rJobSetup.mnPaperHeight; 98 mnDriverDataLen = rJobSetup.mnDriverDataLen; 99 if ( rJobSetup.mpDriverData ) 100 { 101 mpDriverData = (sal_uInt8*)rtl_allocateMemory( mnDriverDataLen ); 102 memcpy( mpDriverData, rJobSetup.mpDriverData, mnDriverDataLen ); 103 } 104 else 105 mpDriverData = NULL; 106 maValueMap = rJobSetup.maValueMap; 107 } 108 109 // ----------------------------------------------------------------------- 110 111 ImplJobSetup::~ImplJobSetup() 112 { 113 rtl_freeMemory( mpDriverData ); 114 } 115 116 // ======================================================================= 117 118 ImplJobSetup* JobSetup::ImplGetData() 119 { 120 if ( !mpData ) 121 mpData = new ImplJobSetup; 122 else if ( mpData->mnRefCount != 1 ) 123 { 124 mpData->mnRefCount--; 125 mpData = new ImplJobSetup( *mpData ); 126 } 127 128 return mpData; 129 } 130 131 // ----------------------------------------------------------------------- 132 133 ImplJobSetup* JobSetup::ImplGetConstData() 134 { 135 if ( !mpData ) 136 mpData = new ImplJobSetup; 137 return mpData; 138 } 139 140 // ----------------------------------------------------------------------- 141 142 const ImplJobSetup* JobSetup::ImplGetConstData() const 143 { 144 if ( !mpData ) 145 ((JobSetup*)this)->mpData = new ImplJobSetup; 146 return mpData; 147 } 148 149 // ======================================================================= 150 151 JobSetup::JobSetup() 152 { 153 DBG_CTOR( JobSetup, NULL ); 154 155 mpData = NULL; 156 } 157 158 // ----------------------------------------------------------------------- 159 160 JobSetup::JobSetup( const JobSetup& rJobSetup ) 161 { 162 DBG_CTOR( JobSetup, NULL ); 163 DBG_CHKOBJ( &rJobSetup, JobSetup, NULL ); 164 DBG_ASSERT( !rJobSetup.mpData || (rJobSetup.mpData->mnRefCount < 0xFFFE), "JobSetup: RefCount overflow" ); 165 166 mpData = rJobSetup.mpData; 167 if ( mpData ) 168 mpData->mnRefCount++; 169 } 170 171 // ----------------------------------------------------------------------- 172 173 JobSetup::~JobSetup() 174 { 175 DBG_DTOR( JobSetup, NULL ); 176 177 if ( mpData ) 178 { 179 if ( mpData->mnRefCount == 1 ) 180 delete mpData; 181 else 182 mpData->mnRefCount--; 183 } 184 } 185 186 // ----------------------------------------------------------------------- 187 188 XubString JobSetup::GetPrinterName() const 189 { 190 if ( mpData ) 191 return mpData->maPrinterName; 192 else 193 { 194 XubString aName; 195 return aName; 196 } 197 } 198 199 // ----------------------------------------------------------------------- 200 201 XubString JobSetup::GetDriverName() const 202 { 203 if ( mpData ) 204 return mpData->maDriver; 205 else 206 { 207 XubString aDriver; 208 return aDriver; 209 } 210 } 211 212 // ----------------------------------------------------------------------- 213 214 String JobSetup::GetValue( const String& rKey ) const 215 { 216 if( mpData ) 217 { 218 ::std::hash_map< ::rtl::OUString, ::rtl::OUString, ::rtl::OUStringHash >::const_iterator it; 219 it = mpData->maValueMap.find( rKey ); 220 return it != mpData->maValueMap.end() ? String( it->second ) : String(); 221 } 222 return String(); 223 } 224 225 // ----------------------------------------------------------------------- 226 227 void JobSetup::SetValue( const String& rKey, const String& rValue ) 228 { 229 if( ! mpData ) 230 mpData = new ImplJobSetup(); 231 232 mpData->maValueMap[ rKey ] = rValue; 233 } 234 235 // ----------------------------------------------------------------------- 236 237 JobSetup& JobSetup::operator=( const JobSetup& rJobSetup ) 238 { 239 DBG_CHKTHIS( JobSetup, NULL ); 240 DBG_CHKOBJ( &rJobSetup, JobSetup, NULL ); 241 DBG_ASSERT( !rJobSetup.mpData || (rJobSetup.mpData->mnRefCount) < 0xFFFE, "JobSetup: RefCount overflow" ); 242 243 // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann 244 if ( rJobSetup.mpData ) 245 rJobSetup.mpData->mnRefCount++; 246 247 // Wenn es keine statischen ImpDaten sind, dann loeschen, wenn es 248 // die letzte Referenz ist, sonst Referenzcounter decrementieren 249 if ( mpData ) 250 { 251 if ( mpData->mnRefCount == 1 ) 252 delete mpData; 253 else 254 mpData->mnRefCount--; 255 } 256 257 mpData = rJobSetup.mpData; 258 259 return *this; 260 } 261 262 // ----------------------------------------------------------------------- 263 264 sal_Bool JobSetup::operator==( const JobSetup& rJobSetup ) const 265 { 266 DBG_CHKTHIS( JobSetup, NULL ); 267 DBG_CHKOBJ( &rJobSetup, JobSetup, NULL ); 268 269 if ( mpData == rJobSetup.mpData ) 270 return sal_True; 271 272 if ( !mpData || !rJobSetup.mpData ) 273 return sal_False; 274 275 ImplJobSetup* pData1 = mpData; 276 ImplJobSetup* pData2 = rJobSetup.mpData; 277 if ( (pData1->mnSystem == pData2->mnSystem) && 278 (pData1->maPrinterName == pData2->maPrinterName) && 279 (pData1->maDriver == pData2->maDriver) && 280 (pData1->meOrientation == pData2->meOrientation) && 281 (pData1->meDuplexMode == pData2->meDuplexMode) && 282 (pData1->mnPaperBin == pData2->mnPaperBin) && 283 (pData1->mePaperFormat == pData2->mePaperFormat) && 284 (pData1->mnPaperWidth == pData2->mnPaperWidth) && 285 (pData1->mnPaperHeight == pData2->mnPaperHeight) && 286 (pData1->mnDriverDataLen == pData2->mnDriverDataLen) && 287 (memcmp( pData1->mpDriverData, pData2->mpDriverData, pData1->mnDriverDataLen ) == 0) && 288 (pData1->maValueMap == pData2->maValueMap) 289 ) 290 return sal_True; 291 292 return sal_False; 293 } 294 295 // ----------------------------------------------------------------------- 296 297 SvStream& operator>>( SvStream& rIStream, JobSetup& rJobSetup ) 298 { 299 DBG_ASSERTWARNING( rIStream.GetVersion(), "JobSetup::>> - Solar-Version not set on rOStream" ); 300 301 // Zur Zeit haben wir noch kein neues FileFormat 302 // if ( rIStream.GetVersion() < JOBSET_FILEFORMAT2 ) 303 { 304 sal_Size nFirstPos = rIStream.Tell(); 305 306 sal_uInt16 nLen = 0; 307 rIStream >> nLen; 308 if ( !nLen ) 309 return rIStream; 310 311 sal_uInt16 nSystem = 0; 312 rIStream >> nSystem; 313 314 char* pTempBuf = new char[nLen]; 315 rIStream.Read( pTempBuf, nLen - sizeof( nLen ) - sizeof( nSystem ) ); 316 if ( nLen >= sizeof(ImplOldJobSetupData)+4 ) 317 { 318 ImplOldJobSetupData* pData = (ImplOldJobSetupData*)pTempBuf; 319 if ( rJobSetup.mpData ) 320 { 321 if ( rJobSetup.mpData->mnRefCount == 1 ) 322 delete rJobSetup.mpData; 323 else 324 rJobSetup.mpData->mnRefCount--; 325 } 326 327 rtl_TextEncoding aStreamEncoding = RTL_TEXTENCODING_UTF8; 328 if( nSystem == JOBSET_FILE364_SYSTEM ) 329 aStreamEncoding = rIStream.GetStreamCharSet(); 330 331 rJobSetup.mpData = new ImplJobSetup; 332 ImplJobSetup* pJobData = rJobSetup.mpData; 333 pJobData->maPrinterName = UniString( pData->cPrinterName, aStreamEncoding ); 334 pJobData->maDriver = UniString( pData->cDriverName, aStreamEncoding ); 335 336 // Sind es unsere neuen JobSetup-Daten? 337 if ( nSystem == JOBSET_FILE364_SYSTEM || 338 nSystem == JOBSET_FILE605_SYSTEM ) 339 { 340 Impl364JobSetupData* pOldJobData = (Impl364JobSetupData*)(pTempBuf + sizeof( ImplOldJobSetupData )); 341 sal_uInt16 nOldJobDataSize = SVBT16ToShort( pOldJobData->nSize ); 342 pJobData->mnSystem = SVBT16ToShort( pOldJobData->nSystem ); 343 pJobData->mnDriverDataLen = SVBT32ToUInt32( pOldJobData->nDriverDataLen ); 344 pJobData->meOrientation = (Orientation)SVBT16ToShort( pOldJobData->nOrientation ); 345 pJobData->meDuplexMode = DUPLEX_UNKNOWN; 346 pJobData->mnPaperBin = SVBT16ToShort( pOldJobData->nPaperBin ); 347 pJobData->mePaperFormat = (Paper)SVBT16ToShort( pOldJobData->nPaperFormat ); 348 pJobData->mnPaperWidth = (long)SVBT32ToUInt32( pOldJobData->nPaperWidth ); 349 pJobData->mnPaperHeight = (long)SVBT32ToUInt32( pOldJobData->nPaperHeight ); 350 if ( pJobData->mnDriverDataLen ) 351 { 352 sal_uInt8* pDriverData = ((sal_uInt8*)pOldJobData) + nOldJobDataSize; 353 pJobData->mpDriverData = (sal_uInt8*)rtl_allocateMemory( pJobData->mnDriverDataLen ); 354 memcpy( pJobData->mpDriverData, pDriverData, pJobData->mnDriverDataLen ); 355 } 356 if( nSystem == JOBSET_FILE605_SYSTEM ) 357 { 358 rIStream.Seek( nFirstPos + sizeof( ImplOldJobSetupData ) + 4 + sizeof( Impl364JobSetupData ) + pJobData->mnDriverDataLen ); 359 while( rIStream.Tell() < nFirstPos + nLen ) 360 { 361 String aKey, aValue; 362 rIStream.ReadByteString( aKey, RTL_TEXTENCODING_UTF8 ); 363 rIStream.ReadByteString( aValue, RTL_TEXTENCODING_UTF8 ); 364 if( aKey.EqualsAscii( "COMPAT_DUPLEX_MODE" ) ) 365 { 366 if( aValue.EqualsAscii( "DUPLEX_UNKNOWN" ) ) 367 pJobData->meDuplexMode = DUPLEX_UNKNOWN; 368 else if( aValue.EqualsAscii( "DUPLEX_OFF" ) ) 369 pJobData->meDuplexMode = DUPLEX_OFF; 370 else if( aValue.EqualsAscii( "DUPLEX_SHORTEDGE" ) ) 371 pJobData->meDuplexMode = DUPLEX_SHORTEDGE; 372 else if( aValue.EqualsAscii( "DUPLEX_LONGEDGE" ) ) 373 pJobData->meDuplexMode = DUPLEX_LONGEDGE; 374 } 375 else 376 pJobData->maValueMap[ aKey ] = aValue; 377 } 378 DBG_ASSERT( rIStream.Tell() == nFirstPos+nLen, "corrupted job setup" ); 379 // ensure correct stream position 380 rIStream.Seek( nFirstPos + nLen ); 381 } 382 } 383 } 384 delete[] pTempBuf; 385 } 386 /* 387 else 388 { 389 } 390 */ 391 392 return rIStream; 393 } 394 395 // ----------------------------------------------------------------------- 396 397 SvStream& operator<<( SvStream& rOStream, const JobSetup& rJobSetup ) 398 { 399 DBG_ASSERTWARNING( rOStream.GetVersion(), "JobSetup::<< - Solar-Version not set on rOStream" ); 400 401 // Zur Zeit haben wir noch kein neues FileFormat 402 // if ( rOStream.GetVersion() < JOBSET_FILEFORMAT2 ) 403 { 404 sal_uInt16 nLen = 0; 405 if ( !rJobSetup.mpData ) 406 rOStream << nLen; 407 else 408 { 409 sal_uInt16 nSystem = JOBSET_FILE605_SYSTEM; 410 411 const ImplJobSetup* pJobData = rJobSetup.ImplGetConstData(); 412 Impl364JobSetupData aOldJobData; 413 sal_uInt16 nOldJobDataSize = sizeof( aOldJobData ); 414 ShortToSVBT16( nOldJobDataSize, aOldJobData.nSize ); 415 ShortToSVBT16( pJobData->mnSystem, aOldJobData.nSystem ); 416 UInt32ToSVBT32( pJobData->mnDriverDataLen, aOldJobData.nDriverDataLen ); 417 ShortToSVBT16( (sal_uInt16)(pJobData->meOrientation), aOldJobData.nOrientation ); 418 ShortToSVBT16( pJobData->mnPaperBin, aOldJobData.nPaperBin ); 419 ShortToSVBT16( (sal_uInt16)(pJobData->mePaperFormat), aOldJobData.nPaperFormat ); 420 UInt32ToSVBT32( (sal_uLong)(pJobData->mnPaperWidth), aOldJobData.nPaperWidth ); 421 UInt32ToSVBT32( (sal_uLong)(pJobData->mnPaperHeight), aOldJobData.nPaperHeight ); 422 423 ImplOldJobSetupData aOldData; 424 memset( &aOldData, 0, sizeof( aOldData ) ); 425 ByteString aPrnByteName( rJobSetup.GetPrinterName(), RTL_TEXTENCODING_UTF8 ); 426 strncpy( aOldData.cPrinterName, aPrnByteName.GetBuffer(), 63 ); 427 ByteString aDriverByteName( rJobSetup.GetDriverName(), RTL_TEXTENCODING_UTF8 ); 428 strncpy( aOldData.cDriverName, aDriverByteName.GetBuffer(), 31 ); 429 // nLen = sizeof( aOldData ) + 4 + nOldJobDataSize + pJobData->mnDriverDataLen; 430 int nPos = rOStream.Tell(); 431 rOStream << nLen; 432 rOStream << nSystem; 433 rOStream.Write( (char*)&aOldData, sizeof( aOldData ) ); 434 rOStream.Write( (char*)&aOldJobData, nOldJobDataSize ); 435 rOStream.Write( (char*)pJobData->mpDriverData, pJobData->mnDriverDataLen ); 436 ::std::hash_map< ::rtl::OUString, ::rtl::OUString, ::rtl::OUStringHash >::const_iterator it; 437 for( it = pJobData->maValueMap.begin(); it != pJobData->maValueMap.end(); ++it ) 438 { 439 rOStream.WriteByteString( it->first, RTL_TEXTENCODING_UTF8 ); 440 rOStream.WriteByteString( it->second, RTL_TEXTENCODING_UTF8 ); 441 } 442 rOStream.WriteByteString( "COMPAT_DUPLEX_MODE" ) ; 443 switch( pJobData->meDuplexMode ) 444 { 445 case DUPLEX_UNKNOWN: rOStream.WriteByteString( "DUPLEX_UNKNOWN" );break; 446 case DUPLEX_OFF: rOStream.WriteByteString( "DUPLEX_OFF" );break; 447 case DUPLEX_SHORTEDGE: rOStream.WriteByteString( "DUPLEX_SHORTEDGE" );break; 448 case DUPLEX_LONGEDGE: rOStream.WriteByteString( "DUPLEX_LONGEDGE" );break; 449 } 450 nLen = sal::static_int_cast<sal_uInt16>(rOStream.Tell() - nPos); 451 rOStream.Seek( nPos ); 452 rOStream << nLen; 453 rOStream.Seek( nPos + nLen ); 454 } 455 } 456 /* 457 else 458 { 459 } 460 */ 461 462 return rOStream; 463 } 464