Settings.cc
上传用户:weiliju62
上传日期:2007-01-06
资源大小:619k
文件大小:6k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /*  cdrdao - write audio CD-Rs in disc-at-once mode
  2.  *
  3.  *  Copyright (C) 1998, 1999 Andreas Mueller <mueller@daneb.ping.de>
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19. /*
  20.  * $Log$
  21.  */
  22. static char rcsid[] = "$Id$";
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <ctype.h>
  26. #include <unistd.h>
  27. #include <errno.h>
  28. #include <string.h>
  29. #include <assert.h>
  30. #include "Settings.h"
  31. #include "CdDevice.h"
  32. #include "util.h"
  33. enum SettingType { SET_INTEGER, SET_STRING };
  34. const char *SET_CDRDAO_PATH = "cdrdaoPath";
  35. const char *SET_RECORD_EJECT_WARNING = "recordEjectWarning";
  36. const char *SET_RECORD_RELOAD_WARNING = "recordReloadWarning";
  37. #define SET_CDDEVICE "cdDevice"
  38. #define SET_CDDEVICE_LEN 8
  39. class SettingEntry {
  40. public:
  41.   SettingEntry(const char *, int);
  42.   SettingEntry(const char *, const char *);
  43.   ~SettingEntry();
  44.   SettingType type_;
  45.   char *name_;
  46.   union {
  47.     int integerValue_;
  48.     char *stringValue_;
  49.   } val_;
  50.   SettingEntry *next_;
  51. };
  52. class SettingsImpl {
  53. public:
  54.   SettingsImpl();
  55.   ~SettingsImpl();
  56.   void addSetting(SettingEntry *);
  57.   SettingEntry *findSetting(const char *, SettingType);
  58.   void set(const char *, int);
  59.   void set(const char *, const char *);
  60.   int read(FILE *);
  61.   
  62.   void parseAndSetValue(char *name, char *valStr);
  63.   SettingEntry *settings_;
  64. };
  65. SettingEntry::SettingEntry(const char *name, int val)
  66. {
  67.   type_ = SET_INTEGER;
  68.   name_ = strdupCC(name);
  69.   val_.integerValue_ = val;
  70. }
  71. SettingEntry::SettingEntry(const char *name, const char *val)
  72. {
  73.   type_ = SET_STRING;
  74.   name_ = strdupCC(name);
  75.   val_.stringValue_ = strdupCC(val);
  76. }
  77. SettingEntry::~SettingEntry()
  78. {
  79.   delete[] name_;
  80.   name_ = NULL;
  81.   if (type_ == SET_STRING) {
  82.     delete[] val_.stringValue_;
  83.     val_.stringValue_ = NULL;
  84.   }
  85. }
  86. SettingsImpl::SettingsImpl()
  87. {
  88.   settings_ = NULL;
  89. }
  90. SettingsImpl::~SettingsImpl()
  91. {
  92.   SettingEntry *next;
  93.   while (settings_ != NULL) {
  94.     next = settings_->next_;
  95.     delete settings_;
  96.     settings_ = next;
  97.   }
  98. }
  99. void SettingsImpl::addSetting(SettingEntry *s)
  100. {
  101.   s->next_ = settings_;
  102.   settings_ = s;
  103. }
  104. SettingEntry *SettingsImpl::findSetting(const char *name, SettingType type)
  105. {
  106.   SettingEntry *run;
  107.   for (run = settings_; run != NULL; run = run->next_) {
  108.     if (run->type_ == type && strcasecmp(run->name_, name) == 0)
  109.       return run;
  110.   }
  111.   return NULL;
  112. }
  113. void SettingsImpl::set(const char *name, int val)
  114. {
  115.   SettingEntry *s = findSetting(name, SET_INTEGER);
  116.   if (s == NULL) {
  117.     addSetting(new SettingEntry(name, val));
  118.   }
  119.   else {
  120.     s->val_.integerValue_ = val;
  121.   }
  122. }
  123. void SettingsImpl::set(const char *name, const char *val)
  124. {
  125.   SettingEntry *s = findSetting(name, SET_STRING);
  126.   if (s == NULL) {
  127.     addSetting(new SettingEntry(name, val));
  128.   }
  129.   else {
  130.     delete[] s->val_.stringValue_;
  131.     s->val_.stringValue_ = strdupCC(val);
  132.   }
  133. }
  134. #define MAX_LINE_LENGTH 1024
  135. int SettingsImpl::read(FILE *fp)
  136. {
  137.   char buf[MAX_LINE_LENGTH];
  138.   char *p, *p1;
  139.   char *name;
  140.   while (fgets(buf, MAX_LINE_LENGTH, fp) != NULL) {
  141.     // handle comment
  142.     if ((p = strchr(buf, '#')) != NULL)
  143.       *p = 0;
  144.     if ((p = strchr(buf, ':')) != NULL) {
  145.       *p++ = 0;
  146.       p1 = buf;
  147.       while (*p1 != 0 && isspace(*p1))
  148. p1++;
  149.       name = p1;
  150.       while (*p1 != 0 && !isspace(*p1))
  151. p1++;
  152.       *p1 = 0;
  153.       while (*p != 0 && isspace(*p))
  154. p++;
  155.       parseAndSetValue(name, p);
  156.     }
  157.   }
  158.   return 0;
  159. }
  160. void SettingsImpl::parseAndSetValue(char *name, char *valStr)
  161. {
  162.   char *p;
  163.   char *val;
  164.   int intValue;
  165.   CdDevice *dev;
  166.   if (name == NULL || *name == 0 || valStr == NULL || *valStr == 0)
  167.     return;
  168.   if (*valStr == '"') {
  169.     val = p = valStr + 1;
  170.     while (*p != 0 && *p != '"')
  171.       p++;
  172.     if (*p == '"') {
  173.       *p = 0;
  174.       if (strncasecmp(name, SET_CDDEVICE, SET_CDDEVICE_LEN) == 0) {
  175. if ((dev = CdDevice::add(val)) != NULL)
  176.   dev->manuallyConfigured(1);
  177.       }
  178.       else {
  179. set(name, val);
  180.       }
  181.     }
  182.   }
  183.   else {
  184.     intValue = strtol(valStr, NULL, 0);
  185.     set(name, intValue);
  186.   }
  187. }
  188. Settings::Settings()
  189. {
  190.   impl_ = new SettingsImpl;
  191.   set(SET_CDRDAO_PATH, "cdrdao");
  192.   set(SET_RECORD_EJECT_WARNING, 1);
  193.   set(SET_RECORD_RELOAD_WARNING, 1);
  194. }
  195. Settings::~Settings()
  196. {
  197.   delete impl_;
  198.   impl_ = NULL;
  199. }
  200. int Settings::read(const char *fname)
  201. {
  202.   FILE *fp;
  203.   if ((fp = fopen(fname, "r")) == NULL)
  204.     return 1;
  205.   impl_->read(fp);
  206.   fclose(fp);
  207.   return 0;
  208. }
  209. int Settings::write(const char *fname) const
  210. {
  211.   int i;
  212.   char *s;
  213.   const CdDevice *drun;
  214.   SettingEntry *run;
  215.   FILE *fp;
  216.   
  217.   if ((fp = fopen(fname, "w")) == NULL) {
  218.     message(-2, "Cannot open "%s" for writing: %s", fname, strerror(errno));
  219.     return 1;
  220.   }
  221.   for (run = impl_->settings_; run != NULL; run = run->next_) {
  222.     switch (run->type_) {
  223.     case SET_INTEGER:
  224.       fprintf(fp, "%s: %dn", run->name_, run->val_.integerValue_);
  225.       break;
  226.     case SET_STRING:
  227.       fprintf(fp, "%s: "%s"n", run->name_, run->val_.stringValue_);
  228.       break;
  229.     }
  230.   }
  231.   for (drun = CdDevice::first(), i = 0; drun != NULL;
  232.        drun = CdDevice::next(drun)) {
  233.     if (drun->manuallyConfigured()) {
  234.       s = drun->settingString();
  235.       fprintf(fp, "%s%d: "%s"n", SET_CDDEVICE, i, s);
  236.       delete[] s;
  237.       i++;
  238.     }
  239.   }
  240.   fclose(fp);
  241.   return 0;
  242. }
  243. int Settings::getInteger(const char *name) const
  244. {
  245.   SettingEntry *s = impl_->findSetting(name, SET_INTEGER);
  246.   if (s != NULL)
  247.     return s->val_.integerValue_;
  248.   else
  249.     return 0;
  250. }
  251.   
  252. const char *Settings::getString(const char *name) const
  253. {
  254.   SettingEntry *s = impl_->findSetting(name, SET_STRING);
  255.   if (s != NULL)
  256.     return s->val_.stringValue_;
  257.   else
  258.     return NULL;
  259. }
  260. void Settings::set(const char *name, int val)
  261. {
  262.   impl_->set(name, val);
  263. }
  264. void Settings::set(const char *name, const char *val)
  265. {
  266.   impl_->set(name, val);
  267. }