cmacfile.cp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:22k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. // include platform specific headers here
  36. #include <stdio.h>
  37. #include <fcntl.h>
  38. #include <Folders.h>
  39. #include <Script.h>
  40. #include "CMacFile.h"
  41. #include "hxtick.h"
  42. #include "FullPathName.h"
  43. #include "hxcom.h"
  44. #include "hxbuffer.h"
  45. #include "hxmm.h"
  46. #include "hxfiles.h" /* for HX_FILE_WRITE */
  47. #ifndef _CARBON
  48. #include "FSpCompat.h"
  49. #include "MoreFilesExtras.h"
  50. #else
  51. #include "MoreFilesX.h"
  52. #endif
  53. OSType CMacFile::sCreator = 'PNst';
  54. OSType CMacFile::sFileType  = 'PNRA';
  55. BOOL gReadDone = FALSE;
  56. ULONG32 gReadCount = 0;
  57. // async callback proc
  58. pascal void ReadCallback(ParamBlockRec* pb);
  59. // async callback UPP
  60. #ifdef _CARBON
  61. static IOCompletionUPP gReadCallbackUPP=NewIOCompletionUPP(ReadCallback);
  62. #else
  63. static IOCompletionUPP gReadCallbackUPP=NewIOCompletionProc(ReadCallback);
  64. #endif
  65. CHXDataFile*
  66. CHXDataFile::Construct (UINT32 ulFlags)
  67. {
  68.     return (CHXDataFile *) new CMacFile;
  69. }
  70. // CHXFile should set the file reference to a value indicating the file is not open
  71. CMacFile::CMacFile (void)
  72. {
  73. mRefNum = 0;
  74. mLastError = noErr;
  75. mAppendMode = FALSE;
  76. mBufferFile = NULL;
  77. mBufferedRead = FALSE;
  78. mWriteFile = NULL;
  79. mBufferedWrite = FALSE;
  80. m_pseudoFileHandle = NULL; // if non-null, a memory manager handle containing the "file data"
  81. m_pseudoFileOffset = 0; // current "read" position in the pseudo file
  82. m_pseudoFileSize = 0; // total pseudo file size
  83. }
  84. // ~CHXFile should close the file if it is open
  85. CMacFile::~CMacFile(void)
  86. {
  87. /* if(mBufferFile)
  88. delete mBufferFile;
  89. mBufferFile = NULL;
  90. }
  91. if(mWriteFile) 
  92. {
  93. delete mWriteFile;
  94. mWriteFile = NULL;
  95. } */
  96. Close(); // close file if necessary
  97. }
  98. // Create a file with the specified mode
  99. // Close the previous file if it was open
  100. HX_RESULT CMacFile::Create(const char *filename, UINT16 mode,BOOL textflag)
  101. {
  102. Close(); // close previous file if necessary
  103. FSSpec theSpec;
  104. OSErr theErr=noErr;
  105. Close(); // close previous file if necessary
  106. theErr = FSSpecFromPathName(filename, &theSpec);
  107. if(!theErr)
  108. {
  109. Boolean targetIsFolder,wasAliased;
  110. theErr = ::ResolveAliasFile(&theSpec,true,&targetIsFolder,&wasAliased);
  111. }
  112. if(theErr==fnfErr)
  113. theErr = FSCreateDataFile(&theSpec,textflag ? 'ttxt' : sCreator ,textflag ? 'TEXT' : sFileType);
  114. if(!theErr)
  115. theErr = FSOpenFile(&theSpec, fsRdWrPerm, &mRefNum);
  116. if(!theErr)
  117. theErr = ::SetEOF(mRefNum, 0L);
  118. if(!theErr)
  119. mFile = theSpec;
  120. mLastError = theErr;
  121. return(theErr ? -1 : 0);
  122. }
  123. // Open a file with the specified permissions
  124. // Close the previous file if it was open
  125. //
  126. // If the file isn't found, look for a 'RLFL' resource *in the current
  127. // resource chain* with the same name as the file.
  128. HX_RESULT CMacFile::Open(const char *filename, UINT16 mode,BOOL textflag)
  129. {
  130. OSErr theErr  = noErr;
  131. short  perm = fsCurPerm;
  132. UCHAR   length  = ::strlen(filename);
  133. FSSpec theSpec;
  134. if(!theErr)
  135. {
  136. Close(); // close previous file if necessary
  137. theErr = FSSpecFromPathName(filename,&theSpec);
  138. if (theErr)  //try adding ':' (partial path)
  139. {
  140.     UCHAR* partial = new UCHAR[length + 2];
  141.     partial[0] = length+1;
  142.     partial[1] = ':';
  143.     ::BlockMoveData(filename,&partial[2],length);
  144.     theErr = FSMakeFSSpec(0,0,partial,&theSpec);
  145.     if (theErr == dirNFErr)
  146.      theErr = fnfErr;
  147.     delete [] partial;
  148. }
  149. if(!theErr)
  150. {
  151. Boolean targetIsFolder,wasAliased;
  152. theErr = ::ResolveAliasFile(&theSpec,true,&targetIsFolder,&wasAliased);
  153. }
  154. }
  155. if(!theErr)
  156. {
  157. // figure out mac file permission
  158. perm = fsRdWrPerm;
  159. if (mode & O_WRONLY)
  160. perm = fsWrPerm;
  161. else if (mode & O_RDONLY)
  162. perm = fsRdPerm;
  163. // Store the permissions for this file for later.
  164. m_mode=mode;
  165. theErr = FSOpenFile(&theSpec, perm, &mRefNum);
  166. }
  167. if(theErr != noErr)
  168. {
  169. if(theErr == fnfErr)
  170. {
  171. theErr = FSSpecFromPathName(filename,&theSpec);
  172. if ((mode & O_CREAT) || (mode & O_WRONLY)) //always create if Write mode
  173. theErr = FSCreateDataFile(&theSpec,textflag ? 'ttxt' : sCreator ,textflag ? 'TEXT' : sFileType);
  174. if(!theErr)
  175. theErr = FSOpenFile(&theSpec, perm, &mRefNum);
  176. }
  177. }
  178. if ((theErr) && (mode & O_RDONLY))
  179. {
  180. Handle resHandle;
  181. SInt32 resSize;
  182. // We couldn't open the file, and the request was read-only
  183. //
  184. // See if there's a pseudo-file resource we can use
  185. //
  186. // We need a handle to the resource so we can read from it, but
  187. // we don't want the whole resource loaded into memory, so we
  188. // set ResLoad to false.
  189. SetResLoad(false);
  190. resHandle = GetNamedResource(kRealFileResource, theSpec.name); // 'RLFL'
  191. SetResLoad(true);
  192. if (resHandle)
  193. {
  194. // we have a handle to the resource; determine
  195. // its size and reset our "file pointer"
  196. resSize = GetResourceSizeOnDisk(resHandle);
  197. if (resSize > 0)
  198. {
  199. m_pseudoFileHandle = resHandle;
  200. m_pseudoFileSize = resSize;
  201. m_pseudoFileOffset = 0;
  202. theErr = noErr;
  203. mRefNum = -1; // signals that we're using a pseudo-file and no actual file is open
  204. }
  205. }
  206. }
  207. if (!m_pseudoFileHandle)
  208. {
  209. if(!theErr && (mode & O_CREAT))
  210. theErr = ::SetEOF(mRefNum, 0L);
  211. if(!theErr)
  212. {
  213. mAppendMode = (mode & O_APPEND);
  214. mFile = theSpec;
  215. if(mode & O_TRUNC) theErr = ::SetEOF(mRefNum, 0L);
  216. }
  217. if(theErr && mRefNum != 0) Close();
  218. }
  219. mLastError = theErr;
  220. return(theErr ? HXR_DOC_MISSING : 0);
  221. }
  222. // Close the previous file if it was open
  223. HX_RESULT CMacFile::Close(void)
  224. {
  225. OSErr theErr = noErr;
  226. if (m_pseudoFileHandle)
  227. {
  228. // "close" our pseudo file
  229. //
  230. // We don't need or want to dispose or release our pseudo-
  231. // file handle since it's not using up memory anyway, and
  232. // releasing it would hurt anyone else who happens to be
  233. // reading from it.  The handle will be released 
  234. // automatically when its owning resource file closes.
  235. m_pseudoFileHandle = 0;
  236. m_pseudoFileOffset = 0;
  237. m_pseudoFileSize = 0;
  238. theErr = noErr;
  239. mRefNum = 0;
  240. }
  241. else if (mRefNum) 
  242. {
  243. if(mBufferFile)
  244. delete mBufferFile;
  245. mBufferFile = NULL;
  246. }
  247. if(mWriteFile) 
  248. {
  249. delete mWriteFile;
  250. mWriteFile = NULL;
  251. }
  252. // close a real file
  253. theErr = ::FSClose(mRefNum);
  254. mRefNum = 0;
  255. if(!theErr) theErr =::FlushVol(nil, mFile.vRefNum);
  256. }
  257. mLastError = theErr;
  258. return(theErr ? -1 : 0);
  259. }
  260. HX_RESULT CMacFile::Delete (const char *filename)
  261. {
  262.     OSErr theErr = noErr;
  263.     FSSpec theSpec;
  264. HX_ASSERT (!m_pseudoFileHandle);
  265. theErr = FSSpecFromPathName(filename,&theSpec);
  266. if (noErr == theErr) 
  267. {
  268. theErr = ::FSpDelete(&theSpec);
  269. }
  270. mLastError = theErr;
  271. return(theErr ? -1 : 0);
  272. }
  273. /* Returns the size of the file in bytes. */
  274. ULONG32 CMacFile::GetSize(void)
  275. {
  276. ULONG32 size=0;
  277. if (m_pseudoFileHandle)
  278. {
  279. size = m_pseudoFileSize;
  280. }
  281. else if (mRefNum) 
  282. {
  283.      ::GetEOF(mRefNum,(long*)&size);
  284.     }
  285.     return size;
  286. }
  287. // Rewinds the file position to the start of the file
  288. HX_RESULT CMacFile::Rewind(void)
  289. {
  290. OSErr theErr;
  291. if (m_pseudoFileHandle)
  292. {
  293. m_pseudoFileOffset = 0;
  294. theErr = noErr;
  295. }
  296. else
  297. {
  298. theErr = ::SetFPos(mRefNum,fsFromStart,0L);
  299. }
  300. mLastError = theErr;
  301. return(theErr ? HXR_INVALID_FILE : 0);
  302. }
  303. // Seek moves the current file position to the offset from the fromWhere specifier
  304. HX_RESULT CMacFile::Seek(ULONG32 offset, UINT16 fromWhere)
  305. {
  306. OSErr theErr = noErr;
  307. if (m_pseudoFileHandle)
  308. {
  309. switch(fromWhere)
  310. {
  311. case SEEK_SET:
  312. m_pseudoFileOffset = offset;
  313. break;
  314. case SEEK_CUR:
  315. m_pseudoFileOffset += offset;
  316. break;
  317. case SEEK_END:
  318. m_pseudoFileOffset = (m_pseudoFileSize - 1) - offset;
  319. break;
  320. }
  321. // don't go beyond the end (we won't return eofErr either to match
  322. // the real seek below)
  323. if (m_pseudoFileOffset >= m_pseudoFileSize)
  324. {
  325. m_pseudoFileOffset = m_pseudoFileSize - 1;
  326. }
  327. theErr = HXR_OK;
  328. }
  329. else if (mBufferedWrite)
  330. {
  331. long pos = 0;
  332. switch(fromWhere)
  333. {
  334. case SEEK_SET:
  335. pos = offset;
  336. break;
  337. case SEEK_CUR:
  338. pos = mWriteFile->GetCurPos() + offset;
  339. break;
  340. case SEEK_END:
  341. pos = (mWriteFile->GetBufSize() - 1) - offset;
  342. break;
  343. }
  344. mWriteFile->Seek(pos);
  345. }
  346. else
  347. {
  348. switch(fromWhere)
  349. {
  350. case SEEK_SET:
  351. fromWhere = fsFromStart;
  352. break;
  353. case SEEK_CUR:
  354. fromWhere = fsFromMark;
  355. break;
  356. case SEEK_END:
  357. fromWhere = fsFromLEOF;
  358. break;
  359. }
  360. theErr =  ::SetFPos(mRefNum,fromWhere,offset);
  361. // returning eofErr was causing problems for ChunkyRes during http play
  362. if (theErr == eofErr)
  363. {
  364. theErr = ::SetEOF(mRefNum,offset);
  365. theErr = ::SetFPos(mRefNum,fromWhere,offset);
  366. theErr = HXR_OK;
  367. }
  368. long pos;
  369. ::GetFPos(mRefNum,(long *)&pos);
  370. if(!theErr && mBufferedRead)
  371. {
  372. long count; 
  373. ::GetEOF(mRefNum, &count);
  374. mBufferFile->PreLoad(pos,count - offset);
  375. }
  376. /* if(!theErr && mBufferedWrite)
  377. {
  378. mWriteFile->Seek(pos);
  379. } */
  380. }
  381. mLastError = theErr;
  382. return(theErr ? HXR_INVALID_FILE : 0);
  383. }
  384. // Tell 
  385. ULONG32 CMacFile::Tell(void)
  386. {
  387. ULONG32 pos;
  388. if (m_pseudoFileHandle)
  389. {
  390. pos = m_pseudoFileOffset;
  391. mLastError = noErr;
  392. }
  393. else
  394. {
  395. mLastError = ::GetFPos(mRefNum,(long *)&pos);
  396. }
  397. return(pos);
  398. }
  399. // callback could be at interrupt time
  400. pascal void ReadCallback(ParamBlockRec* pb)
  401. {
  402.     OSErr theErr = (*pb).ioParam.ioResult;      
  403.     gReadCount = pb->ioParam.ioActCount;
  404.     gReadDone = TRUE;
  405. }
  406. /*  Read reads up to count bytes of data into buf.
  407. returns the number of bytes read, EOF, or -1 if the read failed */
  408. ULONG32 CMacFile::Read (char *buf, ULONG32 count)
  409. {
  410.     OSErr theErr = noErr;
  411. if (m_pseudoFileHandle)
  412. {
  413. INT32 actualCount;
  414. theErr = Read(buf, count, &actualCount);
  415. count = actualCount;
  416. }
  417. else
  418. {
  419. if(mBufferedRead)
  420. {
  421. count = Copy(buf,count);
  422. if(count == 0)
  423. theErr = eofErr;
  424. }
  425. else
  426. {
  427.         // can't do synchronous read at interrupt time
  428.         if (!HXMM_ATINTERRUPT())
  429.         {
  430. theErr = ::FSRead(mRefNum, (long *)&count, buf);
  431.     }
  432.     else
  433.     { // async i/o - callback could be at interrupt time
  434. #if 1
  435.      ParamBlockRec pb;
  436.      gReadCount = 0;
  437.      gReadDone = FALSE;
  438. pb.ioParam.ioRefNum = mRefNum;
  439. pb.ioParam.ioBuffer = buf;
  440. pb.ioParam.ioReqCount = count;
  441. pb.ioParam.ioPosMode=fsAtMark;
  442. pb.ioParam.ioCompletion = gReadCallbackUPP;
  443. theErr = PBReadAsync(&pb);
  444. UINT32 timeout = TickCount() + 60L;
  445. while (!gReadDone && timeout-TickCount() > 0)
  446. {
  447. }
  448. count = gReadCount;
  449. #endif
  450.     }
  451. }
  452. if(theErr == eofErr && count > 0)
  453. theErr = noErr;
  454. }
  455. mLastError = theErr;
  456. return(mLastError ? 0 : count); //smplfsys::read assumes we return 0 for eof
  457. }
  458. /*  Read reads up to count bytes of data into buf.
  459. returns the number of bytes read, EOF, or -1 if the read failed */
  460. INT16 CMacFile::Read (char *buf, INT32 count, INT32 *actualCount)
  461. {
  462. OSErr theErr = noErr;
  463. long readCount = (long) count;
  464. if (m_pseudoFileHandle)
  465. {
  466. // read from our pseudo-file
  467. SInt32 remainingBytes;
  468. remainingBytes = m_pseudoFileSize - m_pseudoFileOffset;
  469. if (remainingBytes <= 0)
  470. {
  471. // we've already exhausted the buffer
  472. theErr = eofErr;
  473. }
  474. else
  475. {
  476. // some bytes remain to be "read" so read them directly
  477. // from the resource into the caller's buffer
  478. if (remainingBytes < count)
  479. {
  480. count = remainingBytes;
  481. }
  482. ReadPartialResource(m_pseudoFileHandle, m_pseudoFileOffset, buf, count);
  483. theErr = ResError();
  484. HX_ASSERT(theErr == noErr);
  485. // while we don't expect any errors, -188 (resourceInMemory) isn't fatal
  486. if (theErr == noErr || theErr == resourceInMemory)
  487. {
  488. // update our pseudo-file pointer
  489. readCount = count;
  490. m_pseudoFileOffset += count;
  491. theErr = noErr;
  492. }
  493. }
  494. }
  495. else
  496. {
  497. if(mBufferedRead)
  498. {
  499. readCount = Copy(buf,readCount);
  500. if(readCount == 0)
  501. theErr = eofErr;
  502. }
  503. else
  504. {
  505.         if (!HXMM_ATINTERRUPT())
  506. theErr = ::FSRead(mRefNum, &readCount, buf);
  507.     else
  508.     { // async i/o - callback could be at interrupt time
  509. #if 0
  510.      ParamBlockRec pb;
  511. // IOCompletionUPP proc = NewIOCompletionProc(ReadCallback);
  512.      gReadCount = 0;
  513.      gReadDone = FALSE;
  514. pb.ioParam.ioRefNum = mRefNum;
  515. pb.ioParam.ioBuffer = buf;
  516. pb.ioParam.ioReqCount = count;
  517. pb.ioParam.ioPosMode=fsAtMark;
  518. pb.ioParam.ioCompletion = m_CompletionProc;
  519. theErr = PBReadAsync(&pb);
  520. EventRecord   theEvent;
  521. long sleepTime=10;
  522. long timeout = 0;
  523. // timeout, in case file read can't complete
  524. while (!gReadDone && timeout < 100)
  525. {
  526. ::WaitNextEvent(everyEvent, &theEvent, sleepTime, nil);
  527. timeout++;
  528. }
  529. count = gReadCount;
  530. #endif
  531.     }
  532. }
  533. }
  534. if(theErr == eofErr && readCount > 0)
  535. theErr = noErr;
  536. if (actualCount)
  537. {
  538. *actualCount = (INT32) readCount;
  539. }
  540. return(theErr);
  541. }
  542. /*  Write writes up to count bytes of data from buf.
  543. returns the number of bytes written, or -1 if the write failed */
  544. ULONG32 CMacFile::Write(const char *buf, ULONG32 count)
  545. {
  546. HX_ASSERT(!m_pseudoFileHandle);
  547.     OSErr theErr = noErr;
  548.     if (!HXMM_ATINTERRUPT())
  549.     {
  550. if(mAppendMode) 
  551. theErr = ::SetFPos(mRefNum,fsFromLEOF,0L);
  552. if(!theErr)
  553. {
  554. if(mBufferedWrite)
  555. mWriteFile->write_data((Ptr)buf,(long)count);
  556. else
  557. {
  558.   theErr = ::FSWrite(mRefNum, (long *)&count, buf);
  559. //check_noerr(theErr);  a disk full error may occur
  560. }
  561. }
  562. mLastError = theErr;
  563. // return(theErr ? -1 : count);
  564.     }
  565.     else
  566.     {
  567. if(mBufferedWrite)
  568. mWriteFile->write_data((Ptr)buf,(long)count);
  569. mLastError = theErr;
  570.     }
  571. //    return count;
  572. return (theErr == noErr? count : -1);
  573. }
  574. /*  Write writes up to count bytes of data from buf.
  575. returns the number of bytes written, or -1 if the write failed */
  576. INT16 CMacFile::Write(const char *buf, INT32 count, INT32 *actualCount)
  577. {
  578. HX_ASSERT(!m_pseudoFileHandle);
  579.     OSErr theErr = noErr;
  580.     *actualCount = 0;
  581.     if (!HXMM_ATINTERRUPT())
  582.     {
  583. long writeCount = 0;
  584. if(mAppendMode) 
  585. theErr = ::SetFPos(mRefNum,fsFromLEOF,0L);
  586. if(!theErr) 
  587. {
  588. writeCount = count;
  589. theErr = ::FSWrite(mRefNum, &writeCount, buf);
  590. }
  591. *actualCount = (INT32) writeCount;
  592.     }
  593.     
  594. //check_noerr(theErr); a disk full error may occur
  595. // elsewhere the file code expects a negative actualCount when
  596. // the write failed
  597.     if (theErr != noErr) *actualCount = -1;
  598.     
  599.     return(theErr);
  600. }
  601. OSErr CMacFile::FSOpenFile(FSSpec *theSpec, short perm, short *fRefNum) 
  602. {
  603. OSErr theErr = noErr;
  604. Boolean  targetIsFolder,wasAliased;
  605. *fRefNum = 0;
  606. theErr = ResolveAliasFile(theSpec,true,&targetIsFolder,&wasAliased);
  607. if(!theErr) theErr = ::FSpOpenDF(theSpec,perm,fRefNum);
  608. if(theErr) *fRefNum = 0;
  609. return(theErr);
  610. }
  611. OSErr CMacFile::FSCreateDataFile(FSSpec *sfFile, OSType creator, OSType type)
  612. {
  613. OSErr theErr = noErr;
  614. theErr =  ::FSpCreate(sfFile,creator,type,smSystemScript);
  615. if(theErr)
  616. {
  617. if(theErr == dupFNErr)
  618. theErr = FSSetFInfo(sfFile, creator, type);
  619. }
  620. return(theErr);
  621. }
  622. OSErr CMacFile::FSSetFInfo(FSSpec *theSpec, OSType creator, OSType type)
  623. {
  624. OSErr theErr = noErr;
  625. #ifndef _CARBON
  626. theErr = FSpChangeCreatorType(theSpec, creator, type);
  627. #else
  628. FSRef ref;
  629. theErr = FSpMakeFSRef(theSpec, &ref);
  630. if (theErr == noErr)
  631. {
  632. theErr = FSChangeCreatorType(&ref, creator, type);
  633. }
  634. #endif
  635. return(theErr);
  636. }
  637. void CMacFile::SetFileType(OSType creator, OSType type)
  638. {
  639. sFileType = type;
  640. sCreator = creator;
  641. }
  642. OSErr CMacFile::FSSetFilePos(short fRefNum, short fromWhere, long offset)
  643. {
  644. HX_ASSERT(fRefNum != -1); // we can't do this on a pseudo file (since this method's static)
  645. /*
  646. if (m_pseudoFileHandle)
  647. {
  648. OSErr err;
  649. switch (fromWhere)
  650. {
  651. case fsAtMark:
  652. err = noErr;
  653. break;
  654. case fsFromMark:
  655. offset += m_pseudoFileOffset;
  656. // fall through...
  657. case fsFromStart:
  658. if (offset < 0) err = posErr;
  659. else if (offset < m_pseudoFileSize) 
  660. {
  661. m_pseudoFileOffset = offset;
  662. err = noErr;
  663. }
  664. else 
  665. {
  666. // offset is >= m_pseudoFileSize
  667. err = eofErr;
  668. m_pseudoFileOffset = m_pseudoFileSize;
  669. }
  670. break;
  671. case fsFromLEOF:
  672. if (offset > 0) err = posErr;
  673. else if (m_pseudoFileSize - (offset + 1) >= 0) 
  674. {
  675. m_pseudoFileOffset = m_pseudoFileSize - (offset + 1);
  676. err = noErr;
  677. }
  678. else 
  679. {
  680. // offset is >= -m_pseudoFileSize
  681. err = posErr;
  682. m_pseudoFileOffset = 0;
  683. }
  684. break;
  685. }
  686. return err;
  687. }
  688. */
  689. return ::SetFPos(fRefNum,fromWhere,offset);
  690. }
  691. long CMacFile::Copy(Ptr destBuf, long numBytes)
  692. {
  693. long count;
  694. // check for buffered i/o
  695. if(mBufferedRead)
  696. count = mBufferFile->Copy(destBuf,numBytes);
  697. else
  698. count = 0;
  699. return(count);
  700. }
  701. HX_RESULT CMacFile::set_buffered_read (char buffered)
  702. {
  703. Boolean OK = TRUE;
  704. HX_ASSERT(!m_pseudoFileHandle);
  705. // If this file is setup for writing then we don't want to do any buffered reading.
  706. if (m_mode & O_WRONLY) return HXR_OK;
  707. if (m_mode & O_RDWR) return HXR_OK;
  708. mBufferedRead = 0;
  709. return HXR_OK; //HACK! - this needs to be redone!
  710. // set up buffered read object if necessary
  711. if(buffered && !mBufferedRead)
  712. {
  713. if(mBufferFile == NULL) 
  714. {
  715. mBufferFile = new CBufferFile;
  716. OK = mBufferFile != NULL;
  717. }
  718. if(OK) 
  719. OK = mBufferFile->Specify(mRefNum);
  720. }
  721. else if(!buffered && mBufferedRead)
  722. {
  723. if(mBufferFile != NULL) 
  724. {
  725. delete mBufferFile;
  726. mBufferFile = NULL;
  727. }
  728. }
  729. mBufferedRead = buffered != 0;
  730. if(OK)
  731. Seek(0,SEEK_SET);
  732. return(OK ? HXR_OK : HXR_OUTOFMEMORY);
  733. }
  734. HX_RESULT CMacFile::set_buffered_write (char buffered)
  735. {
  736. Boolean OK = TRUE;
  737. HX_ASSERT(!m_pseudoFileHandle);
  738. // set up buffered read object if necessary
  739. if(buffered && !mBufferedWrite)
  740. {
  741. if(mWriteFile == NULL) 
  742. {
  743. mWriteFile = new CWriteFile;
  744. OK = mWriteFile != NULL;
  745. }
  746. if(OK) 
  747. {
  748. OK = mWriteFile->Specify(mRefNum,Tell());
  749. }
  750. }
  751. else if(!buffered && mBufferedWrite)
  752. {
  753. if(mWriteFile != NULL) 
  754. {
  755. delete mWriteFile;
  756. mWriteFile = NULL;
  757. }
  758. }
  759. mBufferedWrite = buffered != 0;
  760. return(OK ? HXR_OK : HXR_OUTOFMEMORY);
  761. }
  762. INT16 CMacFile::FileSize(long *size)
  763. {
  764. return ::GetEOF(mRefNum,size);
  765. }
  766. static ULONG32 sPrevSuffix = 0;
  767. BOOL CMacFile::GetTemporaryFileName(const char *tag, char* name)
  768. {
  769. short tempVRefNum;
  770. long tempDirID;
  771. Str255 tempFileName;
  772. FSSpec tempSpec;
  773. OSErr  theErr = noErr;
  774. // build the temp file name in the form tag_sPrevSuffix
  775. // changed from tag.sPrevSuffix because many other portions
  776. // of code STRIP the suffix, and add their own
  777. // thus yielding a very NON unique file name <rlovejoy>
  778. ::sprintf((char *)tempFileName,"%s_%ld",tag,sPrevSuffix++);
  779. // copy the temo file name into the caller's name field in case we
  780. // can't find the Temporary Folder
  781. ::strcpy(name,(char *)tempFileName);
  782. // Try to get the FSSpec of the System Folder's Temporary Folder
  783. // starting with System 8, the preferred temporary folder is the Chewable Items
  784. // folder (aka Cleanup at Startup) GR 12/8/98
  785. theErr = ::FindFolder(kOnSystemDisk,kChewableItemsFolderType,kCreateFolder,&tempVRefNum,&tempDirID);
  786. if (theErr != noErr)
  787. theErr = ::FindFolder(kOnSystemDisk,kTemporaryFolderType,kCreateFolder,&tempVRefNum,&tempDirID);
  788. if(!theErr)
  789. {
  790. // Build an FSSpec for the temp file in the Temporary Folder
  791. #ifdef _CARBON
  792. c2pstrcpy((StringPtr)tempFileName, (char*)tempFileName);
  793. #else
  794. ::c2pstr((char *)tempFileName);
  795. #endif
  796. theErr = ::FSMakeFSSpec(tempVRefNum,tempDirID,tempFileName,&tempSpec);
  797. }
  798. // Note: it is okay for FSMakeFSSpec to return fnfErr since the caller
  799. // is going to create the file.
  800. // Now create the full path name to the temp file
  801. if(!theErr || theErr == fnfErr)
  802. {
  803. theErr = noErr;
  804. CHXString theString;
  805. theErr = PathNameFromFSSpec(&tempSpec, theString);
  806. if(!theErr)
  807. ::strcpy(name,theString);
  808. }
  809. return TRUE;
  810. }