ovr_sdk

view LibOVR/Src/Kernel/OVR_String_PathUtil.cpp @ 0:1b39a1b46319

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