cxfile.cpp

Go to the documentation of this file.
00001 // $Id: cxfile.cpp 1708 2006-08-17 17:13:38Z gerry $
00002 // Implementation of the controlling class of the v2 file format
00003 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00004 ================================XARAHEADERSTART===========================
00005  
00006                Xara LX, a vector drawing and manipulation program.
00007                     Copyright (C) 1993-2006 Xara Group Ltd.
00008        Copyright on certain contributions may be held in joint with their
00009               respective authors. See AUTHORS file for details.
00010 
00011 LICENSE TO USE AND MODIFY SOFTWARE
00012 ----------------------------------
00013 
00014 This file is part of Xara LX.
00015 
00016 Xara LX is free software; you can redistribute it and/or modify it
00017 under the terms of the GNU General Public License version 2 as published
00018 by the Free Software Foundation.
00019 
00020 Xara LX and its component source files are distributed in the hope
00021 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00022 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00023 See the GNU General Public License for more details.
00024 
00025 You should have received a copy of the GNU General Public License along
00026 with Xara LX (see the file GPL in the root directory of the
00027 distribution); if not, write to the Free Software Foundation, Inc., 51
00028 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00029 
00030 
00031 ADDITIONAL RIGHTS
00032 -----------------
00033 
00034 Conditional upon your continuing compliance with the GNU General Public
00035 License described above, Xara Group Ltd grants to you certain additional
00036 rights. 
00037 
00038 The additional rights are to use, modify, and distribute the software
00039 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00040 library and any other such library that any version of Xara LX relased
00041 by Xara Group Ltd requires in order to compile and execute, including
00042 the static linking of that library to XaraLX. In the case of the
00043 "CDraw" library, you may satisfy obligation under the GNU General Public
00044 License to provide source code by providing a binary copy of the library
00045 concerned and a copy of the license accompanying it.
00046 
00047 Nothing in this section restricts any of the rights you have under
00048 the GNU General Public License.
00049 
00050 
00051 SCOPE OF LICENSE
00052 ----------------
00053 
00054 This license applies to this program (XaraLX) and its constituent source
00055 files only, and does not necessarily apply to other Xara products which may
00056 in part share the same code base, and are subject to their own licensing
00057 terms.
00058 
00059 This license does not apply to files in the wxXtra directory, which
00060 are built into a separate library, and are subject to the wxWindows
00061 license contained within that directory in the file "WXXTRA-LICENSE".
00062 
00063 This license does not apply to the binary libraries (if any) within
00064 the "libs" directory, which are subject to a separate license contained
00065 within that directory in the file "LIBS-LICENSE".
00066 
00067 
00068 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00069 ----------------------------------------------
00070 
00071 Subject to the terms of the GNU Public License (see above), you are
00072 free to do whatever you like with your modifications. However, you may
00073 (at your option) wish contribute them to Xara's source tree. You can
00074 find details of how to do this at:
00075   http://www.xaraxtreme.org/developers/
00076 
00077 Prior to contributing your modifications, you will need to complete our
00078 contributor agreement. This can be found at:
00079   http://www.xaraxtreme.org/developers/contribute/
00080 
00081 Please note that Xara will not accept modifications which modify any of
00082 the text between the start and end of this header (marked
00083 XARAHEADERSTART and XARAHEADEREND).
00084 
00085 
00086 MARKS
00087 -----
00088 
00089 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00090 designs are registered or unregistered trademarks, design-marks, and/or
00091 service marks of Xara Group Ltd. All rights in these marks are reserved.
00092 
00093 
00094       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00095                         http://www.xara.com/
00096 
00097 =================================XARAHEADEREND============================
00098  */
00099 
00100 #include "camtypes.h"
00101 
00102 #include "cxfile.h"
00103 //#include "cxfrec.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00104 //#include "cxfrech.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00105 //#include "cxfdefs.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00106 #include "cxfmap.h"
00107 
00108 //#include "ccfile.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00109 //#include "progress.h"
00110 //#include "filtrres.h"
00111 
00112 #include "ccpanose.h"
00113 
00114 #if !defined(EXCLUDE_FROM_XARLIB)
00115 #include "bmpsrc.h"     // BitmapSource
00116 #include "ccbuffil.h"
00117 #endif
00118 
00119 #include "cxftags.h"    // The tag definitions
00120 //#include "cxfdefs.h"  // The constants - in camtypes.h [AUTOMATICALLY REMOVED]
00121 #include "zutil.h"      // ZLIB_VERSIONNO
00122 
00123 #if !defined(EXCLUDE_FROM_XARLIB)
00124 //#include "camfiltr.h" // BaseCamelotFilter - in camtypes.h [AUTOMATICALLY REMOVED]
00125 #else
00126 #include "rechcomp.h"
00127 #endif
00128 
00129 #include "hardwaremanager.h"
00130 using namespace oilHardwareManager;
00131 
00132 
00133 //-----------------------------------------------
00134 
00135 CC_IMPLEMENT_DYNAMIC(CXaraFile,CCObject);
00136 CC_IMPLEMENT_DYNAMIC(StandardDefaultRecordHandler,CamelotRecordHandler);
00137 CC_IMPLEMENT_DYNAMIC(GeneralRecordHandler,CamelotRecordHandler);
00138 
00139 #if !defined(EXCLUDE_FROM_XARLIB)
00140 CC_IMPLEMENT_DYNAMIC(NULLXaraFile,CXaraFile);
00141 #endif
00142 
00143 CC_IMPLEMENT_MEMDUMP(AtomicTagListItem,ListItem)
00144 CC_IMPLEMENT_MEMDUMP(EssentialTagListItem,ListItem)
00145 CC_IMPLEMENT_MEMDUMP(TagDescriptionListItem,ListItem)
00146 CC_IMPLEMENT_MEMDUMP(AtomicTagList,List)
00147 CC_IMPLEMENT_MEMDUMP(EssentialTagList,List)
00148 CC_IMPLEMENT_MEMDUMP(TagDescriptionList,List)
00149 
00150 
00151 // This will get Camelot to display the filename and linenumber of any memory allocations
00152 // that are not released at program exit
00153 // Declare smart memory handling in Debug builds
00154 #define new CAM_DEBUG_NEW
00155 
00156 /********************************************************************************************
00157 
00158 >   CXaraFile::CXaraFile()
00159 
00160     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00161     Created:    20/5/96
00162     Purpose:    Default constructor
00163     SeeAlso:    -
00164 
00165 ********************************************************************************************/
00166 
00167 CXaraFile::CXaraFile()
00168 {
00169     pCCFile         = NULL;
00170     pRecord         = NULL;
00171     WriteToRecord   = FALSE;
00172 
00173     RecordNumber    = 0;
00174 
00175     NumBytesWritten     = 0;
00176     NumBytesRead        = 0;
00177     TotalNumBytesToRead = 0;
00178 
00179     // the record handler list
00180     pRecordHandlerList = NULL;
00181 
00182     // The standard set of record handlers
00183     pDefaultRecordHandler               = NULL;
00184     pStandardDefaultRecordHandler       = NULL;
00185     pStripSubTreeRecordHandler          = NULL;
00186     pStandardStripSubTreeRecordHandler  = NULL;
00187 
00188     StartOfStreamedRecord = 0;
00189     WritingStreamedRecord = FALSE;
00190     CompOffDueToStreamedRecord = FALSE;
00191 
00192     pFilter = NULL;
00193     pMap    = NULL;
00194 
00195 #if defined(EXCLUDE_FROM_XARLIB)
00196     pAtomicTagList = NULL;
00197     pEssentialTagList = NULL;
00198 
00199     EndOfFile = FALSE;
00200 #endif
00201 }
00202 
00203 
00204 /********************************************************************************************
00205 
00206 >   BOOL CXaraFile::OpenToWrite(CCLexFile* pThisCCFile)
00207 
00208     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00209     Created:    20/5/96
00210     Inputs:     pThisCCFile = ptr to the file to write to
00211     Returns:    TRUE if the the system is ready to write to the file
00212                 FALSE otherwise
00213     Purpose:    Opens the CXaraFile object ready for writing.
00214                 It uses the given CCFile object as the file to write to.
00215 
00216                 NOTE:  It is assumed that the supplied CCFile has already been opened for writing.
00217 
00218     Errors:     -
00219     SeeAlso:    Close()
00220 
00221 ********************************************************************************************/
00222 
00223 BOOL CXaraFile::OpenToWrite(CCLexFile* pThisCCFile)
00224 {
00225     // Check entry params
00226     ERROR2IF(pThisCCFile == NULL,FALSE,"pThisCCFile is NULL");
00227 
00228     //  pCCFile should be NULL at this point
00229     ERROR3IF(pCCFile != NULL,"pThisCCFile is NULL");
00230 
00231     // Set our ptr the the CCFile to the one provided
00232     pCCFile = pThisCCFile;
00233 
00234     // Reset the write vars
00235     RecordNumber    = 0;
00236     NumBytesWritten = 0;
00237 
00238     BOOL ok = TRUE;
00239 
00240     // The first 8 bytes should be our unique ID sequence
00241     if (ok) ok = Write((UINT32)CXF_IDWORD1);
00242     if (ok) ok = Write((UINT32)CXF_IDWORD2);
00243 
00244     return ok;
00245 }
00246 
00247 /********************************************************************************************
00248 
00249 >   BOOL CXaraFile::SetUpHandlers(BaseCamelotFilter* pFilter)
00250 
00251     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00252     Created:    19/8/96
00253     Inputs:     pFilter = ptr to associated filter
00254     Returns:    TRUE if the the system is ready to read from the file
00255                 FALSE otherwise
00256     Purpose:    Sets up some record handlers that are needed for reading the file successfully
00257 
00258                 Includes set up of the default record handler & the sub tree stripping handler
00259     Errors:     -
00260     SeeAlso:    Close()
00261 
00262 ********************************************************************************************/
00263 #if !defined(EXCLUDE_FROM_XARLIB)
00264 BOOL CXaraFile::SetUpHandlers(BaseCamelotFilter* pFilter)
00265 {
00266     SetUpHandlerMap();
00267 
00268     BOOL ok = TRUE;
00269 
00270     // Set up the default handler, but only if there hasn't been one set up yet
00271     if (pDefaultRecordHandler == NULL)
00272     {
00273         if (pStandardDefaultRecordHandler == NULL)
00274             pStandardDefaultRecordHandler = new StandardDefaultRecordHandler;
00275 
00276         if (pStandardDefaultRecordHandler == NULL)
00277         {
00278             ERROR3("Unable to create StandardDefaultRecordHandler");
00279             return FALSE;
00280         }
00281 
00282         SetDefaultRecordHandler(pStandardDefaultRecordHandler);
00283     }
00284 
00285     // Init the default handler, and inform it we're about to start importing
00286     if (pDefaultRecordHandler != NULL)
00287     {
00288         if (ok) ok = pDefaultRecordHandler->Init(pFilter);
00289         if (ok) ok = pDefaultRecordHandler->BeginImport();
00290     }
00291 
00292     // Set up the sub tree stripper handler, but only if one has not been set yet
00293     if (pStripSubTreeRecordHandler == NULL)
00294     {
00295         if (pStandardStripSubTreeRecordHandler == NULL)
00296             pStandardStripSubTreeRecordHandler = new StripSubTreeRecordHandler;
00297 
00298         if (pStandardStripSubTreeRecordHandler == NULL)
00299         {
00300             ERROR3("Unable to create standard sub tree stripper");
00301             return FALSE;
00302         }
00303 
00304         SetStripSubTreeRecordHandler(pStandardStripSubTreeRecordHandler);
00305     }
00306 
00307     // Init the sub tree stripper handler, and inform it we're about to start importing
00308     if (pStripSubTreeRecordHandler != NULL)
00309     {
00310         if (ok) ok = pStripSubTreeRecordHandler->Init(pFilter);
00311         if (ok) ok = pStripSubTreeRecordHandler->BeginImport();
00312     }
00313 
00314     return ok;
00315 }
00316 #else
00317 
00318 #define NEW_RECORD_HANDLER(HandlerClassName)                \
00319 {                                                           \
00320     CamelotRecordHandler* pCamelotRecordHandler;            \
00321     pCamelotRecordHandler = new HandlerClassName;           \
00322     if (pCamelotRecordHandler != NULL)                      \
00323         pRecordHandlerList->AddTail(pCamelotRecordHandler); \
00324     else                                                    \
00325         return FALSE;                                       \
00326 }                                                           \
00327 
00328 BOOL CXaraFile::SetUpHandlers(void)
00329 {
00330     BOOL ok = TRUE;
00331     
00332     pRecordHandlerList = new List;
00333     if (!pRecordHandlerList)
00334         return(FALSE);
00335     NEW_RECORD_HANDLER(GeneralRecordHandler);       // The general record handler
00336     NEW_RECORD_HANDLER(CompressionRecordHandler);   // The compression record handler
00337 
00338     // Initialise all the handlers
00339     CamelotRecordHandler* pCamelotRecordHandler = (CamelotRecordHandler*)pRecordHandlerList->GetHead();
00340     while (ok && pCamelotRecordHandler != NULL)
00341     {
00342                 ok = pCamelotRecordHandler->Init(this);
00343         if (ok) ok = pCamelotRecordHandler->BeginImport();
00344 
00345         pCamelotRecordHandler = (CamelotRecordHandler*)pRecordHandlerList->GetNext(pCamelotRecordHandler);
00346     }
00347 
00348     if (ok)
00349     {
00350         SetUpHandlerMap();
00351 
00352         // Set up the default handler, but only if there hasn't been one set up yet
00353         if (pDefaultRecordHandler == NULL)
00354         {
00355             if (pStandardDefaultRecordHandler == NULL)
00356                 pStandardDefaultRecordHandler = new StandardDefaultRecordHandler;
00357 
00358             if (pStandardDefaultRecordHandler == NULL)
00359             {
00360                 ERROR3("Unable to create StandardDefaultRecordHandler");
00361                 return FALSE;
00362             }
00363 
00364             SetDefaultRecordHandler(pStandardDefaultRecordHandler);
00365         }
00366 
00367         // Init the default handler, and inform it we're about to start importing
00368         if (pDefaultRecordHandler != NULL)
00369         {
00370             if (ok) ok = pDefaultRecordHandler->Init(this);
00371             if (ok) ok = pDefaultRecordHandler->BeginImport();
00372         }
00373 
00374         // Set up the sub tree stripper handler, but only if one has not been set yet
00375         if (pStripSubTreeRecordHandler == NULL)
00376         {
00377             if (pStandardStripSubTreeRecordHandler == NULL)
00378                 pStandardStripSubTreeRecordHandler = new StripSubTreeRecordHandler;
00379 
00380             if (pStandardStripSubTreeRecordHandler == NULL)
00381             {
00382                 ERROR3("Unable to create standard sub tree stripper");
00383                 return FALSE;
00384             }
00385 
00386             SetStripSubTreeRecordHandler(pStandardStripSubTreeRecordHandler);
00387         }
00388 
00389         // Init the sub tree stripper handler, and inform it we're about to start importing
00390         if (pStripSubTreeRecordHandler != NULL)
00391         {
00392             if (ok) ok = pStripSubTreeRecordHandler->Init(this);
00393             if (ok) ok = pStripSubTreeRecordHandler->BeginImport();
00394         }
00395     }
00396 
00397     return ok;
00398 }
00399 
00400 void CXaraFile::SetExternalRecordHandler(void* pMagic, RecordHandler* pfnRecordHandler)
00401 {
00402     if (pStandardDefaultRecordHandler)
00403         ((StandardDefaultRecordHandler*)pStandardDefaultRecordHandler)->SetExternalHandler(pMagic, pfnRecordHandler);
00404 }
00405 
00406 #endif
00407 
00408 
00409 /********************************************************************************************
00410 
00411 >   void CXaraFile::ResetHandlers()
00412 
00413     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00414     Created:    19/8/96
00415     Inputs:     -
00416     Returns:    -
00417     Purpose:    Resets the handlers set up via SetUpHandlers()
00418 
00419                 All it does is delete any objects it had to create at set up time.
00420     Errors:     -
00421     SeeAlso:    Close()
00422 
00423 ********************************************************************************************/
00424 
00425 void CXaraFile::ResetHandlers()
00426 {
00427     // Delete the StandardDefaultRecordHandler
00428     if (pStandardDefaultRecordHandler != NULL)
00429     {
00430         delete pStandardDefaultRecordHandler;
00431         pStandardDefaultRecordHandler = NULL;
00432     }
00433 
00434     // Delete the StandardStripSubTreeRecordHandler 
00435     if (pStandardStripSubTreeRecordHandler != NULL)
00436     {
00437         delete pStandardStripSubTreeRecordHandler;
00438         pStandardStripSubTreeRecordHandler = NULL;
00439     }
00440 
00441     // delete the tag-to-handler map
00442     if (pMap != NULL)
00443     {
00444         delete pMap;
00445         pMap = NULL;
00446     }
00447 }
00448 
00449 
00450 /********************************************************************************************
00451 
00452 >   void CXaraFile::SetUpHandlerMap()
00453 
00454     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00455     Created:    28/8/96
00456     Inputs:     -
00457     Returns:    -
00458     Purpose:    Sets up the tag to handler map so that LookUpHandler() can function.
00459     Errors:     -
00460     SeeAlso:    LookUpHandler()
00461 
00462 ********************************************************************************************/
00463 
00464 void CXaraFile::SetUpHandlerMap()
00465 {
00466     if (pMap != NULL)
00467         delete pMap;
00468 
00469     pMap = new CXaraFileMapTagToHandler;
00470 
00471     if (pMap != NULL && pRecordHandlerList != NULL)
00472     {
00473         CXaraFileRecordHandler* pHandler = (CXaraFileRecordHandler*) pRecordHandlerList->GetHead();
00474         while (pHandler != NULL)
00475         {
00476             UINT32* pTagList = pHandler->GetTagList();
00477 
00478             if (pTagList != NULL)
00479             {
00480                 while (*pTagList != CXFRH_TAG_LIST_END)
00481                 {
00482                     pMap->Add(*pTagList,pHandler);
00483                     pTagList++;
00484                 }
00485             }
00486 
00487             pHandler = (CXaraFileRecordHandler*) pRecordHandlerList->GetNext(pHandler);
00488         }
00489     }
00490 }
00491 
00492 /********************************************************************************************
00493 
00494 >   BOOL CXaraFile::OpenToRead(CCLexFile* pThisCCFile)
00495 
00496     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00497     Created:    28/5/96
00498     Inputs:     pThisCCFile = ptr to the file to read from
00499     Returns:    TRUE if the the system is ready to read from the file
00500                 FALSE otherwise
00501     Purpose:    Opens the CXaraFile object ready for reading.
00502                 It uses the given CCFile object as the file to read from.
00503 
00504                 NOTE:   It is assumed that the supplied CCFile has already been opened for reading
00505                         from the start of the file. This function will return FALSE if the initial
00506                         8 bytes do not contain the unique file header sequence.
00507 
00508                 This also function sets the default record handler to the standard one, unless you
00509                 have previously set the default handler with a call to SetDefaultRecordHandler().
00510                 You can also set a default handler with SetDefaultRecordHandler() after this call.
00511                 It's up to you, before or after, which
00512     Errors:     -
00513     SeeAlso:    Close()
00514 
00515 ********************************************************************************************/
00516 
00517 BOOL CXaraFile::OpenToRead(CCLexFile* pThisCCFile)
00518 {
00519     // Check entry params
00520     ERROR2IF(pThisCCFile == NULL,FALSE,"pThisCCFile is NULL");
00521 
00522     //  pCCFile should be NULL at this point
00523     ERROR3IF(pCCFile != NULL,"pThisCCFile is NULL");
00524 
00525     // Set our ptr the the CCFile to the one provided
00526     pCCFile = pThisCCFile;
00527 
00528     // Reset the read vars
00529     RecordNumber        = 0;
00530     NumBytesRead        = 0;
00531     TotalNumBytesToRead = 0;
00532 
00533     BOOL ok = TRUE;
00534     UINT32 n = 0;
00535 
00536     // The first 8 bytes should be our unique ID sequence
00537     if (ok) ok = Read(&n);
00538     if (ok) ok = (n == CXF_IDWORD1);
00539     if (ok) ok = Read(&n);
00540     if (ok) ok = (n == CXF_IDWORD2);
00541 
00542     return ok;
00543 }
00544 
00545 /********************************************************************************************
00546 
00547 >   BOOL CXaraFile::Close()
00548 
00549     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00550     Created:    20/5/96
00551     Inputs:     -
00552     Returns:    TRUE if the the system closed down correctly
00553                 FALSE otherwise
00554     Purpose:    This closes the CXaraFile object.
00555                 You should call this func at the very end of reading from or writing to the file
00556 
00557                 NOTE: The supplied pCCFile passed to OpenToWrite() and OpenToRead() is NOT
00558                 closed.  The calling code will have to handle the low level closing of the file.
00559 
00560     Errors:     -
00561     SeeAlso:    OpenToWrite(), OpenToRead()
00562 
00563 ********************************************************************************************/
00564 
00565 BOOL CXaraFile::Close()
00566 {
00567     // Sanity Check 
00568     ERROR3IF(pCCFile == NULL,"pCCFile is NULL");
00569 
00570     // Reset all handlers that we set up via SetUpHandlers()
00571     ResetHandlers();
00572 
00573     return TRUE;
00574 }
00575 
00576 //--------------------
00577 void CXaraFile::SetDefaultRecordHandler(CXaraFileRecordHandler* pHandler)
00578 {
00579     if (pHandler != NULL)
00580         pDefaultRecordHandler = pHandler;
00581     else
00582         pDefaultRecordHandler = pStandardDefaultRecordHandler;
00583 
00584     ERROR3IF(pDefaultRecordHandler == NULL,"NULL handler ptr");
00585 }
00586 
00587 //--------------------
00588 CXaraFileRecordHandler* CXaraFile::GetDefaultRecordHandler()
00589 {
00590     return pDefaultRecordHandler;
00591 }
00592 
00593 //--------------------
00594 BOOL StandardDefaultRecordHandler::HandleRecord(CXaraFileRecord* pCXaraFileRecord)
00595 {
00596     ERROR2IF(pCXaraFileRecord == NULL,FALSE,"NULL record ptr");
00597 #if !defined(EXCLUDE_FROM_XARLIB)
00598     return UnrecognisedTag(pCXaraFileRecord->GetTag());
00599 #else
00600 
00601     if (m_pfnRecordHandler)
00602     {
00603         return (m_pfnRecordHandler)(m_pMagic, pCXaraFileRecord);
00604     }
00605 
00606     return(TRUE);
00607 #endif
00608 }
00609 
00610 //-------------------------------------------------------------------------------------------
00611 void CXaraFile::SetStripSubTreeRecordHandler(StripSubTreeRecordHandler* pHandler)
00612 {
00613     if (pHandler != NULL)
00614         pStripSubTreeRecordHandler = pHandler;
00615     else
00616         pStripSubTreeRecordHandler = pStandardStripSubTreeRecordHandler;
00617 
00618     ERROR3IF(pStripSubTreeRecordHandler == NULL,"NULL handler ptr");
00619 }
00620 
00621 //--------------------
00622 StripSubTreeRecordHandler* CXaraFile::GetStripSubTreeRecordHandler()
00623 {
00624     return pStripSubTreeRecordHandler;
00625 }
00626 
00627 //--------------------
00628 void CXaraFile::StripNextSubTree()
00629 {
00630     if (pStripSubTreeRecordHandler != NULL)
00631         pStripSubTreeRecordHandler->StripSubTreeOn();
00632 }
00633 
00634 /********************************************************************************************
00635 
00636 >   BOOL CXaraFile::SetCompression(BOOL NewState)
00637 
00638     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00639     Created:    6/6/96
00640     Inputs:     The new compression state required, True for on, False for off
00641     Returns:    TRUE if ok
00642                 FALSE otherwise
00643     Purpose:    Function to turn Compression on or off on the underlying CCFile.
00644                 This is used during reading to change the state of the file compression.
00645     Errors:     -
00646     SeeAlso:    CompressionRecordHandler::HandleRecord(); BaseCamelotFilter::SetCompression();
00647 
00648 ********************************************************************************************/
00649 
00650 BOOL CXaraFile::SetCompression(BOOL NewState)
00651 {
00652     ERROR2IF(pCCFile == NULL,FALSE,"CXaraFile::SetCompression pCCFile is NULL");
00653 
00654     // This is used when reading to change the file compression state
00655     // It is called by the compression record handler when it is given the compression on/off
00656     // tags to handle.
00657     // The CCFile ZLib combination will read in the values
00658     BOOL ok = TRUE;
00659     if (NewState)
00660     {
00661         // If turning on then read the version number and check it
00662         UINT32 Version = 0L;
00663         Read(&Version);
00664         
00665         UINT32 MajorVersion = Version / 100;
00666         UINT32 MinorVersion = Version - MajorVersion * 100;
00667 TRACEUSER( "Neville", _T("CXaraFile::SetCompression compression version %d.%d\n"),MajorVersion,MinorVersion);
00668         
00669         // Now tell CCFile to turn compression on
00670         ok = pCCFile->SetCompression(TRUE);
00671     }
00672     else
00673     {
00674 TRACEUSER( "Neville", _T("CXaraFile::SetCompression off\n"));
00675         // Now tell CCFile to turn compression off
00676         // The Zlib/CCFile combination will automatically read in the CRC and uncompressed size
00677         // and check these.
00678         ok = pCCFile->SetCompression(FALSE);
00679 
00680         pCCFile->SetGoodState();
00681         FilePos Pos = pCCFile->tellIn();
00682 TRACEUSER( "Neville", _T("CXaraFile::SetCompression pos = %d\n"),Pos);
00683     }
00684 
00685     return ok;
00686 }
00687 
00688 /********************************************************************************************
00689 
00690 >   virtual BOOL CXaraFile::StartCompression()
00691 
00692     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00693     Created:    6/6/96
00694     Inputs:     -
00695     Returns:    TRUE if ok
00696                 FALSE otherwise
00697     Purpose:    Function to turn Compression on when we are writing to the file. It asks the
00698                 underlying CCFile and CXaraFile to start the compression process up.
00699                 Will only send the record out if the preference option is on.
00700     Errors:     -
00701     SeeAlso:    StopCompression(); BaseCamelotFilter::StartCompression();
00702 
00703 ********************************************************************************************/
00704 
00705 BOOL CXaraFile::StartCompression()
00706 {
00707     ERROR2IF(pCCFile == NULL,FALSE,"CXaraFile::StartCompression pCCFile is NULL");
00708     
00709     // First check whether we are meant to be doing this or not
00710     // by looking at the filter preference
00711 #if !defined(EXCLUDE_FROM_XARLIB)
00712     if (!BaseCamelotFilter::GetNativeCompression())
00713         return TRUE;
00714 #endif
00715 
00716     if (pCCFile->IsCompressionSet())
00717     {
00718         // Just continue as if nothing has happened.
00719         //ERROR3("Trying to compress an already compressed stream!");
00720         return TRUE;
00721     }
00722 
00723     // Send out a start compression record
00724     CXaraFileRecord Rec(TAG_STARTCOMPRESSION, TAG_STARTCOMPRESSION_SIZE);
00725 
00726     BOOL ok = Rec.Init();
00727 
00728     // Save the version and type of compression all in one word or UINT32.
00729     // Top byte is the type of compression which is zero by default = zlib compression
00730     UINT32 Version = ZLIB_MAJOR_VERSIONNO * 100 + ZLIB_MINOR_VERSIONNO;
00731     Rec.WriteUINT32(Version);
00732     
00733     if (ok) ok = (Write(&Rec) != 0);
00734     
00735     // Now ask the CCFile to turn compression on as everything after this needs to be
00736     // compressed.
00737     // First, see if we have enough memory to start up the compression system
00738     if (ok) ok = pCCFile->InitCompression();
00739     
00740     // If this fails then don't try anything
00741     if (ok) ok = pCCFile->SetCompression(TRUE);
00742     
00743     return ok;
00744 }
00745 
00746 /********************************************************************************************
00747 
00748 >   virtual BOOL CXaraFile::IsCompressionOn()
00749 
00750     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00751     Created:    31/7/96
00752     Inputs:     -
00753     Returns:    TRUE if compression is on
00754                 FALSE if off
00755     Purpose:    This returns the compression state of the associated CCFile object.
00756 
00757                 It returns the result of CCFile::IsCompressionSet()
00758 
00759     Errors:     -
00760     SeeAlso:    StartCompression(); BaseCamelotFilter::StopCompression();
00761 
00762 ********************************************************************************************/
00763 
00764 BOOL CXaraFile::IsCompressionOn()
00765 {
00766     ERROR2IF(pCCFile == NULL,FALSE,"pCCFile is NULL");
00767 
00768     return pCCFile->IsCompressionSet();
00769 }
00770 
00771 
00772 /********************************************************************************************
00773 
00774 >   virtual BOOL CXaraFile::StopCompression()
00775 
00776     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00777     Created:    6/6/96
00778     Inputs:     -
00779     Returns:    TRUE if ok
00780                 FALSE otherwise
00781     Purpose:    Function to turn Compression off when we are writing to the file. It asks the
00782                 underlying CCFile and CXaraFile to stop the compression process.
00783                 Will only send the record out if the preference option is on.
00784     Errors:     -
00785     SeeAlso:    StartCompression(); BaseCamelotFilter::StopCompression();
00786 
00787 ********************************************************************************************/
00788 
00789 BOOL CXaraFile::StopCompression()
00790 {
00791     ERROR2IF(pCCFile == NULL,FALSE,"CXaraFile::StopCompression pCCFile is NULL");
00792 
00793     // First check whether we are meant to be doing this or not
00794     // by looking at the filter preference
00795 #if !defined(EXCLUDE_FROM_XARLIB)
00796     if (!BaseCamelotFilter::GetNativeCompression())
00797         return TRUE;
00798 #endif
00799 
00800     if (!pCCFile->IsCompressionSet())
00801     {
00802         // Just continue as if nothing has happened
00803         //ERROR3("Trying to stop compression on an uncompressed stream!");
00804         return TRUE;
00805     }
00806 
00807     // Now send out the end compression record
00808     UINT32 RecordNumber = WriteRecordHeader(TAG_ENDCOMPRESSION, TAG_ENDCOMPRESSION_SIZE);
00809     if (RecordNumber < 0)
00810         return FALSE;
00811 
00812     // If we are turning compression off then just ask the CCFile to do this for us
00813     // This should write out the CRC and file size to the file, so we cannot use the
00814     // legal way of writing records, we have to use the special WriteHeader function above.
00815     BOOL ok = pCCFile->SetCompression(FALSE);
00816 
00817     return ok;
00818 }
00819 
00820 /********************************************************************************************
00821 
00822 >   virtual CCLexFile* CXaraFile::GetCCFile() const
00823 
00824     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00825     Created:    20/6/96
00826     Inputs:     -
00827     Returns:    The CCLexFile that is being used to export the data.
00828     Purpose:    Function to give public access to the underlying CCLexFile that is being used
00829                 to save out the data.
00830                 Note: only people who have a genuine reason need to access this - e.g. bitmap savers
00831     Errors:     -
00832     SeeAlso:    BitmapListComponent::SaveBitmapDefinition; BaseCamelotFilter::GetCCFile;
00833 
00834 ********************************************************************************************/
00835 
00836 CCLexFile* CXaraFile::GetCCFile() const
00837 {
00838     ERROR2IF(pCCFile == NULL,FALSE,"CXaraFile::GetCCFile pCCFile is NULL");
00839     return pCCFile;
00840 }
00841 
00842 
00843 /********************************************************************************************
00844 
00845 >   UINT32 CXaraFile::GetCurrentRecordSize()
00846 
00847     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00848     Created:    23/8/96
00849     Inputs:     -
00850     Returns:    The size of the current record.
00851     Purpose:    Function to get the current size of the record that has been read in by the 
00852                 CXaraFile and RecordHandlers and are currently processing. This can be used
00853                 by streamed record handlers, such as bitmaps, which need to know the size of
00854                 the recordso that they can update the progress bar size by a proportion of
00855                 this amount on loading. (Not require on saving as the streamed record handlers
00856                 can supply what value they like to the progress system and hence update with
00857                 whatever value they require.
00858     SeeAlso:    BaseCamelotFilter::GetCurrentRecordSize();
00859 
00860 ********************************************************************************************/
00861 
00862 UINT32 CXaraFile::GetCurrentRecordSize()
00863 {
00864     return ReadSize;
00865 }
00866 
00867 
00868 /********************************************************************************************
00869 
00870 >   BOOL CXaraFile::Read(UINT32* pUINT32)
00871 
00872     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00873     Created:    28/5/96
00874     Inputs:     pUINT32 = place to stuff a UINT32 in
00875     Returns:    TRUE if read successfully
00876                 FALSE otherwise
00877     Purpose:    Reads in the give value type from the file
00878     Errors:     -
00879     SeeAlso:    -
00880 
00881 ********************************************************************************************/
00882 
00883 BOOL CXaraFile::Read(UINT32* pUINT32)
00884 {
00885     BOOL ok = Read((BYTE*)pUINT32,sizeof(UINT32));
00886     *pUINT32 = LEtoNative(*pUINT32);
00887     return ok;
00888 }
00889 
00890 BOOL CXaraFile::Read(FLOAT* pf)
00891 {
00892     FloatUnion f;
00893     BOOL ok = (Read((BYTE*)&(f.u_INT32),sizeof(f.u_INT32)));
00894     *pf = LEtoNative(f);
00895     return ok;
00896 }
00897 
00898 BOOL CXaraFile::Read(double* pd)
00899 {
00900     DoubleUnion f;
00901     BOOL ok = (Read((BYTE*)&(f.u_INT64),sizeof(f.u_INT64)));
00902     *pd = LEtoNative(f);
00903     return ok;
00904 }
00905 
00906 BOOL CXaraFile::ReadWCHAR(WCHAR *pw)
00907 {
00908     BOOL ok = Read((BYTE*)pw, SIZEOF_XAR_UTF16);    // sizeof(WCHAR));
00909     *pw = LEtoNative(*pw);
00910     *pw = UTF16ToNative(*pw);
00911     return ok;
00912 }
00913 
00914 /********************************************************************************************
00915 
00916 >   BOOL CXaraFile::Read(BYTE* pBuf,UINT32 Size)
00917 
00918     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00919     Created:    28/5/96
00920     Inputs:     pBuf = ptr to a buffer
00921                 Size = size of the buffer in bytes
00922     Returns:    TRUE if read successfully
00923                 FALSE otherwise
00924     Purpose:    Reads in the give value type from the file
00925     Errors:     -
00926     SeeAlso:    -
00927 
00928 ********************************************************************************************/
00929 
00930 BOOL CXaraFile::Read(BYTE* pBuf,UINT32 Size)
00931 {
00932     ERROR3IF(pBuf == NULL,"pBuf is NULL");
00933 
00934     BOOL ok = (pBuf != NULL);
00935 
00936 //  for (UINT32 i=0;ok && i< Size;i++)
00937 //      ok = Read(pBuf+i);
00938 
00939     pCCFile->read((void*)pBuf,Size);
00940     IncNumBytesRead(Size);
00941 
00942     // AMB commented out eof() line - it seems wrong as reading the last bytes in a file
00943     // will otherwise fail
00944     ok = (!pCCFile->bad() && !pCCFile->fail() /*&& !pCCFile->eof()*/);
00945 
00946     return ok;
00947 }
00948 
00949 /********************************************************************************************
00950 
00951 >   BOOL CXaraFile::Read(BYTE* pBYTE)
00952 
00953     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00954     Created:    28/5/96
00955     Inputs:     pUINT32 = place to stuff a UINT32 in
00956     Returns:    TRUE if read successfully
00957                 FALSE otherwise
00958     Purpose:    Reads in the give value type from the file
00959     Errors:     -
00960     SeeAlso:    -
00961 
00962 ********************************************************************************************/
00963 
00964 BOOL CXaraFile::Read(BYTE* pBYTE)
00965 {
00966     ERROR3IF(pBYTE == NULL,"pBYTE is NULL");
00967     ERROR2IF(pCCFile == NULL,FALSE,"Can't write a BYTE with no pCCFile");
00968 
00969     if (pBYTE == NULL)
00970         return FALSE;
00971 
00972     pCCFile->read((void*)pBYTE);
00973     IncNumBytesRead(1);
00974 
00975     return (!pCCFile->bad() && !pCCFile->fail() && !pCCFile->eof());
00976 }
00977 
00978 /********************************************************************************************
00979 
00980 >   BOOL CXaraFile::Read(TCHAR* pStr,UINT32 MaxChars)
00981 
00982     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00983     Created:    19/6/96
00984     Inputs:     MaxChars = maximum number of characters that this string can take
00985     Outputs:    pStr = String to put the data into
00986     Returns:    TRUE if read successfully
00987                 FALSE otherwise
00988     Purpose:    Reads in the given string from the file
00989     Errors:     -
00990     SeeAlso:    -
00991 
00992 ********************************************************************************************/
00993 
00994 BOOL CXaraFile::Read(TCHAR* pStr,UINT32 MaxChars)
00995 {
00996     return ReadUnicode(pStr,MaxChars);
00997 }
00998 
00999 /********************************************************************************************
01000 
01001 >   BOOL CXaraFile::Read(TCHAR* pStr,UINT32 MaxChars)
01002 
01003     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01004     Created:    19/6/96
01005     Inputs:     MaxChars = maximum number of characters that this string can take
01006     Outputs:    pStr = String to put the data into
01007     Returns:    TRUE if read successfully
01008                 FALSE otherwise
01009     Purpose:    Reads in the given string from the file
01010     Errors:     -
01011     SeeAlso:    -
01012 
01013 ********************************************************************************************/
01014 
01015 BOOL CXaraFile::ReadUnicode(TCHAR* pStr,UINT32 MaxChars)
01016 {
01017     ERROR3IF(pStr == NULL,"pStr is NULL");
01018     ERROR2IF(pCCFile == NULL,FALSE,"Can't read a Unicode String with no pCCFile");
01019 
01020     if (pStr == NULL)
01021         return FALSE;
01022 
01023     BOOL ok = TRUE;
01024 
01025 #ifdef UNICODE
01026     if (MaxChars==0)
01027         return FALSE;
01028 
01029     WCHAR* pBuf = pStr;
01030     WCHAR* pBufEnd = pBuf+MaxChars;             // Pointer arithmetic!
01031     WCHAR c = 0;
01032 
01033     do
01034     {
01035         ok = ReadWCHAR(&c);                     // Read two bytes into the WCHAR buffer
01036         if (!ok) c = 0;                         // If the read failed then write a terminator
01037         *pBuf++ = c;                            // Add the character to the string
01038     }
01039     while (c!=0 && pBuf<pBufEnd);// Until end of string or out of room in buffer
01040 
01041 #else
01042     BYTE* pBuf = (BYTE*)pStr;
01043     BYTE* pBufEnd = pBuf+MaxChars;
01044     BYTE b1 = 1;
01045     BYTE b2 = 1;
01046 
01047     while (ok && !(b1 == 0 && b2 == 0))
01048     {
01049         ok = Read(&b1) && Read(&b2);
01050 
01051         if (ok) ok = (pBuf < pBufEnd);
01052         if (ok) *pBuf++ = b1;
01053     }
01054 #endif
01055 
01056     return ok;
01057 }
01058 
01059 
01060 //------------------------------------------------------------------------------
01061 //------------------------------------------------------------------------------
01062 //------------------------------------------------------------------------------
01063 
01064 /********************************************************************************************
01065 
01066 >   BOOL CXaraFile::Write(UINT32 n)
01067 
01068     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01069     Created:    20/5/96
01070     Inputs:     n = UINT32 to write to
01071     Returns:    TRUE if written successfully
01072                 FALSE otherwise
01073     Purpose:    Writes out the given value to the file
01074     Errors:     -
01075     SeeAlso:    -
01076 
01077 ********************************************************************************************/
01078 
01079 BOOL CXaraFile::Write(UINT32 n)
01080 {
01081     UINT32 t = NativetoLE(n);
01082     return (Write((BYTE*)&t,sizeof(UINT32)));
01083 }
01084 
01085 BOOL CXaraFile::Write(INT32 n)
01086 {
01087     INT32 t = NativetoLE(n);
01088     return (Write((BYTE*)&t,sizeof(INT32)));
01089 }
01090 
01091 BOOL CXaraFile::Write(FLOAT f)
01092 {
01093     FloatUnion u=NativetoLEU(f);
01094     return (Write((BYTE*)&(u.u_INT32),sizeof(u.u_INT32)));
01095 }
01096 
01097 BOOL CXaraFile::Write(double d)
01098 {
01099     DoubleUnion u=NativetoLEU(d);
01100     return (Write((BYTE*)&(u.u_INT64),sizeof(u.u_INT64)));
01101 }
01102 
01103 BOOL CXaraFile::WriteWCHAR(WCHAR w)
01104 {
01105     WCHAR t = NativeToUTF16(w);
01106     t = NativetoLE(t);
01107     return (Write((BYTE*)&t, SIZEOF_XAR_UTF16));        //sizeof(WCHAR)));
01108 }
01109 
01110 BOOL CXaraFile::WriteCCPanose(const CCPanose & MyCCPanose)
01111 {
01112     BOOL ok = TRUE;
01113 
01114     if (ok) ok = Write(MyCCPanose.GetFamilyType());
01115     if (ok) ok = Write(MyCCPanose.GetSerifStyle());
01116     if (ok) ok = Write(MyCCPanose.GetWeight());
01117     if (ok) ok = Write(MyCCPanose.GetProportion());
01118     if (ok) ok = Write(MyCCPanose.GetContrast());
01119     if (ok) ok = Write(MyCCPanose.GetStrokeVariation());
01120     if (ok) ok = Write(MyCCPanose.GetArmStyle());
01121     if (ok) ok = Write(MyCCPanose.GetLetterform());
01122     if (ok) ok = Write(MyCCPanose.GetMidline());
01123     if (ok) ok = Write(MyCCPanose.GetXHeight());
01124 
01125     return ok;
01126 }
01127 
01128 /********************************************************************************************
01129 
01130 >   BOOL CXaraFile::Write(TCHAR* pStr)
01131     BOOL CXaraFile::WriteUnicode(TCHAR* pStr)
01132 
01133     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01134     Created:    23/5/96
01135     Inputs:     pStr = ptr to zero-terminated string
01136     Returns:    TRUE if written successfully
01137                 FALSE otherwise
01138     Purpose:    Writes out the string as a Unicode string (UTF16)
01139     Errors:     -
01140     SeeAlso:    -
01141 
01142 ********************************************************************************************/
01143 
01144 BOOL CXaraFile::Write(TCHAR* pStr)
01145 {
01146     return WriteUnicode(pStr);
01147 }
01148 
01149 BOOL CXaraFile::WriteUnicode(TCHAR* pStr)
01150 {
01151     ERROR3IF(pStr == NULL,"NULL pStr");
01152     if (pStr == NULL)
01153         return FALSE;
01154 
01155 #ifdef UNICODE
01156     // pStr points to a Unicode string, so just write it out
01157     //
01158     // We must cope with byte-order differences between native storage and XAR file storage:
01159     // Native may be big-endian or little-endian, XAR is always little-endian
01160     // Native WCHAR may be 16 or 32 bits, XAR is always 16 bits
01161     // These differences are handled in WriteWCHAR
01162     BOOL ok = TRUE;
01163     WCHAR c = 0;
01164     INT32 i = 0;
01165 
01166     do
01167     {
01168         c = pStr[i++];
01169         ok = WriteWCHAR(c);                     // Read two bytes into the WCHAR buffer
01170         if (!ok) c = 0;                         // If the read failed then write a terminator
01171     }
01172     while (c!=0);// Until end of string or no longer OK to write
01173 
01174     return ok;                                  // If we terminated due to Read failure tell the caller
01175 
01176 #else
01177     // pStr points to an ASCII string, and we want it written as a Unicode string
01178     // Write out each char, followed by a 0 byte
01179 
01180     size_t len = camStrlen(pStr);
01181 
01182     BOOL ok= TRUE;
01183     for (unsigned i=0;ok && i<=len;i++)
01184         ok = Write(BYTE(pStr[i])) && Write(BYTE(0));
01185 
01186     return ok;
01187 #endif
01188 }
01189 
01190 /********************************************************************************************
01191 
01192 >   BOOL CXaraFile::WriteASCII(TCHAR* pStr)
01193 
01194     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01195     Created:    23/5/96
01196     Inputs:     pStr = ptr to zero-terminated string
01197     Returns:    TRUE if written successfully
01198                 FALSE otherwise
01199     Purpose:    Writes out the string as an ASCII string
01200     Errors:     -
01201     SeeAlso:    -
01202 
01203 ********************************************************************************************/
01204 
01205 BOOL CXaraFile::WriteASCII(TCHAR* pStr)
01206 {
01207     ERROR3IF(pStr == NULL,"NULL pStr");
01208     if (pStr == NULL)
01209         return FALSE;
01210 
01211     UINT32 len = camStrlen(pStr);
01212 
01213 #ifdef UNICODE
01214     // Writing a Unicode string at pStr as an ASCII string
01215     // Just write out the first byte of each unicode char.
01216 
01217     BOOL ok= TRUE;
01218     for (UINT32 i=0;ok && i<=len;i++)
01219         ok = Write(BYTE(pStr[i*2]));
01220 
01221     return ok;
01222 #else
01223     // pStr points at an ASCII string, so write it out
01224     return (Write((BYTE*)pStr,len+1));
01225 #endif
01226 }
01227 
01228 
01229 /********************************************************************************************
01230 
01231 >   BOOL CXaraFile::Write(const DocCoord& Coord)
01232 
01233     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01234     Created:    31/5/96
01235     Inputs:     Coord = a coord
01236     Returns:    TRUE if written successfully
01237                 FALSE otherwise
01238     Purpose:    Writes out the coord
01239     Errors:     -
01240     SeeAlso:    -
01241 
01242 ********************************************************************************************/
01243 
01244 BOOL CXaraFile::Write(const DocCoord& Coord)
01245 {
01246     return (Write(Coord.x) && Write(Coord.y));
01247 }
01248 
01249 #if !defined(EXCLUDE_FROM_XARLIB)
01250 /********************************************************************************************
01251 
01252 >   BOOL CXaraFile::WriteBitmapSource(const BitmapSource& Source, UINT32 Height, 
01253                                         BaseCamelotFilter* pThisFilter)
01254 
01255     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
01256     Created:    18/08/96
01257     Inputs:     Source : the BitmapSource to write out
01258                 Height : the height of the bitmap in this source
01259                 pThisFilter : the filter whose IncProgressBarCount we will use for the
01260                 progress indicator
01261     Returns:    TRUE if written successfully
01262                 FALSE otherwise
01263     Purpose:    Writes out the given BitmapSource to this file.
01264 
01265     Errors:     ERROR2's if Height is zero or pThisFilter NULL
01266 
01267 ********************************************************************************************/
01268 
01269 BOOL CXaraFile::WriteBitmapSource(const BitmapSource& Source, UINT32 Height, 
01270                                     BaseCamelotFilter* pThisFilter)
01271 {
01272     ERROR2IF(pThisFilter == NULL, FALSE, "pThisFilter == NULL");
01273     ERROR2IF(Height == 0, FALSE, "Height == 0");
01274 
01275     CCBufferFile* pBufferFile = new CCBufferFile(GetCCFile());
01276     // Now create a file that can fill it
01277     if (pBufferFile == NULL || !pBufferFile->IsInited())
01278     {
01279         return FALSE;
01280     }
01281     // and provide the filter with something to work with
01282     Source.AttachToBufferFile(pBufferFile);
01283 
01284     // Work out how much to increment the progress bar by on each loop
01285     OFFSET Size = Source.GetSize();
01286     UINT32 Increment = (Height * CCBufferFile::DEFAULT_BUFSIZ) / Size;
01287     if (Increment > Height)
01288     {
01289         Increment = Height;
01290     }
01291     else if (Increment < 1)
01292     {
01293         Increment = 1;
01294     }
01295     UINT32 UpdateEvery = Size / (Height * CCBufferFile::DEFAULT_BUFSIZ);
01296 
01297     // Write out the BitmapSource DEFAULT_BUFSIZ bytes at a time
01298     UINT32 WritesSinceUpdate = 0;
01299     while (!pBufferFile->IsAllWritten())
01300     {
01301         pBufferFile->write(NULL, CCBufferFile::DEFAULT_BUFSIZ);
01302         if (pBufferFile->bad() || pBufferFile->fail())
01303         {
01304             delete pBufferFile;
01305             return FALSE;
01306         }
01307 
01308         // We've made some progress so provide some user feedback
01309         ++WritesSinceUpdate;
01310         if (WritesSinceUpdate >= UpdateEvery)
01311         {
01312             pThisFilter->IncProgressBarCount(Increment);
01313             WritesSinceUpdate = 0;
01314         }
01315     };
01316 
01317     // Destroy our file handle
01318     delete pBufferFile;
01319 
01320     return TRUE;
01321 }
01322 #endif
01323 
01324 /********************************************************************************************
01325 
01326 >   BOOL CXaraFile::Write(BYTE* pBuf,UINT32 Size)
01327 
01328     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01329     Created:    20/5/96
01330     Inputs:     pBuf = ptr to a BYTE buffer
01331                 Size = Number of bytes in pBuf
01332     Returns:    TRUE if written successfully
01333                 FALSE otherwise
01334     Purpose:    Writes out the given buffer of bytes to the file.
01335     Errors:     -
01336     SeeAlso:    -
01337 
01338 ********************************************************************************************/
01339 
01340 BOOL CXaraFile::Write( BYTE* pBuf, UINT32 Size )
01341 {
01342     ERROR3IF(pBuf == NULL && Size > 0,"NULL pBuf param yet Size > 0");
01343 
01344     BOOL ok = !(pBuf == NULL && Size > 0);
01345 
01346     for (UINT32 i=0;i<Size && ok;i++)
01347         ok = Write(pBuf[i]);
01348 
01349     return ok;
01350 }
01351 
01352 /********************************************************************************************
01353 
01354 >   virtual BOOL CXaraFile::Write(BYTE b)
01355 
01356     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01357     Created:    20/5/96
01358     Inputs:     b = BYTE to write to
01359     Returns:    TRUE if written successfully
01360                 FALSE otherwise
01361     Purpose:    Writes out the given value to the file
01362     Errors:     -
01363     SeeAlso:    -
01364 
01365 ********************************************************************************************/
01366 
01367 BOOL CXaraFile::Write(BYTE b)
01368 {
01369     ERROR2IF(pCCFile == NULL,FALSE,"Can't write a BYTE with no pCCFile");
01370 
01371     BOOL ok = TRUE;
01372 
01373     if (WriteToRecord && pRecord != NULL)
01374         ok = pRecord->WriteBYTE(b);
01375     else
01376     {
01377         pCCFile->write((void const*)&b);
01378         IncNumBytesWritten(1);
01379     }
01380 
01381     return ok;
01382 }
01383 
01384 /********************************************************************************************
01385 
01386 >   INT32 CXaraFile::StartRecord(UINT32 Tag,INT32 Size)
01387 
01388     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01389     Created:    21/5/96
01390     Inputs:     Tag = the tag for the record
01391                 Size = the size of the data section of the record in bytes, or CXF_UNKNOWN_SIZE
01392     Returns:    The record number of the record being written to the file.
01393                 If the function fails, 0 will be returned
01394     Purpose:    Prepares a record ready for writing to the file.
01395 
01396                 This function prepares a record that is buffered in memory before being
01397                 written out to file.  
01398                 
01399                 After this call all Write() functions write to the data section of the record.
01400                 The complete record (inc. the tag & size fields) is written out when EndRecord() is called.
01401 
01402                 If you know the exact size in bytes of the record you are writing, supply this
01403                 value via the Size parameter.  This allows the write functions to provide additional
01404                 error checking for you (e.g. if you try and write extra bytes)
01405                 
01406                 If you are not sure of the exact number of bytes that will be written to the data
01407                 section, set the Size param to CXF_UNKNOWN_SIZE.  EndRecord() will ensure that the
01408                 written record will have its size field set to the number of bytes that were written.
01409 
01410     Errors:     -
01411     SeeAlso:    EndRecord()
01412 
01413 ********************************************************************************************/
01414 
01415 INT32 CXaraFile::StartRecord(UINT32 Tag,INT32 Size)
01416 {
01417     if (EndRecord())
01418     {
01419         // Inc the record number
01420         RecordNumber++;
01421 
01422         // Create a new record, & initialise it
01423         pRecord = new CXaraFileRecord(Tag,Size);
01424 
01425         WriteToRecord = (pRecord != NULL && pRecord->Init());
01426 
01427         if (WriteToRecord)
01428         {
01429             pRecord->SetRecordNumber(RecordNumber);
01430             return RecordNumber;
01431         }
01432     }
01433 
01434     return 0;
01435 }
01436 
01437 INT32 CXaraFile::StartStreamedRecord(UINT32 Tag,INT32 Size)
01438 {
01439     ERROR2IF(WritingStreamedRecord,0,"Already writing a streamed record.  Forgot to call EndRecord()?");
01440 
01441     WritingStreamedRecord = TRUE;
01442     WriteToRecord = FALSE;
01443 
01444     // Make sure compression off before starting the streamed record.
01445     // If it was turned on, than make sure we know that the writing of the streamed record 
01446     // caused it to be turned off.
01447     CompOffDueToStreamedRecord = IsCompressionOn();
01448     BOOL ok = StopCompression();
01449     
01450     // Must do this after turning compression off as otherwise CCFile will complain
01451     // as FilePos in the compressed stream is an unknown entity
01452     StartOfStreamedRecord = GetFilePos();
01453     
01454     if (ok) ok = Write(Tag);
01455     if (ok) ok = Write(Size);
01456 
01457     if (ok)
01458     {
01459         RecordNumber++;
01460         return RecordNumber;
01461     }
01462 
01463     return 0;
01464 }
01465 
01466 
01467 /********************************************************************************************
01468 
01469 >   BOOL CXaraFile::EndRecord()
01470 
01471     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01472     Created:    21/5/96
01473     Inputs:     -
01474     Returns:    TRUE if the the system wrote out the record
01475                 FALSE otherwise
01476     Purpose:    Ends the current record.
01477 
01478                 If the record was started by StartRecord(), this call will write out the entire
01479                 buffered record (record header and data section) to the file.
01480 
01481     Errors:     -
01482     SeeAlso:    StartRecord()
01483 
01484 ********************************************************************************************/
01485 
01486 BOOL CXaraFile::EndRecord()
01487 {
01488     ERROR3IF(WriteToRecord && pRecord == NULL,"Writing to a NULL record!");
01489 
01490     BOOL ok = TRUE;
01491 
01492     if (WritingStreamedRecord)
01493     {
01494         // Not interested in the result, but we will pass through a variable anyway
01495         // Complete the process of writing out the streamed record
01496         UINT32 RecordSize = 0L;
01497         return EndStreamedRecord(&RecordSize);
01498     }
01499 
01500     if (WriteToRecord && pRecord != NULL)
01501     {
01502         WriteToRecord = FALSE;
01503 
01504 #if !defined(EXCLUDE_FROM_XARLIB)
01505         ERROR3IF(!pRecord->IsDataSectionFull(),"Data section of the record has not been filled");
01506 #endif
01507 
01508         if (ok) ok = Write(pRecord->GetTag());
01509         if (ok) ok = Write(pRecord->GetSize());
01510         if (ok) ok = Write(pRecord->GetBuffer(),pRecord->GetSize());
01511 
01512         delete pRecord;
01513         pRecord = NULL;
01514     }
01515 
01516     return (ok);
01517 }
01518 
01519 /********************************************************************************************
01520 
01521 >   BOOL CXaraFile::EndStreamedRecord(UINT32 *RecordSize)
01522 
01523     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01524     Created:    20/8/96
01525     Inputs:     -
01526     Outputs:    RecordSize - the size of the record just written
01527     Returns:    TRUE if the the system wrote out the record
01528                 FALSE otherwise
01529     Purpose:    Ends the current streamed record.
01530 
01531                 If the record was started by StartStreamedRecord(), this call will do all
01532                 that is necessary to clean up the streamed record.
01533                 This mainly involves:-
01534                     Fixing the size in the record header to be correct.
01535                     Starting up compression, if required
01536 
01537     Errors:     -
01538     SeeAlso:    StartRecord()
01539 
01540 ********************************************************************************************/
01541 
01542 BOOL CXaraFile::EndStreamedRecord(UINT32 *RecordSize)
01543 {
01544     ERROR3IF(!WritingStreamedRecord,"Trying to end a non-streamed record!");
01545     if (!WritingStreamedRecord)
01546         return FALSE;
01547 
01548     BOOL ok = TRUE;
01549     // We must reset WritingStreamedRecord to FALSE immediately, to prevent stack overflow
01550     // due to recursion via the StartCompression() call below
01551     WritingStreamedRecord = FALSE;
01552 
01553     // Use our vitrual function to fix the header up with the correct info
01554     // Null filter overides this to do nothing
01555     UINT32 SizeOfRecord = 0L;
01556     ok = FixStreamedRecordHeader(&SizeOfRecord);
01557     // If we are passed a pointer then return the size to the caller
01558     if (RecordSize)
01559         *RecordSize = SizeOfRecord;
01560     // Add this number to the number of bytes written
01561     TRACEUSER( "Neville", _T("EndStreamedRecord update size by %d\n"),SizeOfRecord);
01562     IncNumBytesWritten(SizeOfRecord);
01563     
01564     // If compression was turned off due to the streamed record, make sure we turn it back on again
01565     if (ok && CompOffDueToStreamedRecord)
01566         ok = StartCompression();
01567 
01568     // Reset the streamed record vars
01569     StartOfStreamedRecord = 0;
01570     CompOffDueToStreamedRecord = FALSE;
01571         
01572     return ok;
01573 }
01574 
01575 /********************************************************************************************
01576 
01577 >   virtual BOOL CXaraFile::FixStreamedRecordHeader(UINT32 *RecordSize)
01578 
01579     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01580     Created:    19/6/96
01581     Inputs:     -
01582     Outputs:    RecordSize - the size of the record just written
01583     Returns:    True if worked ok, False otherwise.
01584     Purpose:    Fixes up the previously saved record header for a streamed record.
01585                 The RecordSize is the size of the data section of the record and so does not
01586                 include the 8 bytes in the header.
01587     Errors:     -
01588     SeeAlso:    -
01589 
01590 ********************************************************************************************/
01591 
01592 BOOL CXaraFile::FixStreamedRecordHeader(UINT32 *RecordSize)
01593 {
01594     ERROR2IF(pCCFile == NULL,FALSE,"CXaraFile::FixStreamedRecordHeader NULL pCCFile");
01595     ERROR2IF(StartOfStreamedRecord == 0,FALSE,"CXaraFile::FixStreamedRecordHeader StartOfStreamedRecord == 0");
01596 
01597     // Note the current position in the file
01598     FilePos Pos = GetFilePos();
01599     // Work out the record size from it and the previosuly stored start of record position
01600     UINT32 Size = Pos-StartOfStreamedRecord-8;
01601     UINT32 tSize = NativetoLE(Size);
01602 
01603     // Seek back to the size field in the record header
01604     pCCFile->seek(StartOfStreamedRecord+4);
01605 
01606     // Fix the size to be correct
01607     if (pCCFile->write(&tSize, 4).fail())
01608         return FALSE;
01609 
01610     // Now get back to where we were in the file
01611     pCCFile->seek(Pos);
01612 
01613     // If we are passed a pointer then return the size to the caller
01614     if (RecordSize)
01615         *RecordSize = Size;
01616 
01617     return TRUE;
01618 }
01619 
01620 
01621 /********************************************************************************************
01622 
01623 >   UINT32 CXaraFile::Write(CXaraFileRecord* pRecord)
01624 
01625     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01626     Created:    31/5/96
01627     Inputs:     pRecord = ptr to a record to write out to file
01628     Returns:    The record number of this record in the file.
01629                 If an error occurs, 0 is returned
01630     Purpose:    Writes out the record to the file
01631     Errors:     -
01632     SeeAlso:    -
01633 
01634 ********************************************************************************************/
01635 
01636 UINT32 CXaraFile::Write(CXaraFileRecord* pRecord)
01637 {
01638     ERROR2IF(pRecord == NULL,FALSE,"pRecord param is NULL");
01639 
01640     BOOL ok = EndRecord();
01641 
01642 #if !defined(EXCLUDE_FROM_XARLIB)
01643     ERROR3IF(!pRecord->IsDataSectionFull(),"Data section of the record has not been filled");
01644 #endif
01645 
01646     if (ok) ok = Write(pRecord->GetTag());
01647     if (ok) ok = Write(pRecord->GetSize());
01648     if (ok) ok = Write(pRecord->GetBuffer(),pRecord->GetSize());
01649 
01650     // Inc the record number
01651     RecordNumber++;
01652 
01653     if (ok)
01654         return RecordNumber;
01655     else
01656         return 0;
01657 }
01658 
01659 /********************************************************************************************
01660 
01661 >   UINT32 CXaraFile::WriteDefinitionRecord(CXaraFileRecord* pRecord)
01662 
01663     Author:     Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
01664     Created:    17/07/97
01665     Inputs:     pRecord = ptr to a record to write out to file
01666     Returns:    The record number of this record in the file.
01667                 If an error occurs, 0 is returned
01668     Purpose:    Writes out the record to the file
01669                 Override this if your filter needs to keep track of definition records
01670 
01671 ********************************************************************************************/
01672 
01673 UINT32 CXaraFile::WriteDefinitionRecord(CXaraFileRecord* pRecord)
01674 {
01675     // This base class just calls the standard Write function
01676     return(Write(pRecord));
01677 }
01678 
01679 
01680 
01681 /********************************************************************************************
01682 
01683 >   UINT32 CXaraFile::WriteRecordHeader(UINT32 Tag, INT32 Size)
01684 
01685     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01686     Created:    6/6/96
01687     Inputs:     Tag     - the tag for this record
01688                 Size    - the size of the record
01689     Returns:    The record number of this record in the file.
01690                 If an error occurs, 0 is returned
01691     Purpose:    Writes out a record header directly to the file.
01692                 It expects the caller to handle other aspects of the record writing.
01693                 This should only be used by people who know what they are doing e.g. compression
01694     Errors:     -
01695     SeeAlso:    -
01696 
01697 ********************************************************************************************/
01698 
01699 UINT32 CXaraFile::WriteRecordHeader(UINT32 Tag, INT32 Size)
01700 {
01701     BOOL ok = TRUE;
01702 
01703     // Make sure we write directly to file
01704     WriteToRecord = FALSE;
01705 
01706     ok = Write(Tag);
01707     if (ok) ok = Write(Size);
01708 
01709     // Inc the record number
01710     RecordNumber++;
01711 
01712     if (ok)
01713         return RecordNumber;
01714     else
01715         return 0;
01716 }
01717 
01718 /********************************************************************************************
01719 
01720 >   FilePos CXaraFile::GetFilePos()
01721 
01722     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01723     Created:    3/6/96
01724     Inputs:     -
01725     Returns:    The current file pos
01726     Purpose:    Gets the current file pos of the associated CCFile object
01727 
01728     Errors:     -
01729     SeeAlso:    -
01730 
01731 ********************************************************************************************/
01732 
01733 FilePos CXaraFile::GetFilePos()
01734 {
01735     ERROR2IF(pCCFile == NULL,0,"No pCCFile ptr");
01736     return pCCFile->tell();
01737 }
01738 
01739 /********************************************************************************************
01740 
01741 >   UINT32 CXaraFile::GetRecordTag()
01742 
01743     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01744     Created:    21/5/96
01745     Inputs:     -
01746     Returns:    The tag value of the current record, or 0xffffffff if it fails
01747     Purpose:    Gets the tag value.
01748 
01749                 You can only call this after StartRecord() and before EndRecord()
01750 
01751     Errors:     -
01752     SeeAlso:    StartRecord(), EndRecord()
01753 
01754 ********************************************************************************************/
01755 
01756 UINT32 CXaraFile::GetRecordTag()
01757 {
01758     ERROR3IF(!WriteToRecord,"Can't get tag - no current record");
01759     ERROR3IF(WriteToRecord && pRecord == NULL,"current record is NULL");
01760 
01761     if (!WriteToRecord || (pRecord == NULL))
01762         return UINT32(-1);
01763 
01764     return pRecord->GetTag();
01765 }
01766 
01767 /********************************************************************************************
01768 
01769 >   INT32 CXaraFile::GetRecordNum()
01770 
01771     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01772     Created:    21/5/96
01773     Inputs:     -
01774     Returns:    The record number for the current record, or 0 if no current record
01775     Purpose:    Gets the current record's record number
01776 
01777                 You can only call this after StartRecord() and before EndRecord()
01778 
01779                 The record number defines the position of the record in the file.
01780                 Record number 1 means the first record in the file, 2 the second, etc.
01781 
01782     Errors:     -
01783     SeeAlso:    StartRecord(), EndRecord()
01784 
01785 ********************************************************************************************/
01786 
01787 INT32 CXaraFile::GetRecordNum()
01788 {
01789     ERROR3IF(!WriteToRecord,"Can't get record num - no current record");
01790 
01791     if (!WriteToRecord)
01792         return 0;
01793 
01794     return RecordNumber; 
01795 }
01796 
01797 /********************************************************************************************
01798 
01799 >   virtual void CXaraFile::GotError(UINT32 errorID)
01800 
01801     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01802     Created:    22/5/96
01803     Inputs:     errorID = ID of error resource string
01804     Returns:    -
01805     Purpose:    Sets an error using the given resource string
01806                 All it does is call the mirror function in the attached CCFile.
01807     SeeAlso:    BaseCamelotFilter::PrepareToExport; BaseCamelotFilter::DoExport
01808     Scope:      Protected
01809 
01810 ********************************************************************************************/
01811 
01812 void CXaraFile::GotError(UINT32 errorID)
01813 {
01814     if (pCCFile != NULL)
01815         pCCFile->GotError(errorID);
01816 }
01817 
01818 /********************************************************************************************
01819 
01820 >   virtual void CXaraFile::GotError( UINT32 errorID , const TCHAR* errorString)
01821 
01822     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01823     Created:    19/8/96
01824     Inputs:     errorID = ID of error resource string
01825                 errorString = ptr to the error string.
01826     Returns:    -
01827     Purpose:    Sets an error using the given resource string
01828                 All it does is call the mirror function in the attached CCFile.
01829     SeeAlso:    BaseCamelotFilter::PrepareToExport; BaseCamelotFilter::DoExport
01830     Scope:      Protected
01831 
01832 ********************************************************************************************/
01833 
01834 void CXaraFile::GotError(UINT32 errorID, const TCHAR* errorString)
01835 {
01836     if (pCCFile != NULL)
01837         pCCFile->GotError(errorID,errorString);
01838 }
01839 
01840 
01841 /********************************************************************************************
01842 
01843 >   BOOL CXaraFile::ReadNextRecordHeader()
01844 
01845     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01846     Created:    28/5/96
01847     Inputs:     -
01848     Returns:    -
01849     Purpose:    Reads in the header (i.e. tag & size fields) of the next record in the file
01850     SeeAlso:    ReadNextRecord()
01851     Scope:      -
01852 
01853 ********************************************************************************************/
01854 
01855 BOOL CXaraFile::ReadNextRecordHeader()
01856 {
01857     BOOL ok = TRUE;
01858 
01859     if (ok) ok = Read(&ReadTag);
01860     if (ok) ok = Read(&ReadSize);
01861     if (ok) RecordNumber++;
01862 
01863     return ok;
01864 }
01865 
01866 /********************************************************************************************
01867 
01868 >   BOOL CXaraFile::RegisterRecordHandler(CXaraFileRecordHandler* pCXaraFileRecordHandler)
01869 
01870     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01871     Created:    28/5/96
01872     Inputs:     pCXaraFileRecordHandler = ptr 
01873     Returns:    -
01874     Purpose:    Finds the record handler that's been registered to handle a record with the given tag value
01875     SeeAlso:    ReadNextRecord()
01876     Scope:      -
01877 
01878 ********************************************************************************************/
01879 
01880 BOOL CXaraFile::RegisterRecordHandlers(List* pListOfHandlers)
01881 {
01882     ERROR2IF(pListOfHandlers == NULL, FALSE,"pListOfHandlers is NULL");
01883     pRecordHandlerList = pListOfHandlers;
01884     return TRUE;
01885 }
01886 
01887 
01888 
01889 /********************************************************************************************
01890 
01891 >   CXaraFileRecordHandler* CXaraFile::LookUpHandler(UINT32 Tag)
01892 
01893     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01894     Created:    28/8/96
01895     Inputs:     Tag = the tag value of a record
01896     Returns:    ptr to the record handler (or NULL if none could be found)
01897     Purpose:    This looks up the tag in the tag-to-handler map
01898 
01899                 If it's not in the map (or there isn't a map) NULL is returned.
01900 
01901     SeeAlso:    FindHandler()
01902     Scope:      -
01903 
01904 ********************************************************************************************/
01905 
01906 CXaraFileRecordHandler* CXaraFile::LookUpHandler(UINT32 Tag)
01907 {
01908     CXaraFileRecordHandler* pHandler = NULL;
01909 
01910     if (pMap != NULL)
01911         pHandler = pMap->LookUp(Tag);
01912 
01913     return pHandler;
01914 }
01915 
01916 /********************************************************************************************
01917 
01918 >   CXaraFileRecordHandler* CXaraFile::SearchForHandler(UINT32 Tag)
01919 
01920     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01921     Created:    19/8/96
01922     Inputs:     Tag = the tag value of a record
01923     Returns:    ptr to the record handler (or NULL if none could be found)
01924     Purpose:    Searches through the list of registered record handlers for a handler
01925                 for the given tag value
01926 
01927                 This will scan the tag list of every registered handler, until the right handler is found.
01928 
01929                 If one can't be found, a ptr to the default record handler is returned (if there is one).
01930 
01931     SeeAlso:    FindHandler()
01932     Scope:      -
01933 
01934 ********************************************************************************************/
01935 
01936 CXaraFileRecordHandler* CXaraFile::SearchForHandler(UINT32 Tag)
01937 {
01938     if (pRecordHandlerList != NULL)
01939     {
01940         CXaraFileRecordHandler* pHandler = (CXaraFileRecordHandler*) pRecordHandlerList->GetHead();
01941         while (pHandler != NULL)
01942         {
01943             if (pHandler->IsTagInList(Tag))
01944                 return pHandler;
01945 
01946             pHandler = (CXaraFileRecordHandler*) pRecordHandlerList->GetNext(pHandler);
01947         }
01948     }
01949 
01950     return NULL;
01951 }
01952 
01953 /********************************************************************************************
01954 
01955 >   CXaraFileRecordHandler* CXaraFile::FindHandler(UINT32 Tag)
01956 
01957     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
01958     Created:    28/5/96
01959     Inputs:     Tag = the tag value of a record
01960     Returns:    ptr to the record handler (or NULL if none could be found)
01961     Purpose:    Finds the record handler that's been registered to handle a record with the given tag value
01962     SeeAlso:    ReadNextRecord()
01963     Scope:      -
01964 
01965 ********************************************************************************************/
01966 
01967 CXaraFileRecordHandler* CXaraFile::FindHandler(UINT32 Tag)
01968 {
01969     ERROR3IF(pRecordHandlerList == NULL && GetDefaultRecordHandler()==NULL,"pRecordHandlerList is NULL & there's no default handler");
01970 
01971     CXaraFileRecordHandler* pHandler = NULL;
01972     
01973     // Does the sub tree stripper want to process the tag?
01974     pHandler = GetStripSubTreeRecordHandler();
01975     if (pHandler != NULL)
01976     {
01977         if (pHandler->IsTagInList(Tag))
01978             return pHandler;
01979     }
01980 
01981     // See if handler is in the map (i.e. do the quick method first)
01982     pHandler = LookUpHandler(Tag);
01983     if (pHandler != NULL)
01984         return pHandler;
01985 
01986     // Search the handler list for a suitable handler
01987     pHandler = SearchForHandler(Tag);
01988     if (pHandler != NULL)
01989         return pHandler;
01990 
01991     // If all else fails, fall through to the default record handler.
01992     return GetDefaultRecordHandler();
01993 }
01994 
01995 /********************************************************************************************
01996 
01997 >   BOOL CXaraFile::ReadNextRecord()
01998 
01999     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02000     Created:    28/5/96
02001     Inputs:     -
02002     Returns:    -
02003     Purpose:    Reads in the next record from the file
02004     SeeAlso:    BaseCamelotFilter::ReadFile
02005     Scope:      -
02006 
02007 ********************************************************************************************/
02008 
02009 BOOL CXaraFile::ReadNextRecord()
02010 {
02011     ERROR2IF(pCCFile == NULL,FALSE,"NULL pCCFile ptr");
02012 
02013     BOOL ok = FALSE;
02014 
02015     if (ReadNextRecordHeader())
02016     {
02017 //      TRACEUSER("Gerry", _T("HandleRecord %d - %d [%d]"), RecordNumber, ReadTag, ReadSize);
02018 
02019         CXaraFileRecordHandler* pCXaraFileRecordHandler = FindHandler(ReadTag);
02020         if (pCXaraFileRecordHandler != NULL)
02021         {
02022             // Only if it is not a streamed record do we want to reda in the data into a buffer
02023             if (pCXaraFileRecordHandler->IsStreamed(ReadTag))
02024             {
02025                 // Its a streamed record so just ask the handler to read it.
02026                 ok = pCXaraFileRecordHandler->HandleStreamedRecord(this,ReadTag,ReadSize,RecordNumber);
02027             }
02028             else
02029             {
02030                 // It is not a streamed record so read it in and ask the handler to
02031                 // deal with it
02032                 CXaraFileRecord* pCXaraFileRecord = new CamelotFileRecord(pFilter,ReadTag,ReadSize);
02033 
02034                 if (pCXaraFileRecord != NULL)
02035                 {
02036                     ok = pCXaraFileRecord->Init();
02037                     pCXaraFileRecord->SetRecordNumber(RecordNumber);
02038 
02039                     // Read data section, if there is one
02040                     if (ok && ReadSize > 0)
02041                     {
02042                         BYTE* pBuf = pCXaraFileRecord->GetBuffer();
02043                         ok = (pBuf != NULL);
02044                         if (ok) ok = Read(pBuf,ReadSize);
02045                     }
02046 
02047                     if (ok) ok = pCXaraFileRecordHandler->HandleRecord(pCXaraFileRecord);
02048 #if !defined(EXCLUDE_FROM_XARLIB)
02049                     if (ok)      pCXaraFileRecordHandler->IncProgressBarCount(pCXaraFileRecord->GetSize()+8);
02050 #endif
02051                     delete pCXaraFileRecord;
02052                 }
02053             }
02054 
02055 #if !defined(EXCLUDE_FROM_XARLIB)
02056             if (ok && pFilter != NULL) ok = pFilter->SetLastRecordHandler(pCXaraFileRecordHandler,ReadTag);
02057 #endif
02058         }
02059         else
02060         {
02061             // No handler for this tag
02062             //TRACEUSER( "Markn", _T("Unhandled tag value : %d\n"),ReadTag);
02063 
02064             // Read the rest of this record, and send the data to oblivion
02065             ok = TRUE;
02066             BYTE b;
02067             for (UINT32 i=0;ok && i<ReadSize;i++)
02068                 ok = Read(&b);
02069         }
02070     }
02071 
02072 //TRACE(_T("ReadNextTag %d %d\n"), ReadTag, ok);
02073 
02074 
02075     return ok;
02076 }
02077 
02078 
02079 #if defined(EXCLUDE_FROM_XARLIB)
02080 /********************************************************************************************
02081 
02082 >   virtual void CXaraFile::AddAtomicTag(AtomicTagListItem* pItem)
02083 
02084     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02085     Created:    16/8/96
02086     Inputs:     pItem = ptr to an atomic list item
02087     Returns:    -
02088     Purpose:    Adds the item to the list of atomic tags compiled during import
02089 
02090     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
02091     Scope:      Protected
02092 
02093 ********************************************************************************************/
02094 
02095 void CXaraFile::AddAtomicTag(AtomicTagListItem* pItem)
02096 {
02097     if (pAtomicTagList == NULL)
02098         pAtomicTagList = new AtomicTagList;
02099 
02100     if (pAtomicTagList != NULL)
02101         pAtomicTagList->AddTail(pItem);
02102 }
02103 
02104 /********************************************************************************************
02105 
02106 >   virtual void CXaraFile::AddEssentialTag(EssentialTagListItem* pItem)
02107 
02108     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02109     Created:    16/8/96
02110     Inputs:     pItem = ptr to an Essential list item
02111     Returns:    -
02112     Purpose:    Adds the item to the list of Essential tags compiled during import
02113 
02114     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
02115     Scope:      Protected
02116 
02117 ********************************************************************************************/
02118 
02119 void CXaraFile::AddEssentialTag(EssentialTagListItem* pItem)
02120 {
02121     if (pEssentialTagList == NULL)
02122         pEssentialTagList = new EssentialTagList;
02123 
02124     if (pEssentialTagList != NULL)
02125         pEssentialTagList->AddTail(pItem);
02126 }
02127 
02128 /********************************************************************************************
02129 
02130 >   BOOL CXaraFile::WriteRemainingAtomicTagDefinitions ()
02131 
02132     Author:     Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
02133     Created:    14/9/2000
02134     Inputs:     -
02135     Outputs:    -
02136     Returns:    TRUE if changed value, FALSE otherwise
02137     Purpose:    All compound nodes (e.g.  bevels, contours, shadows, clipview) are now defined
02138                 as being atomic.  This is so that they can be backwards compatible with CX2.
02139     Errors:     -
02140     SeeAlso:    -
02141 
02142 ********************************************************************************************/
02143 
02144 BOOL CXaraFile::WriteRemainingAtomicTagDefinitions ()
02145 {
02146     BOOL ok = TRUE;
02147     
02148     CXaraFileRecord atomicRec(TAG_ATOMICTAGS, TAG_ATOMICTAGS_SIZE);
02149     if (ok) ok = atomicRec.Init();
02150     if (ok) ok = atomicRec.WriteUINT32(TAG_BEVEL);                      // NodeBevelController
02151     if (ok) ok = atomicRec.WriteUINT32(TAG_BEVELINK);                   // NodeBevel
02152     if (ok) ok = atomicRec.WriteUINT32(TAG_CONTOURCONTROLLER);          // NodeContourController
02153     if (ok) ok = atomicRec.WriteUINT32(TAG_CONTOUR);                        // NodeContour
02154     if (ok) ok = atomicRec.WriteUINT32(TAG_SHADOWCONTROLLER);           // NodeShadowController
02155     if (ok) ok = atomicRec.WriteUINT32(TAG_SHADOW);                     // NodeShadow
02156     if (ok) ok = atomicRec.WriteUINT32(TAG_CLIPVIEWCONTROLLER);         // NodeClipViewController
02157     if (ok) ok = atomicRec.WriteUINT32(TAG_CLIPVIEW);                   // NodeClipView
02158     if (ok) ok = atomicRec.WriteUINT32(TAG_CURRENTATTRIBUTES);          // Current Attributes container/component
02159     if (ok) ok = Write(&atomicRec);
02160 
02161     return (ok);
02162 }
02163 
02164 /********************************************************************************************
02165 
02166 >   virtual BOOL CXaraFile::IsTagInAtomicList(UINT32 Tag)
02167 
02168     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02169     Created:    16/8/96
02170     Inputs:     Tag = tag value to look for
02171     Returns:    TRUE if found, FALSE otherwsie
02172     Purpose:    Searches the atomic tag list to see of the given tag is in the list.
02173 
02174     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
02175     Scope:      Protected
02176 
02177 ********************************************************************************************/
02178 
02179 BOOL CXaraFile::IsTagInAtomicList(UINT32 Tag)
02180 {
02181     if (pAtomicTagList != NULL)
02182     {
02183         AtomicTagListItem* pItem = pAtomicTagList->GetHead();
02184         while (pItem != NULL)
02185         {
02186             if (pItem->GetTag() == Tag)
02187                 return TRUE;
02188 
02189             pItem = pAtomicTagList->GetNext(pItem);
02190         }
02191     }
02192 
02193     return FALSE;
02194 }
02195 
02196 /********************************************************************************************
02197 
02198 >   virtual BOOL CXaraFile::IsTagInEssentialList(UINT32 Tag)
02199 
02200     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02201     Created:    16/8/96
02202     Inputs:     Tag = tag value to look for
02203     Returns:    TRUE if found, FALSE otherwsie
02204     Purpose:    Searches the Essential tag list to see of the given tag is in the list.
02205 
02206     SeeAlso:    BaseCamelotFilter::PrepareToImport; BaseCamelotFilter::DoImport
02207     Scope:      Protected
02208 
02209 ********************************************************************************************/
02210 
02211 BOOL CXaraFile::IsTagInEssentialList(UINT32 Tag)
02212 {
02213     if (pEssentialTagList != NULL)
02214     {
02215         EssentialTagListItem* pItem = pEssentialTagList->GetHead();
02216         while (pItem != NULL)
02217         {
02218             if (pItem->GetTag() == Tag)
02219                 return TRUE;
02220 
02221             pItem = pEssentialTagList->GetNext(pItem);
02222         }
02223     }
02224 
02225     return FALSE;
02226 }
02227 #endif
02228 
02229 
02230 //------------------------------------------------------------------------------------------
02231 //------------------------------------------------------------------------------------------
02232 //------------------------------------------------------------------------------------------
02233 
02234 #if !defined(EXCLUDE_FROM_XARLIB)
02235 /********************************************************************************************
02236 
02237 >   virtual BOOL NULLXaraFile::Write(BYTE b)
02238 
02239     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02240     Created:    4/6/96
02241     Inputs:     b = BYTE to write to
02242     Returns:    TRUE if written successfully
02243                 FALSE otherwise
02244     Purpose:    This version doesn't actually write anything out.
02245                 It just counts those bytes
02246     Errors:     -
02247     SeeAlso:    -
02248 
02249 ********************************************************************************************/
02250 
02251 BOOL NULLXaraFile::Write(BYTE b)
02252 {
02253     BOOL ok = TRUE;
02254 
02255     if (WriteToRecord && pRecord != NULL)
02256         ok = pRecord->WriteBYTE(b);
02257     else
02258         IncNumBytesWritten(1);
02259 
02260     return ok;
02261 }
02262 
02263 /********************************************************************************************
02264 
02265 >   virtual BOOL NULLXaraFile::OpenToWrite(CCLexFile* pThisCCFile)
02266 
02267     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02268     Created:    4/6/96
02269     Inputs:     params not used
02270     Returns:    TRUE 
02271     Purpose:    Writes out the 8 byte header
02272     Errors:     -
02273     SeeAlso:    -
02274 
02275 ********************************************************************************************/
02276 
02277 BOOL NULLXaraFile::OpenToWrite(CCLexFile* pThisCCFile)
02278 {
02279     BOOL ok = TRUE;
02280 
02281     // The first 8 bytes should be our unique ID sequence
02282     if (ok) ok = CXaraFile::Write((UINT32)CXF_IDWORD1);
02283     if (ok) ok = CXaraFile::Write((UINT32)CXF_IDWORD2);
02284 
02285     return ok;
02286 }
02287 
02288 /********************************************************************************************
02289 
02290 >   virtual BOOL NULLXaraFile::Close()
02291 
02292     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02293     Created:    4/6/96
02294     Inputs:     -
02295     Returns:    TRUE 
02296     Purpose:    Doesn't do anything
02297     Errors:     -
02298     SeeAlso:    -
02299 
02300 ********************************************************************************************/
02301 
02302 BOOL NULLXaraFile::Close()
02303 {
02304     return TRUE;
02305 }
02306 
02307 /********************************************************************************************
02308 
02309 >   virtual BOOL NULLXaraFile::GetFilePos()
02310 
02311     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02312     Created:    4/6/96
02313     Inputs:     -
02314     Returns:    0
02315     Purpose:    Always returns 0
02316     Errors:     -
02317     SeeAlso:    -
02318 
02319 ********************************************************************************************/
02320 
02321 FilePos NULLXaraFile::GetFilePos()
02322 {
02323     return 0;
02324 }
02325 
02326 /********************************************************************************************
02327 
02328 >   virtual BOOL NULLXaraFile::IsCompressionOn()
02329 
02330     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02331     Created:    31/7/96
02332     Inputs:     -
02333     Returns:    Always returns FALSE
02334     Purpose:    Function to see if compression is on.
02335                 As this is the null filter used to count objects, it always returns FALSE
02336     Errors:     -
02337     SeeAlso:    StopCompression(); BaseCamelotFilter::StartCompression();
02338 
02339 ********************************************************************************************/
02340 
02341 BOOL NULLXaraFile::IsCompressionOn()
02342 {
02343     return FALSE;
02344 }
02345 
02346 /********************************************************************************************
02347 
02348 >   virtual BOOL NULLXaraFile::StartCompression()
02349 
02350     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
02351     Created:    19/6/96
02352     Inputs:     -
02353     Returns:    TRUE if ok
02354                 FALSE otherwise
02355     Purpose:    Function to turn Compression on when we are writing to the file.
02356                 As this is the null filter used to count objects, do nothing.
02357     Errors:     -
02358     SeeAlso:    StopCompression(); BaseCamelotFilter::StartCompression();
02359 
02360 ********************************************************************************************/
02361 
02362 BOOL NULLXaraFile::StartCompression()
02363 {
02364     return TRUE;
02365 }
02366 
02367 /********************************************************************************************
02368 
02369 >   virtual BOOL NULLXaraFile::StopCompression()
02370 
02371     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
02372     Created:    19/6/96
02373     Inputs:     -
02374     Returns:    TRUE if ok
02375                 FALSE otherwise
02376     Purpose:    Function to turn Compression off when we are writing to the file.
02377                 As this is the null filter used to count objects, do nothing.
02378     Errors:     -
02379     SeeAlso:    StartCompression(); BaseCamelotFilter::StopCompression();
02380 
02381 ********************************************************************************************/
02382 
02383 BOOL NULLXaraFile::StopCompression()
02384 {
02385     return TRUE;
02386 }
02387 
02388 /********************************************************************************************
02389 
02390 >   virtual CCLexFile * NULLXaraFile::GetCCFile() const
02391 
02392     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
02393     Created:    20/6/96
02394     Inputs:     -
02395     Returns:    The CCLexFile that is being used to export the data.
02396     Purpose:    Function to give public access to the underlying CCLexFile that is being used
02397                 to save out the data.
02398                 Note: only people who have a genuine reason need to access this - e.g. bitmap savers
02399                 As this is the null filter used to count objects, do nothing.
02400     Errors:     -
02401     SeeAlso:    BitmapListComponent::SaveBitmapDefinition; BaseCamelotFilter::GetCCFile;
02402 
02403 ********************************************************************************************/
02404 
02405 CCLexFile* NULLXaraFile::GetCCFile() const
02406 {
02407     return NULL;
02408 }
02409 
02410 /********************************************************************************************
02411 
02412 >   virtual BOOL NULLXaraFile::FixStreamedRecordHeader(UINT32 *RecordSize)
02413 
02414     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
02415     Created:    19/6/96
02416     Inputs:     -
02417     Outputs:    RecordSize - the size of the record just written
02418     Returns:    True if worked ok, False otherwise.
02419     Purpose:    Fixes up the previously saved record header for a streamed record.
02420     Errors:     -
02421     SeeAlso:    -
02422 
02423 ********************************************************************************************/
02424 
02425 BOOL NULLXaraFile::FixStreamedRecordHeader(UINT32 *RecordSize)
02426 {
02427     return TRUE;
02428 }
02429 #endif  // EXCLUDE_FROM_XARLIB
02430 
02431 //-----------------------------------------------------------------------------------
02432 //-----------------------------------------------------------------------------------
02433 //-----------------------------------------------------------------------------------
02434 //-----------------------------------------------------------------------------------
02435 
02436 UINT32* GeneralRecordHandler::GetTagList()
02437 {
02438     static UINT32 TagList[] = { TAG_ENDOFFILE,
02439                                 TAG_FILEHEADER,
02440 #if !defined(EXCLUDE_FROM_XARLIB)
02441                                 TAG_UP,
02442                                 TAG_DOWN,
02443                                 TAG_TAGDESCRIPTION,
02444                                 TAG_DOCUMENTNUDGE,
02445 #endif
02446                                 TAG_ATOMICTAGS,
02447                                 TAG_ESSENTIALTAGS,
02448                                 CXFRH_TAG_LIST_END};
02449     return (UINT32*)&TagList;
02450 }
02451 
02452 BOOL GeneralRecordHandler::HandleRecord(CXaraFileRecord* pCXaraFileRecord)
02453 {
02454     ERROR2IF(pCXaraFileRecord == NULL,FALSE,"pCXaraFileRecord is NULL");
02455 
02456     BOOL ok = TRUE;
02457 
02458     switch (pCXaraFileRecord->GetTag())
02459     {
02460         case TAG_FILEHEADER :
02461             ok = HandleFileHeader(pCXaraFileRecord);
02462             break;
02463 
02464         case TAG_ENDOFFILE:
02465 #if !defined(EXCLUDE_FROM_XARLIB)
02466             EndOfFile();
02467 #else
02468             m_pCXFile->SetEndOfFile();
02469 #endif
02470             break;
02471 
02472 #if !defined(EXCLUDE_FROM_XARLIB)
02473         case TAG_UP:
02474             ok = DecInsertLevel();
02475             break;
02476 
02477         case TAG_DOWN:
02478             ok = IncInsertLevel();
02479             break;
02480 
02481         case TAG_TAGDESCRIPTION:
02482             ok = HandleTagDescriptionRecord(pCXaraFileRecord);
02483             break;
02484 
02485         case TAG_DOCUMENTNUDGE:
02486             ok = HandleTagNudgeSizeRecord(pCXaraFileRecord);
02487             break;
02488 #endif
02489         case TAG_ATOMICTAGS:
02490             ok = HandleAtomicTagsRecord(pCXaraFileRecord);
02491             break;
02492 
02493         case TAG_ESSENTIALTAGS:
02494             ok = HandleEssentialTagsRecord(pCXaraFileRecord);
02495             break;
02496 
02497         default:
02498             ok = FALSE;
02499             ERROR3_PF(("I don't handle records with the tag (%d)\n",pCXaraFileRecord->GetTag()));
02500             break;
02501     }
02502 
02503     return ok;
02504 }
02505 
02506 /********************************************************************************************
02507 
02508 >   BOOL GeneralRecordHandler::HandleFileHeader(CXaraFileRecord* pCXaraFileRecord)
02509 
02510     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02511     Created:    14/6/96
02512     Inputs:     pCXaraFileRecord = ptr to a record
02513     Returns:    -
02514     Purpose:    Handles the file header record
02515     Errors:     -
02516     SeeAlso:    -
02517 
02518 ********************************************************************************************/
02519 
02520 BOOL GeneralRecordHandler::HandleFileHeader(CXaraFileRecord* pCXaraFileRecord)
02521 {
02522     BOOL ok = TRUE;
02523     BYTE Buffer[100];
02524     BYTE FileType[4];
02525     UINT32 n;
02526     UINT32 PreCompFlags;
02527     UINT32 FileSize;
02528 
02529     if (ok) ok = pCXaraFileRecord->ReadBuffer(FileType,3);          // File type (ensuring only 3 chars are read)
02530     if (ok) ok = pCXaraFileRecord->ReadUINT32(&FileSize);           // File size
02531     if (ok) ok = pCXaraFileRecord->ReadUINT32(&n);                  // Native/Web link ID
02532     if (ok) ok = pCXaraFileRecord->ReadUINT32(&PreCompFlags);       // Precompression flags
02533     if (ok) ok = pCXaraFileRecord->ReadASCII((TCHAR*)Buffer,100);   // Producer
02534     if (ok) ok = pCXaraFileRecord->ReadASCII((TCHAR*)Buffer,100);   // Producer version
02535     if (ok) ok = pCXaraFileRecord->ReadASCII((TCHAR*)Buffer,100);   // Producer build
02536 
02537 #if !defined(EXCLUDE_FROM_XARLIB)
02538     SetTotalProgressBarCount(FileSize);
02539 
02540     SetImportFileType((char*)FileType);
02541 
02542     ok = SetPreCompression(PreCompFlags);
02543 #endif
02544     return ok;
02545 }
02546 
02547 
02548 /********************************************************************************************
02549 
02550 >   BOOL GeneralRecordHandler::HandleAtomicTagsRecord(CXaraFileRecord* pCXaraFileRecord)
02551 
02552     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02553     Created:    16/8/96
02554     Inputs:     pCXaraFileRecord = ptr to a record
02555     Returns:    -
02556     Purpose:    Handles the atomic tags record
02557     Errors:     -
02558     SeeAlso:    -
02559 
02560 ********************************************************************************************/
02561 
02562 BOOL GeneralRecordHandler::HandleAtomicTagsRecord(CXaraFileRecord* pCXaraFileRecord)
02563 {
02564     ERROR2IF(pCXaraFileRecord == NULL,FALSE,"pCXaraFileRecord is NULL");
02565     ERROR2IF(pCXaraFileRecord->GetTag() != TAG_ATOMICTAGS,FALSE,"I don't handle this tag type");
02566 
02567     BOOL ok = TRUE;
02568 
02569     UINT32 Size = pCXaraFileRecord->GetSize();
02570     UINT32 Tag;
02571 
02572     // Create an atomic tag item for each atomic tag in the record
02573 
02574     for (UINT32 i = 0;ok && i < Size; i+=sizeof(UINT32))
02575     {
02576         AtomicTagListItem* pItem = NULL;
02577 
02578         ok = pCXaraFileRecord->ReadUINT32(&Tag);
02579         if (ok) pItem = new AtomicTagListItem(Tag);
02580         if (ok) ok = (pItem != NULL);
02581         if (ok) AddAtomicTag(pItem);
02582     }
02583 
02584     return ok;
02585 }
02586 
02587 /********************************************************************************************
02588 
02589 >   BOOL GeneralRecordHandler::HandleEssentialTagsRecord(CXaraFileRecord* pCXaraFileRecord)
02590 
02591     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02592     Created:    16/8/96
02593     Inputs:     pCXaraFileRecord = ptr to a record
02594     Returns:    -
02595     Purpose:    Handles the essential tags record
02596     Errors:     -
02597     SeeAlso:    -
02598 
02599 ********************************************************************************************/
02600 
02601 BOOL GeneralRecordHandler::HandleEssentialTagsRecord(CXaraFileRecord* pCXaraFileRecord)
02602 {
02603     ERROR2IF(pCXaraFileRecord == NULL,FALSE,"pCXaraFileRecord is NULL");
02604     ERROR2IF(pCXaraFileRecord->GetTag() != TAG_ESSENTIALTAGS,FALSE,"I don't handle this tag type");
02605 
02606     BOOL ok = TRUE;
02607 
02608     UINT32 Size = pCXaraFileRecord->GetSize();
02609     UINT32 Tag;
02610 
02611     // Create an essential tag item for each essential tag in the record
02612 
02613     for (UINT32 i = 0;ok && i < Size; i+=sizeof(UINT32))
02614     {
02615         EssentialTagListItem* pItem = NULL;
02616 
02617         ok = pCXaraFileRecord->ReadUINT32(&Tag);
02618         if (ok) pItem = new EssentialTagListItem(Tag);
02619         if (ok) ok = (pItem != NULL);
02620         if (ok) AddEssentialTag(pItem);
02621     }
02622 
02623     return ok;
02624 }
02625 
02626 
02627 #if !defined(EXCLUDE_FROM_XARLIB)
02628 /********************************************************************************************
02629 
02630 >   BOOL GeneralRecordHandler::HandleTagDescriptionRecord(CXaraFileRecord* pCXaraFileRecord)
02631 
02632     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02633     Created:    16/8/96
02634     Inputs:     pCXaraFileRecord = ptr to a record
02635     Returns:    -
02636     Purpose:    Handles the tag description record
02637     Errors:     -
02638     SeeAlso:    -
02639 
02640 ********************************************************************************************/
02641 
02642 BOOL GeneralRecordHandler::HandleTagDescriptionRecord(CXaraFileRecord* pCXaraFileRecord)
02643 {
02644     ERROR2IF(pCXaraFileRecord == NULL,FALSE,"pCXaraFileRecord is NULL");
02645     ERROR2IF(pCXaraFileRecord->GetTag() != TAG_TAGDESCRIPTION,FALSE,"I don't handle this tag type");
02646 
02647     BOOL ok = TRUE;
02648 
02649     UINT32 NumTags;
02650     UINT32 Tag;
02651     String_256* pDesc = NULL;
02652 
02653     ok = pCXaraFileRecord->ReadUINT32(&NumTags);
02654 
02655     // Create a tag description item for each tag description in the record
02656 
02657     for (UINT32 i = 0;ok && i < NumTags; i++)
02658     {
02659         TagDescriptionListItem* pItem = NULL;
02660 
02661         pDesc = new String_256;
02662         ok = (pDesc != NULL);
02663 
02664         if (ok) ok = pCXaraFileRecord->ReadUINT32(&Tag);
02665         if (ok) ok = pCXaraFileRecord->ReadUnicode(pDesc);//*pDesc,pDesc->MaxLength());
02666         if (ok) pItem = new TagDescriptionListItem(Tag,pDesc);
02667         if (ok) ok = (pItem != NULL);
02668         if (ok) ok = AddTagDescription(pItem);
02669 
02670         if (!ok && pItem != NULL)
02671         {
02672             delete pItem;
02673             pItem = NULL;
02674         }
02675     }
02676 
02677     return ok;
02678 }
02679 
02680 
02681 
02682 /********************************************************************************************
02683 
02684 >   BOOL GeneralRecordHandler::HandleTagNudgeSizeRecord(CXaraFileRecord* pCXaraFileRecord)
02685 
02686     Author:     Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
02687     Created:    31/8/2000
02688     Inputs:     pCXaraFileRecord = ptr to a record
02689     Returns:    -
02690     Purpose:    Handles the nudge size description record
02691     Errors:     -
02692     SeeAlso:    -
02693 
02694 ********************************************************************************************/
02695 
02696 BOOL GeneralRecordHandler::HandleTagNudgeSizeRecord(CXaraFileRecord* pCXaraFileRecord)
02697 {
02698     ERROR2IF(pCXaraFileRecord == NULL,FALSE,"pCXaraFileRecord is NULL");
02699     ERROR2IF(pCXaraFileRecord->GetTag() != TAG_DOCUMENTNUDGE,FALSE,"I don't handle this tag type");
02700 
02701     BOOL ok = TRUE;
02702 
02703     INT32 val = (INT32) 2835;       //DEFAULT_NUDGE_SIZE;   I'm not moving this just so it will be consistent
02704     
02705     ok = pCXaraFileRecord->ReadINT32 (&val);
02706 
02707     ok = SetDocumentNudgeSize ((UINT32) val);
02708 
02709     return ok;
02710 }
02711 #endif
02712 
02713 /********************************************************************************************
02714 
02715 >   virtual void GeneralRecordHandler::GetRecordDescriptionText(CXaraFileRecord* pRecord,StringBase* pStr)
02716 
02717     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02718     Created:    14/6/96
02719     Inputs:     pRecord = ptr to a record
02720                 pStr = ptr to string to update
02721     Returns:    -
02722     Purpose:    The general record handler text dumper
02723     Errors:     -
02724     SeeAlso:    -
02725 
02726 ********************************************************************************************/
02727 
02728 #ifdef XAR_TREE_DIALOG
02729 void GeneralRecordHandler::GetRecordDescriptionText(CXaraFileRecord* pRecord,StringBase* pStr)
02730 {
02731     if (pStr == NULL || pRecord == NULL)
02732         return;
02733 
02734     // Call base class first
02735     CamelotRecordHandler::GetRecordDescriptionText(pRecord,pStr);
02736 
02737     switch (pRecord->GetTag())
02738     {
02739         case TAG_FILEHEADER :
02740         {
02741             BYTE TypeBytes[4];
02742             TCHAR FileType[4];
02743             FileType[3] = 0;
02744 
02745             TCHAR s[256];
02746             TCHAR Producer[100];
02747             TCHAR ProducerVersion[100];
02748             TCHAR ProducerBuild[100];
02749             UINT32 NativeWebLink;
02750             UINT32 PrecompressionFlags;
02751             UINT32 FileSize;
02752 
02753             pRecord->ReadBuffer(TypeBytes,3);       // File type (ensuring only 3 chars are read)
02754             pRecord->ReadUINT32(&FileSize);             // File size
02755             pRecord->ReadUINT32(&NativeWebLink);            // Native/Web link ID
02756             pRecord->ReadUINT32(&PrecompressionFlags);  // Precompression flags
02757             pRecord->ReadASCII(Producer,100);           // Producer
02758             pRecord->ReadASCII(ProducerVersion,100);    // Producer version
02759             pRecord->ReadASCII(ProducerBuild,100);      // Producer build
02760 
02761             FileType[0] = TypeBytes[0];
02762             FileType[1] = TypeBytes[1];
02763             FileType[2] = TypeBytes[2];
02764             (*pStr) += _T("File Type\t\t\t: ");
02765             (*pStr) += FileType;
02766             (*pStr) += _T("\r\n");
02767 
02768             (*pStr) += _T("Uncompressed File Size\t: ");
02769             camSprintf(s,_T("%d"),FileSize);
02770             (*pStr) += s;
02771             (*pStr) += _T("\r\n");
02772 
02773             (*pStr) += _T("Native/Web Link ID\t: ");
02774             camSprintf(s,_T("%d"),NativeWebLink);
02775             (*pStr) += s;
02776             (*pStr) += _T("\r\n");
02777 
02778             (*pStr) += _T("Precompression Flags\t: ");
02779             camSprintf(s,_T("0x%x"),PrecompressionFlags);
02780             (*pStr) += s;
02781             (*pStr) += _T("\r\n");
02782 
02783             (*pStr) += _T("Producer\t\t\t: ");
02784             (*pStr) += Producer;
02785             (*pStr) += _T("\r\n");
02786 
02787             (*pStr) += _T("Producer Version\t\t: ");
02788             (*pStr) += ProducerVersion;
02789             (*pStr) += _T("\r\n");
02790 
02791             (*pStr) += _T("Producer Build\t\t: ");
02792             (*pStr) += ProducerBuild;
02793             (*pStr) += _T("\r\n");
02794         }
02795         break;
02796 
02797         case TAG_ATOMICTAGS:
02798         {
02799             UINT32 Size = pRecord->GetSize();
02800             UINT32 Tag;
02801             String_256 TagText;
02802 
02803             (*pStr) += _T("Atomic tag list:\r\n");
02804 
02805             for (UINT32 i = 0;i < Size; i+=sizeof(UINT32))
02806             {
02807                 pRecord->ReadUINT32(&Tag);
02808                 GetTagText(Tag,TagText);
02809                 (*pStr) += TagText;
02810                 (*pStr) += _T("\r\n");
02811             }
02812         }
02813         break;
02814 
02815         case TAG_ESSENTIALTAGS:
02816         {
02817             UINT32 Size = pRecord->GetSize();
02818             UINT32 Tag;
02819             String_256 TagText;
02820 
02821             (*pStr) += _T("Essential tag list:\r\n");
02822 
02823             for (UINT32 i = 0;i < Size; i+=sizeof(UINT32))
02824             {
02825                 pRecord->ReadUINT32(&Tag);
02826                 GetTagText(Tag,TagText);
02827                 (*pStr) += TagText;
02828                 (*pStr) += _T("\r\n");
02829             }
02830         }
02831         break;
02832 
02833         case TAG_TAGDESCRIPTION:
02834         {
02835             UINT32 NumTags;
02836             UINT32 Tag;
02837             String_256 Desc,TagText;
02838 
02839             (*pStr) += _T("Tag description list:\r\n");
02840 
02841             pRecord->ReadUINT32(&NumTags);
02842 
02843             for (UINT32 i = 0;i < NumTags; i++)
02844             {
02845                 pRecord->ReadUINT32(&Tag);
02846                 pRecord->ReadUnicode(&Desc);//Desc,Desc.MaxLength());
02847                 GetTagText(Tag,TagText);
02848                 (*pStr) += TagText;
02849                 (*pStr) += _T(" (");
02850                 (*pStr) += Desc;
02851                 (*pStr) += _T(")\r\n");
02852             }
02853         }
02854         break;
02855     }
02856 }
02857 #endif

Generated on Sat Nov 10 03:44:56 2007 for Camelot by  doxygen 1.4.4