home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1994 June / NEBULA_SE.ISO / SourceCode / MiscKit / Source / MiscLogFile.m < prev    next >
Encoding:
Text File  |  1994-01-26  |  4.8 KB  |  211 lines

  1. //
  2. //    MiscLogFile.m -- a generic class to simplify keeping a log file
  3. //        Written by Don Yacktman (c) 1993 by Don Yacktman.
  4. //                Version 1.0.  All rights reserved.
  5. //
  6. //        This notice may not be removed from this source code.
  7. //
  8. //        This is a free object!  Contact the author for the latest version.
  9. //        Don Yacktman, 4279 N. Ivy Lane, Provo, UT, 84604
  10. //        e-mail:  Don_Yacktman@byu.edu
  11. //
  12. //    This object is included in the MiscKit by permission from the author
  13. //    and its use is governed by the MiscKit license, found in the file
  14. //    "LICENSE.rtf" in the MiscKit distribution.  Please refer to that file
  15. //    for a list of all applicable permissions and restrictions.
  16. //    
  17.  
  18. #import <misckit/misckit.h>
  19. #import <stdio.h>
  20.  
  21. @interface MiscLogFile(private)
  22.  
  23. - _newLine;    // forces the log to start without any history.
  24. - _printRepeats; // "Last line repeated x times."
  25.  
  26. @end
  27.  
  28. @implementation MiscLogFile
  29.  
  30. - init
  31. {
  32.     id ret = [super init];
  33.     fileOpen = NO; special = NO;
  34.     return ret;
  35. }
  36.  
  37. - fileName { return fileName; }
  38. - setFileName:aString
  39. {
  40.     if (fileOpen) [self closeFile];
  41.     [lockFile free];
  42.     lockFile = nil;
  43.     special = NO;
  44.     fileName = aString;
  45.     return self;
  46. }
  47.  
  48. - setLockFile:newLockFile
  49. {
  50.     [lockFile free];
  51.     lockFile = newLockFile;
  52.     return self;
  53. }
  54.  
  55. - (BOOL)addLineToLogFile:aString
  56. {
  57.     if (![self openFile]) return NO;
  58.     if (![self appendToLogFile:aString andFlush:NO]) return NO;
  59.     if (![self closeFile]) return NO;
  60.     return YES;
  61. }
  62.  
  63. - _newLine    // forces the log to start without any history.
  64. {
  65.     repeats = 0;
  66.     if (lastLine) {
  67.         [lastLine free]; lastLine = nil;
  68.     }
  69.     return self;
  70. }
  71.  
  72. - (BOOL)openFile
  73. {
  74.     if (special) return YES;    // stdin and stdout are open already
  75.     if (fileOpen) return YES;    // file is already open
  76.     if (lockFile) if (![lockFile lock]) return NO; // lock if needed
  77.     file = fopen([fileName stringValue], "a");    // do the open
  78.     if (!file) return NO;
  79.     fileOpen = YES;
  80.     [self _newLine];
  81.     return YES;
  82. }
  83.  
  84. - (BOOL)closeFile
  85. {
  86.     if (special) return YES;    // don't close stdin or stdout
  87.     if (!fileOpen) return NO;    // can't close an unopened file
  88.     [self _printRepeats];
  89.     fclose(file);
  90.     if (lockFile) if (![lockFile unlock]) return NO;    // unlock if needed
  91.     fileOpen = NO;
  92.     return YES;
  93. }
  94.  
  95. - _printRepeats
  96. {
  97.     if (repeats) {
  98.         fprintf(file, "Last line repeated %d time%s\n", repeats,
  99.                 ((repeats == 1) ? "." : "s."));
  100.     }
  101.     [self _newLine];
  102.     return self;
  103. }
  104.  
  105. - (BOOL)appendToLogFile:aString andFlush:(BOOL)flushFlag
  106. {
  107.     if (!fileOpen) return NO;
  108.     // if the file is open, then we should have the lock.
  109.     // however, the user can get around our mechanism if they want, so
  110.     // we'd best check anyway, just to be sure.
  111.     if (lockFile && !special) if (![lockFile haveLock]) return NO;
  112.     // flushing will force a write; not flushing allows us to "compress"
  113.     // log messages by printing only number of repeats.
  114.     if (lastLine && !flushFlag) { // have a previous line, see if it repeats...
  115.         if ([lastLine isEqual:aString]) { // same as before
  116.             repeats++;
  117.             return YES; // don't print; keep tallying
  118.     }    }
  119.     // if got here, the log line is different than last time.
  120.     [self _printRepeats];
  121.     fprintf(file, "%s", [aString stringValue]);
  122.     lastLine = [aString copy];
  123.     if (flushFlag) if (fflush(file) == EOF) return NO;
  124.     return YES;
  125. }
  126.  
  127. - usestdout
  128. {
  129.     [self setFileName:[[MiscString alloc] initString:"stdout"]];
  130.     special = YES;
  131.     fileOpen = YES;
  132.     file = stdout;
  133.     return self;
  134. }
  135.  
  136. - usestderr
  137. {
  138.     [self setFileName:[[MiscString alloc] initString:"stderr"]];
  139.     special = YES;
  140.     fileOpen = YES;
  141.     file = stderr;
  142.     return self;
  143. }
  144.  
  145. - (FILE *)file { if (fileOpen) return file; else return NULL; }
  146. - (BOOL)fileIsOpen { return fileOpen; }
  147. - (BOOL)special { return special; }
  148. - lockFile { return lockFile; }
  149.  
  150. - copy
  151. {    // copies do not have locks or open logs... only original can!
  152.     id myCopy = [[MiscLogFile alloc] init];
  153.     [myCopy setFileName:fileName];
  154.     [myCopy setLockFile:[lockFile copy]];
  155.     return myCopy;
  156. }
  157.  
  158. - read:(NXTypedStream *)stream
  159. {
  160.     [super read:stream];
  161.     fileName = NXReadObject(stream);
  162.     lockFile = NXReadObject(stream);
  163.     return self;
  164. }
  165.  
  166. - write:(NXTypedStream *)stream
  167. {
  168.     [super write:stream];
  169.     NXWriteObject(stream, fileName);
  170.     NXWriteObject(stream, lockFile);
  171.     return self;
  172. }
  173.  
  174. // NXTransport protocol implementation:
  175. - encodeUsing:(id <NXEncoding>)portal
  176. {
  177.     [portal encodeObjectBycopy:fileName];
  178.     [portal encodeObjectBycopy:lockFile];
  179.     return self;
  180. }
  181.  
  182. - decodeUsing:(id <NXDecoding>)portal
  183. {
  184.     fileName = [portal decodeObject];
  185.     lockFile = [portal decodeObject];
  186.     return self;
  187. }
  188.  
  189. - encodeRemotelyFor:(NXConnection *)connection
  190.     freeAfterEncoding:(BOOL *)flagp isBycopy:(BOOL)isByCopy
  191. {
  192.     if (isByCopy) {
  193.         *flagp = NO; // object will copy.
  194.         return self; //encode object (copy it)
  195.     }
  196.     *flagp = NO; // object will copy.
  197.     // super will encode the proxy otherwise
  198.     return [super encodeRemotelyFor:connection
  199.                 freeAfterEncoding:flagp isBycopy:isByCopy];
  200. }
  201.  
  202. - free
  203. {
  204.     if (fileOpen) [self closeFile];
  205.     [lockFile free];
  206.     [fileName free];
  207.     return [super free];
  208. }
  209.  
  210. @end
  211.