/[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 2529 - (hide annotations) (download)
Tue Mar 4 20:41:47 2014 UTC (6 years ago) by schoenebeck
File size: 10534 byte(s)
* SFZ format: Added support for "#include" instruction (modified patch
  which was originally posted by Sergey on LS mailing list).
* Bumped version (1.0.0.svn34).

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

  ViewVC Help
Powered by ViewVC