cmacfile.cp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:23k
源码类别:

Symbian

开发平台:

Visual C++

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