OVR_String_PathUtil.cpp
Go to the documentation of this file.
00001 /************************************************************************************
00002 
00003 Filename    :   OVR_String_PathUtil.cpp
00004 Content     :   String filename/url helper function
00005 Created     :   September 19, 2012
00006 Notes       : 
00007 
00008 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
00009 
00010 Use of this software is subject to the terms of the Oculus license
00011 agreement provided at the time of installation or download, or which
00012 otherwise accompanies this software in either electronic or hard copy form.
00013 
00014 ************************************************************************************/
00015 
00016 #include "OVR_String.h"
00017 #include "OVR_UTF8Util.h"
00018 
00019 namespace OVR {
00020 
00021 //--------------------------------------------------------------------
00022 // ***** Path-Scanner helper function 
00023 
00024 // Scans file path finding filename start and extension start, fills in their addess.
00025 void ScanFilePath(const char* url, const char** pfilename, const char** pext)
00026 { 
00027     const char* urlStart = url;
00028     const char *filename = 0;
00029     const char *lastDot = 0;
00030 
00031     UInt32 charVal = UTF8Util::DecodeNextChar(&url);
00032 
00033     while (charVal != 0)
00034     {
00035         if ((charVal == '/') || (charVal == '\\'))
00036         {
00037             filename = url;
00038             lastDot  = 0;
00039         }
00040         else if (charVal == '.')
00041         {
00042             lastDot = url - 1;
00043         }
00044         
00045         charVal = UTF8Util::DecodeNextChar(&url);
00046     }
00047 
00048     if (pfilename)
00049     {
00050         // It was a naked filename
00051         if (urlStart && (*urlStart != '.') && *urlStart)
00052             *pfilename = urlStart;
00053         else
00054             *pfilename = filename;
00055     }
00056 
00057     if (pext)
00058     {
00059         *pext = lastDot;
00060     }
00061 }
00062 
00063 // Scans till the end of protocol. Returns first character past protocol,
00064 // 0 if not found.
00065 //  - protocol: 'file://', 'http://'
00066 const char* ScanPathProtocol(const char* url)
00067 {    
00068     UInt32 charVal = UTF8Util::DecodeNextChar(&url);
00069     UInt32 charVal2;
00070    
00071     while (charVal != 0)
00072     {
00073         // Treat a colon followed by a slash as absolute.
00074         if (charVal == ':')
00075         {
00076             charVal2 = UTF8Util::DecodeNextChar(&url);
00077             charVal  = UTF8Util::DecodeNextChar(&url);
00078             if ((charVal == '/') && (charVal2 == '\\'))
00079                 return url;
00080         }
00081         charVal = UTF8Util::DecodeNextChar(&url);
00082     }
00083     return 0;
00084 }
00085 
00086 
00087 //--------------------------------------------------------------------
00088 // ***** String Path API implementation
00089 
00090 bool String::HasAbsolutePath(const char* url)
00091 {
00092     // Absolute paths can star with:
00093     //  - protocols:        'file://', 'http://'
00094     //  - windows drive:    'c:\'
00095     //  - UNC share name:   '\\share'
00096     //  - unix root         '/'
00097 
00098     // On the other hand, relative paths are:
00099     //  - directory:        'directory/file'
00100     //  - this directory:   './file'
00101     //  - parent directory: '../file'
00102     // 
00103     // For now, we don't parse '.' or '..' out, but instead let it be concatenated
00104     // to string and let the OS figure it out. This, however, is not good for file
00105     // name matching in library/etc, so it should be improved.
00106 
00107     if (!url || !*url)
00108         return true; // Treat empty strings as absolute.    
00109 
00110     UInt32 charVal = UTF8Util::DecodeNextChar(&url);
00111 
00112     // Fist character of '/' or '\\' means absolute url.
00113     if ((charVal == '/') || (charVal == '\\'))
00114         return true;
00115 
00116     while (charVal != 0)
00117     {
00118         // Treat a colon followed by a slash as absolute.
00119         if (charVal == ':')
00120         {
00121             charVal = UTF8Util::DecodeNextChar(&url);
00122             // Protocol or windows drive. Absolute.
00123             if ((charVal == '/') || (charVal == '\\'))
00124                 return true;
00125         }
00126         else if ((charVal == '/') || (charVal == '\\'))
00127         {
00128             // Not a first character (else 'if' above the loop would have caught it).
00129             // Must be a relative url.
00130             break;
00131         }
00132 
00133         charVal = UTF8Util::DecodeNextChar(&url);
00134     }
00135 
00136     // We get here for relative paths.
00137     return false;    
00138 }
00139 
00140 
00141 bool String::HasExtension(const char* path)
00142 {
00143     const char* ext = 0;
00144     ScanFilePath(path, 0, &ext);
00145     return ext != 0;
00146 }
00147 bool String::HasProtocol(const char* path)
00148 {
00149     return ScanPathProtocol(path) != 0;
00150 }
00151 
00152 
00153 String  String::GetPath() const
00154 {
00155     const char* filename = 0;
00156     ScanFilePath(ToCStr(), &filename, 0);
00157 
00158     // Technically we can have extra logic somewhere for paths,
00159     // such as enforcing protocol and '/' only based on flags,
00160     // but we keep it simple for now.
00161     return String(ToCStr(), filename ? (filename-ToCStr()) : GetSize());
00162 }
00163 
00164 String  String::GetProtocol() const
00165 {
00166     const char* protocolEnd = ScanPathProtocol(ToCStr());
00167     return String(ToCStr(), protocolEnd ? (protocolEnd-ToCStr()) : 0);
00168 }
00169 
00170 String  String::GetFilename() const
00171 {
00172     const char* filename = 0;
00173     ScanFilePath(ToCStr(), &filename, 0);
00174     return String(filename);
00175 }
00176 String  String::GetExtension() const
00177 {
00178     const char* ext = 0;
00179     ScanFilePath(ToCStr(), 0, &ext);
00180     return String(ext);
00181 }
00182 
00183 void    String::StripExtension()
00184 {
00185     const char* ext = 0;
00186     ScanFilePath(ToCStr(), 0, &ext);    
00187     if (ext)
00188     {
00189         *this = String(ToCStr(), ext-ToCStr());
00190     }
00191 }
00192 
00193 void    String::StripProtocol()
00194 {
00195     const char* protocol = ScanPathProtocol(ToCStr());
00196     if (protocol)
00197         AssignString(protocol, OVR_strlen(protocol));
00198 }
00199 
00200 } // OVR


oculus_sdk
Author(s):
autogenerated on Mon Oct 6 2014 03:01:19