2 * Copyright (c) 2021 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()
24 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
25 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
35 VisualUrl::ProtocolType ResolveLocation(const std::string& url)
37 const char* urlCStr = url.c_str();
38 const uint32_t length = url.size();
39 if((length > 7) && urlCStr[5] == ':' && urlCStr[6] == '/' && urlCStr[7] == '/')
41 // https:// or enbuf://
42 const char hOre = tolower(urlCStr[0]);
43 const char tOrn = tolower(urlCStr[1]);
44 const char tOrb = tolower(urlCStr[2]);
45 const char pOru = tolower(urlCStr[3]);
46 const char sOrf = tolower(urlCStr[4]);
53 return VisualUrl::REMOTE;
61 return VisualUrl::BUFFER;
64 else if((length > 6) && urlCStr[4] == ':' && urlCStr[5] == '/' && urlCStr[6] == '/')
67 const char hOrd = tolower(urlCStr[0]);
68 const char tOra = tolower(urlCStr[1]);
69 const char tOrl = tolower(urlCStr[2]);
70 const char pOri = tolower(urlCStr[3]);
76 return VisualUrl::REMOTE;
83 return VisualUrl::TEXTURE;
86 else if((length > 5) && urlCStr[3] == ':' && urlCStr[4] == '/' && urlCStr[5] == '/')
89 const char fOrs = tolower(urlCStr[0]);
90 const char tOrs = tolower(urlCStr[1]);
91 const char pOrh = tolower(urlCStr[2]);
96 return VisualUrl::REMOTE;
102 return VisualUrl::REMOTE;
105 return VisualUrl::LOCAL;
108 VisualUrl::Type ResolveType(const std::string& url)
110 // if only one char in string, can only be regular image
111 const std::size_t count = url.size();
114 // parsing from the end for better chance of early outs
121 char SVG[4] = {'g', 'v', 's', '.'};
122 char GIF[4] = {'f', 'i', 'g', '.'};
123 char WEBP[5] = {'p', 'b', 'e', 'w', '.'};
124 char JSON[5] = {'n', 'o', 's', 'j', '.'};
125 unsigned int svgScore = 0;
126 unsigned int gifScore = 0;
127 unsigned int webpScore = 0;
128 unsigned int jsonScore = 0;
132 const char currentChar = tolower(url[index]);
133 const std::size_t offsetFromEnd = count - index - 1u;
134 if((offsetFromEnd < sizeof(SVG)) && (currentChar == SVG[offsetFromEnd]))
136 // early out if SVG as can't be used in N patch for now
137 if(++svgScore == sizeof(SVG))
139 return VisualUrl::SVG;
142 if((offsetFromEnd < sizeof(GIF)) && (currentChar == GIF[offsetFromEnd]))
144 // early out if GIF as can't be used in N patch for now
145 if(++gifScore == sizeof(GIF))
147 return VisualUrl::GIF;
150 if((offsetFromEnd < sizeof(WEBP)) && (currentChar == WEBP[offsetFromEnd]))
152 // early out if WEBP as can't be used in N patch for now
153 if(++webpScore == sizeof(WEBP))
155 return VisualUrl::WEBP;
158 if((offsetFromEnd < sizeof(JSON)) && (currentChar == JSON[offsetFromEnd]))
160 // early out if JSON as can't be used in N patch for now
161 if(++jsonScore == sizeof(JSON))
163 return VisualUrl::JSON;
170 if('.' == currentChar)
178 if(('#' == currentChar) || ('9' == currentChar))
184 // early out, not a valid N/9-patch URL
185 return VisualUrl::REGULAR_IMAGE;
191 if('.' == currentChar)
193 return VisualUrl::N_PATCH;
197 // early out, not a valid N/9-patch URL
198 return VisualUrl::REGULAR_IMAGE;
205 // if we got here it is a regular image
206 return VisualUrl::REGULAR_IMAGE;
211 VisualUrl::VisualUrl()
213 mType(VisualUrl::REGULAR_IMAGE),
214 mLocation(VisualUrl::LOCAL)
218 VisualUrl::VisualUrl(const std::string& url)
220 mType(VisualUrl::REGULAR_IMAGE),
221 mLocation(VisualUrl::LOCAL)
225 mLocation = ResolveLocation(url);
226 if(VisualUrl::TEXTURE != mLocation && VisualUrl::BUFFER != mLocation)
228 // TEXTURE and BUFFER location url doesn't need type resolving, REGULAR_IMAGE is fine
229 mType = ResolveType(url);
233 Toolkit::VisualFactory factory = Toolkit::VisualFactory::Get();
236 GetImplementation(factory).GetTextureManager().UseExternalResource(*this);
242 VisualUrl::VisualUrl(const VisualUrl& url)
245 mLocation(url.mLocation)
247 if(VisualUrl::TEXTURE == mLocation || VisualUrl::BUFFER == mLocation)
249 Toolkit::VisualFactory factory = Toolkit::VisualFactory::Get();
252 GetImplementation(factory).GetTextureManager().UseExternalResource(*this);
257 VisualUrl::~VisualUrl()
259 if(VisualUrl::TEXTURE == mLocation)
261 Toolkit::VisualFactory factory = Toolkit::VisualFactory::Get();
264 GetImplementation(factory).GetTextureManager().RemoveExternalTexture(mUrl);
267 else if(VisualUrl::BUFFER == mLocation)
269 Toolkit::VisualFactory factory = Toolkit::VisualFactory::Get();
272 GetImplementation(factory).GetTextureManager().RemoveExternalEncodedImageBuffer(mUrl);
277 VisualUrl& VisualUrl::operator=(const VisualUrl& url)
281 if(VisualUrl::TEXTURE == mLocation)
283 Toolkit::VisualFactory factory = Toolkit::VisualFactory::Get();
286 GetImplementation(factory).GetTextureManager().RemoveExternalTexture(mUrl);
289 else if(VisualUrl::BUFFER == mLocation)
291 Toolkit::VisualFactory factory = Toolkit::VisualFactory::Get();
294 GetImplementation(factory).GetTextureManager().RemoveExternalEncodedImageBuffer(mUrl);
300 mLocation = url.mLocation;
302 if(VisualUrl::TEXTURE == mLocation || VisualUrl::BUFFER == mLocation)
304 Toolkit::VisualFactory factory = Toolkit::VisualFactory::Get();
307 GetImplementation(factory).GetTextureManager().UseExternalResource(*this);
314 const std::string& VisualUrl::GetUrl() const
319 VisualUrl::Type VisualUrl::GetType() const
324 VisualUrl::ProtocolType VisualUrl::GetProtocolType() const
329 bool VisualUrl::IsValid() const
331 return mUrl.size() > 0u;
334 bool VisualUrl::IsLocalResource() const
336 return mLocation == VisualUrl::LOCAL;
339 bool VisualUrl::IsBufferResource() const
341 return mLocation == VisualUrl::BUFFER;
344 std::string VisualUrl::GetLocation() const
346 return GetLocation(mUrl);
349 std::string VisualUrl::CreateTextureUrl(const std::string& location)
351 return "dali://" + location;
354 std::string VisualUrl::CreateBufferUrl(const std::string& location)
356 return "enbuf://" + location;
359 VisualUrl::ProtocolType VisualUrl::GetProtocolType(const std::string& url)
361 return ResolveLocation(url);
364 std::string VisualUrl::GetLocation(const std::string& url)
366 const auto location = url.find("://");
367 if(std::string::npos != location)
369 return url.substr(location + 3u); // 3 characters forwards from the start of ://
374 } // namespace Internal
376 } // namespace Toolkit