home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / OS / FWFiles / Sources / SLFilRep.cpp < prev   
Encoding:
Text File  |  1996-08-16  |  23.6 KB  |  904 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                SLFilRep.cpp
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef FWEXCDEF_H
  13. #include "FWExcDef.h"
  14. #endif
  15.  
  16. #ifndef FWFILE_H
  17. #include "FWFileSy.h"
  18. #endif
  19.  
  20. #ifndef FWFILESP_H
  21. #include "FWFileSp.h"
  22. #endif
  23.  
  24. #if defined(FW_BUILD_WIN) && !defined(__WINDOWS_H)
  25. #include <windows.h>
  26. #endif
  27.  
  28. #include <Limits.h>
  29.  
  30. #ifndef FWPRIDEB_H
  31. #include "FWPriDeb.h"
  32. #endif
  33.  
  34. #ifndef FWEXCDEF_H
  35. #include "FWExcDef.h"
  36. #endif
  37.  
  38. #ifndef FWEXCEPT_H
  39. #include "FWExcept.h"
  40. #endif
  41.  
  42. #if defined(FW_BUILD_MAC) && !defined(__FILES__)
  43. #include "Files.h"
  44. #endif
  45.  
  46. #if defined(FW_BUILD_WIN) && !defined(IO_H)
  47. #include "io.h"
  48. #endif
  49.  
  50. /*
  51.  *  This file was generated by the SOM Compiler.
  52.  *  Generated using: 
  53.  *      SOM Emitter emitxtm.dll: 2.33
  54.  */
  55.  
  56. #define FW_OFile_Class_Source
  57. class FW_CPrivFileRep;
  58. #include "SLFilRep.xih"
  59.  
  60. #ifdef FW_BUILD_MAC
  61. #pragma segment File
  62. #endif
  63.  
  64. #ifdef FW_BUILD_WIN16
  65. extern "C" void FAR PASCAL DOS3Call();                // We use this instead of calling "Int 21h"
  66. #endif
  67.  
  68.  
  69. #if defined(__MWERKS__) && GENERATING68K
  70. // A hack to work around a bug
  71. #pragma import list somGetGlobalEnvironment, somNewObjectInstance
  72. #endif
  73.  
  74. //----------------------------------------------------------------------------------------
  75. // Forward definitions
  76. //----------------------------------------------------------------------------------------
  77.  
  78. static void privOpenFile(FW_OFile *somSelf, Environment *ev, FW_Boolean allowCreate);
  79. static void privCloseFile(FW_OFile *somSelf, Environment *ev);
  80. static void privDoRead(FW_OFile *somSelf, Environment *ev, void* destination, long count);
  81. static void privDoWrite(FW_OFile *somSelf, Environment *ev, const void* source, long count);
  82.  
  83. #ifdef FW_BUILD_WIN
  84. static short privWinGetIOBufferSize(long bytesDesired, const void* buffer);
  85. static FW_PlatformError privWinPrimitiveRead(FW_FileAccessHandle handle,
  86.                                                     short bytesToRead,
  87.                                                     void* buffer,
  88.                                                     short& bytesActuallyRead);
  89. static FW_PlatformError privWinPrimitiveWrite(FW_FileAccessHandle handle,
  90.                                                      short bytesToWrite,
  91.                                                      const void* buffer,
  92.                                                      short& bytesActuallyWritten);
  93.  
  94. static FW_PlatformError privWinMoveFilePointer(FW_OFile *somSelf, 
  95.                                                       Environment *ev,
  96.                                                       long markOffset,
  97.                                                       FW_EFS_MoveMethods positioningMode,
  98.                                                       long& newPosition);
  99. #endif
  100.  
  101.  
  102. //========================================================================================
  103. // struct FW_CPrivFileRep
  104. //    This struct contains the body of the file representation
  105. //========================================================================================
  106.  
  107. class FW_CPrivFileRep
  108. {
  109. public:
  110.     FW_DECLARE_AUTO(FW_CPrivFileRep)
  111.  
  112.     FW_CPrivFileRep(Environment *ev,
  113.                     FW_OFileSpecification* fileSpecification);
  114.     FW_CPrivFileRep(Environment *ev,
  115.                     FW_OFileSpecification* fileSpecification, 
  116.                     FW_SAccessPermission* permission);
  117.  
  118.     ~FW_CPrivFileRep();
  119.  
  120.     FW_OFileSpecification*        fFileSpec;
  121.     FW_SAccessPermission        fPermission;
  122.     FW_FileAccessHandle            fFileHandle;
  123. };
  124.  
  125.  
  126. FW_DEFINE_AUTO(FW_CPrivFileRep)
  127.  
  128. //----------------------------------------------------------------------------------------
  129. // FW_CPrivFileRep::FW_CPrivFileRep
  130. //----------------------------------------------------------------------------------------
  131.  
  132. inline FW_CPrivFileRep::FW_CPrivFileRep(Environment *ev,
  133.                                         FW_OFileSpecification* fileSpecification) :
  134.     fFileHandle(0)
  135. {
  136.     fPermission.fAccess = FW_kReadWrite;
  137.     fPermission.fDeny   = FW_kDenyReadWrite;
  138.     fFileSpec = new FW_OFileSpecification;
  139.     fFileSpec->AssignOFileSpecification(ev, fileSpecification);
  140.  
  141.     FW_END_CONSTRUCTOR
  142. }
  143.  
  144.  
  145. inline FW_CPrivFileRep::FW_CPrivFileRep(Environment *ev,
  146.                                         FW_OFileSpecification* fileSpecification, 
  147.                                         FW_SAccessPermission* permission) :
  148.     fPermission(*permission),
  149.     fFileHandle(0)
  150. {
  151.     fFileSpec = new FW_OFileSpecification;
  152.     fFileSpec->AssignOFileSpecification(ev, fileSpecification);
  153.  
  154.     FW_END_CONSTRUCTOR
  155. }
  156.  
  157.  
  158. //----------------------------------------------------------------------------------------
  159. // FW_CPrivFileRep::~FW_CPrivFileRep
  160. //----------------------------------------------------------------------------------------
  161.  
  162. inline FW_CPrivFileRep::~FW_CPrivFileRep()
  163. {
  164.     FW_START_DESTRUCTOR
  165.     delete fFileSpec;
  166. }
  167.  
  168.  
  169.  
  170. //----------------------------------------------------------------------------------------
  171. //    FW_OFile__InitWithExclusiveAccess
  172. //  Open with exclusive access
  173. //----------------------------------------------------------------------------------------
  174.  
  175. SOM_Scope void  SOMLINK FW_OFile__InitWithExclusiveAccess(FW_OFile *somSelf, Environment *ev,
  176.         FW_OFileSpecification* fileSpecification,
  177.         FW_Boolean allowCreate)
  178. {
  179.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  180.  
  181.     FW_SOM_TRY
  182.     {
  183.         somThis->fRep = FW_NEW(FW_CPrivFileRep, (ev, fileSpecification));
  184.         privOpenFile(somSelf, ev, allowCreate);
  185.     }
  186.     FW_SOM_CATCH
  187. }
  188.  
  189.  
  190. //----------------------------------------------------------------------------------------
  191. //    FW_OFile__InitWithPermissions
  192. //  Open with specified permissions.
  193. //----------------------------------------------------------------------------------------
  194.  
  195. SOM_Scope void  SOMLINK FW_OFile__InitWithPermissions(FW_OFile *somSelf, Environment *ev,
  196.         FW_OFileSpecification* fileSpecification,
  197.         FW_SAccessPermission* permission,
  198.         FW_Boolean allowCreate)
  199. {
  200.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  201.  
  202.     FW_SOM_TRY
  203.     {
  204.         somThis->fRep = FW_NEW(FW_CPrivFileRep, (ev, fileSpecification, permission));
  205.         privOpenFile(somSelf, ev, allowCreate);
  206.     }
  207.     FW_SOM_CATCH
  208. }
  209.  
  210.  
  211. //----------------------------------------------------------------------------------------
  212. //    FW_OFile__Read
  213. //  Read 'count' bytes from current position to 'destination' and
  214. //  increment current position by 'count'.
  215. //----------------------------------------------------------------------------------------
  216.  
  217. SOM_Scope void  SOMLINK FW_OFile__Read(FW_OFile *somSelf, Environment *ev,
  218.         void* destination,
  219.         long count)
  220. {
  221.     FW_SOM_TRY
  222.     {
  223.         privDoRead(somSelf, ev, destination, count);
  224.     }
  225.     FW_SOM_CATCH
  226. }
  227.  
  228.  
  229. //----------------------------------------------------------------------------------------
  230. //    FW_OFile__Write
  231. //  Write 'count' bytes from 'source' to current file position.
  232. //----------------------------------------------------------------------------------------
  233.  
  234. SOM_Scope void  SOMLINK FW_OFile__Write(FW_OFile *somSelf, Environment *ev,
  235.         void* source,
  236.         long count)
  237. {
  238.     FW_SOM_TRY
  239.     {
  240.         privDoWrite(somSelf, ev, source, count);
  241.     }
  242.     FW_SOM_CATCH
  243. }
  244.  
  245.  
  246. //----------------------------------------------------------------------------------------
  247. //    FW_OFile__GetLength
  248. //  Return the logical size of the file.
  249. //----------------------------------------------------------------------------------------
  250.  
  251. SOM_Scope long  SOMLINK FW_OFile__GetLength(FW_OFile *somSelf, Environment *ev)
  252. {
  253.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  254.  
  255.     FW_SOM_TRY
  256.     {
  257.         FW_CPrivFileRep& rep = *somThis->fRep;
  258.         long length;
  259.  
  260. #ifdef FW_BUILD_WIN
  261.         // Since Windows does not support this feature directly, we have to reset the file
  262.         //   pointer to get the length and then restore the original position.
  263.         long oldPosition = somSelf->GetPosition(ev);
  264.         FW_FailOnError(privWinMoveFilePointer(somSelf, ev, 0, FW_kFromEnd, length));
  265.         FW_FailOnError(privWinMoveFilePointer(somSelf, ev, oldPosition, FW_kFromStart, oldPosition));
  266. #endif
  267.  
  268. #ifdef FW_BUILD_MAC
  269.         long macEOF;
  270.     
  271.         FW_FailOnError(::GetEOF(rep.fFileHandle, &macEOF));
  272.         length = macEOF;
  273. #endif
  274.  
  275.         return length;
  276.     }
  277.     FW_SOM_CATCH
  278.     return 0;
  279. }
  280.  
  281.  
  282. //----------------------------------------------------------------------------------------
  283. //    FW_OFile__SetLength
  284. //  Return the logical size of the file.
  285. //----------------------------------------------------------------------------------------
  286.  
  287. SOM_Scope void  SOMLINK FW_OFile__SetLength(FW_OFile *somSelf, Environment *ev,
  288.         long length)
  289. {
  290.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  291.  
  292.     FW_SOM_TRY
  293.     {
  294.         FW_CPrivFileRep& rep = *somThis->fRep;
  295.         FW_PlatformError theError = FW_xNoError;
  296.         long currentLength = somSelf->GetLength(ev);
  297.  
  298. #ifdef FW_BUILD_WIN16
  299.         long oldPosition = somSelf->GetPosition(ev);
  300.         FW_FailOnError(privWinMoveFilePointer(somSelf, ev, length, FW_kFromStart, length));
  301.         
  302.         // writing 0 bytes truncates the file at the current position
  303.         char buf;
  304.         short actualWritten;
  305.         FW_PlatformError writeError = privWinPrimitiveWrite(rep.fFileHandle, 0, &buf, actualWritten);
  306.         
  307.         // move back to the old position, regardless of whether the write was successfull
  308.         if (oldPosition > length)
  309.             oldPosition = length;
  310.         FW_PlatformError seekError = privWinMoveFilePointer(somSelf, ev, oldPosition, FW_kFromStart, oldPosition);
  311.         
  312.         if (writeError != FW_xNoError)
  313.             FW_FailOnError(writeError);
  314.         else
  315.             FW_FailOnError(seekError);
  316. #endif
  317.     
  318. #ifdef FW_BUILD_WIN32
  319.         long oldPosition = somSelf->GetPosition(ev);
  320.         somSelf->SetPosition(ev, FW_kFromStart, length);
  321.         if (!::SetEndOfFile(rep.fFileHandle))
  322.             theError = ::GetLastError();
  323.         somSelf->SetPosition(ev, FW_kFromStart, oldPosition);
  324. #endif
  325.     
  326. #ifdef FW_BUILD_MAC
  327.         theError = ::SetEOF(rep.fFileHandle, length);
  328. #endif
  329.     
  330.         FW_FailOnError(theError);
  331.     }
  332.     FW_SOM_CATCH
  333. }
  334.  
  335.  
  336. //----------------------------------------------------------------------------------------
  337. //    FW_OFile__GetPosition
  338. //  Return current file position.
  339. //----------------------------------------------------------------------------------------
  340.  
  341. SOM_Scope long  SOMLINK FW_OFile__GetPosition(FW_OFile *somSelf, Environment *ev)
  342. {
  343.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  344.  
  345.     FW_SOM_TRY
  346.     {
  347.         FW_CPrivFileRep& rep = *somThis->fRep;
  348.         FW_PlatformError theError = FW_xNoError;
  349.         long currentPosition;
  350.     
  351. #ifdef FW_BUILD_WIN
  352.         theError = privWinMoveFilePointer(somSelf, ev, 0, FW_kFromCurrent, currentPosition);
  353. #endif
  354.     
  355. #ifdef FW_BUILD_MAC
  356.         theError = ::GetFPos(rep.fFileHandle, ¤tPosition);
  357. #endif
  358.     
  359.         FW_FailOnError(theError);
  360.         return currentPosition;
  361.     }
  362.     FW_SOM_CATCH
  363.     return 0;
  364. }
  365.  
  366.  
  367. //----------------------------------------------------------------------------------------
  368. //    FW_OFile__SetPosition
  369. //  Set current file position using mode.
  370. //----------------------------------------------------------------------------------------
  371.  
  372. SOM_Scope void  SOMLINK FW_OFile__SetPosition(FW_OFile *somSelf, Environment *ev,
  373.         long positioningMode,
  374.         long markOffset)
  375. {
  376.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  377.  
  378.     FW_SOM_TRY
  379.     {
  380.         FW_CPrivFileRep& rep = *somThis->fRep;
  381.         FW_PlatformError theError = FW_xNoError;
  382.         
  383. #ifdef FW_BUILD_WIN
  384.         theError = privWinMoveFilePointer(somSelf, ev, markOffset, (FW_EFS_MoveMethods)positioningMode, markOffset);
  385. #endif
  386.     
  387. #ifdef FW_BUILD_MAC
  388.         long newLength = markOffset;
  389.         theError = ::SetFPos(rep.fFileHandle, positioningMode, newLength);
  390. #endif
  391.     
  392. #ifdef FW_BUILD_WIN16
  393.         // Win16 returns this error to indicate an invalid positioningMode.
  394.         if (theError == FW_kPermissionError)
  395.             theError = FW_kParameterError;
  396. #endif
  397.     
  398.         FW_FailOnError(theError);
  399.     }
  400.     FW_SOM_CATCH
  401. }
  402.  
  403.  
  404. //----------------------------------------------------------------------------------------
  405. //    FW_OFile__BytesToEndOfFile
  406. //  Returns the number of bytes from the current position to the
  407. //    end of the file.
  408. //----------------------------------------------------------------------------------------
  409.  
  410. SOM_Scope long  SOMLINK FW_OFile__BytesToEndOfFile(FW_OFile *somSelf, Environment *ev)
  411. {
  412.     FW_SOM_TRY
  413.     {
  414.         return (somSelf->GetLength(ev) - somSelf->GetPosition(ev));
  415.     }
  416.     FW_SOM_CATCH
  417.     return 0;
  418. }
  419.  
  420.  
  421. //----------------------------------------------------------------------------------------
  422. //    FW_OFile__GetPermissions
  423. //  Returns the permissions used to open this file.
  424. //----------------------------------------------------------------------------------------
  425.  
  426. SOM_Scope void  SOMLINK FW_OFile__GetPermissions(FW_OFile *somSelf, Environment *ev,
  427.         FW_SAccessPermission* thePerms)
  428. {
  429. FW_UNUSED(ev);
  430.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  431.  
  432.     *thePerms = somThis->fRep->fPermission;
  433. }
  434.  
  435.  
  436. //----------------------------------------------------------------------------------------
  437. //    FW_OFile__GetFileSpecification
  438. //  Returns a reference to the file.  This routine is primarily used for
  439. //    exception handling.
  440. //----------------------------------------------------------------------------------------
  441.  
  442. SOM_Scope FW_OFileSpecification*  SOMLINK FW_OFile__GetFileSpecification(FW_OFile *somSelf, Environment *ev)
  443. {
  444. FW_UNUSED(ev);
  445.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  446.  
  447.     return somThis->fRep->fFileSpec;
  448. }
  449.  
  450.  
  451. //----------------------------------------------------------------------------------------
  452. //    FW_OFile__GetFileHandle
  453. //  Returns the native platform handle to the file.
  454. //----------------------------------------------------------------------------------------
  455.  
  456. SOM_Scope FW_FileAccessHandle*  SOMLINK FW_OFile__GetFileHandle(FW_OFile *somSelf, Environment *ev)
  457. {
  458. FW_UNUSED(ev);
  459.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  460.  
  461.     return &somThis->fRep->fFileHandle;
  462. }
  463.  
  464.  
  465. //----------------------------------------------------------------------------------------
  466. //    FW_OFile__IsEqual
  467. //  Equality operator.
  468. //----------------------------------------------------------------------------------------
  469.  
  470. SOM_Scope FW_Boolean  SOMLINK FW_OFile__IsEqual(FW_OFile *somSelf, Environment *ev,
  471.         FW_OFile* theOtherFile)
  472. {
  473.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  474.  
  475.     FW_SOM_TRY
  476.     {
  477.         FW_CPrivFileRep& rep = *somThis->fRep;
  478.         return (rep.fFileHandle == *theOtherFile->GetFileHandle(ev)) 
  479.                 && (rep.fFileSpec->IsSameAs(ev, theOtherFile->GetFileSpecification(ev)));
  480.     }
  481.     FW_SOM_CATCH
  482.     return FALSE;
  483. }
  484.  
  485.  
  486. //----------------------------------------------------------------------------------------
  487. //    FW_OFile__somInit
  488. //----------------------------------------------------------------------------------------
  489.  
  490. SOM_Scope void  SOMLINK FW_OFile__somInit(FW_OFile *somSelf)
  491. {
  492.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  493.  
  494.     FW_OFile_parent_FW_ORefCount_somInit(somSelf);
  495.  
  496.     somThis->fRep = 0;
  497. }
  498.  
  499.  
  500. //----------------------------------------------------------------------------------------
  501. //    FW_OFile__somUninit
  502. //----------------------------------------------------------------------------------------
  503.  
  504. SOM_Scope void  SOMLINK FW_OFile__somUninit(FW_OFile *somSelf)
  505. {
  506.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  507.  
  508.     FW_SOM_UNINIT_TRY
  509.     {
  510.         privCloseFile(somSelf, somGetGlobalEnvironment());
  511.     
  512.         delete somThis->fRep;
  513.  
  514.         FW_OFile_parent_FW_ORefCount_somUninit(somSelf);
  515.     }
  516.     FW_SOM_UNINIT_CATCH
  517. }
  518.  
  519.  
  520. //----------------------------------------------------------------------------------------
  521. //    privOpenFile
  522. //
  523. //    Opens the file using the permissions set with SetPermission.  If no permissions were
  524. //    set, it tries to open the file for exclusive access.  If the file is already open,
  525. //    nothing happens.  If any other errors occur, they are thrown as exceptions.
  526. //----------------------------------------------------------------------------------------
  527. static void privOpenFile(FW_OFile *somSelf, Environment *ev, FW_Boolean allowCreate)
  528. {
  529.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  530.     FW_CPrivFileRep& rep = *somThis->fRep;
  531.     FW_PlatformError theError = FW_xNoError;
  532.     unsigned long accessMode = rep.fPermission.fAccess;
  533.     unsigned long denyMode   = rep.fPermission.fDeny;
  534.  
  535. #ifdef FW_BUILD_WIN
  536.     FW_CString fileName;
  537.  
  538.     rep.fFileSpec->GetFullPath(ev, fileName);
  539. #endif
  540.  
  541. #ifdef FW_BUILD_WIN16
  542.     OFSTRUCT Buffer;
  543.     rep.fFileHandle = ::OpenFile((const FW_Char*)fileName, &Buffer, accessMode | denyMode);
  544.     if (rep.fFileHandle == FW_kInvalidAccessHandle)
  545.         theError = Buffer.nErrCode;
  546. #endif
  547.  
  548. #ifdef FW_BUILD_WIN32
  549.     // If we allowCreate, always open the file.  Otherwise, open only if it 
  550.     // already exists.
  551.     long openMode = (allowCreate ? OPEN_ALWAYS : OPEN_EXISTING);
  552.     
  553.     char szFileName[_MAX_PATH];
  554.     fileName.ExportCString(szFileName);
  555.     
  556.     rep.fFileHandle = ::CreateFile(szFileName, 
  557.                                    accessMode, 
  558.                                    denyMode, 
  559.                                    NULL,
  560.                                    openMode, 
  561.                                    FILE_ATTRIBUTE_NORMAL, 
  562.                                    (HANDLE)NULL);
  563.                                
  564.     if (rep.fFileHandle == FW_kInvalidAccessHandle)
  565.         theError = ::GetLastError();
  566. #endif
  567.  
  568. #ifdef FW_BUILD_MAC
  569.     // If we allowCreate, then try creating the file.  If the file already 
  570.     // exists, we will FW_CATCH the attempt to re-create it and merrily roll 
  571.     // along.  If the file does not exist, it will when we're done.
  572.     if (allowCreate)
  573.     {
  574.         FW_TRY
  575.         {
  576.             FW_FileSystem_CreateFile(ev, rep.fFileSpec, FALSE);
  577.         }
  578.         FW_CATCH_BEGIN
  579.         FW_CATCH(FW_XException, theException)
  580.         {
  581.             if (theException.GetPlatformError() != FW_xFileExists)
  582.                 FW_THROW_SAME();
  583.         }
  584.         FW_CATCH_END
  585.  
  586.         // At this point, the file exists (modulo another thread nuking it).
  587.     }
  588.  
  589.     // Check to see if file sharing exists on this volume.  If it does, open the file using
  590.     // deny modes.
  591.     FSSpec theMacSpec;
  592.  
  593.     rep.fFileSpec->MacGetFSSpec(ev, &theMacSpec);
  594.  
  595.     if (FW_FileSystem_MacIsVolumeShared(ev, theMacSpec.vRefNum))
  596.     {
  597.         HParamBlockRec paramBlock;
  598.  
  599.         paramBlock.fileParam.ioNamePtr = (StringPtr) & (theMacSpec.name);
  600.         paramBlock.fileParam.ioVRefNum = theMacSpec.vRefNum;
  601.         paramBlock.fileParam.ioDirID = theMacSpec.parID;
  602.         paramBlock.accessParam.ioDenyModes = accessMode | denyMode;
  603.  
  604.         theError = ::PBHOpenDenySync(¶mBlock);
  605.         rep.fFileHandle = paramBlock.fileParam.ioFRefNum;
  606.     }
  607.     else
  608.         theError = ::FSpOpenDF(&(theMacSpec), accessMode, &rep.fFileHandle);
  609.     
  610. #endif    
  611.     
  612.     FW_FailOnError(theError);
  613. }
  614.  
  615. //----------------------------------------------------------------------------------------
  616. //    privCloseFile
  617. //----------------------------------------------------------------------------------------
  618. static void privCloseFile(FW_OFile *somSelf, Environment *ev)
  619. {
  620. FW_UNUSED(ev);
  621.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  622.     FW_CPrivFileRep& rep = *somThis->fRep;
  623.     FW_PlatformError theError = FW_xNoError;
  624.  
  625. #if 0
  626. //#ifdef FW_BUILD_WIN16
  627.     FW_FileAccessHandle handle = rep.fFileHandle;
  628.     
  629.     __asm {
  630.         mov        bx, [handle]
  631.         mov        ah, 03Eh
  632.     }
  633.     
  634.     DOS3Call();
  635.         
  636.     __asm {
  637.         jc        _error
  638.         xor        ax, ax
  639.     }
  640.  
  641.     _error:
  642.         
  643.     __asm {
  644.         mov        theError, ax
  645.     }
  646. #endif
  647.  
  648. #ifdef FW_BUILD_WIN32
  649.     if(!::CloseHandle(rep.fFileHandle))
  650.         theError = ::GetLastError();
  651. #endif
  652.  
  653. #ifdef FW_BUILD_MAC
  654.     theError = ::FSClose(rep.fFileHandle);
  655. #endif
  656.  
  657.     FW_FailOnError(theError);
  658.         
  659.     rep.fFileHandle = FW_kInvalidAccessHandle;
  660. }
  661.  
  662.  
  663. #ifdef FW_BUILD_WIN16
  664. //----------------------------------------------------------------------------------------
  665. //    privWinGetIOBufferSize
  666. //----------------------------------------------------------------------------------------
  667. static short privWinGetIOBufferSize(long bytesDesired, const void* buffer)
  668. {
  669.     short offset = (short)(long)buffer;
  670.     long max = 0x10000L - offset;
  671.     if(max > bytesDesired)
  672.         max = bytesDesired;
  673.     return max > 16384 ? 16384 : (short)max;
  674. }
  675.                                        
  676.  
  677. //----------------------------------------------------------------------------------------
  678. //    privWinPrimitiveRead
  679. //----------------------------------------------------------------------------------------
  680. static FW_PlatformError privWinPrimitiveRead(FW_FileAccessHandle handle,
  681.                                                     short bytesToRead,
  682.                                                     void* buffer,
  683.                                                     short& bytesActuallyRead)
  684. {
  685.     FW_PlatformError theError;
  686.     
  687.     __asm {
  688.         mov        ah, 03Fh
  689.         mov        bx, [handle]
  690.         mov        cx, [bytesToRead]
  691.         push    ds
  692.         lds        dx, [buffer]
  693.     }
  694.     
  695.     DOS3Call();
  696.         
  697.     __asm {
  698.         pop        ds
  699.         jc        _error
  700.         les        bx, [bytesActuallyRead]
  701.         mov        es:[bx], ax
  702.         xor        ax, ax
  703.     }
  704.     
  705.     _error:
  706.     
  707.     __asm {
  708.         mov        theError, ax
  709.     };
  710.     
  711.     return (theError);
  712. }
  713.  
  714.  
  715. //----------------------------------------------------------------------------------------
  716. //    privWinPrimitiveWrite
  717. //----------------------------------------------------------------------------------------
  718. static FW_PlatformError privWinPrimitiveWrite(FW_FileAccessHandle handle,
  719.                                                      short bytesToWrite,
  720.                                                      const void* buffer,
  721.                                                      short& bytesActuallyWritten)
  722. {
  723.     FW_PlatformError theError;
  724.     
  725.     __asm {
  726.         mov        ah, 040h
  727.         mov        bx, [handle]
  728.         mov        cx, [bytesToWrite]
  729.         push    ds
  730.         lds        dx, [buffer]
  731.     }
  732.     
  733.     DOS3Call();
  734.         
  735.     __asm {
  736.         pop        ds
  737.         jc        _error
  738.         les        bx, [bytesActuallyWritten]
  739.         mov        es:[bx], ax
  740.         xor        ax, ax
  741.     }
  742.     
  743.     _error:
  744.     
  745.     _asm {
  746.         mov        theError, ax
  747.     };
  748.     
  749.     return (theError);
  750. }
  751. #endif
  752.  
  753. //----------------------------------------------------------------------------------------
  754. // privDoRead
  755. //----------------------------------------------------------------------------------------
  756. static void privDoRead(FW_OFile *somSelf, Environment *ev, void* destination, long count)
  757. {
  758. FW_UNUSED(ev);
  759.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  760.     FW_CPrivFileRep& rep = *somThis->fRep;
  761.     FW_PlatformError theError = FW_xNoError;
  762.     
  763.     FW_ASSERT (count >= 0);
  764.         
  765. #ifdef FW_BUILD_WIN16
  766.     long toRead = count;
  767.     while(toRead > 0)
  768.     {
  769.         short readNow = privWinGetIOBufferSize(toRead, destination);
  770.         short actualRead;
  771.         theError = privWinPrimitiveRead(rep.fFileHandle, readNow, destination, actualRead);
  772.         
  773.         if(theError != 0)
  774.             break;
  775.             
  776.         toRead -= actualRead;
  777.  
  778.         if(actualRead < readNow)
  779.             break;
  780.             
  781.         destination = ((char __huge*) destination) + toRead;
  782.     }
  783.     
  784.     if (toRead != 0)
  785.         theError = FW_kEndOfFileReached;
  786. #endif
  787.  
  788. #ifdef FW_BUILD_WIN32
  789.     DWORD actualRead;
  790.     if(!::ReadFile(rep.fFileHandle, destination, count, &actualRead, NULL))
  791.         theError = ::GetLastError();
  792. #endif
  793.  
  794. #ifdef FW_BUILD_MAC
  795.     theError = ::FSRead(rep.fFileHandle, &count, destination);
  796. #endif
  797.  
  798.     FW_FailOnError(theError);
  799. }
  800.  
  801.  
  802. //----------------------------------------------------------------------------------------
  803. //    privDoWrite
  804. //----------------------------------------------------------------------------------------
  805. static void privDoWrite(FW_OFile *somSelf, Environment *ev, const void* source, long count)
  806. {
  807. FW_UNUSED(ev);
  808.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  809.     FW_CPrivFileRep& rep = *somThis->fRep;
  810.     FW_PlatformError theError = FW_xNoError;
  811.  
  812.     FW_ASSERT (count > 0);
  813.     
  814. #ifdef FW_BUILD_WIN16
  815.     long toWrite = count;
  816.     while(toWrite > 0)
  817.     {
  818.         short writeNow = privWinGetIOBufferSize(toWrite, source);
  819.         short actualWritten;
  820.         theError = privWinPrimitiveWrite(rep.fFileHandle, writeNow, source, actualWritten);
  821.         
  822.         if(theError != 0)
  823.             break;
  824.             
  825.         toWrite -= actualWritten;
  826.  
  827.         if(actualWritten < writeNow)
  828.             break;
  829.             
  830.         source = ((const char __huge*) source) + toWrite;
  831.     }
  832.         
  833.     if (toWrite != 0)
  834.         theError = FW_kDiskFull;
  835. #endif
  836.  
  837. #ifdef FW_BUILD_WIN32
  838.     DWORD actualWrite;
  839.     if(!::WriteFile(rep.fFileHandle, source, count, &actualWrite, NULL))
  840.         theError = ::GetLastError();
  841. #endif
  842.  
  843. #ifdef FW_BUILD_MAC
  844.      theError = ::FSWrite(rep.fFileHandle, &count, source);
  845. #endif
  846.  
  847.     FW_FailOnError(theError);
  848. }
  849.  
  850.  
  851. #ifdef FW_BUILD_WIN
  852. //----------------------------------------------------------------------------------------
  853. //    privWinMoveFilePointer
  854. //----------------------------------------------------------------------------------------
  855. static FW_PlatformError privWinMoveFilePointer(FW_OFile *somSelf,
  856.                                                       Environment *ev,
  857.                                                       long markOffset,
  858.                                                       FW_EFS_MoveMethods positioningMode,
  859.                                                       long& newPosition)
  860. {
  861.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  862.     FW_CPrivFileRep& rep = *somThis->fRep;
  863.     FW_PlatformError theError = FW_xNoError;
  864.  
  865. #ifdef FW_BUILD_WIN16
  866.     FW_FileAccessHandle handle = rep.fFileHandle;
  867.     
  868.     __asm {
  869.         mov     ax, [positioningMode]
  870.         mov     ah, 42h
  871.         mov        bx, [handle]
  872.         mov     dx, word ptr [markOffset]
  873.         mov     cx, word ptr [markOffset+2]
  874.     }
  875.     
  876.     DOS3Call();
  877.         
  878.     __asm {
  879.         jc        _error
  880.         les     bx, [newPosition]
  881.         mov     word ptr es:[bx], ax
  882.         mov     word ptr es:[bx+2], dx
  883.         xor     ax, ax
  884.     }
  885.             
  886.     _error:
  887.     
  888.     __asm {
  889.         mov        theError, ax
  890.     }
  891. #endif
  892.  
  893. #ifdef FW_BUILD_WIN32
  894.     newPosition = ::SetFilePointer(rep.fFileHandle, markOffset, NULL, positioningMode);
  895.     if (newPosition == FW_kInvalidSeek)
  896.         theError = ::GetLastError();
  897. #endif
  898.  
  899.     return theError;
  900. }
  901. #endif
  902.  
  903.  
  904.