home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Text⁄Files / MakeWrite / MakeWrite Folder / MWFileStuff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-16  |  6.7 KB  |  324 lines  |  [TEXT/KAHL]

  1. /*
  2.  * MWFileStuff.c - file routines of general usefulness.
  3.  */
  4.  
  5. # include    "TransSkel.h"
  6.  
  7. # include    "MWFileStuff.h"
  8. # include    "MakeWrite.h"
  9.  
  10.  
  11. /* ---------------------------------------------------------------- */
  12. /*                    Generic Error Message Routine                    */
  13. /* ---------------------------------------------------------------- */
  14.  
  15.  
  16. /*
  17.  * If errNo isn't noErr, then print a message.  The message is found
  18.  * in the 'STR ' resource of the same number as the file err.  If
  19.  * no resource is found with that number, use a default message.
  20.  */
  21.  
  22. void
  23. FileErr (OSErr errNo)
  24. {
  25. StringHandle    h;
  26. Str255            numStr;
  27. Str255            meaning;
  28.  
  29.     if (errNo == noErr)
  30.         return;
  31.  
  32.     CopyString ("\pNo error message available", meaning);    /* default */
  33.  
  34.     h = GetString (errNo);
  35.     if (h != nil && HomeResFile ((Handle) h) == CurResFile ())
  36.     {
  37.         HLock ((Handle) h);
  38.         CopyString (*h, meaning);
  39.         HUnlock ((Handle) h);
  40.         ReleaseResource ((Handle) h);
  41.     }
  42.  
  43.     NumToString ((long) errNo, numStr);
  44.     Message ("\pI/O error ", numStr, "\p: ", meaning);
  45. }
  46.  
  47.  
  48. /* ---------------------------------------------------------------- */
  49. /*            Routines to get or open files for input or output        */
  50. /* ---------------------------------------------------------------- */
  51.  
  52.  
  53. static Point    dlogWhere = { 70, 100 };    /* Get/PutFile dlog location */
  54. static Str255    buttonTitle;                /* "Open" button title */
  55.  
  56.  
  57. /*
  58.  * GFFilter is a SFGetFile filter to set the name of the "Open"
  59.  * button.
  60.  */
  61.  
  62. static pascal short
  63. GFFilter (short theItem, DialogPtr theDialog)
  64. {
  65.     if (theItem == -1)    /* change "Open" button name */
  66.         SetCTitle (SkelGetDlogCtl (theDialog, 1), buttonTitle);
  67.     return (theItem);
  68. }
  69.  
  70.  
  71. /*
  72.  * Get a filename for input.
  73.  */
  74.  
  75. Boolean
  76. GetInputFile (StringPtr bTitle, OSType type, SFReply *inFile)
  77. {
  78.     CopyString (bTitle, buttonTitle);    /* set title for "Open" button */
  79.     SFPGetFile (dlogWhere, "\p", nil, 1, &type, GFFilter, inFile,
  80.                                     getDlgID, SkelDlogFilter (nil, true));
  81.     SkelRmveDlogFilter ();
  82.     SkelDoUpdates ();
  83.     return (inFile->good);
  84. }
  85.  
  86.  
  87. /*
  88.  * Open a filename for input.
  89.  */
  90.  
  91. Boolean
  92. OpenInputFile (SFReply *inFile, short *f)
  93. {
  94. OSErr    result;
  95.  
  96.     result = FSOpen (inFile->fName, inFile->vRefNum, f);
  97.     if (result != noErr)
  98.     {
  99.         FileErr (result);
  100.         Message3 ("\pCannot open \"", inFile->fName, "\p\".");
  101.     }
  102.     return (result == noErr);
  103. }
  104.  
  105.  
  106. /*
  107.  * Get a filename for output.
  108.  * Pass the current name and volume reference, and whether to
  109.  * ask for a name even if one is known.  Return the information
  110.  * in the SFReply record.
  111.  *
  112.  * Note: if ask is false and the name isn't "Untitled", the name
  113.  * passed is assumed to be the correct name to use and is returned.
  114.  * This may seem odd, but eliminates making the check every place
  115.  * from which this is called.
  116.  */
  117.  
  118. Boolean
  119. GetOutputFile (Boolean ask, StringPtr fName, short vRefNum, SFReply *outFile)
  120. {
  121.     CopyString (fName, outFile->fName);
  122.     outFile->vRefNum = vRefNum;
  123.     if (ask || CompareString ("\pUntitled", fName) == 0)
  124.     {
  125.         SFPPutFile (dlogWhere, "\pWrite to...", fName, nil, outFile,
  126.                                     putDlgID, SkelDlogFilter (nil, true));
  127.         SkelRmveDlogFilter ();
  128.         SkelDoUpdates ();
  129.         if (!outFile->good)
  130.             return (false);
  131.     }
  132.     return (true);
  133. }
  134.  
  135.  
  136. /*
  137.  * Open output file, creating if necessary.  Truncate contents as well.
  138.  */
  139.  
  140. Boolean
  141. OpenOutputFile (SFReply *outFile, OSType creator, OSType type, short *f)
  142. {
  143. FInfo    fndrInfo;
  144. OSErr    result;
  145.  
  146.     if (GetFInfo (outFile->fName, outFile->vRefNum, &fndrInfo) == noErr)
  147.     {
  148.         if (fndrInfo.fdCreator != creator || fndrInfo.fdType != type)
  149.         {
  150.             Message3 ("\p\"", outFile->fName, "\p\" is not a file of the proper type");
  151.             return (false);
  152.         }
  153.     }
  154.     else    /* Doesn't exist.  Try to create it. */
  155.     {
  156.         result = Create (outFile->fName, outFile->vRefNum, creator, type);
  157.         if (result != noErr)
  158.         {
  159.             FileErr (result);
  160.             Message3 ("\pCan't create \"", outFile->fName, "\p\"");
  161.             return (false);
  162.         }
  163.         else                /* new file now - set Finder info */
  164.         {
  165.             (void) GetFInfo (outFile->fName, outFile->vRefNum, &fndrInfo);
  166.             fndrInfo.fdFlags &= ~1;        /* clear init'ed bit */
  167.             fndrInfo.fdLocation.h = 0;
  168.             fndrInfo.fdLocation.v = 0;
  169.             fndrInfo.fdFldr = 0;
  170.             (void) SetFInfo (outFile->fName, outFile->vRefNum, &fndrInfo);
  171.         }
  172.     }
  173.  
  174.     result = FSOpen (outFile->fName, outFile->vRefNum, f);
  175.     if (result != noErr)
  176.     {
  177.         FileErr (result);
  178.         Message3 ("\pCan't write to \"", outFile->fName, "\p\".");
  179.     }
  180.     else
  181.         (void) SetEOF (*f, 0L);    /* clear contents */
  182.  
  183.     return (result == noErr);
  184. }
  185.  
  186.  
  187. /* ---------------------------------------------------------------- */
  188. /*                    Seek, Read, Write on open files                    */
  189. /* ---------------------------------------------------------------- */
  190.  
  191.  
  192. /*
  193.  * Seek to given position in file
  194.  */
  195.  
  196. void
  197. FileSeek (short f, long pos)
  198. {
  199.     (void) SetFPos (f, fsFromStart, pos);
  200. }
  201.  
  202.  
  203. /*
  204.  * Return current file position
  205.  */
  206.  
  207. long
  208. FilePos (short f)
  209. {
  210. long    pos;
  211.  
  212.     (void) GetFPos (f, &pos);
  213.     return (pos);
  214. }
  215.  
  216.  
  217. /*
  218.  * Read the given number of bytes from a file.  Return false
  219.  * if fail.  Note that false is returned if something is read, but
  220.  * not the full amount, thus the caller should know exactly how
  221.  * much to read when close to the end of the file.
  222.  */
  223.  
  224. Boolean
  225. FileRead (short f, Ptr p, long amount)
  226. {
  227. OSErr    result;
  228. long    read;
  229. Boolean    ok = false;
  230.  
  231.     read = amount;
  232.     if ((result = FSRead (f, &read, p)) != noErr && result != eofErr)
  233.         FileErr (result);
  234.     else
  235.         ok = (amount == read);
  236.     return (ok);
  237. }
  238.  
  239.  
  240. /*
  241.  * Write the given number of bytes from a file.  Return false
  242.  * if fail.
  243.  */
  244.  
  245. Boolean
  246. FileWrite (short f, Ptr p, long amount)
  247. OSErr    result;
  248. long    written;
  249. Boolean    ok = false;
  250.  
  251.     written = amount;
  252.     if ((result = FSWrite (f, &written, p)) != noErr)
  253.         FileErr (result);
  254.     else if (amount != written)
  255.         Message1 ("\pIncomplete write operation");
  256.     else
  257.         ok = true;
  258.     return (ok);
  259. }
  260.  
  261.  
  262. /* ---------------------------------------------------------------- */
  263. /*                        Read, Write on data types                    */
  264. /* ---------------------------------------------------------------- */
  265.  
  266.  
  267. Boolean
  268. ReadInteger (short f, short *val)
  269. {
  270.     return (FileRead (f, (Ptr) val, (long) sizeof (short)));
  271. }
  272.  
  273.  
  274. Boolean
  275. WriteInteger (short f, short val)
  276. {
  277.     return (FileWrite (f, (Ptr) &val, (long) sizeof (short)));
  278. }
  279.  
  280.  
  281. Boolean
  282. WriteLongint (short f, long val)
  283. {
  284.     return (FileWrite (f, (Ptr) &val, (long) sizeof (long)));
  285. }
  286.  
  287.  
  288. Boolean
  289. WriteString (short f, StringPtr s)
  290. {
  291.     return (FileWrite (f, (Ptr) s, (long) (s[0] + 1)));
  292. }
  293.  
  294.  
  295. Boolean
  296. ReadString (short f, StringPtr s)
  297. {
  298.     return (FileRead (f, (Ptr) s, 1L) && FileRead (f, (Ptr) (s + 1), (long) s[0]));
  299. }
  300.  
  301.  
  302. /*
  303.  * Write n zero bytes, and make sure the file position ends up on
  304.  * a word boundary (by writing an extra zero byte if necessary).
  305.  * ZeroPad (0) to just align the boundary.
  306.  * Return false if file error.
  307.  */
  308.  
  309. Boolean
  310. ZeroPad (short f, short n)
  311. {
  312. char    c = 0;
  313.  
  314.     if ((FilePos (f) + n) % 2 != 0)        /* write enough to align on boundary */
  315.         ++n;
  316.     while (n-- > 0)
  317.     {
  318.         if (!FileWrite (f, (Ptr) &c, 1L))
  319.             return (false);
  320.     }
  321.     return (true);
  322. }
  323.