2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <dali-toolkit/internal/visuals/visual-url.h>
21 #include <cstring> // for toupper()
33 VisualUrl::ProtocolType ResolveLocation( const std::string& url )
35 const char* urlCStr = url.c_str();
36 const uint32_t length = url.size();
37 if( ( length > 7 ) && urlCStr[5] == ':' && urlCStr[6] == '/' && urlCStr[7] == '/' )
40 if( ( 'h' == tolower( urlCStr[0] ) )&&
41 ( 't' == tolower( urlCStr[1] ) )&&
42 ( 't' == tolower( urlCStr[2] ) )&&
43 ( 'p' == tolower( urlCStr[3] ) )&&
44 ( 's' == tolower( urlCStr[4] ) ) )
46 return VisualUrl::REMOTE;
49 else if( ( length > 6 ) && urlCStr[4] == ':' && urlCStr[5] == '/' && urlCStr[6] == '/' )
52 const char hOrd = tolower( urlCStr[0] );
53 const char tOra = tolower( urlCStr[1] );
54 const char tOrl = tolower( urlCStr[2] );
55 const char pOri = tolower( urlCStr[3] );
61 return VisualUrl::REMOTE;
68 return VisualUrl::TEXTURE;
71 else if( ( length > 5 ) && urlCStr[3] == ':' && urlCStr[4] == '/' && urlCStr[5] == '/' )
74 const char fOrS = tolower( urlCStr[0] );
75 if( ( 'f' == fOrS )||( 's' == fOrS ) )
77 const char tOrs = tolower( urlCStr[1] );
78 if( ( 't' == tOrs )||( 's' == tOrs ) )
80 const char pOrh = tolower( urlCStr[2] );
81 if( ( 'p' == pOrh )||( 'h' == pOrh ) )
83 return VisualUrl::REMOTE;
88 return VisualUrl::LOCAL;
92 VisualUrl::Type ResolveType( const std::string& url )
94 // if only one char in string, can only be regular image
95 const std::size_t count = url.size();
98 // parsing from the end for better chance of early outs
99 enum { SUFFIX, HASH, HASH_DOT } state = SUFFIX;
100 char SVG[ 4 ] = { 'g', 'v', 's', '.' };
101 char GIF[ 4 ] = { 'f', 'i', 'g', '.' };
102 char WEBP[ 5 ] = { 'p', 'b', 'e', 'w', '.' };
103 char JSON[ 5 ] = { 'n', 'o', 's', 'j', '.' };
104 unsigned int svgScore = 0;
105 unsigned int gifScore = 0;
106 unsigned int webpScore = 0;
107 unsigned int jsonScore = 0;
109 while( --index >= 0 )
111 const char currentChar = tolower( url[ index ] );
112 const std::size_t offsetFromEnd = count - index - 1u;
113 if( ( offsetFromEnd < sizeof(SVG) )&&( currentChar == SVG[ offsetFromEnd ] ) )
115 // early out if SVG as can't be used in N patch for now
116 if( ++svgScore == sizeof(SVG) )
118 return VisualUrl::SVG;
121 if( ( offsetFromEnd < sizeof(GIF) )&&( currentChar == GIF[ offsetFromEnd ] ) )
123 // early out if GIF as can't be used in N patch for now
124 if( ++gifScore == sizeof(GIF) )
126 return VisualUrl::GIF;
129 if( ( offsetFromEnd < sizeof(WEBP) )&&( currentChar == WEBP[ offsetFromEnd ] ) )
131 // early out if WEBP as can't be used in N patch for now
132 if( ++webpScore == sizeof(WEBP) )
134 return VisualUrl::WEBP;
137 if( ( offsetFromEnd < sizeof(JSON) )&&( currentChar == JSON[ offsetFromEnd ] ) )
139 // early out if JSON as can't be used in N patch for now
140 if( ++jsonScore == sizeof(JSON) )
142 return VisualUrl::JSON;
149 if( '.' == currentChar )
157 if( ( '#' == currentChar ) || ( '9' == currentChar ) )
163 // early out, not a valid N/9-patch URL
164 return VisualUrl::REGULAR_IMAGE;
170 if( '.' == currentChar )
172 return VisualUrl::N_PATCH;
176 // early out, not a valid N/9-patch URL
177 return VisualUrl::REGULAR_IMAGE;
184 // if we got here it is a regular image
185 return VisualUrl::REGULAR_IMAGE;
191 VisualUrl::VisualUrl()
193 mType( VisualUrl::REGULAR_IMAGE ),
194 mLocation( VisualUrl::LOCAL )
198 VisualUrl::VisualUrl( const std::string& url )
200 mType( VisualUrl::REGULAR_IMAGE ),
201 mLocation( VisualUrl::LOCAL )
205 mLocation = ResolveLocation( url );
206 if( VisualUrl::TEXTURE != mLocation )
208 // TEXTURE location url doesn't need type resolving, REGULAR_IMAGE is fine
209 mType = ResolveType( url );
214 VisualUrl::VisualUrl( const VisualUrl& url )
217 mLocation( url.mLocation )
221 VisualUrl& VisualUrl::operator=( const VisualUrl& url )
227 mLocation = url.mLocation;
232 const std::string& VisualUrl::GetUrl() const
237 VisualUrl::Type VisualUrl::GetType() const
242 VisualUrl::ProtocolType VisualUrl::GetProtocolType() const
247 bool VisualUrl::IsValid() const
249 return mUrl.size() > 0u;
252 bool VisualUrl::IsLocalResource() const
254 return mLocation == VisualUrl::LOCAL;
257 std::string VisualUrl::GetLocation() const
259 const auto location = mUrl.find( "://" );
260 if( std::string::npos != location )
262 return mUrl.substr( location + 3u ); // 3 characters forwards from the start of ://
267 std::string VisualUrl::CreateTextureUrl( const std::string& location )
269 return "dali://" + location;