c3c675d2d95cd2916015ccbd2624464471c02488
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / visual-url.cpp
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 // CLASS HEADER
18 #include <dali-toolkit/internal/visuals/visual-url.h>
19
20 // EXTERNAL HEADERS
21 #include <cstring> // for toupper()
22
23 namespace Dali
24 {
25 namespace Toolkit
26 {
27 namespace Internal
28 {
29
30 namespace
31 {
32
33 VisualUrl::Location ResolveLocation( const std::string& url)
34 {
35   const char FTP[] = { 'f', 't', 'p', ':', '/', '/' };
36   const char SSH[] = { 's', 's', 'h', ':', '/', '/' };
37   const char HTTP[] = { 'h', 't', 't', 'p', ':', '/', '/' };
38   const char HTTPS[] = { 'h', 't', 't', 'p', 's', ':', '/', '/' };
39
40   const int MATCH_FTP = 0x01;
41   const int MATCH_SSH = 0x02;
42   const int MATCH_HTTP = 0x04;
43   const int MATCH_HTTPS = 0x08;
44
45   const char* urlCStr = url.c_str();
46   if( url.size() > 6 )
47   {
48     if( urlCStr[3] == ':' || urlCStr[4] == ':' || urlCStr[5] == ':' )
49     {
50       int flags = 0x0F;
51       for( unsigned int i=0; i < sizeof(HTTPS); ++i )
52       {
53         char c = tolower( urlCStr[i] );
54         if( i < sizeof(FTP) && (flags & MATCH_FTP) && c != FTP[i] )
55         {
56           flags &= ~MATCH_FTP;
57         }
58         if( i < sizeof(SSH) && (flags & MATCH_SSH) && c != SSH[i] )
59         {
60           flags &= ~MATCH_SSH;
61         }
62         if( i < sizeof(HTTP) && (flags & MATCH_HTTP) && c != HTTP[i] )
63         {
64           flags &= ~MATCH_HTTP;
65         }
66         if( i < sizeof(HTTPS) && (flags & MATCH_HTTPS) && c != HTTPS[i] )
67         {
68           flags &= ~MATCH_HTTPS;
69         }
70
71         if( (flags & (MATCH_FTP | MATCH_SSH | MATCH_HTTP | MATCH_HTTPS )) == 0 )
72         {
73           break;
74         }
75       }
76
77       if( flags )
78       {
79         return VisualUrl::REMOTE;
80       }
81     }
82   }
83   return VisualUrl::LOCAL;
84 }
85
86
87 VisualUrl::Type ResolveType( const std::string& url )
88 {
89   // if only one char in string, can only be regular image
90   const std::size_t count = url.size();
91   if( count > 0 )
92   {
93     // parsing from the end for better chance of early outs
94     enum { SUFFIX, HASH, HASH_DOT } state = SUFFIX;
95     char SVG[ 4 ] = { 'g', 'v', 's', '.' };
96     char GIF[ 4 ] = { 'f', 'i', 'g', '.' };
97     unsigned int svgScore = 0;
98     unsigned int gifScore = 0;
99     int index = count;
100     while( --index >= 0 )
101     {
102       const char currentChar = url[ index ];
103       const std::size_t offsetFromEnd = count - index - 1u;
104       if( ( offsetFromEnd < sizeof(SVG) )&&( tolower( currentChar ) == SVG[ offsetFromEnd ] ) )
105       {
106         // early out if SVG as can't be used in N patch for now
107         if( ++svgScore == sizeof(SVG) )
108         {
109           return VisualUrl::SVG;
110         }
111       }
112       if( ( offsetFromEnd < sizeof(GIF) )&&( tolower( currentChar ) == GIF[ offsetFromEnd ] ) )
113       {
114         // early out if GIF
115         if( ++gifScore == sizeof(GIF) )
116         {
117           return VisualUrl::GIF;
118         }
119       }
120       switch( state )
121       {
122         case SUFFIX:
123         {
124           if( '.' == currentChar )
125           {
126             state = HASH;
127           }
128           break;
129         }
130         case HASH:
131         {
132           if( ( '#' == currentChar ) || ( '9' == currentChar ) )
133           {
134             state = HASH_DOT;
135           }
136           else
137           {
138             // early out, not a valid N/9-patch URL
139             return VisualUrl::REGULAR_IMAGE;
140           }
141           break;
142         }
143         case HASH_DOT:
144         {
145           if( '.' == currentChar )
146           {
147             return VisualUrl::N_PATCH;
148           }
149           else
150           {
151             // early out, not a valid N/9-patch URL
152             return VisualUrl::REGULAR_IMAGE;
153           }
154           break;
155         }
156       }
157     }
158   }
159   // if we got here it is a regular image
160   return VisualUrl::REGULAR_IMAGE;
161 }
162
163 }
164
165
166 VisualUrl::VisualUrl()
167 : mUrl(),
168   mType( VisualUrl::REGULAR_IMAGE ),
169   mLocation( VisualUrl::LOCAL )
170 {
171 }
172
173 VisualUrl::VisualUrl( const std::string& url )
174 : mUrl( url ),
175   mType( VisualUrl::REGULAR_IMAGE ),
176   mLocation( VisualUrl::LOCAL )
177 {
178   if( ! url.empty() )
179   {
180     mLocation = ResolveLocation( url );
181     mType = ResolveType( url );
182   }
183 }
184
185 VisualUrl::VisualUrl( const VisualUrl& url )
186 : mUrl( url.mUrl ),
187   mType( url.mType ),
188   mLocation( url.mLocation )
189 {
190 }
191
192 VisualUrl& VisualUrl::operator=( const VisualUrl& url )
193 {
194   if( &url != this )
195   {
196     mUrl = url.mUrl;
197     mType = url.mType;
198     mLocation = url.mLocation;
199   }
200   return *this;
201 }
202
203 const std::string& VisualUrl::GetUrl() const
204 {
205   return mUrl;
206 }
207
208 VisualUrl::Type VisualUrl::GetType() const
209 {
210   return mType;
211 }
212
213 VisualUrl::Location VisualUrl::GetLocation() const
214 {
215   return mLocation;
216 }
217
218 bool VisualUrl::IsValid() const
219 {
220   return mUrl.size() > 0u;
221 }
222
223 bool VisualUrl::IsLocal() const
224 {
225   return mLocation == VisualUrl::LOCAL;
226 }
227
228
229
230 } // Internal
231 } // Toolkit
232 } // Dali