51 int GetDriverParamInt(const char* const* parm, const char* name, int def) |
51 int GetDriverParamInt(const char* const* parm, const char* name, int def) |
52 { |
52 { |
53 const char* p = GetDriverParam(parm, name); |
53 const char* p = GetDriverParam(parm, name); |
54 return p != NULL ? atoi(p) : def; |
54 return p != NULL ? atoi(p) : def; |
55 } |
55 } |
|
56 |
|
57 /** |
|
58 * Find the requested driver and return its class. |
|
59 * @param name the driver to select. |
|
60 * @post Sets the driver so GetCurrentDriver() returns it too. |
|
61 */ |
|
62 const Driver *DriverFactoryBase::SelectDriver(const char *name, Driver::Type type) |
|
63 { |
|
64 if (GetDrivers().size() == 0) return NULL; |
|
65 |
|
66 if (*name == '\0') { |
|
67 /* Probe for this driver */ |
|
68 for (int priority = 10; priority >= 0; priority--) { |
|
69 Drivers::iterator it = GetDrivers().begin(); |
|
70 for (; it != GetDrivers().end(); ++it) { |
|
71 DriverFactoryBase *d = (*it).second; |
|
72 |
|
73 /* Check driver type */ |
|
74 if (d->type != type) continue; |
|
75 if (d->priority != priority) continue; |
|
76 |
|
77 Driver *newd = d->CreateInstance(); |
|
78 const char *err = newd->Start(NULL); |
|
79 if (err == NULL) { |
|
80 DEBUG(driver, 1, "Successfully probed %s driver '%s'", GetDriverTypeName(type), d->name); |
|
81 delete *GetActiveDriver(type); |
|
82 *GetActiveDriver(type) = newd; |
|
83 return newd; |
|
84 } |
|
85 |
|
86 DEBUG(driver, 1, "Probing %s driver '%s' failed with error: %s", GetDriverTypeName(type), d->name, err); |
|
87 delete newd; |
|
88 } |
|
89 } |
|
90 error("Couldn't find any suitable %s driver", GetDriverTypeName(type)); |
|
91 } else { |
|
92 char *parm; |
|
93 char buffer[256]; |
|
94 const char *parms[32]; |
|
95 |
|
96 /* Extract the driver name and put parameter list in parm */ |
|
97 strecpy(buffer, name, lastof(buffer)); |
|
98 parm = strchr(buffer, ':'); |
|
99 parms[0] = NULL; |
|
100 if (parm != NULL) { |
|
101 uint np = 0; |
|
102 /* Tokenize the parm. */ |
|
103 do { |
|
104 *parm++ = '\0'; |
|
105 if (np < lengthof(parms) - 1) parms[np++] = parm; |
|
106 while (*parm != '\0' && *parm != ',') parm++; |
|
107 } while (*parm == ','); |
|
108 parms[np] = NULL; |
|
109 } |
|
110 |
|
111 /* Find this driver */ |
|
112 Drivers::iterator it = GetDrivers().begin(); |
|
113 for (; it != GetDrivers().end(); ++it) { |
|
114 DriverFactoryBase *d = (*it).second; |
|
115 |
|
116 /* Check driver type */ |
|
117 if (d->type != type) continue; |
|
118 |
|
119 /* Check driver name */ |
|
120 if (strcasecmp(buffer, d->name) != 0) continue; |
|
121 |
|
122 /* Found our driver, let's try it */ |
|
123 Driver *newd = d->CreateInstance(); |
|
124 |
|
125 const char *err = newd->Start(parms); |
|
126 if (err != NULL) { |
|
127 delete newd; |
|
128 error("Unable to load driver '%s'. The error was: %s", d->name, err); |
|
129 } |
|
130 |
|
131 DEBUG(driver, 1, "Successfully loaded %s driver '%s'", GetDriverTypeName(type), d->name); |
|
132 delete *GetActiveDriver(type); |
|
133 *GetActiveDriver(type) = newd; |
|
134 return newd; |
|
135 } |
|
136 error("No such %s driver: %s\n", GetDriverTypeName(type), buffer); |
|
137 } |
|
138 } |
|
139 |
|
140 /** |
|
141 * Register a driver internally, based on its name. |
|
142 * @param name the name of the driver. |
|
143 * @note an assert() will be trigger if 2 driver with the same name try to register. |
|
144 */ |
|
145 void DriverFactoryBase::RegisterDriver(const char *name, Driver::Type type, int priority) |
|
146 { |
|
147 /* Don't register nameless Drivers */ |
|
148 if (name == NULL) return; |
|
149 |
|
150 this->name = strdup(name); |
|
151 this->type = type; |
|
152 this->priority = priority; |
|
153 |
|
154 /* Prefix the name with driver type to make it unique */ |
|
155 char buf[32]; |
|
156 strecpy(buf, GetDriverTypeName(type), lastof(buf)); |
|
157 strecpy(buf + 5, name, lastof(buf)); |
|
158 |
|
159 #if !defined(NDEBUG) || defined(WITH_ASSERT) |
|
160 /* NDEBUG disables asserts and gives a warning: unused variable 'P' */ |
|
161 std::pair<Drivers::iterator, bool> P = |
|
162 #endif /* !NDEBUG */ |
|
163 GetDrivers().insert(Drivers::value_type(buf, this)); |
|
164 assert(P.second); |
|
165 } |
|
166 |
|
167 /** |
|
168 * Build a human readable list of available drivers, grouped by type. |
|
169 */ |
|
170 char *DriverFactoryBase::GetDriversInfo(char *p, const char *last) |
|
171 { |
|
172 for (Driver::Type type = Driver::DT_BEGIN; type != Driver::DT_END; type++) { |
|
173 p += snprintf(p, last - p, "List of %s drivers:\n", GetDriverTypeName(type)); |
|
174 |
|
175 for (int priority = 10; priority >= 0; priority--) { |
|
176 Drivers::iterator it = GetDrivers().begin(); |
|
177 for (; it != GetDrivers().end(); it++) { |
|
178 DriverFactoryBase *d = (*it).second; |
|
179 if (d->type != type) continue; |
|
180 if (d->priority != priority) continue; |
|
181 p += snprintf(p, last - p, "%18s: %s\n", d->name, d->GetDescription()); |
|
182 } |
|
183 } |
|
184 |
|
185 p += snprintf(p, last - p, "\n"); |
|
186 } |
|
187 |
|
188 return p; |
|
189 } |