/[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 1424 by schoenebeck, Sun Oct 14 22:00:17 2007 UTC revision 3091 by schoenebeck, Mon Jan 16 15:01:21 2017 UTC
# Line 1  Line 1 
1  /***************************************************************************  /***************************************************************************
2   *                                                                         *   *                                                                         *
3   *   Copyright (C) 2007 Christian Schoenebeck                              *   *   Copyright (C) 2007-2017 Christian Schoenebeck                         *
4   *                                                                         *   *                                                                         *
5   *   This library is free software; you can redistribute it and/or modify  *   *   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  *   *   it under the terms of the GNU General Public License as published by  *
# Line 23  Line 23 
23  // for function hexsToNumber()  // for function hexsToNumber()
24  #include "global_private.h"  #include "global_private.h"
25    
26    #include <sstream>
27    
28  namespace LinuxSampler {  namespace LinuxSampler {
29    
30    Path::Path() : drive(0), absolute(false) {
31    }
32    
33    Path::Path(std::string path) {
34        #if WIN32
35        *this = fromWindows(path);
36        #else
37        *this = fromPosix(path);
38        #endif
39    }
40    
41  void Path::appendNode(std::string Name) {  void Path::appendNode(std::string Name) {
42      if (!Name.size()) return;      if (!Name.size()) return;
43      elements.push_back(Name);      elements.push_back(Name);
44  }  }
45    
46  std::string Path::toPosix() {  void Path::setDrive(const char& Drive) {
47        drive = Drive;
48        absolute = true;
49    }
50    
51    std::string Path::toNativeFSPath() const {
52        #if WIN32
53        return toWindows();
54        #else
55        return toPosix();
56        #endif
57    }
58    
59    std::string Path::toPosix() const {
60      // POSIX paths consist of forward slash separators and requires forward      // POSIX paths consist of forward slash separators and requires forward
61      // 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
62      // "." and ".." have special meanings      // "." and ".." have special meanings
# Line 41  std::string Path::toPosix() { Line 67  std::string Path::toPosix() {
67          // encode percent characters          // encode percent characters
68          std::string e = elements[iElement];          std::string e = elements[iElement];
69          for (          for (
70              int pos = e.find("%"); pos != std::string::npos;              int pos = (int)e.find("%"); pos != std::string::npos;
71              pos = e.find("%", pos+2)              pos = (int)e.find("%", pos+2)
72          ) e.replace(pos/*offset*/, 1/*length*/, "%%"/*by*/);          ) e.replace(pos/*offset*/, 1/*length*/, "%%"/*by*/);
73          // encode forward slashes          // encode forward slashes
74          for (          for (
75              int pos = e.find("/"); pos != std::string::npos;              int pos = (int)e.find("/"); pos != std::string::npos;
76              pos = e.find("/", pos+3)              pos = (int)e.find("/", pos+3)
77          ) e.replace(pos/*offset*/, 1/*length*/, "%2f"/*by*/);          ) e.replace(pos/*offset*/, 1/*length*/, "%2f"/*by*/);
78          // append encoded node to full encoded path          // append encoded node to full encoded path
79          result += "/" + e;          result += "/" + e;
# Line 56  std::string Path::toPosix() { Line 82  std::string Path::toPosix() {
82      return result;      return result;
83  }  }
84    
85  std::string Path::toDbPath() {  std::string Path::toDbPath() const {
86      std::string result;      std::string result;
87      for (int iElement = 0; iElement < elements.size(); iElement++) {      for (int iElement = 0; iElement < elements.size(); iElement++) {
88          // replace all slashes with '\0'          // replace all slashes with '\0'
# Line 71  std::string Path::toDbPath() { Line 97  std::string Path::toDbPath() {
97      return result;      return result;
98  }  }
99    
100  std::string Path::toLscp() {  std::string Path::toLscp() const {
101      std::string result;      std::string result;
102        #if WIN32
103        if(drive) {
104            result.assign(&drive,1);
105            result += ":";
106        }
107        #endif
108      for (int iElement = 0; iElement < elements.size(); iElement++) {      for (int iElement = 0; iElement < elements.size(); iElement++) {
109          // replace "special characters" by LSCP escape sequences          // replace "special characters" by LSCP escape sequences
110          std::string e = elements[iElement];          std::string e = elements[iElement];
# Line 104  std::string Path::toLscp() { Line 136  std::string Path::toLscp() {
136      return result;      return result;
137  }  }
138    
139    std::string Path::toWindows() const {
140        std::stringstream result;
141            const char cDrive =
142                ((drive >= 'A' && drive <= 'Z') || (drive >= 'a' && drive <= 'z'))
143                ? drive : '?';
144        result << cDrive;
145        result << ':';
146        for (int iElement = 0; iElement < elements.size(); iElement++) {
147            // append encoded node to full encoded path
148            result << "\\" << elements[iElement];
149        }
150        if (elements.empty()) result << '\\';
151        return result.str();
152    }
153    
154  Path Path::operator+(const Path& p) {  Path Path::operator+(const Path& p) {
155      Path result = *this;      Path result = *this;
156      for (int i = 0; i < p.elements.size(); i++)      for (int i = 0; i < p.elements.size(); i++)
# Line 115  Path Path::operator+(const Path* p) { Line 162  Path Path::operator+(const Path* p) {
162      return *this + *p;      return *this + *p;
163  }  }
164    
165    Path Path::fromUnknownFS(std::string path) {
166        bool hasDrive = false;
167        int nSlash = 0, nBackSlash = 0;
168    
169        if (path.length() >= 2)
170            hasDrive = (path[1] == ':');
171    
172        for (size_t i = 0; i < path.size(); ++i) {
173            if (path[i] == '/')  nSlash++;
174            if (path[i] == '\\') nBackSlash++;
175        }
176    
177        if (!hasDrive && nSlash > nBackSlash)
178            return Path::fromPosix(path);
179        else if (hasDrive || nBackSlash > nSlash)
180            return Path::fromWindows(path);
181        else
182            return Path(path); // expect local file system encoding
183    }
184    
185  Path Path::fromPosix(std::string path) {  Path Path::fromPosix(std::string path) {
186      Path result;      Path result;
187      // first split the nodes      // first split the nodes
188      {      {
189          int nodeEnd;          int nodeEnd;
190          for (          for (
191              int nodeBegin = path.find_first_not_of('/');              int nodeBegin = (int)path.find_first_not_of('/');
192              nodeBegin != std::string::npos;              nodeBegin != std::string::npos;
193              nodeBegin = path.find_first_not_of('/', nodeEnd)              nodeBegin = (int)path.find_first_not_of('/', nodeEnd)
194          ) {          ) {
195              nodeEnd = path.find_first_of('/', nodeBegin);              nodeEnd = (int)path.find_first_of('/', nodeBegin);
196              result.appendNode(              result.appendNode(
197                  (nodeEnd != std::string::npos) ?                  (nodeEnd != std::string::npos) ?
198                      path.substr(nodeBegin, nodeEnd - nodeBegin) :                      path.substr(nodeBegin, nodeEnd - nodeBegin) :
# Line 136  Path Path::fromPosix(std::string path) { Line 203  Path Path::fromPosix(std::string path) {
203      // resolve POSIX escape sequences in all nodes      // resolve POSIX escape sequences in all nodes
204      for (int iNode = 0; iNode < result.elements.size(); iNode++) {      for (int iNode = 0; iNode < result.elements.size(); iNode++) {
205          std::string& s = result.elements[iNode];          std::string& s = result.elements[iNode];
206          for (int pos = s.find('%'); pos < s.length(); pos = s.find('%', ++pos)) {          for (size_t pos = s.find('%'); pos < s.length(); pos = s.find('%', ++pos)) {
207              if (pos+1 >= s.length()) { // unexpected character              if (pos+1 >= s.length()) { // unexpected character
208                  //TODO: we might want to throw an exception here, for now we simply replace the character by '?'                  //TODO: we might want to throw an exception here, for now we simply replace the character by '?'
209                  s.replace(pos, 1, "?");                  s.replace(pos, 1, "?");
# Line 158  Path Path::fromPosix(std::string path) { Line 225  Path Path::fromPosix(std::string path) {
225              s.replace(pos, 3, pcAscii);              s.replace(pos, 3, pcAscii);
226          }          }
227      }      }
228        // check whether given string reflects an absolute path
229        // (indicated by a forward slash as first character on POSIX)
230        result.absolute = !path.empty() && path[0] == '/';
231      return result;      return result;
232  }  }
233    
# Line 167  Path Path::fromDbPath(std::string path) Line 237  Path Path::fromDbPath(std::string path)
237      {      {
238          int nodeEnd;          int nodeEnd;
239          for (          for (
240              int nodeBegin = path.find_first_not_of('/');              int nodeBegin = (int)path.find_first_not_of('/');
241              nodeBegin != std::string::npos;              nodeBegin != std::string::npos;
242              nodeBegin = path.find_first_not_of('/', nodeEnd)              nodeBegin = (int)path.find_first_not_of('/', nodeEnd)
243          ) {          ) {
244              nodeEnd = path.find_first_of('/', nodeBegin);              nodeEnd = (int)path.find_first_of('/', nodeBegin);
245    
246              std::string s = (nodeEnd != std::string::npos) ?              std::string s = (nodeEnd != std::string::npos) ?
247                  path.substr(nodeBegin, nodeEnd - nodeBegin) :                  path.substr(nodeBegin, nodeEnd - nodeBegin) :
# Line 184  Path Path::fromDbPath(std::string path) Line 254  Path Path::fromDbPath(std::string path)
254      return result;      return result;
255  }  }
256    
257    Path Path::fromWindows(std::string path) {
258        Path result;
259    
260        int nodeEnd = 0;
261    
262        // first retrieve drive
263        if (path.size() >= 2 && path.c_str()[1] == ':') {
264            result.setDrive(path.c_str()[0]);
265            nodeEnd = 2;
266        }
267    
268        // split the nodes
269        {
270            for (
271                int nodeBegin = (int)path.find_first_not_of('\\', nodeEnd);
272                nodeBegin != std::string::npos;
273                nodeBegin = (int)path.find_first_not_of('\\', nodeEnd)
274            ) {
275                nodeEnd = (int)path.find_first_of('\\', nodeBegin);
276                result.appendNode(
277                    (nodeEnd != std::string::npos) ?
278                        path.substr(nodeBegin, nodeEnd - nodeBegin) :
279                        path.substr(nodeBegin)
280                );
281            }
282        }
283    
284        // check whether given string reflects an absolute path
285        // (indicated either by a backslash or drive at the beginning on Windows)
286        result.absolute = result.drive || (!path.empty() && path[0] == '\\');
287    
288        return result;
289    }
290    
291    std::string Path::getName(std::string path) {
292        Path p;
293        #if WIN32
294        p.fromWindows(path);
295        #else
296        p.fromPosix(path);
297        #endif
298        
299        return p.getName();
300    }
301    
302    std::string Path::getName() const {
303        if(elements.empty()) return "";
304        return elements[elements.size() - 1];
305    }
306    
307    std::string Path::getBaseName(std::string path) {
308        Path p;
309        #if WIN32
310        p = fromWindows(path);
311        #else
312        p = fromPosix(path);
313        #endif
314        
315        return p.getBaseName();
316    }
317    
318    std::string Path::getBaseName() const {
319        std::string name = getName();
320        size_t lastdot = name.find_last_of('.');
321        if(lastdot == std::string::npos) return name;
322        return name.substr(0, lastdot);
323    }
324    
325    std::string Path::stripLastName() {
326        if (elements.size() > 0) elements.pop_back();
327        #if WIN32
328        return toWindows();
329        #else
330        return toPosix();
331        #endif
332    }
333    
334    std::string Path::stripLastName(std::string path) {
335        Path p;
336        #if WIN32
337        p = fromWindows(path);
338        #else
339        p = fromPosix(path);
340        #endif
341    
342        return p.stripLastName();
343    }
344    
345    bool Path::isAbsolute() const {
346        return absolute;
347    }
348    
349    std::vector<std::string>& Path::nodes() {
350        return elements;
351    }
352    
353  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.1424  
changed lines
  Added in v.3091

  ViewVC Help
Powered by ViewVC