/[svn]/linuxsampler/trunk/src/common/Path.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/common/Path.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1943 - (hide annotations) (download)
Tue Jul 14 18:25:11 2009 UTC (14 years, 9 months ago) by persson
File size: 9572 byte(s)
* fixed instrument database recursive import, which was broken on
  Windows

1 schoenebeck 1332 /***************************************************************************
2     * *
3     * Copyright (C) 2007 Christian Schoenebeck *
4     * *
5     * This library 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 library 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 library; if not, write to the Free Software *
17     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
18     * MA 02111-1307 USA *
19     ***************************************************************************/
20    
21     #include "Path.h"
22    
23 schoenebeck 1399 // for function hexsToNumber()
24 schoenebeck 1424 #include "global_private.h"
25 schoenebeck 1399
26 schoenebeck 1471 #include <sstream>
27    
28 schoenebeck 1332 namespace LinuxSampler {
29    
30 schoenebeck 1471 Path::Path() : drive(0) {
31     }
32    
33 schoenebeck 1332 void Path::appendNode(std::string Name) {
34     if (!Name.size()) return;
35     elements.push_back(Name);
36     }
37    
38 schoenebeck 1471 void Path::setDrive(const char& Drive) {
39     drive = Drive;
40     }
41    
42     std::string Path::toPosix() const {
43 schoenebeck 1332 // POSIX paths consist of forward slash separators and requires forward
44     // slashes in path and file names to be encoded as "%2f", the file names
45     // "." and ".." have special meanings
46     // (see http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_169
47     // and http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_266 )
48     std::string result;
49     for (int iElement = 0; iElement < elements.size(); iElement++) {
50 schoenebeck 1338 // encode percent characters
51 schoenebeck 1332 std::string e = elements[iElement];
52     for (
53 schoenebeck 1338 int pos = e.find("%"); pos != std::string::npos;
54     pos = e.find("%", pos+2)
55     ) e.replace(pos/*offset*/, 1/*length*/, "%%"/*by*/);
56     // encode forward slashes
57     for (
58 schoenebeck 1332 int pos = e.find("/"); pos != std::string::npos;
59 schoenebeck 1338 pos = e.find("/", pos+3)
60 schoenebeck 1332 ) e.replace(pos/*offset*/, 1/*length*/, "%2f"/*by*/);
61     // append encoded node to full encoded path
62     result += "/" + e;
63     }
64     if (!result.size()) result = "/";
65     return result;
66     }
67    
68 schoenebeck 1471 std::string Path::toDbPath() const {
69 iliev 1345 std::string result;
70     for (int iElement = 0; iElement < elements.size(); iElement++) {
71     // replace all slashes with '\0'
72     std::string e = elements[iElement];
73     for (int i = 0; i < e.length(); i++) {
74     if (e.at(i) == '/') e.at(i) = '\0';
75     }
76     // append encoded node to full encoded path
77     result += "/" + e;
78     }
79     if (!result.size()) result = "/";
80     return result;
81     }
82    
83 schoenebeck 1471 std::string Path::toLscp() const {
84 schoenebeck 1399 std::string result;
85 senoner 1537 #if WIN32
86     if(drive) {
87     result.assign(&drive,1);
88     result += ":";
89     }
90     #endif
91 schoenebeck 1399 for (int iElement = 0; iElement < elements.size(); iElement++) {
92     // replace "special characters" by LSCP escape sequences
93     std::string e = elements[iElement];
94     for (int i = 0; i < e.length(); i++) {
95     const char c = e.c_str()[i];
96     if (
97     !(c >= '0' && c <= '9') &&
98     !(c >= 'a' && c <= 'z') &&
99     !(c >= 'A' && c <= 'Z') &&
100     !(c == '!') && !(c == '#') && !(c == '$') && !(c == '%') &&
101     !(c == '&') && !(c == '(') && !(c == ')') && !(c == '*') &&
102     !(c == '+') && !(c == ',') && !(c == '-') && !(c == '.') &&
103     !(c == ':') && !(c == ';') && !(c == '<') && !(c == '=') &&
104     !(c == '>') && !(c == '?') && !(c == '@') && !(c == '[') &&
105     !(c == ']') && !(c == '^') && !(c == '_') && !(c == '`') &&
106     !(c == '{') && !(c == '|') && !(c == '}') && !(c == '~')
107     ) {
108     // convert the "special" character into a "\xHH" LSCP escape sequence
109     char buf[5];
110     snprintf(buf, sizeof(buf), "\\x%02x", static_cast<unsigned char>(c));
111     e.replace(i, 1, buf);
112     i += 3;
113     }
114     }
115     // append encoded node to full encoded path
116     result += "/" + e;
117     }
118     if (!result.size()) result = "/";
119     return result;
120     }
121    
122 schoenebeck 1471 std::string Path::toWindows() const {
123     std::stringstream result;
124 senoner 1481 const char cDrive =
125     ((drive >= 'A' && drive <= 'Z') || (drive >= 'a' && drive <= 'z'))
126 schoenebeck 1471 ? drive : '?';
127 senoner 1481 result << cDrive;
128 schoenebeck 1471 result << ':';
129     for (int iElement = 0; iElement < elements.size(); iElement++) {
130     // append encoded node to full encoded path
131     result << "\\" << elements[iElement];
132     }
133 persson 1943 if (elements.empty()) result << '\\';
134 schoenebeck 1471 return result.str();
135     }
136    
137 schoenebeck 1332 Path Path::operator+(const Path& p) {
138     Path result = *this;
139     for (int i = 0; i < p.elements.size(); i++)
140     result.elements.push_back(p.elements[i]);
141     return result;
142     }
143    
144     Path Path::operator+(const Path* p) {
145     return *this + *p;
146     }
147    
148 schoenebeck 1399 Path Path::fromPosix(std::string path) {
149     Path result;
150     // first split the nodes
151     {
152     int nodeEnd;
153     for (
154     int nodeBegin = path.find_first_not_of('/');
155     nodeBegin != std::string::npos;
156     nodeBegin = path.find_first_not_of('/', nodeEnd)
157     ) {
158     nodeEnd = path.find_first_of('/', nodeBegin);
159     result.appendNode(
160     (nodeEnd != std::string::npos) ?
161     path.substr(nodeBegin, nodeEnd - nodeBegin) :
162     path.substr(nodeBegin)
163     );
164     }
165     }
166     // resolve POSIX escape sequences in all nodes
167     for (int iNode = 0; iNode < result.elements.size(); iNode++) {
168     std::string& s = result.elements[iNode];
169     for (int pos = s.find('%'); pos < s.length(); pos = s.find('%', ++pos)) {
170     if (pos+1 >= s.length()) { // unexpected character
171     //TODO: we might want to throw an exception here, for now we simply replace the character by '?'
172     s.replace(pos, 1, "?");
173     continue;
174     }
175     if (s.c_str()[pos+1] == '%') {
176     s.replace(pos, 2, "%");
177     continue;
178     }
179     if (pos+2 >= s.length()) {
180     //TODO: we might want to throw an exception here, for now we simply replace the character by '?'
181     s.replace(pos, 2, "?");
182     continue;
183     }
184     // expecting a "%HH" sequence here, convert it into the respective character
185     const std::string sHex = s.substr(pos+1, 2);
186     char cAscii = hexsToNumber(sHex.c_str()[1], sHex.c_str()[0]);
187     char pcAscii[] = { cAscii, 0 };
188     s.replace(pos, 3, pcAscii);
189     }
190     }
191     return result;
192     }
193    
194 iliev 1403 Path Path::fromDbPath(std::string path) {
195     Path result;
196     // first split the nodes
197     {
198     int nodeEnd;
199     for (
200     int nodeBegin = path.find_first_not_of('/');
201     nodeBegin != std::string::npos;
202     nodeBegin = path.find_first_not_of('/', nodeEnd)
203     ) {
204     nodeEnd = path.find_first_of('/', nodeBegin);
205    
206     std::string s = (nodeEnd != std::string::npos) ?
207     path.substr(nodeBegin, nodeEnd - nodeBegin) :
208     path.substr(nodeBegin);
209    
210     for (int i = 0; i < s.length(); i++) if (s.at(i) == '\0') s.at(i) = '/';
211     result.appendNode(s);
212     }
213     }
214     return result;
215     }
216    
217 senoner 1481 Path Path::fromWindows(std::string path) {
218 schoenebeck 1471 Path result;
219    
220     int nodeEnd = 0;
221    
222     // first retrieve drive
223     if (path.size() >= 2 && path.c_str()[1] == ':') {
224     result.setDrive(path.c_str()[0]);
225     nodeEnd = 2;
226     }
227    
228     // split the nodes
229     {
230     for (
231     int nodeBegin = path.find_first_not_of('\\', nodeEnd);
232     nodeBegin != std::string::npos;
233     nodeBegin = path.find_first_not_of('\\', nodeEnd)
234     ) {
235     nodeEnd = path.find_first_of('\\', nodeBegin);
236     result.appendNode(
237     (nodeEnd != std::string::npos) ?
238     path.substr(nodeBegin, nodeEnd - nodeBegin) :
239     path.substr(nodeBegin)
240     );
241     }
242     }
243    
244     return result;
245     }
246    
247 iliev 1782 std::string Path::getName(std::string path) {
248     Path p;
249     #if WIN32
250     p.fromWindows(path);
251     #else
252     p.fromPosix(path);
253     #endif
254    
255     return p.getName();
256     }
257    
258     std::string Path::getName() {
259     if(elements.empty()) return "";
260     return elements[elements.size() - 1];
261     }
262    
263     std::string Path::getBaseName(std::string path) {
264     Path p;
265     #if WIN32
266     p = fromWindows(path);
267     #else
268     p = fromPosix(path);
269     #endif
270    
271     return p.getBaseName();
272     }
273    
274     std::string Path::getBaseName() {
275     std::string name = getName();
276     size_t lastdot = name.find_last_of('.');
277     if(lastdot == std::string::npos) return name;
278     return name.substr(0, lastdot);
279     }
280    
281 schoenebeck 1332 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC