rev |
line source |
nuclear@0
|
1 /************************************************************************************
|
nuclear@0
|
2
|
nuclear@0
|
3 Filename : OVR_String_PathUtil.cpp
|
nuclear@0
|
4 Content : String filename/url helper function
|
nuclear@0
|
5 Created : September 19, 2012
|
nuclear@0
|
6 Notes :
|
nuclear@0
|
7
|
nuclear@0
|
8 Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
|
nuclear@0
|
9
|
nuclear@0
|
10 Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
|
nuclear@0
|
11 you may not use the Oculus VR Rift SDK except in compliance with the License,
|
nuclear@0
|
12 which is provided at the time of installation or download, or which
|
nuclear@0
|
13 otherwise accompanies this software in either electronic or hard copy form.
|
nuclear@0
|
14
|
nuclear@0
|
15 You may obtain a copy of the License at
|
nuclear@0
|
16
|
nuclear@0
|
17 http://www.oculusvr.com/licenses/LICENSE-3.2
|
nuclear@0
|
18
|
nuclear@0
|
19 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
|
nuclear@0
|
20 distributed under the License is distributed on an "AS IS" BASIS,
|
nuclear@0
|
21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
nuclear@0
|
22 See the License for the specific language governing permissions and
|
nuclear@0
|
23 limitations under the License.
|
nuclear@0
|
24
|
nuclear@0
|
25 ************************************************************************************/
|
nuclear@0
|
26
|
nuclear@0
|
27 #include "OVR_String.h"
|
nuclear@0
|
28 #include "OVR_UTF8Util.h"
|
nuclear@0
|
29
|
nuclear@0
|
30 namespace OVR {
|
nuclear@0
|
31
|
nuclear@0
|
32 //--------------------------------------------------------------------
|
nuclear@0
|
33 // ***** Path-Scanner helper function
|
nuclear@0
|
34
|
nuclear@0
|
35 // Scans file path finding filename start and extension start, fills in their addess.
|
nuclear@0
|
36 void ScanFilePath(const char* url, const char** pfilename, const char** pext)
|
nuclear@0
|
37 {
|
nuclear@0
|
38 const char* urlStart = url;
|
nuclear@0
|
39 const char *filename = 0;
|
nuclear@0
|
40 const char *lastDot = 0;
|
nuclear@0
|
41
|
nuclear@0
|
42 uint32_t charVal = UTF8Util::DecodeNextChar(&url);
|
nuclear@0
|
43
|
nuclear@0
|
44 while (charVal != 0)
|
nuclear@0
|
45 {
|
nuclear@0
|
46 if ((charVal == '/') || (charVal == '\\'))
|
nuclear@0
|
47 {
|
nuclear@0
|
48 filename = url;
|
nuclear@0
|
49 lastDot = 0;
|
nuclear@0
|
50 }
|
nuclear@0
|
51 else if (charVal == '.')
|
nuclear@0
|
52 {
|
nuclear@0
|
53 lastDot = url - 1;
|
nuclear@0
|
54 }
|
nuclear@0
|
55
|
nuclear@0
|
56 charVal = UTF8Util::DecodeNextChar(&url);
|
nuclear@0
|
57 }
|
nuclear@0
|
58
|
nuclear@0
|
59 if (pfilename)
|
nuclear@0
|
60 {
|
nuclear@0
|
61 // It was a naked filename
|
nuclear@0
|
62 if (urlStart && (*urlStart != '.') && *urlStart)
|
nuclear@0
|
63 *pfilename = urlStart;
|
nuclear@0
|
64 else
|
nuclear@0
|
65 *pfilename = filename;
|
nuclear@0
|
66 }
|
nuclear@0
|
67
|
nuclear@0
|
68 if (pext)
|
nuclear@0
|
69 {
|
nuclear@0
|
70 *pext = lastDot;
|
nuclear@0
|
71 }
|
nuclear@0
|
72 }
|
nuclear@0
|
73
|
nuclear@0
|
74 // Scans till the end of protocol. Returns first character past protocol,
|
nuclear@0
|
75 // 0 if not found.
|
nuclear@0
|
76 // - protocol: 'file://', 'http://'
|
nuclear@0
|
77 const char* ScanPathProtocol(const char* url)
|
nuclear@0
|
78 {
|
nuclear@0
|
79 uint32_t charVal = UTF8Util::DecodeNextChar(&url);
|
nuclear@0
|
80 uint32_t charVal2;
|
nuclear@0
|
81
|
nuclear@0
|
82 while (charVal != 0)
|
nuclear@0
|
83 {
|
nuclear@0
|
84 // Treat a colon followed by a slash as absolute.
|
nuclear@0
|
85 if (charVal == ':')
|
nuclear@0
|
86 {
|
nuclear@0
|
87 charVal2 = UTF8Util::DecodeNextChar(&url);
|
nuclear@0
|
88 charVal = UTF8Util::DecodeNextChar(&url);
|
nuclear@0
|
89 if ((charVal == '/') && (charVal2 == '\\'))
|
nuclear@0
|
90 return url;
|
nuclear@0
|
91 }
|
nuclear@0
|
92 charVal = UTF8Util::DecodeNextChar(&url);
|
nuclear@0
|
93 }
|
nuclear@0
|
94 return 0;
|
nuclear@0
|
95 }
|
nuclear@0
|
96
|
nuclear@0
|
97
|
nuclear@0
|
98 //--------------------------------------------------------------------
|
nuclear@0
|
99 // ***** String Path API implementation
|
nuclear@0
|
100
|
nuclear@0
|
101 bool String::HasAbsolutePath(const char* url)
|
nuclear@0
|
102 {
|
nuclear@0
|
103 // Absolute paths can star with:
|
nuclear@0
|
104 // - protocols: 'file://', 'http://'
|
nuclear@0
|
105 // - windows drive: 'c:\'
|
nuclear@0
|
106 // - UNC share name: '\\share'
|
nuclear@0
|
107 // - unix root '/'
|
nuclear@0
|
108
|
nuclear@0
|
109 // On the other hand, relative paths are:
|
nuclear@0
|
110 // - directory: 'directory/file'
|
nuclear@0
|
111 // - this directory: './file'
|
nuclear@0
|
112 // - parent directory: '../file'
|
nuclear@0
|
113 //
|
nuclear@0
|
114 // For now, we don't parse '.' or '..' out, but instead let it be concatenated
|
nuclear@0
|
115 // to string and let the OS figure it out. This, however, is not good for file
|
nuclear@0
|
116 // name matching in library/etc, so it should be improved.
|
nuclear@0
|
117
|
nuclear@0
|
118 if (!url || !*url)
|
nuclear@0
|
119 return true; // Treat empty strings as absolute.
|
nuclear@0
|
120
|
nuclear@0
|
121 uint32_t charVal = UTF8Util::DecodeNextChar(&url);
|
nuclear@0
|
122
|
nuclear@0
|
123 // Fist character of '/' or '\\' means absolute url.
|
nuclear@0
|
124 if ((charVal == '/') || (charVal == '\\'))
|
nuclear@0
|
125 return true;
|
nuclear@0
|
126
|
nuclear@0
|
127 while (charVal != 0)
|
nuclear@0
|
128 {
|
nuclear@0
|
129 // Treat a colon followed by a slash as absolute.
|
nuclear@0
|
130 if (charVal == ':')
|
nuclear@0
|
131 {
|
nuclear@0
|
132 charVal = UTF8Util::DecodeNextChar(&url);
|
nuclear@0
|
133 // Protocol or windows drive. Absolute.
|
nuclear@0
|
134 if ((charVal == '/') || (charVal == '\\'))
|
nuclear@0
|
135 return true;
|
nuclear@0
|
136 }
|
nuclear@0
|
137 else if ((charVal == '/') || (charVal == '\\'))
|
nuclear@0
|
138 {
|
nuclear@0
|
139 // Not a first character (else 'if' above the loop would have caught it).
|
nuclear@0
|
140 // Must be a relative url.
|
nuclear@0
|
141 break;
|
nuclear@0
|
142 }
|
nuclear@0
|
143
|
nuclear@0
|
144 charVal = UTF8Util::DecodeNextChar(&url);
|
nuclear@0
|
145 }
|
nuclear@0
|
146
|
nuclear@0
|
147 // We get here for relative paths.
|
nuclear@0
|
148 return false;
|
nuclear@0
|
149 }
|
nuclear@0
|
150
|
nuclear@0
|
151
|
nuclear@0
|
152 bool String::HasExtension(const char* path)
|
nuclear@0
|
153 {
|
nuclear@0
|
154 const char* ext = 0;
|
nuclear@0
|
155 ScanFilePath(path, 0, &ext);
|
nuclear@0
|
156 return ext != 0;
|
nuclear@0
|
157 }
|
nuclear@0
|
158 bool String::HasProtocol(const char* path)
|
nuclear@0
|
159 {
|
nuclear@0
|
160 return ScanPathProtocol(path) != 0;
|
nuclear@0
|
161 }
|
nuclear@0
|
162
|
nuclear@0
|
163
|
nuclear@0
|
164 String String::GetPath() const
|
nuclear@0
|
165 {
|
nuclear@0
|
166 const char* filename = 0;
|
nuclear@0
|
167 ScanFilePath(ToCStr(), &filename, 0);
|
nuclear@0
|
168
|
nuclear@0
|
169 // Technically we can have extra logic somewhere for paths,
|
nuclear@0
|
170 // such as enforcing protocol and '/' only based on flags,
|
nuclear@0
|
171 // but we keep it simple for now.
|
nuclear@0
|
172 return String(ToCStr(), filename ? (filename-ToCStr()) : GetSize());
|
nuclear@0
|
173 }
|
nuclear@0
|
174
|
nuclear@0
|
175 String String::GetProtocol() const
|
nuclear@0
|
176 {
|
nuclear@0
|
177 const char* protocolEnd = ScanPathProtocol(ToCStr());
|
nuclear@0
|
178 return String(ToCStr(), protocolEnd ? (protocolEnd-ToCStr()) : 0);
|
nuclear@0
|
179 }
|
nuclear@0
|
180
|
nuclear@0
|
181 String String::GetFilename() const
|
nuclear@0
|
182 {
|
nuclear@0
|
183 const char* filename = 0;
|
nuclear@0
|
184 ScanFilePath(ToCStr(), &filename, 0);
|
nuclear@0
|
185 return String(filename);
|
nuclear@0
|
186 }
|
nuclear@0
|
187 String String::GetExtension() const
|
nuclear@0
|
188 {
|
nuclear@0
|
189 const char* ext = 0;
|
nuclear@0
|
190 ScanFilePath(ToCStr(), 0, &ext);
|
nuclear@0
|
191 return String(ext);
|
nuclear@0
|
192 }
|
nuclear@0
|
193
|
nuclear@0
|
194 void String::StripExtension()
|
nuclear@0
|
195 {
|
nuclear@0
|
196 const char* ext = 0;
|
nuclear@0
|
197 ScanFilePath(ToCStr(), 0, &ext);
|
nuclear@0
|
198 if (ext)
|
nuclear@0
|
199 {
|
nuclear@0
|
200 *this = String(ToCStr(), ext-ToCStr());
|
nuclear@0
|
201 }
|
nuclear@0
|
202 }
|
nuclear@0
|
203
|
nuclear@0
|
204 void String::StripProtocol()
|
nuclear@0
|
205 {
|
nuclear@0
|
206 const char* protocol = ScanPathProtocol(ToCStr());
|
nuclear@0
|
207 if (protocol)
|
nuclear@0
|
208 AssignString(protocol, OVR_strlen(protocol));
|
nuclear@0
|
209 }
|
nuclear@0
|
210
|
nuclear@0
|
211 } // OVR
|