FaxDB.c++
上传用户:weiyuanprp
上传日期:2020-05-20
资源大小:1169k
文件大小:5k
源码类别:

传真(Fax)编程

开发平台:

C/C++

  1. /* $Id: FaxDB.c++,v 1.4 2007/10/23 17:45:14 faxguy Exp $ */
  2. /*
  3.  * Copyright (c) 1990-1996 Sam Leffler
  4.  * Copyright (c) 1991-1996 Silicon Graphics, Inc.
  5.  * HylaFAX is a trademark of Silicon Graphics
  6.  *
  7.  * Permission to use, copy, modify, distribute, and sell this software and 
  8.  * its documentation for any purpose is hereby granted without fee, provided
  9.  * that (i) the above copyright notices and this permission notice appear in
  10.  * all copies of the software and related documentation, and (ii) the names of
  11.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  12.  * publicity relating to the software without the specific, prior written
  13.  * permission of Sam Leffler and Silicon Graphics.
  14.  * 
  15.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  16.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  17.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  18.  * 
  19.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  20.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  21.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  22.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  23.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  24.  * OF THIS SOFTWARE.
  25.  */
  26. #include "FaxDB.h"
  27. #include "RE.h"
  28. FaxDBRecord::FaxDBRecord()
  29. {
  30.     parent = 0;
  31. }
  32. FaxDBRecord::FaxDBRecord(FaxDBRecord* other)
  33. {
  34.     if ((parent = other))
  35. parent->inc();
  36. }
  37. FaxDBRecord::~FaxDBRecord()
  38. {
  39.     if (parent)
  40. parent->dec();
  41. }
  42. const char* FaxDBRecord::className() const { return "FaxDBRecord"; }
  43. const fxStr FaxDBRecord::nullStr("");
  44. const fxStr&
  45. FaxDBRecord::find(const fxStr& key)
  46. {
  47.     const fxStr* s = 0;
  48.     FaxDBRecord* rec = this;
  49.     for (; rec && !(s = rec->dict.find(key)); rec = rec->parent)
  50. ;
  51.     return (s ? *s : nullStr);
  52. }
  53. void FaxDBRecord::set(const fxStr& key, const fxStr& value)
  54.     { dict[key] = value; }
  55. fxIMPLEMENT_StrKeyObjValueDictionary(FaxValueDict, fxStr)
  56. FaxDB::FaxDB(const fxStr& file) : filename(file)
  57. {
  58.     FILE* fd = fopen(file, "r");
  59.     if (fd) {
  60. lineno = 0;
  61. parseDatabase(fd, 0);
  62. fclose(fd);
  63.     }
  64. }
  65. FaxDB::~FaxDB()
  66. {
  67. }
  68. const char* FaxDB::className() const { return "FaxDB"; }
  69. fxStr FaxDB::nameKey("Name");
  70. fxStr FaxDB::numberKey("FAX-Number");
  71. fxStr FaxDB::companyKey("Company");
  72. fxStr FaxDB::locationKey("Location");
  73. fxStr FaxDB::phoneKey("Voice-Number");
  74. fxStr FaxDB::mailAddrKey("Mail-Address");
  75. FaxDBRecord*
  76. FaxDB::find(const fxStr& s, fxStr* name)
  77. {
  78.     fxStr canon(s);
  79.     canon.lowercase();
  80.     for (u_int l = 0; l < canon.length(); l = canon.next(l, "+?*[].\")) {
  81. canon.insert('\', l);
  82. l += 2;
  83.     }
  84.     RE pat(canon);
  85.     for (FaxInfoDictIter iter(dict); iter.notDone(); iter++) {
  86. fxStr t(iter.key());
  87. t.lowercase();
  88. if (pat.Find(t)) {
  89.     if (name)
  90. *name = iter.key();
  91.     return (iter.value());
  92. }
  93.     }
  94.     return (0);
  95. }
  96. FaxDBRecord* FaxDB::operator[](const fxStr& name) { return dict[name]; }
  97. const fxStr& FaxDB::getFilename() { return filename; }
  98. FaxInfoDict& FaxDB::getDict() { return dict; }
  99. void FaxDB::add(const fxStr& key, FaxDBRecord* r) { dict[key] = r; }
  100. void
  101. FaxDB::parseDatabase(FILE* fd, FaxDBRecord* parent)
  102. {
  103.     FaxDBRecordPtr rec(new FaxDBRecord(parent));
  104.     fxStr key;
  105.     while (getToken(fd, key)) {
  106. if (key == "]") {
  107.     if (parent == 0)
  108. fprintf(stderr, "%s: line %d: Unmatched "]".n",
  109.     (const char*) filename, lineno);
  110.     break;
  111. }
  112. if (key == "[") {
  113.     parseDatabase(fd, rec);     // recurse to form hierarchy
  114.     continue;
  115. }
  116. fxStr value;
  117. if (!getToken(fd, value))
  118.     break;
  119. if (value != ":") {
  120.     fprintf(stderr, "%s: line %d: Missing ":" separator.n",
  121. (const char*) filename, lineno);
  122.     continue;
  123. }
  124. if (!getToken(fd, value))
  125.     break;
  126. rec->set(key, value);
  127. if (key == nameKey) // XXX what about duplicates?
  128.     add(value, rec);
  129.     }
  130. }
  131. #include "StackBuffer.h"
  132. #include <ctype.h>
  133. bool
  134. FaxDB::getToken(FILE* fd, fxStr& token)
  135. {
  136.     int c;
  137. top:
  138.     if ((c = getc(fd)) == EOF)
  139. return (false);
  140.     while (isspace(c)) {
  141. if (c == 'n')
  142.     lineno++;
  143. c = getc(fd);
  144.     }
  145.     if (c == '#') {
  146. while ((c = getc(fd)) != EOF && c != 'n')
  147.     ;
  148. if (c == EOF)
  149.     return (false);
  150. lineno++;
  151. goto top;
  152.     }
  153.     if (c == '[' || c == ']' || c == ':') {
  154. char buf[2];
  155. buf[0] = c;
  156. buf[1] = '';
  157. token = buf;
  158. return (true);
  159.     }
  160.     fxStackBuffer buf;
  161.     if (c == '"') {
  162. while ((c = getc(fd)) != EOF) {
  163.     if (c == '\') {
  164. c = getc(fd);
  165. if (c == EOF) {
  166.     fprintf(stderr, "%s: Premature EOF.n", (const char*) filename);
  167.     return (false);
  168. }
  169. // XXX handle standard escapes
  170. if (c == 'n')
  171.     lineno++;
  172.     } else {
  173. if (c == '"')
  174.     break;
  175. if (c == 'n')
  176.     lineno++;
  177.     }
  178.     buf.put(c);
  179. }
  180.     } else {
  181. do
  182.     buf.put(c);
  183. while ((c = getc(fd)) != EOF && !isspace(c) &&
  184.   c != ':' && c != ']' && c != '[' && c != '#');
  185. if (c != EOF)
  186.     ungetc(c, fd);
  187.     }
  188.     buf.set('');
  189.     token = (const char*) buf;
  190.     return (true);
  191. }
  192. #ifdef notdef
  193. void
  194. FaxDB::write()
  195. {
  196.     fxStr temp(filename | "#");
  197.     FILE* fp = fopen(temp, "w");
  198.     if (fp) {
  199. write(fp);
  200. fclose(fp);
  201. ::rename(temp, filename);
  202.     }
  203. }
  204. void
  205. FaxDB::write(FILE* fp)
  206. {
  207.     for (FaxInfoDictIter iter(dict); iter.notDone(); iter++) {
  208. fprintf(fp, "[ Name: "%s"n", (char*) iter.key());
  209. FaxDBRecord* r = iter.value();
  210. const fxStr& 
  211. fprintf(fp, "]n");
  212.     }
  213. }
  214. #endif
  215. fxIMPLEMENT_StrKeyPtrValueDictionary(FaxInfoDict, FaxDBRecord*)