/[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 1403 - (hide annotations) (download)
Fri Oct 12 09:12:22 2007 UTC (16 years, 6 months ago) by iliev
File size: 7422 byte(s)
* _escapeLscpResponse now escapes backslashes
* implemented new method Path::fromDbPath

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     #include "global.h"
25    
26 schoenebeck 1332 namespace LinuxSampler {
27    
28     void Path::appendNode(std::string Name) {
29     if (!Name.size()) return;
30     elements.push_back(Name);
31     }
32    
33     std::string Path::toPosix() {
34     // POSIX paths consist of forward slash separators and requires forward
35     // slashes in path and file names to be encoded as "%2f", the file names
36     // "." and ".." have special meanings
37     // (see http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_169
38     // and http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_266 )
39     std::string result;
40     for (int iElement = 0; iElement < elements.size(); iElement++) {
41 schoenebeck 1338 // encode percent characters
42 schoenebeck 1332 std::string e = elements[iElement];
43     for (
44 schoenebeck 1338 int pos = e.find("%"); pos != std::string::npos;
45     pos = e.find("%", pos+2)
46     ) e.replace(pos/*offset*/, 1/*length*/, "%%"/*by*/);
47     // encode forward slashes
48     for (
49 schoenebeck 1332 int pos = e.find("/"); pos != std::string::npos;
50 schoenebeck 1338 pos = e.find("/", pos+3)
51 schoenebeck 1332 ) e.replace(pos/*offset*/, 1/*length*/, "%2f"/*by*/);
52     // append encoded node to full encoded path
53     result += "/" + e;
54     }
55     if (!result.size()) result = "/";
56     return result;
57     }
58    
59 iliev 1345 std::string Path::toDbPath() {
60     std::string result;
61     for (int iElement = 0; iElement < elements.size(); iElement++) {
62     // replace all slashes with '\0'
63     std::string e = elements[iElement];
64     for (int i = 0; i < e.length(); i++) {
65     if (e.at(i) == '/') e.at(i) = '\0';
66     }
67     // append encoded node to full encoded path
68     result += "/" + e;
69     }
70     if (!result.size()) result = "/";
71     return result;
72     }
73    
74 schoenebeck 1399 std::string Path::toLscp() {
75     std::string result;
76     for (int iElement = 0; iElement < elements.size(); iElement++) {
77     // replace "special characters" by LSCP escape sequences
78     std::string e = elements[iElement];
79     for (int i = 0; i < e.length(); i++) {
80     const char c = e.c_str()[i];
81     if (
82     !(c >= '0' && c <= '9') &&
83     !(c >= 'a' && c <= 'z') &&
84     !(c >= 'A' && c <= 'Z') &&
85     !(c == '!') && !(c == '#') && !(c == '$') && !(c == '%') &&
86     !(c == '&') && !(c == '(') && !(c == ')') && !(c == '*') &&
87     !(c == '+') && !(c == ',') && !(c == '-') && !(c == '.') &&
88     !(c == ':') && !(c == ';') && !(c == '<') && !(c == '=') &&
89     !(c == '>') && !(c == '?') && !(c == '@') && !(c == '[') &&
90     !(c == ']') && !(c == '^') && !(c == '_') && !(c == '`') &&
91     !(c == '{') && !(c == '|') && !(c == '}') && !(c == '~')
92     ) {
93     // convert the "special" character into a "\xHH" LSCP escape sequence
94     char buf[5];
95     snprintf(buf, sizeof(buf), "\\x%02x", static_cast<unsigned char>(c));
96     e.replace(i, 1, buf);
97     i += 3;
98     }
99     }
100     // append encoded node to full encoded path
101     result += "/" + e;
102     }
103     if (!result.size()) result = "/";
104     return result;
105     }
106    
107 schoenebeck 1332 Path Path::operator+(const Path& p) {
108     Path result = *this;
109     for (int i = 0; i < p.elements.size(); i++)
110     result.elements.push_back(p.elements[i]);
111     return result;
112     }
113    
114     Path Path::operator+(const Path* p) {
115     return *this + *p;
116     }
117    
118 schoenebeck 1399 Path Path::fromPosix(std::string path) {
119     Path result;
120     // first split the nodes
121     {
122     int nodeEnd;
123     for (
124     int nodeBegin = path.find_first_not_of('/');
125     nodeBegin != std::string::npos;
126     nodeBegin = path.find_first_not_of('/', nodeEnd)
127     ) {
128     nodeEnd = path.find_first_of('/', nodeBegin);
129     result.appendNode(
130     (nodeEnd != std::string::npos) ?
131     path.substr(nodeBegin, nodeEnd - nodeBegin) :
132     path.substr(nodeBegin)
133     );
134     }
135     }
136     // resolve POSIX escape sequences in all nodes
137     for (int iNode = 0; iNode < result.elements.size(); iNode++) {
138     std::string& s = result.elements[iNode];
139     for (int pos = s.find('%'); pos < s.length(); pos = s.find('%', ++pos)) {
140     if (pos+1 >= s.length()) { // unexpected character
141     //TODO: we might want to throw an exception here, for now we simply replace the character by '?'
142     s.replace(pos, 1, "?");
143     continue;
144     }
145     if (s.c_str()[pos+1] == '%') {
146     s.replace(pos, 2, "%");
147     continue;
148     }
149     if (pos+2 >= s.length()) {
150     //TODO: we might want to throw an exception here, for now we simply replace the character by '?'
151     s.replace(pos, 2, "?");
152     continue;
153     }
154     // expecting a "%HH" sequence here, convert it into the respective character
155     const std::string sHex = s.substr(pos+1, 2);
156     char cAscii = hexsToNumber(sHex.c_str()[1], sHex.c_str()[0]);
157     char pcAscii[] = { cAscii, 0 };
158     s.replace(pos, 3, pcAscii);
159     }
160     }
161     return result;
162     }
163    
164 iliev 1403 Path Path::fromDbPath(std::string path) {
165     Path result;
166     // first split the nodes
167     {
168     int nodeEnd;
169     for (
170     int nodeBegin = path.find_first_not_of('/');
171     nodeBegin != std::string::npos;
172     nodeBegin = path.find_first_not_of('/', nodeEnd)
173     ) {
174     nodeEnd = path.find_first_of('/', nodeBegin);
175    
176     std::string s = (nodeEnd != std::string::npos) ?
177     path.substr(nodeBegin, nodeEnd - nodeBegin) :
178     path.substr(nodeBegin);
179    
180     for (int i = 0; i < s.length(); i++) if (s.at(i) == '\0') s.at(i) = '/';
181     result.appendNode(s);
182     }
183     }
184     return result;
185     }
186    
187 schoenebeck 1332 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC