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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1338 by schoenebeck, Sun Sep 9 23:30:34 2007 UTC revision 1471 by schoenebeck, Mon Nov 5 13:56:26 2007 UTC
# Line 20  Line 20 
20    
21  #include "Path.h"  #include "Path.h"
22    
23    // for function hexsToNumber()
24    #include "global_private.h"
25    
26    #include <sstream>
27    
28  namespace LinuxSampler {  namespace LinuxSampler {
29    
30    Path::Path() : drive(0) {
31    }
32    
33  void Path::appendNode(std::string Name) {  void Path::appendNode(std::string Name) {
34      if (!Name.size()) return;      if (!Name.size()) return;
35      elements.push_back(Name);      elements.push_back(Name);
36  }  }
37    
38  std::string Path::toPosix() {  void Path::setDrive(const char& Drive) {
39        drive = Drive;
40    }
41    
42    std::string Path::toPosix() const {
43      // POSIX paths consist of forward slash separators and requires forward      // 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      // slashes in path and file names to be encoded as "%2f", the file names
45      // "." and ".." have special meanings      // "." and ".." have special meanings
# Line 53  std::string Path::toPosix() { Line 65  std::string Path::toPosix() {
65      return result;      return result;
66  }  }
67    
68    std::string Path::toDbPath() const {
69        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    std::string Path::toLscp() const {
84        std::string result;
85        for (int iElement = 0; iElement < elements.size(); iElement++) {
86            // replace "special characters" by LSCP escape sequences
87            std::string e = elements[iElement];
88            for (int i = 0; i < e.length(); i++) {
89                const char c = e.c_str()[i];
90                if (
91                    !(c >= '0' && c <= '9') &&
92                    !(c >= 'a' && c <= 'z') &&
93                    !(c >= 'A' && c <= 'Z') &&
94                    !(c == '!') && !(c == '#') && !(c == '$') && !(c == '%') &&
95                    !(c == '&') && !(c == '(') && !(c == ')') && !(c == '*') &&
96                    !(c == '+') && !(c == ',') && !(c == '-') && !(c == '.') &&
97                    !(c == ':') && !(c == ';') && !(c == '<') && !(c == '=') &&
98                    !(c == '>') && !(c == '?') && !(c == '@') && !(c == '[') &&
99                    !(c == ']') && !(c == '^') && !(c == '_') && !(c == '`') &&
100                    !(c == '{') && !(c == '|') && !(c == '}') && !(c == '~')
101                ) {
102                    // convert the "special" character into a "\xHH" LSCP escape sequence
103                    char buf[5];
104                    snprintf(buf, sizeof(buf), "\\x%02x", static_cast<unsigned char>(c));
105                    e.replace(i, 1, buf);
106                    i += 3;
107                }
108            }
109            // append encoded node to full encoded path
110            result += "/" + e;
111        }
112        if (!result.size()) result = "/";
113        return result;
114    }
115    
116    std::string Path::toWindows() const {
117        std::stringstream result;
118        result <<
119            ((drive >= 'A' && drive <= 'Z') || (drive >= 'a' && drive <= 'z'))
120                ? drive : '?';
121        result << ':';
122        for (int iElement = 0; iElement < elements.size(); iElement++) {
123            // append encoded node to full encoded path
124            result << "\\" << elements[iElement];
125        }
126        return result.str();
127    }
128    
129  Path Path::operator+(const Path& p) {  Path Path::operator+(const Path& p) {
130      Path result = *this;      Path result = *this;
131      for (int i = 0; i < p.elements.size(); i++)      for (int i = 0; i < p.elements.size(); i++)
# Line 64  Path Path::operator+(const Path* p) { Line 137  Path Path::operator+(const Path* p) {
137      return *this + *p;      return *this + *p;
138  }  }
139    
140    Path Path::fromPosix(std::string path) {
141        Path result;
142        // first split the nodes
143        {
144            int nodeEnd;
145            for (
146                int nodeBegin = path.find_first_not_of('/');
147                nodeBegin != std::string::npos;
148                nodeBegin = path.find_first_not_of('/', nodeEnd)
149            ) {
150                nodeEnd = path.find_first_of('/', nodeBegin);
151                result.appendNode(
152                    (nodeEnd != std::string::npos) ?
153                        path.substr(nodeBegin, nodeEnd - nodeBegin) :
154                        path.substr(nodeBegin)
155                );
156            }
157        }
158        // resolve POSIX escape sequences in all nodes
159        for (int iNode = 0; iNode < result.elements.size(); iNode++) {
160            std::string& s = result.elements[iNode];
161            for (int pos = s.find('%'); pos < s.length(); pos = s.find('%', ++pos)) {
162                if (pos+1 >= s.length()) { // unexpected character
163                    //TODO: we might want to throw an exception here, for now we simply replace the character by '?'
164                    s.replace(pos, 1, "?");
165                    continue;
166                }
167                if (s.c_str()[pos+1] == '%') {
168                    s.replace(pos, 2, "%");
169                    continue;
170                }
171                if (pos+2 >= s.length()) {
172                    //TODO: we might want to throw an exception here, for now we simply replace the character by '?'
173                    s.replace(pos, 2, "?");
174                    continue;
175                }
176                // expecting a "%HH" sequence here, convert it into the respective character
177                const std::string sHex = s.substr(pos+1, 2);
178                char cAscii = hexsToNumber(sHex.c_str()[1], sHex.c_str()[0]);
179                char pcAscii[] = { cAscii, 0 };
180                s.replace(pos, 3, pcAscii);
181            }
182        }
183        return result;
184    }
185    
186    Path Path::fromDbPath(std::string path) {
187        Path result;
188        // first split the nodes
189        {
190            int nodeEnd;
191            for (
192                int nodeBegin = path.find_first_not_of('/');
193                nodeBegin != std::string::npos;
194                nodeBegin = path.find_first_not_of('/', nodeEnd)
195            ) {
196                nodeEnd = path.find_first_of('/', nodeBegin);
197    
198                std::string s = (nodeEnd != std::string::npos) ?
199                    path.substr(nodeBegin, nodeEnd - nodeBegin) :
200                    path.substr(nodeBegin);
201    
202                for (int i = 0; i < s.length(); i++) if (s.at(i) == '\0') s.at(i) = '/';
203                result.appendNode(s);
204            }
205        }
206        return result;
207    }
208    
209    Path Path::fromWindowsPath(std::string path) {
210        Path result;
211    
212        int nodeEnd = 0;
213    
214        // first retrieve drive
215        if (path.size() >= 2 && path.c_str()[1] == ':') {
216            result.setDrive(path.c_str()[0]);
217            nodeEnd = 2;
218        }
219    
220        // split the nodes
221        {
222            for (
223                int nodeBegin = path.find_first_not_of('\\', nodeEnd);
224                nodeBegin != std::string::npos;
225                nodeBegin = path.find_first_not_of('\\', nodeEnd)
226            ) {
227                nodeEnd = path.find_first_of('\\', nodeBegin);
228                result.appendNode(
229                    (nodeEnd != std::string::npos) ?
230                        path.substr(nodeBegin, nodeEnd - nodeBegin) :
231                        path.substr(nodeBegin)
232                );
233            }
234        }
235    
236        return result;
237    }
238    
239  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.1338  
changed lines
  Added in v.1471

  ViewVC Help
Powered by ViewVC