cmacfile_carbon.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:20k
源码类别:

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 <fcntl.h>
  36. #include "CMacFile.h"
  37. #include "MoreFilesX.h"
  38. #include "filespecutils.h"
  39. #include "hx_moreprocesses.h"
  40. #include "hxstrutl.h"
  41. OSType CMacFile::sCreator = 'PNst';
  42. OSType CMacFile::sFileType  = 'PNRA';
  43. BOOL gReadDone = FALSE;
  44. ULONG32 gReadCount = 0;
  45. // async callback proc
  46. pascal void ReadCallback(ParamBlockRec* pb);
  47. // async callback UPP
  48. static IOCompletionUPP gReadCallbackUPP=NewIOCompletionUPP(ReadCallback);
  49. CHXDataFile*
  50. CHXDataFile::Construct(UINT32 ulFlags, IUnknown** ppCommonObj)
  51. {
  52.     return (CHXDataFile *) new CMacFile;
  53. }
  54. // CHXFile should set the file reference to a value indicating the file is not open
  55. CMacFile::CMacFile (void)
  56. {
  57. mRefNum = 0;
  58. mLastError = noErr;
  59. mAppendMode = FALSE;
  60. mBufferFile = NULL;
  61. mBufferedRead = FALSE;
  62. mWriteFile = NULL;
  63. mBufferedWrite = FALSE;
  64. m_pseudoFileHandle = NULL; // if non-null, a memory manager handle containing the "file data"
  65. m_pseudoFileOffset = 0; // current "read" position in the pseudo file
  66. m_pseudoFileSize = 0; // total pseudo file size
  67. }
  68. // ~CHXFile should close the file if it is open
  69. CMacFile::~CMacFile(void)
  70. {
  71. Close(); // close file if necessary
  72. }
  73. // Create a file with the specified mode
  74. // Close the previous file if it was open
  75. HX_RESULT CMacFile::Create(const char *filename, UINT16 mode,BOOL textflag)
  76. {
  77. Close(); // close previous file if necessary
  78. CHXFileSpecifier fileSpec(filename);
  79. require_return(fileSpec.IsSet(), HXR_INVALID_PATH);
  80. BOOL bExistsAlready;
  81. OSErr err = noErr;
  82. // if the file already exists, it might be an alias file to somewhere else
  83. // (well, the pre-Carbon code checked for this; I'm not sure why we're resolving
  84. // an alias file if this path already exists)
  85. bExistsAlready = CHXFileSpecUtils::FileExists(fileSpec);
  86. if (bExistsAlready)
  87. {
  88. CHXFileSpecUtils::ResolveFileSpecifierAlias(fileSpec);
  89. bExistsAlready = CHXFileSpecUtils::FileExists(fileSpec);
  90. }
  91. // create the file if it doesn't already exist
  92. FSRef parentRef;
  93. HFSUniStr255 hfsName;
  94. FSRef openFileRef;
  95. parentRef = (FSRef) fileSpec.GetParentDirectory();
  96. hfsName = fileSpec.GetNameHFSUniStr255();
  97. if (!bExistsAlready)
  98. {
  99. FSCatalogInfo catInfo;
  100. FileInfo fInfo;
  101. FSSpec *kDontWantSpec = NULL;
  102. ZeroInit(&fInfo);
  103. fInfo.fileCreator = textflag ? 'ttxt' : sCreator;
  104. fInfo.fileType = textflag ? 'TEXT' : sFileType;
  105. (* (FileInfo *) &catInfo.finderInfo) = fInfo;
  106. err = FSCreateFileUnicode(&parentRef, hfsName.length,
  107. hfsName.unicode, kFSCatInfoFinderInfo, &catInfo,
  108. &openFileRef, kDontWantSpec);
  109. }
  110. else // already existed...
  111. {
  112. openFileRef = (FSRef) fileSpec;
  113. }
  114. // open the file (to mimic Windows' create semantics)
  115. if (err == noErr)
  116. {
  117. HFSUniStr255 dataForkName;
  118. dataForkName.length = 0;
  119. err = FSGetDataForkName(&dataForkName);
  120. check_noerr(err);
  121. err = FSOpenFork(&openFileRef, dataForkName.length, dataForkName.unicode,
  122. fsRdWrPerm, &mRefNum);
  123. }
  124. if (err == noErr)
  125. {
  126. mFile = openFileRef;
  127. err = FSSetForkSize(mRefNum, fsFromStart, 0);
  128. }
  129. mLastError = err;
  130. return (err != noErr ? -1 : 0);
  131. }
  132. // Open a file with the specified permissions
  133. // Close the previous file if it was open
  134. //
  135. // If the file isn't found, look for a 'RLFL' resource *in the current
  136. // resource chain* with the same name as the file.
  137. HX_RESULT CMacFile::Open(const char *filename, UINT16 mode,BOOL textflag)
  138. {
  139. Close(); // close previous file if necessary
  140. CHXFileSpecifier fileSpec(filename);
  141. if (!fileSpec.IsSet()) return HXR_INVALID_PATH; // fails if we're trying to open a file inside a non-existing directory
  142. short perm;
  143. // figure out mac file permission
  144. perm = fsRdPerm;
  145. if (mode & O_WRONLY)
  146. {
  147. perm = fsWrPerm;
  148. }
  149. else if (mode & O_RDONLY)
  150. {
  151. perm = fsRdPerm;
  152. }
  153.         else if (mode & O_RDWR)
  154.         {
  155.                 perm = fsRdWrPerm;
  156.         }
  157. // Store the permissions for this file for later.
  158. m_mode = mode;
  159. BOOL bExistsAlready;
  160. OSErr err = fnfErr;
  161. bExistsAlready = CHXFileSpecUtils::FileExists(fileSpec);
  162. if (bExistsAlready)
  163. {
  164. CHXFileSpecUtils::ResolveFileSpecifierAlias(fileSpec);
  165. bExistsAlready = CHXFileSpecUtils::FileExists(fileSpec);
  166. }
  167. if (!bExistsAlready && ((mode & O_CREAT) || (mode & O_WRONLY)))
  168. {
  169. return Create(filename, mode, textflag);
  170. }
  171. if (bExistsAlready)
  172. {
  173. HFSUniStr255 dataForkName;
  174. FSRef openFileRef;
  175. dataForkName.length = 0;
  176. err = FSGetDataForkName(&dataForkName);
  177. check_noerr(err);
  178. openFileRef = (FSRef) fileSpec;
  179. err = FSOpenFork(&openFileRef, dataForkName.length, dataForkName.unicode,
  180. perm, &mRefNum);
  181. if (err == noErr)
  182. {
  183. mFile = openFileRef;
  184. }
  185. }
  186. if ((err != noErr) && (mode & O_RDONLY))
  187. {
  188. Handle resHandle;
  189. SInt32 resSize;
  190. Str255 pascFileName;
  191. // We couldn't open the file, and the request was read-only
  192. //
  193. // See if there's a pseudo-file resource we can use
  194. //
  195. // We need a handle to the resource so we can read from it, but
  196. // we don't want the whole resource loaded into memory, so we
  197. // set ResLoad to false.
  198. SetResLoad(false);
  199. fileSpec.GetName().MakeStr255(pascFileName);
  200. resHandle = GetNamedResource(kRealFileResource, pascFileName); // 'RLFL'
  201. SetResLoad(true);
  202. if (resHandle)
  203. {
  204. // we have a handle to the resource; determine
  205. // its size and reset our "file pointer"
  206. resSize = GetResourceSizeOnDisk(resHandle);
  207. if (resSize > 0)
  208. {
  209. m_pseudoFileHandle = resHandle;
  210. m_pseudoFileSize = resSize;
  211. m_pseudoFileOffset = 0;
  212. err = noErr;
  213. mRefNum = -1; // signals that we're using a pseudo-file and no actual file is open
  214. }
  215. }
  216. }
  217. if (!m_pseudoFileHandle)
  218. {
  219. if((err == noErr) && (mode & O_CREAT))
  220. {
  221. err = ::SetEOF(mRefNum, 0L);
  222. }
  223. if(err == noErr)
  224. {
  225. mAppendMode = (mode & O_APPEND);
  226. if (mode & O_TRUNC) 
  227. {
  228. err = ::SetEOF(mRefNum, 0L);
  229. }
  230. }
  231. if (err != noErr && mRefNum != 0) 
  232. {
  233. Close();
  234. }
  235. }
  236. mLastError = err;
  237. return(err != noErr ? HXR_DOC_MISSING : 0);
  238. }
  239. // Close the previous file if it was open
  240. HX_RESULT CMacFile::Close(void)
  241. {
  242. OSErr err = noErr;
  243. if (m_pseudoFileHandle)
  244. {
  245. // "close" our pseudo file
  246. //
  247. // We don't need or want to dispose or release our pseudo-
  248. // file handle since it's not using up memory anyway, and
  249. // releasing it would hurt anyone else who happens to be
  250. // reading from it.  The handle will be released 
  251. // automatically when its owning resource file closes.
  252. m_pseudoFileHandle = 0;
  253. m_pseudoFileOffset = 0;
  254. m_pseudoFileSize = 0;
  255. err = noErr;
  256. mRefNum = 0;
  257. }
  258. else if (mRefNum) 
  259. {
  260. if (mBufferFile)
  261. delete mBufferFile;
  262. mBufferFile = NULL;
  263. }
  264. if (mWriteFile) 
  265. {
  266. delete mWriteFile;
  267. mWriteFile = NULL;
  268. }
  269. OSErr tempErr;
  270. FSVolumeRefNum vRefNum;
  271. tempErr = FSGetVRefNum(&mFile, &vRefNum);
  272. // close a real file
  273. err = ::FSCloseFork(mRefNum);
  274. mRefNum = 0;
  275. if (err == noErr && tempErr == noErr) 
  276. {
  277. tempErr = ::FlushVol(nil, vRefNum);
  278. }
  279. }
  280. mLastError = err;
  281. return(err != noErr ? -1 : 0);
  282. }
  283. HX_RESULT CMacFile::Delete (const char *filename)
  284. {
  285. HX_RESULT res;
  286. require_return(!m_pseudoFileHandle, HXR_INVALID_OPERATION);
  287. CHXFileSpecifier fileSpec(filename);
  288. res = CHXFileSpecUtils::RemoveFile(fileSpec);
  289. return SUCCEEDED(res) ? 0 : -1;
  290. }
  291. /* Returns the size of the file in bytes. */
  292. ULONG32 CMacFile::GetSize(void)
  293. {
  294. ULONG32 fileSize = 0;
  295. if (m_pseudoFileHandle)
  296. {
  297. fileSize = m_pseudoFileSize;
  298. }
  299. else if (mRefNum) 
  300. {
  301. OSErr err;
  302. SInt64 forkSize;
  303. err = FSGetForkSize(mRefNum, &forkSize);
  304. if (err == noErr)
  305. {
  306. fileSize = (ULONG32) forkSize;
  307. }
  308. }
  309. else
  310. {
  311. check(!"Cannot get file size because no file is open");
  312. }
  313. return fileSize;
  314.  }
  315. // Rewinds the file position to the start of the file
  316. HX_RESULT CMacFile::Rewind(void)
  317. {
  318. OSErr err;
  319. if (m_pseudoFileHandle)
  320. {
  321. m_pseudoFileOffset = 0;
  322. err = noErr;
  323. }
  324. else
  325. {
  326. err = ::FSSetForkPosition(mRefNum, fsFromStart, 0);
  327. }
  328. mLastError = err;
  329. return(err != noErr ? HXR_INVALID_FILE : HXR_OK);
  330. }
  331. // Seek moves the current file position to the offset from the fromWhere specifier
  332. HX_RESULT CMacFile::Seek(ULONG32 offset, UINT16 fromWhere)
  333. {
  334. OSErr err = noErr;
  335. if (m_pseudoFileHandle)
  336. {
  337. switch(fromWhere)
  338. {
  339. case SEEK_SET:
  340. m_pseudoFileOffset = offset;
  341. break;
  342. case SEEK_CUR:
  343. m_pseudoFileOffset += offset;
  344. break;
  345. case SEEK_END:
  346. m_pseudoFileOffset = (m_pseudoFileSize - 1) - offset;
  347. break;
  348. }
  349. // don't go beyond the end (we won't return eofErr either to match
  350. // the real seek below)
  351. if (m_pseudoFileOffset >= m_pseudoFileSize)
  352. {
  353. m_pseudoFileOffset = m_pseudoFileSize - 1;
  354. }
  355. err = HXR_OK;
  356. }
  357. else if (mBufferedWrite)
  358. {
  359. long pos = 0;
  360. switch(fromWhere)
  361. {
  362. case SEEK_SET:
  363. pos = offset;
  364. break;
  365. case SEEK_CUR:
  366. pos = mWriteFile->GetCurPos() + offset;
  367. break;
  368. case SEEK_END:
  369. pos = (mWriteFile->GetBufSize() - 1) - offset;
  370. break;
  371. }
  372. mWriteFile->Seek(pos);
  373. }
  374. else
  375. {
  376. switch(fromWhere)
  377. {
  378. case SEEK_SET:
  379. fromWhere = fsFromStart;
  380. break;
  381. case SEEK_CUR:
  382. fromWhere = fsFromMark;
  383. break;
  384. case SEEK_END:
  385. fromWhere = fsFromLEOF;
  386. break;
  387. }
  388. err =  ::SetFPos(mRefNum, fromWhere, offset);
  389. // returning eofErr was causing problems for ChunkyRes during http play
  390. if (err == eofErr)
  391. {
  392. err = ::SetEOF(mRefNum, offset);
  393. err = ::SetFPos(mRefNum, fromWhere, offset);
  394. err = HXR_OK;
  395. }
  396. long pos;
  397. ::GetFPos(mRefNum,(long *)&pos);
  398. if(!err && mBufferedRead)
  399. {
  400. long count; 
  401. ::GetEOF(mRefNum, &count);
  402. mBufferFile->PreLoad(pos,count - offset);
  403. }
  404. /* if(!theErr && mBufferedWrite)
  405. {
  406. mWriteFile->Seek(pos);
  407. } */
  408. }
  409. mLastError = err;
  410. return(err != noErr ? HXR_INVALID_FILE : 0);
  411. }
  412. // Tell 
  413. ULONG32 CMacFile::Tell(void)
  414. {
  415. ULONG32 pos;
  416. if (m_pseudoFileHandle)
  417. {
  418. pos = m_pseudoFileOffset;
  419. mLastError = noErr;
  420. }
  421. else
  422. {
  423. mLastError = ::GetFPos(mRefNum,(long *)&pos);
  424. }
  425. return(pos);
  426. }
  427. // callback could be at interrupt time
  428. pascal void ReadCallback(ParamBlockRec* pb)
  429. {
  430.     OSErr theErr = (*pb).ioParam.ioResult;      
  431.     gReadCount = pb->ioParam.ioActCount;
  432.     gReadDone = TRUE;
  433. }
  434. /*  Read reads up to count bytes of data into buf.
  435. returns the number of bytes read, EOF, or -1 if the read failed */
  436. ULONG32 CMacFile::Read (char *buf, ULONG32 count)
  437. {
  438. OSErr theErr = noErr;
  439. if (m_pseudoFileHandle)
  440. {
  441. INT32 actualCount;
  442. theErr = Read(buf, count, &actualCount);
  443. count = actualCount;
  444. }
  445. else
  446. {
  447. if(mBufferedRead)
  448. {
  449. count = Copy(buf,count);
  450. if(count == 0)
  451. theErr = eofErr;
  452. }
  453. else
  454. {
  455.         // can't do synchronous read at interrupt time
  456.         if (IsRunningNativeOnMacOSX() || IsMacInCooperativeThread())
  457.         {
  458. theErr = ::FSRead(mRefNum, (long *)&count, buf);
  459.     }
  460.     else
  461.     { // async i/o - callback could be at interrupt time
  462. #if 1
  463.      ParamBlockRec pb;
  464.      gReadCount = 0;
  465.      gReadDone = FALSE;
  466. pb.ioParam.ioRefNum = mRefNum;
  467. pb.ioParam.ioBuffer = buf;
  468. pb.ioParam.ioReqCount = count;
  469. pb.ioParam.ioPosMode=fsAtMark;
  470. pb.ioParam.ioCompletion = gReadCallbackUPP;
  471. theErr = PBReadAsync(&pb);
  472. UINT32 timeout = TickCount() + 60L;
  473. while (!gReadDone && timeout-TickCount() > 0)
  474. {
  475. }
  476. count = gReadCount;
  477. #endif
  478.     }
  479. }
  480. if (theErr == eofErr && count > 0)
  481. {
  482. theErr = noErr;
  483. }
  484. }
  485. mLastError = theErr;
  486. return(mLastError ? 0 : count); //smplfsys::read assumes we return 0 for eof
  487. }
  488. /*  Read reads up to count bytes of data into buf.
  489. returns the number of bytes read, EOF, or -1 if the read failed */
  490. INT16 CMacFile::Read (char *buf, INT32 count, INT32 *actualCount)
  491. {
  492. OSErr theErr = noErr;
  493. long readCount = (long) count;
  494. if (m_pseudoFileHandle)
  495. {
  496. // read from our pseudo-file
  497. SInt32 remainingBytes;
  498. remainingBytes = m_pseudoFileSize - m_pseudoFileOffset;
  499. if (remainingBytes <= 0)
  500. {
  501. // we've already exhausted the buffer
  502. theErr = eofErr;
  503. }
  504. else
  505. {
  506. // some bytes remain to be "read" so read them directly
  507. // from the resource into the caller's buffer
  508. if (remainingBytes < count)
  509. {
  510. count = remainingBytes;
  511. }
  512. ReadPartialResource(m_pseudoFileHandle, m_pseudoFileOffset, buf, count);
  513. theErr = ResError();
  514. HX_ASSERT(theErr == noErr);
  515. // while we don't expect any errors, -188 (resourceInMemory) isn't fatal
  516. if (theErr == noErr || theErr == resourceInMemory)
  517. {
  518. // update our pseudo-file pointer
  519. readCount = count;
  520. m_pseudoFileOffset += count;
  521. theErr = noErr;
  522. }
  523. }
  524. }
  525. else
  526. {
  527. if(mBufferedRead)
  528. {
  529. readCount = Copy(buf,readCount);
  530. if(readCount == 0)
  531. theErr = eofErr;
  532. }
  533. else
  534. {
  535.         if (IsRunningNativeOnMacOSX() || IsMacInCooperativeThread())
  536. theErr = ::FSRead(mRefNum, &readCount, buf);
  537.     else
  538.     { // async i/o - callback could be at interrupt time
  539. #if 0
  540.      ParamBlockRec pb;
  541. // IOCompletionUPP proc = NewIOCompletionProc(ReadCallback);
  542.      gReadCount = 0;
  543.      gReadDone = FALSE;
  544. pb.ioParam.ioRefNum = mRefNum;
  545. pb.ioParam.ioBuffer = buf;
  546. pb.ioParam.ioReqCount = count;
  547. pb.ioParam.ioPosMode=fsAtMark;
  548. pb.ioParam.ioCompletion = m_CompletionProc;
  549. theErr = PBReadAsync(&pb);
  550. EventRecord   theEvent;
  551. long sleepTime=10;
  552. long timeout = 0;
  553. // timeout, in case file read can't complete
  554. while (!gReadDone && timeout < 100)
  555. {
  556. ::WaitNextEvent(everyEvent, &theEvent, sleepTime, nil);
  557. timeout++;
  558. }
  559. count = gReadCount;
  560. #endif
  561.     }
  562. }
  563. }
  564. if(theErr == eofErr && readCount > 0)
  565. theErr = noErr;
  566. if (actualCount)
  567. {
  568. *actualCount = (INT32) readCount;
  569. }
  570. return(theErr);
  571. }
  572. /*  Write writes up to count bytes of data from buf.
  573. returns the number of bytes written, or -1 if the write failed */
  574. ULONG32 CMacFile::Write(const char *buf, ULONG32 count)
  575. {
  576. HX_ASSERT(!m_pseudoFileHandle);
  577.     OSErr theErr = noErr;
  578.     if (IsRunningNativeOnMacOSX() || IsMacInCooperativeThread())
  579.     {
  580. if(mAppendMode) 
  581. {
  582. theErr = ::SetFPos(mRefNum,fsFromLEOF,0L);
  583. }
  584. if(!theErr)
  585. {
  586. if(mBufferedWrite)
  587. {
  588. mWriteFile->write_data((Ptr)buf,(long)count);
  589. }
  590. else
  591. {
  592.   theErr = ::FSWrite(mRefNum, (long *)&count, buf);
  593. //check_noerr(theErr);  a disk full error may occur
  594. }
  595. }
  596. mLastError = theErr;
  597. // return(theErr ? -1 : count);
  598.     }
  599.     else
  600.     {
  601. if(mBufferedWrite)
  602. {
  603. mWriteFile->write_data((Ptr)buf,(long)count);
  604. }
  605. mLastError = theErr;
  606.     }
  607. return ((theErr == noErr) ? count : -1);
  608. }
  609. /*  Write writes up to count bytes of data from buf.
  610. returns the number of bytes written, or -1 if the write failed */
  611. INT16 CMacFile::Write(const char *buf, INT32 count, INT32 *actualCount)
  612. {
  613. HX_ASSERT(!m_pseudoFileHandle);
  614.     OSErr theErr = noErr;
  615.     *actualCount = 0;
  616.     if (IsRunningNativeOnMacOSX() || IsMacInCooperativeThread())
  617.     {
  618. long writeCount = 0;
  619. if(mAppendMode) 
  620. theErr = ::SetFPos(mRefNum, fsFromLEOF, 0L);
  621. if(!theErr) 
  622. {
  623. writeCount = count;
  624. theErr = ::FSWrite(mRefNum, &writeCount, buf);
  625. }
  626. *actualCount = (INT32) writeCount;
  627.     }
  628.     
  629. //check_noerr(theErr); a disk full error may occur
  630. // elsewhere the file code expects a negative actualCount when
  631. // the write failed
  632.     if (theErr != noErr) *actualCount = -1;
  633.     
  634.     return(theErr);
  635. }
  636. void CMacFile::SetFileType(OSType creator, OSType type)
  637. {
  638. sFileType = type;
  639. sCreator = creator;
  640. }
  641. long CMacFile::Copy(Ptr destBuf, long numBytes)
  642. {
  643. long count;
  644. // check for buffered i/o
  645. if(mBufferedRead)
  646. count = mBufferFile->Copy(destBuf,numBytes);
  647. else
  648. count = 0;
  649. return(count);
  650. }
  651. HX_RESULT CMacFile::set_buffered_read (char buffered)
  652. {
  653. Boolean OK = TRUE;
  654. HX_ASSERT(!m_pseudoFileHandle);
  655. // If this file is setup for writing then we don't want to do any buffered reading.
  656. if (m_mode & O_WRONLY) return HXR_OK;
  657. if (m_mode & O_RDWR) return HXR_OK;
  658. mBufferedRead = 0;
  659. return HXR_OK; //HACK! - this needs to be redone!
  660. // set up buffered read object if necessary
  661. if(buffered && !mBufferedRead)
  662. {
  663. if(mBufferFile == NULL) 
  664. {
  665. mBufferFile = new CBufferFile;
  666. OK = mBufferFile != NULL;
  667. }
  668. if(OK) 
  669. OK = mBufferFile->Specify(mRefNum);
  670. }
  671. else if(!buffered && mBufferedRead)
  672. {
  673. if(mBufferFile != NULL) 
  674. {
  675. delete mBufferFile;
  676. mBufferFile = NULL;
  677. }
  678. }
  679. mBufferedRead = buffered != 0;
  680. if(OK)
  681. Seek(0,SEEK_SET);
  682. return(OK ? HXR_OK : HXR_OUTOFMEMORY);
  683. }
  684. HX_RESULT CMacFile::set_buffered_write (char buffered)
  685. {
  686. Boolean OK = TRUE;
  687. HX_ASSERT(!m_pseudoFileHandle);
  688. // set up buffered read object if necessary
  689. if(buffered && !mBufferedWrite)
  690. {
  691. if(mWriteFile == NULL) 
  692. {
  693. mWriteFile = new CWriteFile;
  694. OK = mWriteFile != NULL;
  695. }
  696. if(OK) 
  697. {
  698. OK = mWriteFile->Specify(mRefNum,Tell());
  699. }
  700. }
  701. else if(!buffered && mBufferedWrite)
  702. {
  703. if(mWriteFile != NULL) 
  704. {
  705. delete mWriteFile;
  706. mWriteFile = NULL;
  707. }
  708. }
  709. mBufferedWrite = buffered != 0;
  710. return(OK ? HXR_OK : HXR_OUTOFMEMORY);
  711. }
  712. // This seems to exist solely so FileIO::status can get the size and an error value;
  713. // Otherwise, it's redundant with GetSize
  714. INT16 CMacFile::FileSize(long *size)
  715. {
  716. if (m_pseudoFileSize)
  717. {
  718. *size = m_pseudoFileSize;
  719. return 0;
  720. }
  721. return ::GetEOF(mRefNum, size);
  722. }
  723. BOOL CMacFile::GetTemporaryFileName(const char *tag, char* name, UINT32 ulBufLen)
  724. {
  725. // we'll make a temp name like tag_2345
  726. CHXString tempNameTemplate(tag);
  727. tempNameTemplate += "_%SUB%";
  728. CHXDirSpecifier tempDirSpec = CHXFileSpecUtils::GetSystemTempDirectory();
  729. CHXFileSpecifier tempFileSpec = CHXFileSpecUtils::GetUniqueTempFileSpec(
  730. tempDirSpec, (const char *) tempNameTemplate, "%SUB%");
  731. // copy the temp path to the supplied buffer, name
  732. name[0] = '';
  733. if (tempFileSpec.IsSet())
  734. {
  735. CHXString strPath = tempFileSpec.GetPathName();
  736. SafeStrCpy(name, (const char *) strPath, ulBufLen);
  737. return TRUE;
  738. }
  739. return FALSE;
  740. }