home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C++ / Applications / Quotes 1.0 / src / document.cp < prev    next >
Encoding:
Text File  |  1995-12-09  |  5.6 KB  |  199 lines  |  [TEXT/KAHL]

  1. #include "document.h"
  2. #include <Errors.h>
  3.  
  4. int QuotesDocument::available(void) const {
  5.     return (**hrsrcCookie).cFortune;
  6. }
  7.  
  8. unsigned char *QuotesDocument::text(void) const {
  9.     return pchFortune;
  10. }
  11.  
  12. OSErr QuotesDocument::draw(int sel) {
  13.     OSErr err;
  14.     long *pFortune = &(**hrsrcCookie).fortune[0];
  15.     if (sel < 0 || sel >= (**hrsrcCookie).cFortune) // fortunes are from 0 to cFortune-1, cFortune points to EOF
  16.         err = paramErr;
  17.     else {
  18.         long posCookie = pFortune[sel];
  19.         long size = pFortune[sel+1] - posCookie;
  20.         if (size > MAX_FORTUNE)
  21.             size = MAX_FORTUNE;
  22.         if (sel < (**hrsrcCookie).cFortune-1)
  23.             size -= 2; // remove the two consecutive cookie separators
  24.         if (pchFortune) {
  25.             SetPtrSize((Ptr)pchFortune, size+1);
  26.             err = MemError();
  27.             if (err != noErr) {
  28.                 DisposePtr((Ptr)pchFortune);
  29.                 pchFortune = (unsigned char *)NewPtr(size+1);
  30.             }
  31.         } else
  32.             pchFortune = (unsigned char *)NewPtr(size+1);
  33.         if (pchFortune == NULL)
  34.             err = notEnoughMemoryErr;
  35.         else {
  36.             err = SetFPos(selData, fsFromStart, posCookie);
  37.             if (err == noErr)
  38.                 err = FSRead(selData, &size, pchFortune); // read the fortune from the cookie
  39.                 pchFortune[size] = 0;
  40.         }
  41.     }
  42.     return err;
  43. }
  44.  
  45. QuotesDocument::QuotesDocument(FSSpec fs, OSErr &err) {
  46.     pchFortune = NULL;
  47.     selSave = SAVE_NO;
  48.     fsCookie = fs;
  49.     unsigned long sizeCurrent = current_size();
  50.     long response;
  51.     err = Gestalt(gestaltFSAttr, &response);
  52.     int fHasFSSpec;
  53.     if (err == noErr)
  54.         fHasFSSpec = response & (1<<gestaltHasFSSpecCalls);
  55.     else {
  56.         fHasFSSpec = 0;
  57.         err = noErr;
  58.     }
  59.     if (fHasFSSpec)
  60.         err = FSpOpenDF(&fsCookie, fsRdPerm, &selData);
  61.     else {
  62.         err = HOpenDF(fsCookie.vRefNum, fsCookie.parID, (ConstStr255Param)&fsCookie.name, fsRdPerm, &selData);
  63.         if (err == paramErr)
  64.             err = HOpen(fsCookie.vRefNum, fsCookie.parID, (ConstStr255Param)&fsCookie.name, fsRdPerm, &selData);
  65.     }
  66.     if (fHasFSSpec)
  67.         selResource = FSpOpenResFile(&fsCookie, fsRdWrPerm);
  68.     else
  69.         selResource = HOpenResFile(fsCookie.vRefNum, fsCookie.parID, (ConstStr255Param)&fsCookie.name, fsRdWrPerm);
  70.     err = ResError();
  71.     if (err == noErr) {
  72.         UseResFile(selResource);
  73.         hrsrcCookie = (CookieResource **)Get1Resource(TYPE_COOKIE, ID_COOKIE);
  74.     } else
  75.         hrsrcCookie = NULL;
  76.     if (hrsrcCookie == NULL) { // does the file need a cookie?
  77.         hrsrcCookie = (CookieResource **)NewHandle(MAX_FORTUNE); // create full size cookie resource
  78.         if (hrsrcCookie == NULL)
  79.             err = notEnoughMemoryErr;
  80.         else {
  81.             err = scan();
  82.             if (err == noErr || err == eofErr) {
  83.                 SetHandleSize((Handle)hrsrcCookie, resource_size() );
  84.                 if (err == noErr) {
  85.                     selSave = SAVE_NEW; // create a new cookie
  86.                     (**hrsrcCookie).size = sizeCurrent;
  87.                 }
  88.             }
  89.             err = MemError();
  90.         }
  91.     } else {
  92.         if (sizeCurrent == (**hrsrcCookie).size) {
  93.             DetachResource((Handle)hrsrcCookie);
  94.             err = noErr; // cookie is still valid
  95.         } else {
  96.             SetHandleSize((Handle)hrsrcCookie, MAX_FORTUNE); // resize to full size cookie resource
  97.             err = MemError();
  98.             if (err == noErr) {
  99.                 err = scan(); 
  100.                 if (err == noErr || err == eofErr) {
  101.                     SetHandleSize((Handle)hrsrcCookie, resource_size() );
  102.                     if (err == noErr) {
  103.                         selSave = SAVE_UPDATE; // update cookie
  104.                         (**hrsrcCookie).size = sizeCurrent;
  105.                     }
  106.                 }
  107.                 err = MemError();
  108.             } else
  109.                 err = notEnoughMemoryErr;
  110.         }
  111.     }
  112. }
  113.  
  114. // update cookie resource by scanning cookie data file, and set error in cookie
  115. OSErr QuotesDocument::scan(void) {
  116.     int iFortune = 0;
  117.     long cCh = 1;
  118.     long posCookie; // position within the data fork of the cookie file
  119.     int fCookieBreak = 0;
  120.     char ch;
  121.     OSErr errRead = SetFPos(selData, fsFromStart, 0);
  122.     HLock((char **)hrsrcCookie);
  123.     long *pFortune = &(**hrsrcCookie).fortune[0];
  124.     pFortune[iFortune++] = 0;
  125.     while (errRead == noErr && cCh == 1) {
  126.         errRead = FSRead(selData, &cCh, &ch); // read one character from the cookie data fork
  127.         if (errRead == eofErr)
  128.             break;
  129.         if (ch  == COOKIE_SEPARATOR)
  130.             if (fCookieBreak) {
  131.                 fCookieBreak = 0;
  132.                 errRead = GetFPos(selData, &posCookie);
  133.                 if (errRead == noErr)
  134.                     pFortune[iFortune++] = posCookie; // record current position
  135.                 if (iFortune == LAST_FORTUNE)
  136.                     errRead = eofErr; // limit cookie to LAST_FORTUNE number of fortunes
  137.             } else
  138.                 fCookieBreak = 1;
  139.         else
  140.             fCookieBreak = 0;
  141.     }
  142.     errRead = GetEOF(selData, &posCookie);
  143.     if (errRead == noErr)
  144.         pFortune[iFortune] = posCookie;
  145.     HUnlock((char **)hrsrcCookie);
  146.     (**hrsrcCookie).cFortune = iFortune;
  147.     return errRead;
  148. }
  149.  
  150. unsigned long QuotesDocument::resource_size(void) const {
  151.     return sizeof(CookieResource) + (**hrsrcCookie).cFortune*sizeof(long);
  152. }
  153.  
  154. Boolean QuotesDocument::save(void) const {
  155.     return (selSave != SAVE_NO);
  156. }
  157.  
  158. void QuotesDocument::discard(void) {
  159.     selSave = SAVE_NO;
  160. }
  161.  
  162. unsigned long QuotesDocument::current_size(void) const {
  163.     CInfoPBRec info;
  164.     info.hFileInfo.ioCompletion = NULL;
  165.     info.hFileInfo.ioFDirIndex = 0;
  166.     info.hFileInfo.ioNamePtr = fsCookie.name;
  167.     info.hFileInfo.ioVRefNum = fsCookie.vRefNum;
  168.     info.hFileInfo.ioDirID = fsCookie.parID;
  169.     PBGetCatInfo(&info, 0);
  170.     if (info.hFileInfo.ioResult == noErr)
  171.         return info.hFileInfo.ioFlLgLen;
  172.     else
  173.         return 0;
  174. }
  175.  
  176. QuotesDocument::~QuotesDocument() {
  177.     OSErr err;
  178.     switch (selSave) {
  179.         case SAVE_NO:
  180.             DisposeHandle((Handle)hrsrcCookie);
  181.             break;
  182.         case SAVE_UPDATE:
  183.             ChangedResource((Handle)hrsrcCookie);
  184.             err = ResError();
  185.             if (err == noErr)
  186.                 WriteResource((Handle)hrsrcCookie);
  187.             break;
  188.         case SAVE_NEW:
  189.             UseResFile(selResource);
  190.             AddResource((Handle)hrsrcCookie, TYPE_COOKIE, ID_COOKIE, NULL);
  191.             err = ResError();
  192.             if (err == noErr)
  193.                 WriteResource((Handle)hrsrcCookie);
  194.     }
  195.     if (selResource != -1)  // if selResource == -1, then hrsrcCookie is not a resource
  196.         CloseResFile(selResource);
  197.     FSClose(selData);
  198. }
  199.