[2.2.1] Add a condition to remove needless log message
[platform/framework/native/appfw.git] / src / base / utility / FBaseUtilUri.cpp
1 //
2 // Copyright (c) 2012 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 /**
18  * @file                FBaseUtilUri.cpp
19  * @brief               This is the implementation file for Uri class.
20  */
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <new>
24 #include <unique_ptr.h>
25 #include <FBaseUtilUri.h>
26 #include <FBaseInteger.h>
27 #include <FBaseCharacter.h>
28 #include <FBaseShort.h>
29 #include <FBaseUtilStringTokenizer.h>
30 #include <FBaseUtilStringUtil.h>
31 #include <FBaseSysLog.h>
32
33 namespace Tizen { namespace Base { namespace Utility
34 {
35
36 static const wchar_t HEX_DIGITS[] = {L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7', L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F'};
37
38 /////////////////////////////////////////////////////////////////////////////////
39 // Life-cycle
40
41 Uri::Uri(void)
42         : __port(-1)
43         , __hasScheme(false)
44         , __ipv6ByteCount(0)
45         , __pUriImpl(null)
46 {
47 }
48
49 Uri::Uri(const Uri& uri)
50         : __pUriImpl(null)
51 {
52         SetUri(uri);
53 }
54
55 Uri::~Uri(void)
56 {
57         Clear();
58 }
59
60 void
61 Uri::SetUri(const Uri& uri)
62 {
63         __scheme = uri.__scheme;
64         __ssp = uri.__ssp;
65         __authority = uri.__authority;
66         __host = uri.__host;
67         __fragment = uri.__fragment;
68         __path = uri.__path;
69         __userInfo = uri.__userInfo;
70         __query = uri.__query;
71         __ipv4 = uri.__ipv4;
72         __ipv6 = uri.__ipv6;
73
74         __encodedAuth = uri.__encodedAuth;
75         __encodedFragment = uri.__encodedFragment;
76         __encodedPath = uri.__encodedPath;
77         __encodedQuery = uri.__encodedQuery;
78         __encodedSsp = uri.__encodedSsp;
79         __encodedUserInfo = uri.__encodedUserInfo;
80
81         __port = uri.__port;
82         __hasScheme = uri.__hasScheme;
83         __ipv6ByteCount = uri.__ipv6ByteCount;
84 }
85
86 result
87 Uri::SetUri(const Tizen::Base::String& str)
88 {
89         SysTryReturnResult(NID_BASE_UTIL, str.GetLength() > 0, E_INVALID_ARG, "Invalid argument is used. An empty String.");
90
91         Clear();
92
93         result r = ParseUri(str);
94         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_INVALID_FORMAT, "Translating [%s] into [%s].", GetErrorMessage(r), GetErrorMessage(E_INVALID_FORMAT));
95
96         return E_SUCCESS;
97 }
98
99 result
100 Uri::SetUri(const Tizen::Base::String& scheme, const Tizen::Base::String& ssp, const Tizen::Base::String& fragment)
101 {
102         String empty;
103
104         // scheme, ssp(opaquePart), authority, user-info, host, port, path, query, fragment
105         return SetUri(scheme, ssp, empty, empty, empty, -1, empty, empty, fragment);
106 }
107
108 result
109 Uri::SetUri(const Tizen::Base::String& scheme, const Tizen::Base::String& userInfo, const Tizen::Base::String& host, int port,
110                         const Tizen::Base::String& path, const Tizen::Base::String& query,
111                         const Tizen::Base::String& fragment)
112 {
113         String empty;
114
115         // scheme, ssp(opaquePart), authority, user-info, host, port, path, query, fragment
116         return SetUri(scheme, empty, empty, userInfo, host, port, path, query, fragment);
117 }
118
119 result
120 Uri::SetUri(const Tizen::Base::String& scheme, const Tizen::Base::String& host, const Tizen::Base::String& path,
121                         const Tizen::Base::String& fragment)
122 {
123         String empty;
124
125         // scheme, ssp(opaquePart), authority, user-info, host, port, path, query, fragment
126         return SetUri(scheme, empty, empty, empty, host, -1, path, L"", fragment);
127 }
128
129 result
130 Uri::SetUri(const Tizen::Base::String& scheme, const Tizen::Base::String& authority, const Tizen::Base::String& path,
131                         const Tizen::Base::String& query,
132                         const Tizen::Base::String& fragment)
133 {
134         String empty;
135
136         // scheme, ssp(opaquePart), authority, user-info, host, port, path, query, fragment
137         return SetUri(scheme, empty, authority, empty, empty, -1, path, query, fragment);
138 }
139
140 ////////////////////////////////////////////////////////////////////////////////
141 /// Operator
142
143 Uri&
144 Uri::operator =(const Uri& rhs)
145 {
146         if (&rhs != this)
147         {
148                 SetUri(rhs);
149         }
150         return *this;
151 }
152
153 ////////////////////////////////////////////////////////////////////////////////
154 // Accessor
155
156 Tizen::Base::String
157 Uri::GetAuthority(void) const
158 {
159         return __authority;
160 }
161
162 Tizen::Base::String
163 Uri::GetFragment(void) const
164 {
165         return __fragment;
166 }
167
168 Tizen::Base::String
169 Uri::GetHost(void) const
170 {
171         return __host;
172 }
173
174 Tizen::Base::String
175 Uri::GetPath(void) const
176 {
177         return __path;
178 }
179
180 int
181 Uri::GetPort(void) const
182 {
183         return __port;
184 }
185
186 Tizen::Base::String
187 Uri::GetQuery(void) const
188 {
189         return __query;
190 }
191
192 Tizen::Base::String
193 Uri::GetScheme(void) const
194 {
195         return __scheme;
196 }
197
198 Tizen::Base::String
199 Uri::GetSchemeSpecificPart(void) const
200 {
201         return __ssp;
202 }
203
204 Tizen::Base::String
205 Uri::GetUserInfo(void) const
206 {
207         return __userInfo;
208 }
209
210 Tizen::Base::String
211 Uri::GetEncodedAuthority(void) const
212 {
213         return __encodedAuth;
214 }
215
216 Tizen::Base::String
217 Uri::GetEncodedFragment(void) const
218 {
219         return __encodedFragment;
220 }
221
222 Tizen::Base::String
223 Uri::GetEncodedPath(void) const
224 {
225         return __encodedPath;
226 }
227
228 Tizen::Base::String
229 Uri::GetEncodedQuery(void) const
230 {
231         return __encodedQuery;
232 }
233
234 Tizen::Base::String
235 Uri::GetEncodedSchemeSpecificPart(void) const
236 {
237         return __encodedSsp;
238 }
239
240 Tizen::Base::String
241 Uri::GetEncodedUserInfo(void) const
242 {
243         return __encodedUserInfo;
244 }
245
246 bool
247 Uri::IsAbsolute(void) const
248 {
249         // If the URI has a scheme, then it is an absolute URI.
250         if (__hasScheme)
251         {
252                 return true;
253         }
254         else
255         {
256                 return false;
257         }
258 }
259
260 bool
261 Uri::IsOpaque(void) const
262 {
263         String scheme = GetScheme();
264         String ssp = GetSchemeSpecificPart();
265
266         if (scheme.IsEmpty())
267         {
268                 return false;
269         }
270
271         if (!ssp.IsEmpty())
272         {
273                 if (ssp[0] == L'/')
274                 {
275                         return false;
276                 }
277                 else
278                 {
279                         return true;
280                 }
281         }
282         else
283         {
284                 return false;
285         }
286 }
287
288 Tizen::Base::String
289 Uri::GetEncodedString(void) const
290 {
291         String strbuf;
292
293         // Scheme
294         if (!__scheme.IsEmpty())
295         {
296                 strbuf.Append(__scheme);
297                 strbuf.Append(L':');
298         }
299
300         if (!__encodedSsp.IsEmpty())
301         {
302                 strbuf.Append(__encodedSsp);
303         }
304         else
305         {
306                 if (!__host.IsEmpty())
307                 {
308                         // Check the Host
309                         strbuf.Append(L"//");
310
311                         // Check the Userinfo
312                         if (!__encodedUserInfo.IsEmpty())
313                         {
314                                 strbuf.Append(__encodedUserInfo);
315                                 strbuf.Append(L'@');
316                         }
317
318                         int indexOf = 0;
319                         result re = E_SUCCESS;
320                         re = __host.IndexOf(L':', 0, indexOf);
321
322                         String openBracket(L"[");
323                         String closeBracket(L"]");
324
325                         bool start = __host.StartsWith(openBracket, 0);
326                         bool end = __host.EndsWith(closeBracket);
327
328                         bool needBracket = false;
329                         if (!start && !end && re == E_SUCCESS)
330                         {
331                                 needBracket = true;
332                         }
333                         else
334                         {
335                                 needBracket = false;
336                         }
337
338                         if (needBracket)
339                         {
340                                 strbuf.Append(L'[');
341                         }
342
343                         strbuf.Append(__host);
344
345                         if (needBracket)
346                         {
347                                 strbuf.Append(L']');
348                         }
349
350                         // Check the port
351                         if (__port >= 0)
352                         {
353                                 strbuf.Append(L':');
354                                 strbuf.Append(__port);
355                         }
356                 }
357                 else if (!__encodedAuth.IsEmpty())
358                 {
359                         strbuf.Append(L"//");
360                         strbuf.Append(__encodedAuth);
361                 }
362                 // AppendAuthority end
363
364                 if (!__encodedPath.IsEmpty())
365                 {
366                         strbuf.Append(__encodedPath);
367                 }
368
369                 if (!__encodedQuery.IsEmpty())
370                 {
371                         strbuf.Append(L'?');
372                         strbuf.Append(__encodedQuery);
373                 }
374         }
375         // AppendSchemeSpecificPart end
376
377         //AppendFragment(strbuf, __encodedFragment);
378         if (!__encodedFragment.IsEmpty())
379         {
380                 strbuf.Append(L'#');
381                 strbuf.Append(__encodedFragment);
382         }
383         // AppendFragment end
384
385         return strbuf;
386 }
387
388 ////////////////////////////////////////////////////////////////////////////////////////////
389 // Operations
390
391 int
392 Uri::CompareTo(const Uri& uri) const
393 {
394         bool thisOpaque = false;
395         bool thatOpaque = false;
396
397         String query;
398         String otherQuery;
399         String path;
400         String otherPath;
401         String host;
402         String otherHost;
403         String fragment;
404         String otherFragment;
405         int ret = 0;
406
407         //////////////////////////////////////////////////
408         //                   Opaque                         //
409         /////////////////////////////////////////////////
410         thisOpaque = IsOpaque();
411         thatOpaque = uri.IsOpaque();
412
413         // Both the current instance and a given instance are opaque
414         if (thisOpaque && thatOpaque)
415         {
416                 // Compare Scheme-specific-part
417                 ret = Compare(__ssp, uri.__ssp);
418
419                 if (ret != 0)
420                 {
421                         return ret;
422                 }
423
424                 // compare fragment
425                 ret = Compare(__fragment, uri.__fragment);
426
427                 return ret;
428
429         }
430         else if (thisOpaque && !thatOpaque)
431         {
432                 return 1;
433         }
434         else if (!thisOpaque && thatOpaque)
435         {
436                 return -1;
437         }
438
439         //////////////////////////////////////////////////
440         //               Hierarchical                  //
441         /////////////////////////////////////////////////
442         if (!__host.IsEmpty() && !uri.__host.IsEmpty())
443         {
444                 // Server-based URI
445                 // Compare User-info
446                 ret = Compare(__userInfo, uri.__userInfo);
447
448                 if (ret != 0)
449                 {
450                         return ret;
451                 }
452
453                 // Compare host
454                 ret = Compare(__host, uri.__host);
455
456                 if (ret != 0)
457                 {
458                         return ret;
459                 }
460
461                 // Compare port
462                 int portDiff = __port - uri.__port;
463                 if (portDiff > 0)
464                 {
465                         return 1;
466                 }
467                 else if (portDiff == 0)
468                 {
469                         ret = 0;
470                 }
471                 else
472                 {
473                         return -1;
474                 }
475         }
476         else
477         {
478                 // If one of them is registry-based URI, then compare authority.
479                 ret = Compare(__authority, uri.__authority);
480
481                 if (ret != 0)
482                 {
483                         return ret;
484                 }
485         }
486
487         // Compare path
488         ret = Compare(__path, uri.__path);
489         if (ret != 0)
490         {
491                 return ret;
492         }
493
494         // Compare query
495         ret = Compare(__query, uri.__query);
496         if (ret != 0)
497         {
498                 return ret;
499         }
500
501         // Compare fragment
502         ret = Compare(__fragment, uri.__fragment);
503
504         return ret;
505 }
506
507 bool
508 Uri::Equals(const Tizen::Base::Object& obj) const
509 {
510         // Check that obj is an Uri instance.
511         const Uri* pOther = dynamic_cast< const Uri* >(&obj);
512         if (pOther == null)
513         {
514                 return false;
515         }
516
517         int ret = CompareTo(*pOther);
518         if (ret != 0)
519         {
520                 return false;
521         }
522
523         return true;
524 }
525
526 int
527 Uri::GetHashCode(void) const
528 {
529         return ToString().GetHashCode();
530 }
531
532 Uri
533 Uri::Normalize(void)
534 {
535         result r = E_SUCCESS;
536         Uri resultUri;
537
538         // If the current instance is opaque or the path of the current instance is undefined or an empty string,
539         // return itself.
540         if (__path.IsEmpty() || IsOpaque())
541         {
542                 return *this;
543         }
544
545         String normalizedUri;
546         normalizedUri = InternalNormalize(__path);
547         if (normalizedUri == __path || GetLastResult() == E_INVALID_ARG)
548         {
549                 return *this;
550         }
551
552         if (!__scheme.IsEmpty())
553         {
554                 r = resultUri.SetScheme(__scheme);
555                 SysTryReturn(NID_BASE_UTIL, !IsFailed(r), *this, r, "[%s] : Failed to set scheme.", GetErrorMessage(r));
556         }
557
558         if (!__fragment.IsEmpty())
559         {
560                 r = resultUri.SetFragment(__fragment);
561                 SysTryReturn(NID_BASE_UTIL, !IsFailed(r), *this, r, "[%s] : Failed to set fragment.", GetErrorMessage(r));
562         }
563
564         if (!__authority.IsEmpty())
565         {
566                 r = resultUri.SetAuthority(__authority);
567                 SysTryReturn(NID_BASE_UTIL, !IsFailed(r), *this, r, "[%s] : Failed to set authority.", GetErrorMessage(r));
568         }
569
570         if (!__userInfo.IsEmpty())
571         {
572                 r = resultUri.SetUserInfo(__userInfo);
573                 SysTryReturn(NID_BASE_UTIL, !IsFailed(r), *this, r, "[%s] : Failed to set userinfo.", GetErrorMessage(r));
574         }
575
576         if (!__host.IsEmpty())
577         {
578                 r = resultUri.SetHost(__host);
579                 SysTryReturn(NID_BASE_UTIL, !IsFailed(r), *this, r, "[%s] : Failed to set host.", GetErrorMessage(r));
580         }
581
582         resultUri.SetPort(__port);
583
584         r = resultUri.SetPath(normalizedUri);
585         SysTryReturn(NID_BASE_UTIL, !IsFailed(r), *this, r, "[%s] : Failed to set path.", GetErrorMessage(r));
586
587         if (!__query.IsEmpty())
588         {
589                 r = resultUri.SetQuery(__query);
590                 SysTryReturn(NID_BASE_UTIL, !IsFailed(r), *this, r, "[%s] : Failed to set query.", GetErrorMessage(r));
591         }
592
593         return resultUri;
594 }
595
596 result
597 Uri::ParseAuthority(Uri& uri)
598 {
599         result r = E_SUCCESS;
600
601         if (!__host.IsEmpty() || __authority.IsEmpty())
602         {
603                 uri = *this;
604                 return r;
605         }
606
607         String str = ToString();
608
609         Uri tempUri;
610         r = tempUri.SetUri(str);
611         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
612
613         r = ParseServerAuthority(str, tempUri.__host, tempUri.__userInfo, tempUri.__port);
614         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
615
616         uri = tempUri;
617
618         return r;
619 }
620
621 result
622 Uri::Relativize(const Uri& uri, Uri& resultUri)
623 {
624         return Relativize(*this, uri, resultUri);
625 }
626
627 result
628 Uri::Resolve(const Uri& uri, Uri& resultUri)
629 {
630         return Resolve(*this, uri, resultUri);
631 }
632
633 result
634 Uri::SetAuthority(const Tizen::Base::String& authority)
635 {
636         bool isAuth = VerifyAuthority(authority);
637
638         SysTryReturn(NID_BASE_UTIL, isAuth, E_INVALID_FORMAT, E_INVALID_FORMAT, "[%s] Invalid Authority.", GetErrorMessage(E_INVALID_FORMAT));
639
640         if (IsEncoded(authority))
641         {
642                 __encodedAuth = authority;
643                 __authority = Decode(authority);
644         }
645         else
646         {
647                 __authority = authority;
648                 __encodedAuth = Encode(authority);
649         }
650
651         return E_SUCCESS;
652 }
653
654 result
655 Uri::SetFragment(const Tizen::Base::String& fragment)
656 {
657         bool isFragment = VerifyUriChar(fragment);
658
659         SysTryReturn(NID_BASE_UTIL, isFragment, E_INVALID_FORMAT, E_INVALID_FORMAT, "[%s] Invalid Fragment.", GetErrorMessage(E_INVALID_FORMAT));
660
661         if (IsEncoded(fragment))
662         {
663                 __encodedFragment = fragment;
664                 __fragment = Decode(fragment);
665         }
666         else
667         {
668                 __fragment = fragment;
669                 __encodedFragment = Encode(fragment);
670         }
671
672         return E_SUCCESS;
673 }
674
675 result
676 Uri::SetHost(const Tizen::Base::String& host)
677 {
678         bool isHost = VerifyHost(host);
679
680         SysTryReturn(NID_BASE_UTIL, isHost, E_INVALID_FORMAT, E_INVALID_FORMAT, "[%s] Invalid Host.", GetErrorMessage(E_INVALID_FORMAT));
681
682         __host = host;
683
684         return E_SUCCESS;
685 }
686
687 result
688 Uri::SetPath(const Tizen::Base::String& path)
689 {
690         bool isPath = VerifyPath(path);
691
692         SysTryReturn(NID_BASE_UTIL, isPath, E_INVALID_FORMAT, E_INVALID_FORMAT, "[%s] Invalid Path.", GetErrorMessage(E_INVALID_FORMAT));
693
694         if (IsEncoded(path))
695         {
696                 __encodedPath = path;
697                 __path = Decode(path);
698         }
699         else
700         {
701                 __path = path;
702                 __encodedPath = Encode(path);
703         }
704
705         return E_SUCCESS;
706 }
707
708 result
709 Uri::SetPort(int port)
710 {
711         SysTryReturn(NID_BASE_UTIL, port >= 0, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. The port(%d) MUST be greater than or equal to 0.", GetErrorMessage(E_INVALID_ARG), port);
712
713         __port = port;
714
715         return E_SUCCESS;
716 }
717
718 result
719 Uri::SetQuery(const Tizen::Base::String& query)
720 {
721         bool isQuery = VerifyUriChar(query);
722
723         SysTryReturn(NID_BASE_UTIL, isQuery, E_INVALID_FORMAT, E_INVALID_FORMAT, "[%s] Invalid Query.", GetErrorMessage(E_INVALID_FORMAT));
724
725         if (IsEncoded(query))
726         {
727                 __encodedQuery = query;
728                 __query = Decode(query);
729         }
730         else
731         {
732                 __query = query;
733                 __encodedQuery = Encode(query);
734         }
735
736         return E_SUCCESS;
737 }
738
739 result
740 Uri::SetScheme(const Tizen::Base::String& scheme)
741 {
742         bool isScheme = VerifyScheme(scheme);
743
744         SysTryReturn(NID_BASE_UTIL, isScheme, E_INVALID_FORMAT, E_INVALID_FORMAT, "[%s] Invalid Scheme.", GetErrorMessage(E_INVALID_FORMAT));
745
746         __scheme = scheme;
747
748         return E_SUCCESS;
749 }
750
751 result
752 Uri::SetSchemeSpecificPart(const Tizen::Base::String& ssp)
753 {
754         bool isSsp = VerifyUriChar(ssp);
755
756         SysTryReturn(NID_BASE_UTIL, isSsp, E_INVALID_FORMAT, E_INVALID_FORMAT, "[%s] Invalid SchemeSpecificPart.", GetErrorMessage(E_INVALID_FORMAT));
757
758         if (IsEncoded(ssp))
759         {
760                 __encodedSsp = ssp;
761                 __ssp = Decode(ssp);
762         }
763         else
764         {
765                 __ssp = ssp;
766                 __encodedSsp = Encode(ssp);
767         }
768
769         return E_SUCCESS;
770 }
771
772 result
773 Uri::SetUserInfo(const Tizen::Base::String& userInfo)
774 {
775         bool isUserInfo = VerifyUserInfo(userInfo);
776
777         SysTryReturn(NID_BASE_UTIL, isUserInfo, E_INVALID_FORMAT, E_INVALID_FORMAT, "[%s] Invalid UserInfo.", GetErrorMessage(E_INVALID_FORMAT));
778
779         if (IsEncoded(userInfo))
780         {
781                 __encodedUserInfo = userInfo;
782                 __userInfo = Decode(userInfo);
783         }
784         else
785         {
786                 __userInfo = userInfo;
787                 __encodedUserInfo = Encode(userInfo);
788         }
789
790         return E_SUCCESS;
791 }
792
793 Tizen::Base::String
794 Uri::ToString(void) const
795 {
796         String strbuf;
797
798         // Scheme
799         if (!__scheme.IsEmpty())
800         {
801                 strbuf.Append(__scheme);
802                 strbuf.Append(L':');
803         }
804
805         if (IsOpaque())
806         {
807                 strbuf.Append(__ssp);
808         }
809         else
810         {
811                 if (!__host.IsEmpty())
812                 {
813                         // Check the Host
814                         strbuf.Append(L"//");
815
816                         // Check the Userinfo
817                         if (!__userInfo.IsEmpty())
818                         {
819                                 strbuf.Append(__userInfo);
820                                 strbuf.Append(L'@');
821                         }
822
823                         int indexOf = 0;
824                         result re = E_SUCCESS;
825                         re = __host.IndexOf(L':', 0, indexOf);
826
827                         String openBracket(L"[");
828                         String closeBracket(L"]");
829
830                         bool start = __host.StartsWith(openBracket, 0);
831                         bool end = __host.EndsWith(closeBracket);
832
833                         bool needBracket = false;
834                         if (!start && !end && re == E_SUCCESS)
835                         {
836                                 needBracket = true;
837                         }
838                         else
839                         {
840                                 needBracket = false;
841                         }
842
843                         if (needBracket)
844                         {
845                                 strbuf.Append(L'[');
846                         }
847
848                         strbuf.Append(__host);
849
850                         if (needBracket)
851                         {
852                                 strbuf.Append(L']');
853                         }
854
855                         // Check the port
856                         if (__port >= 0)
857                         {
858                                 strbuf.Append(L':');
859                                 strbuf.Append(__port);
860                         }
861                 }
862                 else if (!__authority.IsEmpty())
863                 {
864                         strbuf.Append(L"//");
865                         strbuf.Append(__authority);
866                 }
867                 // AppendAuthority end
868
869                 if (!__path.IsEmpty())
870                 {
871                         strbuf.Append(__path);
872                 }
873
874                 if (!__query.IsEmpty())
875                 {
876                         strbuf.Append(L'?');
877                         strbuf.Append(__query);
878                 }
879         }
880         // AppendSchemeSpecificPart end
881
882         //AppendFragment(strbuf, __fragment);
883         if (!__fragment.IsEmpty())
884         {
885                 strbuf.Append(L'#');
886                 strbuf.Append(__fragment);
887         }
888         // AppendFragment end
889
890         return strbuf;
891 }
892
893 ////////////////////////////////////////////////////////////////////////
894 // Private methods
895 //
896 // This method constructs an URI instance.
897 //
898 result
899 Uri::SetUri(const Tizen::Base::String& scheme, const Tizen::Base::String& opaque, const Tizen::Base::String& authority,
900                         const Tizen::Base::String& userInfo, const Tizen::Base::String& host, int port, const Tizen::Base::String& path,
901                         const Tizen::Base::String& query,
902                         const Tizen::Base::String& fragment)
903 {
904         result r = E_SUCCESS;
905         String fullUri;
906         String strbuf;
907
908         // Scheme
909         if (!scheme.IsEmpty())
910         {
911                 // Check that an extracted scheme is satisfied with RFC2396.
912                 bool isScheme = VerifyScheme(scheme);
913                 SysTryReturnResult(NID_BASE_UTIL, isScheme, E_INVALID_FORMAT, "The scheme is invalid.");
914
915                 r = strbuf.Append(scheme);
916                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Failed to append the scheme.");
917
918                 r = strbuf.Append(L':');
919                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Failed to append L':'.");
920         }
921
922         r = AppendSchemeSpecificPart(strbuf, opaque, authority, userInfo, host, port, path, query);
923         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
924
925         r = AppendFragment(strbuf, fragment);
926         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
927
928         fullUri = strbuf;
929
930         r = SetUri(fullUri);
931         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Failed to set the uri.");
932
933         return E_SUCCESS;
934 }
935
936 result
937 Uri::AppendSchemeSpecificPart(Tizen::Base::String& strbuf, const Tizen::Base::String& opaque, const Tizen::Base::String& authority,
938                                                           const Tizen::Base::String& userInfo, const Tizen::Base::String& host, int port,
939                                                           const Tizen::Base::String& path,
940                                                           const Tizen::Base::String& query) const
941 {
942         result r = E_SUCCESS;
943         // Opaque part
944         if (!opaque.IsEmpty())
945         {
946                 SysTryReturnResult(NID_BASE_UTIL, VerifyUriChar(opaque), E_INVALID_FORMAT, "The opaque is invalid.");
947                 r = strbuf.Append(opaque);
948                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Failed to append opaque.");
949         }
950         else
951         {
952                 r = AppendAuthority(strbuf, authority, userInfo, host, port);
953                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Failed to append the authority.");
954
955                 if (!path.IsEmpty())
956                 {
957                         SysTryReturnResult(NID_BASE_UTIL, VerifyPath(path), E_INVALID_FORMAT, "The path is invalid.");
958                         r = strbuf.Append(path);
959                 }
960
961                 if (!query.IsEmpty())
962                 {
963                         SysTryReturnResult(NID_BASE_UTIL, VerifyUriChar(query), E_INVALID_FORMAT, "The query is invalid.");
964                         r = strbuf.Append(L'?');
965                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Failed to append L'?'.");
966
967                         r = strbuf.Append(query);
968                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Failed to append the query.");
969                 }
970         }
971
972         return E_SUCCESS;
973 }
974
975 result
976 Uri::AppendFragment(Tizen::Base::String& strbuf, const Tizen::Base::String& fragment) const
977 {
978         if (!fragment.IsEmpty())
979         {
980                 SysTryReturnResult(NID_BASE_UTIL, VerifyUriChar(fragment), E_INVALID_FORMAT, "The fragment is invalid.");
981
982                 result r = strbuf.Append(L'#');
983                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Failed to append L'#'.");
984
985                 r = strbuf.Append(fragment);
986                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Failed to append the fragment.");
987         }
988
989         return E_SUCCESS;
990 }
991
992 result
993 Uri::AppendAuthority(Tizen::Base::String& strbuf, const Tizen::Base::String& authority, const Tizen::Base::String& userInfo,
994                                          const Tizen::Base::String& host,
995                                          int port) const
996 {
997         result r = E_SUCCESS;
998
999         String doubleSlash(L"//");
1000
1001         if (!host.IsEmpty())
1002         {
1003                 // Check the Host
1004                 SysTryReturnResult(NID_BASE_UTIL, VerifyHost(host), E_INVALID_FORMAT, "The host is invalid.");
1005
1006                 r = strbuf.Append(doubleSlash);
1007                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Failed to append the doubleSlash.");
1008
1009                 // Check the Userinfo
1010                 if (!userInfo.IsEmpty())
1011                 {
1012                         SysTryReturnResult(NID_BASE_UTIL, VerifyUserInfo(userInfo), E_INVALID_FORMAT, "The userInfo is invalid.");
1013                         r = strbuf.Append(userInfo);
1014                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Failed to append the userInfo.");
1015
1016                         r = strbuf.Append(L'@');
1017                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Failed to append L'@'.");
1018                 }
1019
1020                 int indexOf = 0;
1021                 result re = E_SUCCESS;
1022                 re = host.IndexOf(L':', 0, indexOf);
1023
1024                 String openBracket(L"[");
1025                 String closeBracket(L"]");
1026
1027                 bool start = host.StartsWith(openBracket, 0);
1028                 bool end = host.EndsWith(closeBracket);
1029
1030                 bool needBracket = true;
1031                 if (!start && !end && re == E_SUCCESS)
1032                 {
1033                         needBracket = true;
1034                 }
1035                 else
1036                 {
1037                         needBracket = false;
1038                 }
1039
1040                 if (needBracket)
1041                 {
1042                         r = strbuf.Append(L'[');
1043                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Failed to append L'['.");
1044                 }
1045
1046                 r = strbuf.Append(host);
1047                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Failed to append the host.");
1048
1049                 if (needBracket)
1050                 {
1051                         r = strbuf.Append(L']');
1052                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Failed to append L']'.");
1053                 }
1054
1055                 // Check the port
1056                 const int UNDEFINED_PORT = -1;
1057                 if (port >= 0)
1058                 {
1059                         r = strbuf.Append(L':');
1060                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Failed to append L':'.");
1061
1062                         r = strbuf.Append(port);
1063                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Failed to append the port.");
1064                 }
1065                 else if (port != UNDEFINED_PORT)
1066                 {
1067                         return E_INVALID_FORMAT;
1068                 }
1069         }
1070         else if (!authority.IsEmpty())
1071         {
1072                 r = strbuf.Append(doubleSlash);
1073                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Failed to append the doubleSlash.");
1074
1075                 SysTryReturnResult(NID_BASE_UTIL, VerifyAuthority(authority), E_INVALID_FORMAT, "The authority is invalid.");
1076                 r = strbuf.Append(authority);
1077                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Failed to append the authority.");
1078         }
1079
1080         return E_SUCCESS;
1081 }
1082
1083 //
1084 // This method breaks a given string into Uri components.
1085 // str : [scheme:]<scheme-specific-part>[#<fragment>]
1086 //
1087 result
1088 Uri::ParseUri(const Tizen::Base::String& str)
1089 {
1090         result r = E_SUCCESS;
1091         wchar_t colon = L':';
1092         wchar_t sharp = L'#';
1093         int indexOf = 0;
1094         int startSsp = 0;
1095         int curIndex = 0; // points the current index
1096         int startFragment = 0;
1097         int lengthOfUri = str.GetLength();
1098
1099         String authority;
1100         String path;
1101         String query;
1102
1103         /////////////////////////////////////////////////////////////////
1104         // First, exract a scheme component from a given string.//
1105         ////////////////////////////////////////////////////////////////
1106
1107         // Check the space
1108         SysTryReturnResult(NID_BASE_UTIL, str[0] != L' ', E_INVALID_FORMAT, "Invalid Scheme.");
1109
1110         // Get a index of ':'
1111         r = str.IndexOf(colon, 0, indexOf);
1112         if (indexOf >= 0 && r == E_SUCCESS)
1113         {
1114                 // There is a scheme componenet.
1115                 String scheme;
1116                 r = str.SubString(0, indexOf, scheme);
1117                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1118
1119                 // Check that an extracted scheme is satisfied with RFC2396.
1120                 SysTryReturnResult(NID_BASE_UTIL, VerifyScheme(scheme), E_INVALID_FORMAT, "Invalid Scheme.");
1121
1122                 curIndex = indexOf;
1123                 __scheme = scheme;
1124                 __hasScheme = true;
1125         }
1126         else
1127         {
1128                 // In case there is no scheme component, the Uri is a hierarchical URI.
1129                 startSsp = 0;
1130                 __hasScheme = false;
1131         }
1132
1133         ////////////////////////////////////////////////////////////////////////
1134         // Second, extract a scheme-specific-part from a given string.//
1135         ///////////////////////////////////////////////////////////////////////
1136         if (__hasScheme) // This URI has a scheme.
1137         {
1138                 startSsp = ++curIndex; // skip ':'
1139                 SysTryReturnResult(NID_BASE_UTIL, startSsp < lengthOfUri, E_INVALID_FORMAT, "startSsp must be less than lengthOfUri.");
1140
1141                 if (str[startSsp] == '/')
1142                 {
1143                         // Hierarchical URI
1144                         r = ParseHierarchicalUri(str, startSsp, authority, path, query, curIndex);
1145                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1146
1147                         SetAndEncodeAuthority(authority, path, query);
1148
1149                         String ssp;
1150                         r = str.SubString(startSsp, curIndex - startSsp, ssp);
1151                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1152
1153                         if (IsEncoded(ssp))
1154                         {
1155                                 __ssp = Decode(ssp);
1156                                 __encodedSsp = ssp;
1157                         }
1158                         else
1159                         {
1160                                 __ssp = ssp;
1161                                 __encodedSsp = Encode(ssp);
1162                         }
1163
1164                 }
1165                 else
1166                 {
1167                         // Opaque URI
1168                         String ssp;
1169
1170                         r = str.IndexOf(sharp, curIndex, (int&)startFragment);
1171                         if (startFragment > curIndex && r == E_SUCCESS)
1172                         {
1173                                 r = str.SubString(startSsp, startFragment - curIndex, ssp);
1174                                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1175                         }
1176                         else if (r == E_OBJ_NOT_FOUND)
1177                         {
1178                                 startFragment = 0;
1179                                 r = str.SubString(startSsp, lengthOfUri - curIndex, ssp);
1180                                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1181                         }
1182                         else
1183                         {
1184                                 return r;
1185                         }
1186
1187                         SysTryReturnResult(NID_BASE_UTIL, VerifyUriChar(ssp), E_INVALID_FORMAT, "Invalid Opaque URI.");
1188
1189                         // Opaque URI is not subject to further parsing.
1190                         if (IsEncoded(ssp))
1191                         {
1192                                 __ssp = Decode(ssp);
1193                                 __encodedSsp = ssp;
1194                         }
1195                         else
1196                         {
1197                                 __ssp = ssp;
1198                                 __encodedSsp = Encode(ssp);
1199                         }
1200
1201                         if (startFragment == 0)
1202                         {
1203                                 return E_SUCCESS;
1204                         }
1205
1206                         // Check the fragment
1207                         String fragment;
1208
1209                         startFragment++;
1210                         r = str.SubString(startFragment, lengthOfUri - startFragment, fragment);
1211                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1212
1213                         SysTryReturnResult(NID_BASE_UTIL, VerifyUriChar(fragment), E_INVALID_FORMAT, "Invalid Fragment.");
1214
1215                         if (IsEncoded(fragment))
1216                         {
1217                                 __fragment = Decode(fragment);
1218                                 __encodedFragment = fragment;
1219                         }
1220                         else
1221                         {
1222                                 __fragment = fragment;
1223                                 __encodedFragment = Encode(fragment);
1224                         }
1225
1226                         return E_SUCCESS;
1227                 }
1228         }
1229         else // This URI doesn't have a Scheme. - www.samsung.com[#ocean]
1230         {
1231                 startSsp = 0;
1232
1233                 r = ParseHierarchicalUri(str, startSsp, authority, path, query, curIndex);
1234                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1235
1236                 String ssp;
1237                 r = str.SubString(startSsp, curIndex - startSsp, ssp);
1238                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1239
1240                 if (IsEncoded(ssp))
1241                 {
1242                         __ssp = Decode(ssp);
1243                         __encodedSsp = ssp;
1244                 }
1245                 else
1246                 {
1247                         __ssp = ssp;
1248                         __encodedSsp = Encode(ssp);
1249                 }
1250
1251                 SetAndEncodeAuthority(authority, path, query);
1252         }
1253
1254         //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1255         // Parse an authority component. The authority component is registry_based or server_based authority.//
1256         // Server_based authority consists of user-info, host and port.//
1257         /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1258         if (!authority.IsEmpty())
1259         {
1260                 String userInfo;
1261                 String host;
1262                 int port = 0;
1263
1264                 String newAuth;
1265                 r = ParseAuthority(authority, curIndex, newAuth, userInfo, host, port);
1266                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1267
1268                 if (!userInfo.IsEmpty())
1269                 {
1270                         if (IsEncoded(userInfo))
1271                         {
1272                                 __userInfo = Decode(userInfo);
1273                                 __encodedUserInfo = userInfo;
1274                         }
1275                         else
1276                         {
1277                                 __userInfo = userInfo;
1278                                 __encodedUserInfo = Encode(userInfo);
1279                         }
1280                 }
1281
1282                 if (!host.IsEmpty())
1283                 {
1284                         __host = host;
1285                 }
1286
1287                 __port = port;
1288         }
1289
1290         /////////////////////////////////////////////////
1291         // Finally, extract a fragment component //
1292         ////////////////////////////////////////////////
1293         startFragment = curIndex;
1294         if (startFragment < lengthOfUri && str[startFragment] == '#')
1295         {
1296                 startFragment++;
1297                 String fragment;
1298
1299                 if (startFragment < lengthOfUri)
1300                 {
1301                         r = str.SubString(startFragment, lengthOfUri - startFragment, fragment);
1302                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1303                 }
1304
1305                 SysTryReturnResult(NID_BASE_UTIL, VerifyUriChar(fragment), E_INVALID_FORMAT, "Invalid Fragment.");
1306
1307                 if (IsEncoded(fragment))
1308                 {
1309                         __fragment = Decode(fragment);
1310                         __encodedFragment = fragment;
1311                 }
1312                 else
1313                 {
1314                         __fragment = fragment;
1315                         __encodedFragment = Encode(fragment);
1316                 }
1317
1318                 curIndex += fragment.GetLength() + 1; // skip '#'
1319         }
1320
1321         SysTryReturnResult(NID_BASE_UTIL, curIndex >= lengthOfUri, E_INVALID_FORMAT, "curIndex must be greater than or equal to lengthOfUri.");
1322
1323         return E_SUCCESS;
1324 }
1325
1326 void
1327 Uri::SetAndEncodeAuthority(const Tizen::Base::String& authority, const Tizen::Base::String& path, const Tizen::Base::String& query)
1328 {
1329         bool isEncoded = false;
1330
1331         //// Authority ////
1332         if (!authority.IsEmpty())
1333         {
1334                 isEncoded = IsEncoded(authority);
1335                 if (isEncoded)
1336                 {
1337                         __authority = Decode(authority);
1338                         __encodedAuth = authority;
1339                 }
1340                 else
1341                 {
1342                         __authority = authority;
1343                         __encodedAuth = Encode(authority);
1344                 }
1345         }
1346
1347         //// Path ////
1348         if (!path.IsEmpty())
1349         {
1350                 isEncoded = IsEncoded(path);
1351                 if (isEncoded)
1352                 {
1353                         __path = Decode(path);
1354                         __encodedPath = path;
1355                 }
1356                 else
1357                 {
1358                         __path = path;
1359                         __encodedPath = Encode(path);
1360                 }
1361         }
1362
1363         //// Query ////
1364         if (!query.IsEmpty())
1365         {
1366                 isEncoded = IsEncoded(query);
1367                 if (isEncoded)
1368                 {
1369                         __query = Decode(query);
1370                         __encodedQuery = query;
1371                 }
1372                 else
1373                 {
1374                         __query = query;
1375                         __encodedQuery = Encode(query);
1376                 }
1377         }
1378 }
1379
1380 result
1381 Uri::ParseHierarchicalUri(const Tizen::Base::String& str, int startSsp, Tizen::Base::String& authority, Tizen::Base::String& path,
1382                                                   Tizen::Base::String& query,
1383                                                   int& index)
1384 {
1385         result r = E_SUCCESS;
1386         int curIndex = startSsp;
1387
1388         String tempPath;
1389         String queSharp(L"?#");
1390         String doubleSlash(L"//");
1391
1392         int position = 0;
1393         int temp = -1;
1394
1395         bool startsWith = str.StartsWith(doubleSlash, curIndex);
1396
1397         if (startsWith)
1398         {
1399                 curIndex += 2;
1400
1401                 String special(L"/?#");
1402                 int index = Scan(str, curIndex, special);
1403                 if (index > curIndex)
1404                 {
1405                         r = str.SubString(curIndex, index - curIndex, authority);
1406                         SysTryCatch(NID_BASE_UTIL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
1407                 }
1408                 else if (index >= str.GetLength())
1409                 {
1410                         r = E_INVALID_FORMAT;
1411                         goto CATCH;
1412                 }
1413
1414                 curIndex += authority.GetLength();
1415                 if (curIndex == str.GetLength())
1416                 {
1417                         r = E_SUCCESS;
1418                         goto CATCH;
1419                 }
1420         }
1421
1422         queSharp.IndexOf(str[0], 0, temp);
1423         if (temp >= 0)
1424         {
1425                 position = 0;
1426         }
1427         else
1428         {
1429                 position = Scan(str, curIndex, queSharp);
1430
1431                 if (position == curIndex && authority.GetLength() == 0)
1432                 {
1433                         // If both authority and path are empty, it returns error.
1434                         r = E_INVALID_FORMAT;
1435                         goto CATCH;
1436                 }
1437         }
1438
1439         r = str.SubString(curIndex, position - curIndex, tempPath);
1440         SysTryCatch(NID_BASE_UTIL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
1441
1442         SysTryReturnResult(NID_BASE_UTIL, VerifyPath(tempPath), E_INVALID_FORMAT, "Invalid Path.");
1443
1444         path = tempPath;
1445
1446         curIndex = position;
1447
1448         // If there is no query after question-mark "?", this method returns E_SUCCESS and saves empty string as query.
1449         if (curIndex < str.GetLength() && str[curIndex] == L'?' && ++curIndex < str.GetLength())
1450         {
1451                 String tempQuery;
1452
1453                 int indexOf = 0;
1454                 r = str.IndexOf(L'#', curIndex, indexOf);
1455                 if (r == E_SUCCESS)
1456                 {
1457                         r = str.SubString(curIndex, indexOf - curIndex, tempQuery);
1458                         SysTryCatch(NID_BASE_UTIL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
1459                 }
1460                 else if (r == E_OBJ_NOT_FOUND)
1461                 {
1462                         r = str.SubString(curIndex, tempQuery);
1463                         SysTryCatch(NID_BASE_UTIL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
1464                 }
1465                 else
1466                 {
1467                         SysTryCatch(NID_BASE_UTIL, false, , r, "[%s] Propagating.", GetErrorMessage(r));
1468                 }
1469
1470                 bool isQuery = VerifyUriChar(tempQuery);
1471                 if (isQuery)
1472                 {
1473                         query = tempQuery;
1474                 }
1475                 curIndex += query.GetLength();
1476         }
1477
1478 CATCH:
1479         index = curIndex;
1480         return r;
1481 }
1482
1483 //
1484 // This method parses an authority component.
1485 // This component is server based or registrty authority.
1486 //
1487 result
1488 Uri::ParseAuthority(const Tizen::Base::String& str, int curIndex, Tizen::Base::String& newAuth, Tizen::Base::String& userInfo,
1489                                         Tizen::Base::String& host,
1490                                         int& port)
1491 {
1492         result r = E_SUCCESS;
1493
1494         bool isServerChar = VerifyServerAuthority(str);
1495         bool isRegChar = VerifyRegistryAuthority(str);
1496
1497         if (isRegChar && !isServerChar)
1498         {
1499                 newAuth = str;
1500                 return E_SUCCESS;
1501         }
1502
1503         if (isServerChar)
1504         {
1505                 r = ParseServerAuthority(str, userInfo, host, port);
1506                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1507
1508                 newAuth = str;
1509         }
1510
1511         if (isRegChar)
1512         {
1513                 newAuth = str;
1514         }
1515
1516         return E_SUCCESS;
1517 }
1518
1519 //
1520 // This method parses a server_based authority componenet.
1521 // server_based authority : [user-info@]<host>[:port]
1522 //
1523 result
1524 Uri::ParseServerAuthority(const Tizen::Base::String& str, Tizen::Base::String& user, Tizen::Base::String& host, int& port)
1525 {
1526         result r = E_SUCCESS;
1527         int indexOf = 0;
1528         int index = 0;
1529         String userInfo;
1530
1531         // User-info
1532         r = str.IndexOf(L'@', 0, indexOf);
1533         if (r == E_SUCCESS)
1534         {
1535                 r = str.SubString(0, indexOf, userInfo);
1536                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1537
1538                 SysTryReturnResult(NID_BASE_UTIL, VerifyUserInfo(userInfo), E_INVALID_FORMAT, "Invalid UserInfo.");
1539
1540                 user = userInfo;
1541
1542                 index += indexOf + 1; // skip '@'
1543         }
1544
1545         // IPv4 or IPv6 address
1546         if (str[0] == L'[')
1547         {
1548                 // IPv6 not supported
1549                 return E_INVALID_FORMAT;
1550         }
1551         else
1552         {
1553                 String ip4;
1554                 int count = 0;
1555
1556                 r = ParseIpv4(str, index, count); // length of ipv4 string
1557                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1558
1559                 if (count >= 0)
1560                 {
1561                         r = str.SubString(0, count, ip4);
1562                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1563
1564                         host = ip4;
1565                 }
1566                 else if (count < 0)
1567                 {
1568                         // This is a host name
1569                         String tmpHost;
1570
1571                         r = ParseHostName(str, index, tmpHost);
1572                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1573
1574                         host = tmpHost;
1575                 }
1576         }
1577
1578         // Port
1579         if (host.IsEmpty())
1580         {
1581                 port = -1;
1582                 return E_SUCCESS;
1583         }
1584
1585         index += host.GetLength();
1586         if (index < str.GetLength() && str[index] == L':')
1587         {
1588                 String tmpPort;
1589
1590                 index++;
1591                 r = str.IndexOf(L'/', index, indexOf);
1592                 if (r == E_SUCCESS)
1593                 {
1594                         r = str.SubString(index, indexOf - index, tmpPort);
1595                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1596                 }
1597                 else if (r == E_OBJ_NOT_FOUND)
1598                 {
1599                         r = str.SubString(index, tmpPort);
1600                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1601                 }
1602
1603                 int tmpPortLen = tmpPort.GetLength();
1604                 for (int i = 0; i < tmpPortLen; i++)
1605                 {
1606                         wchar_t ch = tmpPort[i];
1607                         SysTryReturnResult(NID_BASE_UTIL, Character::IsDigit(ch), E_INVALID_FORMAT, "The character is not a digit.");
1608                 }
1609                 index += tmpPort.GetLength();
1610
1611                 int ret = 0;
1612                 r = Integer::Parse(tmpPort, 10, ret);
1613                 port = ret;
1614         }
1615         else
1616         {
1617                 port = -1;
1618         }
1619
1620         SysTryReturnResult(NID_BASE_UTIL, index >= str.GetLength(), E_INVALID_FORMAT, "index must be greater than or equal to str.GetLength().");
1621
1622         return E_SUCCESS;
1623 }
1624
1625 //
1626 // This method parses a host name and returns a host name as an out-param.
1627 //
1628 result
1629 Uri::ParseHostName(const Tizen::Base::String& str, int index, Tizen::Base::String& host)
1630 {
1631         result r = E_SUCCESS;
1632         int indexOf = 0;
1633
1634         int strLen = str.GetLength();
1635         r = str.IndexOf(L':', index, indexOf);
1636         if (r == E_SUCCESS)
1637         {
1638                 r = str.SubString(index, indexOf - index, host);
1639                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1640         }
1641         else if (r == E_OBJ_NOT_FOUND)
1642         {
1643                 //host = str;
1644                 r = str.SubString(index, host);
1645                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1646         }
1647
1648         for (int i = 0; i < strLen; i++)
1649         {
1650                 if (str[i] == L'%')
1651                 {
1652                         wchar_t ch1 = str[i + 1];
1653                         wchar_t ch2 = str[i + 2];
1654                         bool escape = IsEscapedChar(ch1, ch2);
1655                         if (!escape)
1656                         {
1657                                 break;
1658                         }
1659
1660                         host = L"";
1661                         return E_SUCCESS;
1662                 }
1663         }
1664
1665         SysTryReturnResult(NID_BASE_UTIL, VerifyHost(host), E_INVALID_FORMAT, "Invalid Host.");
1666
1667         return E_SUCCESS;
1668 }
1669
1670 //
1671 // This method parses an IPv6 address.
1672 // This method covers all and only the following cases :
1673 //              hex_seq
1674 //              hex_seq : IPv4 address
1675 //              hex_seq ::
1676 //              hex_seq :: hex_seq
1677 //              hex_seq :: hex_seq : IPv4 address
1678 //              :: hex_seq
1679 //              :: hex_seq : IPv4 address
1680 //              ::
1681 //
1682 // Additionally, we constrain the IPv6 address as follows :
1683 //              1) IPv6 address without compressed zeros should contain exactly 16 bytes.
1684 //              2) IPv6 address with comporessed zeros should contain less than 16 bytes.
1685 //
1686 result
1687 Uri::ParseIpv6(const Tizen::Base::String& ip6, Tizen::Base::String& outIpv6)
1688 {
1689         // TODO : It will be implemented
1690         return E_SUCCESS;
1691 }
1692
1693 result
1694 Uri::ParseIpv4(const Tizen::Base::String& str, int start, int& count)
1695 {
1696         result r = E_SUCCESS;
1697         String dot(L".");
1698         String ipHost;
1699
1700         r = str.SubString(start, ipHost);
1701         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1702
1703         // Set the index as an end position of ipv4
1704         count = ipHost.GetLength();
1705
1706         StringTokenizer strTok(ipHost, dot);
1707
1708         // Check that a given string consists of digit or dot.
1709         int ipHostLen = ipHost.GetLength();
1710         for (int i = 0; i < ipHostLen; i++)
1711         {
1712                 wchar_t ch = ipHost[i];
1713                 if (ch != L'.' && !(Character::IsDigit(ch)))
1714                 {
1715                         count = -1;
1716                         return E_SUCCESS;
1717                 }
1718         }
1719
1720         while (strTok.HasMoreTokens())
1721         {
1722                 String token;
1723
1724                 r = strTok.GetNextToken(token);
1725                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1726
1727                 int ret = 0;
1728                 r = Integer::Parse(token, 10, ret);
1729                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
1730
1731                 // each part of IPv4 address cannot exceed 255.
1732                 if (ret < 0 || ret > 255)
1733                 {
1734                         return E_INVALID_FORMAT;
1735                 }
1736         }
1737
1738         return E_SUCCESS;
1739 }
1740
1741 //////////////////////////////////////////////////////////////////////////////////////////
1742 // Verify a component
1743
1744 //
1745 // This method verifies whether a given string is scheme format or not.
1746 // The scheme has an combination of alphabet, digit, plus(+), dash(-) and period(.).
1747 // The first character must be an alphabet.
1748 //
1749 bool
1750 Uri::VerifyScheme(const Tizen::Base::String& str) const
1751 {
1752         bool isAlpha = Character::IsLetter(str[0]);
1753         if (!isAlpha)
1754         {
1755                 return false;
1756         }
1757
1758         int strLen = str.GetLength();
1759         for (int i = 1; i < strLen; i++)
1760         {
1761                 if ((str[i] != '+') && (str[i] != '-') && (str[i] != '.') && (!Character::IsAlphaNumeric(str[i])) &&
1762                         (!Character::IsDigit(str[i])))
1763                 {
1764                         return false;
1765                 }
1766         }
1767
1768         return true;
1769 }
1770
1771 bool
1772 Uri::VerifyAuthority(const Tizen::Base::String& str) const
1773 {
1774         bool isReg = VerifyRegistryAuthority(str);
1775         bool isServer = VerifyServerAuthority(str);
1776
1777         if (isReg || isServer)
1778         {
1779                 return true;
1780         }
1781         else
1782         {
1783                 return false;
1784         }
1785 }
1786
1787 bool
1788 Uri::VerifyHost(const Tizen::Base::String& str) const
1789 {
1790         int length = str.GetLength();
1791
1792         for (int i = 0; i < length; i++)
1793         {
1794                 wchar_t ch = str[i];
1795                 if (ch != L'-' && ch != L'.' && !Character::IsAlphaNumeric(ch) && !Character::IsDigit(ch))
1796                 {
1797                         return false;
1798                 }
1799
1800                 if (ch == L'-')
1801                 {
1802                         if (i == 0 || i == length - 1)
1803                         {
1804                                 return false;
1805                         }
1806                 }
1807         }
1808         return true;
1809 }
1810
1811 bool
1812 Uri::VerifyPath(const Tizen::Base::String& str) const
1813 {
1814         result r = E_SUCCESS;
1815         String reserved(L":@&=+$\",;/");
1816
1817         int strLen = str.GetLength();
1818         for (int i = 0; i < strLen; i++)
1819         {
1820                 int indexOf = 0;
1821                 r = reserved.IndexOf(str[i], 0, indexOf);
1822
1823                 if (str[i] == L'%')
1824                 {
1825                         wchar_t ch1 = str[i + 1];
1826                         wchar_t ch2 = str[i + 2];
1827                         bool escape = IsEscapedChar(ch1, ch2);
1828                         if (!escape)
1829                         {
1830                                 return false;
1831                         }
1832                 }
1833                 else if (str[i] == L' ')    // add a space
1834                 {
1835                 }
1836                 else if (r == E_OBJ_NOT_FOUND && !Character::IsAlphaNumeric(str[i]) && !Character::IsDigit(str[i]) && !IsMark(str[i]))
1837                 {
1838                         // Check the unicode letter
1839                         if (!(Character::GetUnicodeCategory(str[i]) == UNICODE_LETTER))
1840                         {
1841                                 return false;
1842                         }
1843                 }
1844         }
1845         return true;
1846 }
1847
1848 bool
1849 Uri::VerifyUserInfo(const Tizen::Base::String& str) const
1850 {
1851         String reserved(L";:&=+$,");
1852         int strLen = str.GetLength();
1853
1854         for (int i = 0; i < strLen; i++)
1855         {
1856                 int indexOf = 0;
1857                 reserved.IndexOf(str[i], 0, indexOf);
1858
1859                 if (str[i] == L'%')
1860                 {
1861                         wchar_t ch1 = str[i + 1];
1862                         wchar_t ch2 = str[i + 2];
1863                         bool escape = IsEscapedChar(ch1, ch2);
1864                         if (!escape)
1865                         {
1866                                 return false;
1867                         }
1868                 }
1869                 else if (str[i] == L' ')    // add a space
1870                 {
1871                 }
1872                 else if (indexOf < 0 && !Character::IsAlphaNumeric(str[i]) && !Character::IsDigit(str[i]) && !IsMark(str[i]))
1873                 {
1874                         // Check the unicode letter
1875                         if (!(Character::GetUnicodeCategory(str[i]) == UNICODE_LETTER))
1876                         {
1877                                 return false;
1878                         }
1879                 }
1880         }
1881         return true;
1882 }
1883
1884 bool
1885 Uri::VerifyUriChar(const Tizen::Base::String& str) const
1886 {
1887         result r = E_SUCCESS;
1888         // [ ] removed form "reserved"
1889         //  RFC 2732: (Format for Literal IPv6 Addresses in URLs) is not supported for now.
1890         String reserved(L";/?:@&=+$,");
1891         String delims(L"<>#\"");    // <, >, #, %, "
1892         int strLen = str.GetLength();
1893
1894         for (int i = 0; i < strLen; i++)
1895         {
1896                 wchar_t ch = str[i];
1897                 int indexOf = 0;
1898
1899                 r = delims.IndexOf(ch, 0, indexOf);     // check delims
1900                 if (r == E_SUCCESS)
1901                 {
1902                         return false;
1903                 }
1904
1905                 r = reserved.IndexOf(ch, 0, indexOf);
1906                 if (ch == L'%')
1907                 {
1908                         wchar_t ch1 = str[i + 1];
1909                         wchar_t ch2 = str[i + 2];
1910                         bool escape = IsEscapedChar(ch1, ch2);
1911                         if (!escape)
1912                         {
1913                                 return false;
1914                         }
1915                 }
1916                 else if (IsControlChar(ch))     // control
1917                 {
1918                         return false;
1919                 }
1920                 else if ((ch != ' ') && (ch < 0x80) && !Character::IsAlphaNumeric(ch) && !Character::IsDigit(ch) && !IsMark(ch) &&
1921                                  !(r == E_SUCCESS))
1922                 {
1923                         // Check the unicode letter
1924                         if (!(Character::GetUnicodeCategory(str[i]) == UNICODE_LETTER))
1925                         {
1926                                 return false;
1927                         }
1928                 }
1929         }
1930         return true;
1931 }
1932
1933 //
1934 // This method checks that a given string consists of only server_based characters.
1935 // @return              True if a string consists of only server_based characters.
1936 //
1937 bool
1938 Uri::VerifyServerAuthority(const Tizen::Base::String& str) const
1939 {
1940         result r = E_SUCCESS;
1941         String special(L".:@[]");
1942
1943         int indexOf = 0;
1944         int strLen = str.GetLength();
1945         // Server based authority consists of alphabets, digits, marks(-_!.~*'()), escaped(%hexhex), and ;:&=+$'',@[]
1946         for (int i = 0; i < strLen; i++)
1947         {
1948                 wchar_t ch = str[i];
1949                 r = special.IndexOf(ch, 0, indexOf);
1950
1951                 if (ch == L'-' || IsUserInfo(ch) || r == E_SUCCESS)
1952                 {
1953                         // This string is a server_based authority character
1954                         if (ch == L'%')
1955                         {
1956                                 // escaped octets
1957                                 if (!IsEscapedChar(str[i + 1], str[i + 2]))
1958                                 {
1959                                         return false;
1960                                 }
1961                         }
1962                 }
1963                 else
1964                 {
1965                         // Check the unicode letter
1966                         if (!(Character::GetUnicodeCategory(str[i]) == UNICODE_LETTER))
1967                         {
1968                                 return false;
1969                         }
1970                 }
1971         }
1972         return true;
1973 }
1974
1975 //
1976 // This method checks that a given string consists of only registry_based characters.
1977 // @return              True if a string consists of only registry_based characters.
1978 //
1979 bool
1980 Uri::VerifyRegistryAuthority(const Tizen::Base::String& str) const
1981 {
1982         result r = E_SUCCESS;
1983         String specialChar(L"@%;:&=+$,");
1984
1985         int indexOf = 0;
1986         int strLen = str.GetLength();
1987         for (int i = 0; i < strLen; i++)
1988         {
1989                 wchar_t ch = str[i];
1990                 r = specialChar.IndexOf(ch, 0, indexOf);
1991
1992                 if (!(Character::IsAlphaNumeric(ch)) && !(Character::IsDigit(ch)) && !IsMark(ch) && !(indexOf >= 0 && r == E_SUCCESS))
1993                 {
1994                         // Check the unicode letter
1995                         if (!(Character::GetUnicodeCategory(str[i]) == UNICODE_LETTER))
1996                         {
1997                                 return false;
1998                         }
1999                 }
2000                 else if (ch == L'%')
2001                 {
2002                         if (!IsEscapedChar(str[i + 1], str[i + 2]))
2003                         {
2004                                 return false;
2005                         }
2006                 }
2007         }
2008
2009         return true;
2010 }
2011
2012 //////////////////////////////////////////////////////////////////////
2013 // Utility methods such as IsUserInfo, IsMark and so on.
2014
2015 //
2016 // This method returns true if a given wchar_t is a user-info character.
2017 // user-info char : alphabet, digit, -_.!~*'(), ;:&=+$,
2018 //
2019 bool
2020 Uri::IsUserInfo(wchar_t mch) const
2021 {
2022         result r = E_SUCCESS;
2023         String specialChar(L";:&=+$,");
2024
2025         if (mch == L'%' || Character::IsAlphaNumeric(mch) || Character::IsDigit(mch) || IsMark(mch))
2026         {
2027                 return true;
2028         }
2029
2030         int indexOf = 0;
2031         r = specialChar.IndexOf(mch, 0, indexOf);
2032         if (indexOf >= 0 && r == E_SUCCESS)
2033         {
2034                 return true;
2035         }
2036
2037         return false;
2038 }
2039
2040 //
2041 // This method returns true if a given wchar_t is a mark character.
2042 // mark char : -_.!~*'()
2043 //
2044 bool
2045 Uri::IsMark(wchar_t mch) const
2046 {
2047         result r = E_SUCCESS;
2048         String mark(L"-_.!~*'()");
2049
2050         int indexOf = 0;
2051
2052         r = mark.IndexOf(mch, 0, indexOf);
2053         if (indexOf >= 0 && r == E_SUCCESS)
2054         {
2055                 return true;
2056         }
2057
2058         return false;
2059 }
2060
2061 bool
2062 Uri::IsControlChar(wchar_t ch) const
2063 {
2064         if ((ch <= 0x009F) && ((ch <= 0x001F) || (ch >= 0x007F)))
2065         {
2066                 return true;
2067         }
2068         else
2069         {
2070                 return false;
2071         }
2072 }
2073
2074 bool
2075 Uri::IsEscapedChar(wchar_t ch1, wchar_t ch2) const
2076 {
2077         if ((ch1 >= L'a' && ch1 <= L'f') || (ch1 >= L'A' && ch1 <= L'F') || Character::IsDigit(ch1))
2078         {
2079                 if ((ch2 >= L'a' && ch2 <= L'f') || (ch2 >= L'A' && ch2 <= L'F') || Character::IsDigit(ch2))
2080                 {
2081                         return true;
2082                 }
2083         }
2084
2085         return false;
2086 }
2087
2088 ////////////////////////////////////////////////////////////////////////
2089 // Private operations
2090
2091 //
2092 // This method finds the first character in the stop-string.
2093 //
2094 int
2095 Uri::Scan(const Tizen::Base::String& str, int start, const Tizen::Base::String& stopString)
2096 {
2097         result r = E_SUCCESS;
2098         int index = start;
2099         int strLen = str.GetLength();
2100         while (index < strLen)
2101         {
2102                 int indexOf = 0;
2103                 wchar_t ch = str[index];
2104
2105                 r = stopString.IndexOf(ch, 0, indexOf);
2106                 if (r == E_SUCCESS)
2107                 {
2108                         break;
2109                 }
2110
2111                 index++;
2112         }
2113         return index;
2114 }
2115
2116 //
2117 // This method convers a component represented by UTF8 to a component represented by Unicode.
2118 //
2119 Tizen::Base::String
2120 Uri::Decode(const Tizen::Base::String& str)
2121 {
2122         if (str.IsEmpty())
2123         {
2124                 return str;
2125         }
2126
2127         result r = E_SUCCESS;
2128
2129         int len = str.GetLength();
2130         int index = 0;
2131
2132         String decodedBuf;
2133
2134         while (index < len)
2135         {
2136                 if (str[index] != L'%')
2137                 {
2138                         decodedBuf.Append(str[index]);
2139                         index++;
2140                         continue;
2141                 }
2142
2143                 ByteBuffer bb;
2144                 r = bb.Construct(20);
2145
2146                 while (1)
2147                 {
2148                         String utf8Str;
2149                         r = str.SubString(index + 1, 2, utf8Str);
2150
2151                         short ret = 0;
2152                         r = Short::Parse(utf8Str, 16, ret);
2153                         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, str, r, "[%s] Propagating.", GetErrorMessage(r));
2154
2155                         r = bb.SetByte((byte) ret);
2156
2157                         index = index + 3;
2158
2159                         if (index >= len || str[index] != '%')
2160                         {
2161                                 r = bb.SetByte(0);
2162                                 break;
2163                         }
2164                 }
2165
2166                 String unicode;
2167                 r = StringUtil::Utf8ToString((char*) bb.GetPointer(), unicode);
2168
2169                 if (IsFailed(r))
2170                 {
2171                         decodedBuf.Append(L'?');
2172                 }
2173                 else
2174                 {
2175                         decodedBuf.Append(unicode);
2176                 }
2177         }
2178
2179         return decodedBuf;
2180 }
2181
2182 //
2183 // This method converts a component represented by Unicode to a component represented by UTF8.
2184 //
2185 Tizen::Base::String
2186 Uri::Encode(const Tizen::Base::String& str) const
2187 {
2188         if (str.IsEmpty())
2189         {
2190                 return str;
2191         }
2192
2193         String upper;
2194         WcharBuffer wchar_tBuf;
2195
2196         result r = wchar_tBuf.Construct(str.GetLength() + 1);
2197
2198         String strbuf;
2199
2200         r = wchar_tBuf.SetArray(str.GetPointer(), 0, str.GetLength());
2201         SysTryReturn(NID_BASE_UTIL, !IsFailed(r), str, r, "[%s] Propagating.", GetErrorMessage(r));
2202
2203         r = wchar_tBuf.Set(L'\0');
2204         SysTryReturn(NID_BASE_UTIL, !IsFailed(r), str, r, "[%s] Propagating.", GetErrorMessage(r));
2205
2206         wchar_tBuf.Flip();
2207
2208         std::unique_ptr< char[] > pChar(new (std::nothrow) char[10]);
2209         SysTryReturn(NID_BASE_UTIL, pChar != null, str, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
2210         memset(pChar.get(), 0, 10);
2211
2212         while (wchar_tBuf.HasRemaining())
2213         {
2214                 wchar_t mch = 0x00;
2215                 r = wchar_tBuf.Get(mch);
2216                 SysTryReturn(NID_BASE_UTIL, !IsFailed(r), str, r, "[%s] Propagating.", GetErrorMessage(r));
2217
2218                 if (mch == 0)
2219                 {
2220                         break;
2221                 }
2222
2223                 if (mch >= 0x0080 || IsControlChar(mch))
2224                 {
2225                         WcharBuffer tmpBuf;
2226                         String tempStr;
2227
2228                         String unicode;
2229
2230                         int bbPos = 0;
2231
2232                         r = tmpBuf.Construct(2);
2233                         SysTryReturn(NID_BASE_UTIL, !IsFailed(r), str, r, "[%s] Propagating.", GetErrorMessage(r));
2234
2235                         r = tmpBuf.Set(mch);
2236                         SysTryReturn(NID_BASE_UTIL, !IsFailed(r), str, r, "[%s] Propagating.", GetErrorMessage(r));
2237
2238                         r = tmpBuf.Set(L'\0');
2239                         SysTryReturn(NID_BASE_UTIL, !IsFailed(r), str, r, "[%s] Propagating.", GetErrorMessage(r));
2240
2241                         tmpBuf.Flip();
2242
2243                         tempStr = tmpBuf.GetPointer();
2244                         std::unique_ptr< ByteBuffer > pBuf(StringUtil::StringToUtf8N(tempStr));
2245                         SysTryReturn(NID_BASE_UTIL, pBuf != null, str, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
2246
2247                         while (bbPos < pBuf->GetLimit() - 1) // null
2248                         {
2249                                 byte b = '\0';
2250                                 r = pBuf->GetByte(bbPos, b);
2251                                 SysTryReturn(NID_BASE_UTIL, !IsFailed(r), str, r, "[%s] Propagating.", GetErrorMessage(r));
2252
2253                                 sprintf(pChar.get() + (bbPos * 3), "%%%x", (int) b);
2254                                 bbPos++;
2255                         }
2256
2257                         r = StringUtil::Utf8ToString(pChar.get(), unicode);
2258                         SysTryReturn(NID_BASE_UTIL, !IsFailed(r), str, r, "[%s] Propagating.", GetErrorMessage(r));
2259
2260                         r = unicode.ToUpper(upper);
2261
2262                         r = strbuf.Append(upper);
2263                         SysTryReturn(NID_BASE_UTIL, !IsFailed(r), str, r, "[%s] Propagating.", GetErrorMessage(r));
2264                 }
2265                 else if (mch == 0x20)
2266                 {
2267                         String unicode(L"%20");
2268                         r = strbuf.Append(unicode);
2269                         SysTryReturn(NID_BASE_UTIL, !IsFailed(r), str, r, "[%s] Propagating.", GetErrorMessage(r));
2270                 }
2271                 else // ASCII character
2272                 {
2273                         r = strbuf.Append(mch);
2274                         SysTryReturn(NID_BASE_UTIL, !IsFailed(r), str, r, "[%s] Propagating.", GetErrorMessage(r));
2275                 }
2276         }
2277
2278         SetLastResult(E_SUCCESS);
2279         return strbuf;
2280 }
2281
2282 result
2283 Uri::AppendEscape(Tizen::Base::String& strbuf, byte b)
2284 {
2285         byte bt1 = '\0';
2286         byte bt2 = '\0';
2287
2288         result r = strbuf.Append(L'%');
2289         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2290
2291         bt1 = (b >> 4) & 0x0f;
2292         r = strbuf.Append(HEX_DIGITS[bt1]);
2293         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2294
2295         bt2 = (b >> 0) & 0x0f;
2296         r = strbuf.Append(HEX_DIGITS[bt2]);
2297         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2298
2299         return E_SUCCESS;
2300 }
2301
2302 // This method compares str1 and str2 after replacing all uppercase letters with their lowercase letters
2303 int
2304 Uri::Compare(const Tizen::Base::String& str1, const Tizen::Base::String& str2) const
2305 {
2306         String small1;
2307         String small2;
2308
2309         if (str1.IsEmpty())
2310         {
2311                 if (str2.IsEmpty())
2312                 {
2313                         // Both pStr1 and pStr2 are null
2314                         return 0;
2315                 }
2316                 else
2317                 {
2318                         // pStr1 is null but pStr isn't.
2319                         return -1;
2320                 }
2321         }
2322         else
2323         {
2324                 if (str2.IsEmpty())
2325                 {
2326                         // pStr1 is not null but pStr2 is null
2327                         return 1;
2328                 }
2329         }
2330
2331         // Replace all uppercase letters with their lowercase letters
2332         str1.ToLower(small1);
2333         str2.ToLower(small2);
2334
2335         return small1.CompareTo(small2);
2336
2337 }
2338
2339 //////////////////////////////////////////////////////////////////////////////////////////
2340 // Normalization
2341
2342 Tizen::Base::String
2343 Uri::InternalNormalize(const Tizen::Base::String& path)
2344 {
2345         result r = E_SUCCESS;
2346         String joinedStr;
2347         String str;
2348         int segCount = 0;
2349         int join = 0;
2350
2351         std::unique_ptr< WcharBuffer > pBuf(StringUtil::StringToMbN(path, 0, path.GetLength()));
2352         if (pBuf == null)
2353         {
2354                 return str;
2355         }
2356
2357         // Get the number of segments from a given path
2358         segCount = GetNumberOfSegments(path);
2359         if (segCount <= 0)
2360         {
2361                 return path;
2362         }
2363
2364         // Get the first index of each segment
2365         std::unique_ptr< int[] > pSegments(new (std::nothrow) int[segCount]);
2366         SplitIntoSegments(*pBuf, pSegments.get(), segCount);
2367
2368         // Remove dots
2369         RemoveDots(*pBuf, pSegments.get(), segCount, path.GetLength());
2370
2371         // Prevent scheme-name confusion
2372         AddLeadingDot(*pBuf, pSegments.get(), segCount);
2373
2374         // Join the remaining segments and returns the result
2375         join = Join(*pBuf, pSegments.get(), segCount);
2376
2377         r = StringUtil::MbToString(*pBuf, str);
2378         SysTryReturn(NID_BASE_UTIL, !IsFailed(r), L"", E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(E_INVALID_ARG));
2379
2380         // Empty String
2381         if (str.IsEmpty())
2382         {
2383                 return str;
2384         }
2385
2386         r = str.SubString(0, join - 1, joinedStr);
2387         SysTryReturn(NID_BASE_UTIL, !IsFailed(r), L"", E_INVALID_ARG, "[%s] Propagating.", GetErrorMessage(E_INVALID_ARG));
2388
2389         if (joinedStr.Equals(path))
2390         {
2391                 return path;    // String was already normalized.
2392         }
2393
2394         SetLastResult(E_SUCCESS);
2395         return joinedStr;
2396 }
2397
2398 //
2399 // This method returns the number of segments from a given path.
2400 //
2401 int
2402 Uri::GetNumberOfSegments(const Tizen::Base::String& path) const
2403 {
2404         bool normal = true;
2405         int segCount = 0;
2406         int endIndex = path.GetLength() - 1;
2407         int p = 0;
2408
2409         // find the index of non-slash character
2410         while (p <= endIndex)
2411         {
2412                 if (path[p] != L'/')
2413                 {
2414                         break;
2415                 }
2416                 p++;
2417         }
2418         if (p > 1)
2419         {
2420                 normal = false;
2421         }
2422
2423         // Scan segments
2424         while (p <= endIndex)
2425         {
2426                 // Looking at '.' or '..'
2427                 if ((path[p] == L'.') && ((p == endIndex) || ((path[p + 1] == L'/') ||
2428                                                                                                           ((path[p + 1] == L'.') && ((p + 1 == endIndex) || (path[p + 2] == L'/'))))))
2429                 {
2430                         normal = false;
2431                 }
2432                 segCount++;
2433
2434                 // Find the beginning index of next segment
2435                 while (p <= endIndex)
2436                 {
2437                         if (path[p++] != L'/')
2438                         {
2439                                 continue;
2440                         }
2441
2442                         // skip redundant slashes
2443                         while (p <= endIndex)
2444                         {
2445                                 if (path[p] != L'/')
2446                                 {
2447                                         break;
2448                                 }
2449
2450                                 normal = false;
2451                                 p++;
2452                         }
2453
2454                         break;
2455                 }
2456         }
2457
2458         if (normal)
2459         {
2460                 return -1;
2461         }
2462         else
2463         {
2464                 return segCount;
2465         }
2466 }
2467
2468 void
2469 Uri::SplitIntoSegments(Tizen::Base::WcharBuffer& mb, int* segments, int segCount)
2470 {
2471         int end = StringUtil::GetStringLengthInMb(mb);
2472
2473         //int end = mb.GetLimit() - 1;
2474         int p = 0;
2475         int index = 0; // the index of current segment
2476
2477         // skip initial slash
2478         while (p <= end)
2479         {
2480                 if (mb[p] != L'/')
2481                 {
2482                         break;
2483                 }
2484                 mb[p] = L'\0';
2485                 p++;
2486         }
2487
2488         while (p <= end)
2489         {
2490                 if (index >= segCount)
2491                 {
2492                         break;
2493                 }
2494
2495                 // start of segment
2496                 segments[index] = p;
2497                 index++;
2498                 p++;
2499
2500                 // Find beginning of next segment
2501                 while (p <= end)
2502                 {
2503                         if (mb[p++] != L'/')
2504                         {
2505                                 continue;
2506                         }
2507                         mb[p - 1] = L'\0';
2508
2509                         // skip redundant slash
2510                         while (p <= end)
2511                         {
2512                                 if (mb[p] != L'/')
2513                                 {
2514                                         break;
2515                                 }
2516                                 mb[p++] = L'\0';
2517                         }
2518                         break;
2519                 }
2520         }
2521
2522         // index must be equal to the length of segments[]
2523 }
2524
2525 void
2526 Uri::RemoveDots(const Tizen::Base::WcharBuffer& mb, int* segments, int segCount, int length)
2527 {
2528         int end = length;
2529
2530         for (int i = 0; i < segCount; i++)
2531         {
2532                 int dots = 0; // number of dots found
2533
2534                 // Find next occurrence of "." or "..
2535                 do
2536                 {
2537                         int p = segments[i];
2538                         if (mb[p] == '.')
2539                         {
2540                                 if (p == end)
2541                                 {
2542                                         dots = 1;
2543                                         break;
2544                                 }
2545                                 else if (mb[p + 1] == L'\0')
2546                                 {
2547                                         dots = 1;
2548                                         break;
2549                                 }
2550                                 else if ((mb[p + 1] == L'.') && ((p + 1 == end) || (mb[p + 2] == L'\0')))
2551                                 {
2552                                         dots = 2;
2553                                         break;
2554                                 }
2555                         }
2556                         i++;
2557                 }
2558                 while (i < segCount);
2559
2560                 if ((i > segCount) || (dots == 0))
2561                 {
2562                         break;
2563                 }
2564
2565                 if (dots == 1 && i < segCount)
2566                 {
2567                         // Remove this occurrence of '.'
2568                         segments[i] = -1;
2569                 }
2570                 else
2571                 {
2572                         // If there is a preceding non-".." segment, remove both that segment and this occurrence of "..";
2573                         // otherwise, leave this ".." segment as-is.
2574                         int j = 0;
2575                         for (j = i - 1; j >= 0; j--)
2576                         {
2577                                 if (segments[j] != -1)
2578                                 {
2579                                         break;
2580                                 }
2581                         }
2582
2583                         if (j >= 0)
2584                         {
2585                                 int q = segments[j];
2586                                 if (!((mb[q] == '.') && (mb[q + 1] == '.') && (mb[q + 2] == '\0')))
2587                                 {
2588                                         segments[i] = -1;
2589                                         segments[j] = -1;
2590                                 }
2591                         }
2592                 }
2593         }
2594 }
2595
2596 void
2597 Uri::AddLeadingDot(Tizen::Base::WcharBuffer& mb, int* segments, int segCount)
2598 {
2599         if (mb[0] == L'\0')
2600         {
2601                 // The path is absolute
2602                 return;
2603         }
2604
2605         int firstSegment = 0;           // Index of first segment
2606         while (firstSegment < segCount)
2607         {
2608                 if (segments[firstSegment] >= 0)
2609                 {
2610                         break;
2611                 }
2612                 firstSegment++;
2613         }
2614
2615         if ((firstSegment >= segCount) || (firstSegment == 0))
2616         {
2617                 // The path is empty, or else the original first segment survived,
2618                 // in which case we already know that no leading "." is needed
2619                 return;
2620         }
2621
2622         int p = segments[firstSegment];
2623         while ((mb[p] != L':') && (mb[p] != L'\0') && (p < mb.GetLimit()))
2624         {
2625                 p++;
2626         }
2627
2628         if (mb[p] == L'\0' || p >= mb.GetLimit())
2629         {
2630                 // No colon in first segment, so no "." needed
2631                 return;
2632         }
2633
2634         // At this point we know that the first segment is unused,
2635         // hence we can insert a "." segment at that position
2636         mb[0] = L'.';
2637         mb[1] = L'\0';
2638         segments[0] = 0;
2639 }
2640
2641 // Join the segments in the given path according to the given segment-index array,
2642 // ignoring those segments whose index entries have been set to -1, and inserting slashes as needed.
2643 // Return the length of the resulting path.
2644 //
2645 // Preconditions:
2646 //   segs[i] == -1 implies segment i is to be ignored
2647 //   path computed by split, as above, with '\0' having replaced '/'
2648 //
2649 // Postconditions:
2650 //   path[0] .. path[return value] == Resulting path
2651 //
2652 int
2653 Uri::Join(Tizen::Base::WcharBuffer& mb, int* segments, int segCount)
2654 {
2655
2656         int end = mb.GetLimit() - 1;
2657         int p = 0;
2658
2659         if (mb[p] == L'\0')
2660         {
2661                 // Restore initial slash for absolute paths
2662                 mb[p++] = L'/';
2663         }
2664
2665         for (int i = 0; i < segCount; i++)
2666         {
2667                 int q = segments[i];
2668                 if (q == -1)
2669                 {
2670                         // ignore this segment
2671                         continue;
2672                 }
2673
2674                 if (p == q)
2675                 {
2676                         // skip to its end
2677                         while ((p <= end) && (mb[p] != L'\0'))
2678                         {
2679                                 p++;
2680                         }
2681                         if (p <= end)
2682                         {
2683                                 // Preserve trailing slash
2684                                 mb[p++] = L'/';
2685                         }
2686                 }
2687                 else if (p < q)
2688                 {
2689                         while ((q <= end) && mb[q] != L'\0')
2690                         {
2691                                 mb[p++] = mb[q++];
2692                         }
2693                         if (q < end)
2694                         {
2695                                 // Preserve trailing slash
2696                                 mb[p++] = L'/';
2697                         }
2698                 }
2699         }
2700         if (p == mb.GetLimit())
2701         {
2702                 result r = E_SUCCESS;
2703                 r = mb.SetLimit(p + 1);
2704                 if (IsFailed(r))
2705                 {
2706                         return p;
2707                 }
2708         }
2709         mb[p++] = L'\0';
2710
2711         return p;
2712 }
2713
2714 ///////////////////////////////////////////////////////////////////////////////////////////////
2715 // Resolution
2716
2717 //
2718 // This method implements Uri resolution in RFC2396 5.2
2719 //
2720 result
2721 Uri::Resolve(const Uri& baseUri, const Uri& childUri, Uri& resultUri)
2722 {
2723         result r = E_SUCCESS;
2724
2725         // If either baseUri or childUri is opaque, then resultUri is childUri
2726         if (baseUri.IsOpaque() || childUri.IsOpaque())
2727         {
2728                 resultUri = childUri;
2729                 return E_SUCCESS;
2730         }
2731
2732         // 5.2(2) If scheme, authority, path, and query of childUri are null,
2733         // the components of baseUri are copied to components of resultUri.
2734         if ((childUri.__scheme.IsEmpty()) && (childUri.__authority.IsEmpty()) && (childUri.__path.IsEmpty())
2735                 && (!childUri.__fragment.IsEmpty()) && (childUri.__query.IsEmpty()))
2736         {
2737                 if ((!baseUri.__fragment.IsEmpty()) && (childUri.__fragment.GetLength() == baseUri.__fragment.GetLength()))
2738                 {
2739                         resultUri = baseUri;
2740                         return E_SUCCESS;
2741                 }
2742
2743                 if (!baseUri.__scheme.IsEmpty())
2744                 {
2745                         r = resultUri.SetScheme(baseUri.__scheme);
2746                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2747                 }
2748
2749                 if (!baseUri.__authority.IsEmpty())
2750                 {
2751                         r = resultUri.SetAuthority(baseUri.__authority);
2752                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2753                 }
2754
2755                 if (!baseUri.__userInfo.IsEmpty())
2756                 {
2757                         r = resultUri.SetUserInfo(baseUri.__userInfo);
2758                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2759                 }
2760
2761                 if (!baseUri.__host.IsEmpty())
2762                 {
2763                         r = resultUri.SetHost(baseUri.__host);
2764                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2765                 }
2766
2767                 resultUri.SetPort(baseUri.__port);
2768
2769                 if (!baseUri.__path.IsEmpty())
2770                 {
2771                         r = resultUri.SetPath(baseUri.__path);
2772                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2773                 }
2774
2775                 if (!childUri.__fragment.IsEmpty())
2776                 {
2777                         r = resultUri.SetFragment(childUri.__fragment);
2778                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2779                 }
2780
2781                 if (!baseUri.__query.IsEmpty())
2782                 {
2783                         r = resultUri.SetQuery(baseUri.__query);
2784                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2785                 }
2786
2787                 return E_SUCCESS;
2788         }
2789
2790         // 5.2(3) child is an absolute URI
2791         if (!childUri.__scheme.IsEmpty())
2792         {
2793                 resultUri = childUri;
2794                 return E_SUCCESS;
2795         }
2796
2797         if (!baseUri.__scheme.IsEmpty())
2798         {
2799                 r = resultUri.SetScheme(baseUri.__scheme);
2800                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2801         }
2802
2803         if (!childUri.__query.IsEmpty())
2804         {
2805                 r = resultUri.SetQuery(childUri.__query);
2806                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2807         }
2808
2809         if (!childUri.__fragment.IsEmpty())
2810         {
2811                 r = resultUri.SetFragment(childUri.__fragment);
2812                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2813         }
2814
2815         // 5.2(4) Authority
2816         if (childUri.__authority.IsEmpty())
2817         {
2818                 if (!baseUri.__authority.IsEmpty())
2819                 {
2820                         r = resultUri.SetAuthority(baseUri.__authority);
2821                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2822                 }
2823
2824                 if (!baseUri.__host.IsEmpty())
2825                 {
2826                         r = resultUri.SetHost(baseUri.__host);
2827                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2828                 }
2829
2830                 if (!baseUri.__userInfo.IsEmpty())
2831                 {
2832                         r = resultUri.SetUserInfo(baseUri.__userInfo);
2833                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2834                 }
2835
2836                 resultUri.SetPort(baseUri.__port);
2837
2838                 String resolve;
2839                 String encodedPath = childUri.__encodedPath;
2840                 if (!encodedPath.IsEmpty())
2841                 {
2842                         resolve = childUri.__encodedPath;
2843                 }
2844
2845                 if ((!resolve.IsEmpty()) && (resolve[0] == L'/'))
2846                 {
2847                         // 5.2(5) child uri's path is absolute
2848                         if (!encodedPath.IsEmpty())
2849                         {
2850                                 r = resultUri.SetPath(encodedPath);
2851                                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2852                         }
2853                 }
2854                 else
2855                 {
2856                         String encPath = baseUri.__encodedPath;
2857                         if (!encPath.IsEmpty())
2858                         {
2859                                 // 5.2(6) Resolve relative path
2860                                 String relPath = ResolvePath(encPath, resolve, baseUri.IsAbsolute());
2861                                 if (relPath.IsEmpty())
2862                                 {
2863                                         return GetLastResult();
2864                                 }
2865
2866                                 r = resultUri.SetPath(relPath);
2867                                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2868                         }
2869                 }
2870         }
2871         else
2872         {
2873                 if (!childUri.__authority.IsEmpty())
2874                 {
2875                         r = resultUri.SetAuthority(childUri.__authority);
2876                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2877                 }
2878
2879                 if (!childUri.__host.IsEmpty())
2880                 {
2881                         r = resultUri.SetHost(childUri.__host);
2882                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2883                 }
2884
2885                 if (!childUri.__userInfo.IsEmpty())
2886                 {
2887                         r = resultUri.SetUserInfo(childUri.__userInfo);
2888                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2889                 }
2890
2891                 resultUri.SetPort(childUri.__port);
2892
2893                 if (!childUri.__path.IsEmpty())
2894                 {
2895                         r = resultUri.SetPath(childUri.__path);
2896                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2897                 }
2898         }
2899
2900         return E_SUCCESS;
2901 }
2902
2903 // RFC2396 5.2(6)
2904 Tizen::Base::String
2905 Uri::ResolvePath(const String& basePath, const String& childPath, bool isAbsolute)
2906 {
2907         result r = E_SUCCESS;
2908         String path;
2909
2910         int indexOf = 0;
2911         r = basePath.LastIndexOf(L'/', basePath.GetLength() - 1, indexOf);
2912
2913         int len = childPath.GetLength();
2914
2915         if (len == 0)
2916         {
2917                 if (indexOf >= 0 && r == E_SUCCESS)
2918                 {
2919                         r = basePath.SubString(0, indexOf + 1, path);
2920                         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, String(), r, "[%s] Propagating.", GetErrorMessage(r));
2921                 }
2922         }
2923         // 5.2 (6a)
2924         else
2925         {
2926                 String strbuf;
2927
2928                 if (r == E_SUCCESS)
2929                 {
2930                         String tmpath;
2931                         r = basePath.SubString(0, indexOf + 1, tmpath);
2932                         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, String(), r, "[%s] Propagating.", GetErrorMessage(r));
2933
2934                         r = strbuf.Append(tmpath);
2935                         SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, String(), r, "[%s] Propagating.", GetErrorMessage(r));
2936                 }
2937
2938                 r = strbuf.Append(childPath);
2939                 SysTryReturn(NID_BASE_UTIL, r == E_SUCCESS, String(), r, "[%s] Propagating.", GetErrorMessage(r));
2940
2941                 path = strbuf;
2942         }
2943
2944         return InternalNormalize(path);
2945 }
2946
2947 //////////////////////////////////////////////////////////////////////////
2948 // Relativize
2949 result
2950 Uri::Relativize(const Uri& baseUri, const Uri& childUri, Uri& resultUri)
2951 {
2952         result r = E_SUCCESS;
2953
2954         // If either base URI or child URI is opaque, result URI is the childUri.
2955         if (baseUri.IsOpaque() || childUri.IsOpaque())
2956         {
2957                 resultUri = childUri;
2958                 return E_SUCCESS;
2959         }
2960
2961         int ret1 = Compare(baseUri.__scheme, childUri.__scheme);
2962
2963         bool equal = false;
2964         if (!baseUri.__authority.IsEmpty() && !childUri.__authority.IsEmpty())
2965         {
2966                 equal = EqualsComponent(baseUri.__authority, childUri.__authority);
2967         }
2968
2969         if ((ret1 != 0) || (!equal))
2970         {
2971                 resultUri = childUri;
2972                 return E_SUCCESS;
2973         }
2974
2975         String basePath = InternalNormalize(baseUri.__path);
2976         String childPath = InternalNormalize(childUri.__path);
2977
2978         if (basePath.Equals(childPath) == false)
2979         {
2980                 String newBp;
2981                 String slash(L"/");
2982
2983                 bool endWith = basePath.EndsWith(slash);
2984                 if (!endWith)
2985                 {
2986                         String strbuf(basePath);
2987
2988                         r = strbuf.Append(slash);
2989                         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
2990
2991                         newBp = strbuf;
2992                 }
2993                 else
2994                 {
2995                         newBp = basePath;
2996                 }
2997
2998                 bool startsWith = childPath.StartsWith(basePath, 0);
2999
3000                 if (!startsWith)
3001                 {
3002                         resultUri = childUri;
3003                         return E_SUCCESS;
3004                 }
3005         }
3006
3007         String path;
3008         r = childPath.SubString(basePath.GetLength(), path);
3009         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_SUCCESS, "Translating [%s] into [%s].", GetErrorMessage(r), GetErrorMessage(E_SUCCESS));
3010
3011         r = resultUri.SetPath(path);
3012         SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
3013
3014         if (!childUri.__query.IsEmpty())
3015         {
3016                 r = resultUri.SetQuery(childUri.__query);
3017                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
3018         }
3019
3020         if (!childUri.__fragment.IsEmpty())
3021         {
3022                 r = resultUri.SetFragment(childUri.__fragment);
3023                 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, r, "Propagating.");
3024         }
3025
3026         return r;
3027 }
3028
3029 //
3030 // This method compares two components. If a component is encoded,
3031 // then its raw component is compared with another component.
3032 //
3033 bool
3034 Uri::EqualsComponent(const Tizen::Base::String& comp1, const Tizen::Base::String& comp2)
3035 {
3036         result r = E_SUCCESS;
3037
3038         if (comp1 == comp2)
3039         {
3040                 return true;
3041         }
3042
3043         if (comp1.GetLength() != comp2.GetLength())
3044         {
3045                 return false;
3046         }
3047
3048         int indexOf = 0;
3049         r = comp1.IndexOf(L'%', 0, indexOf);
3050         if (r == E_OBJ_NOT_FOUND)
3051         {
3052                 return comp1.Equals(comp2);
3053         }
3054
3055         int len = comp1.GetLength();
3056         for (int i = 0; i < len; )
3057         {
3058                 wchar_t c1 = (comp1)[i];
3059                 wchar_t c2 = (comp2)[i];
3060                 if (c1 != L'%')
3061                 {
3062                         if (c1 != c2)
3063                         {
3064                                 return false;
3065                         }
3066                         i++;
3067                         continue;
3068                 }
3069                 i++;
3070
3071                 if (Character::ToLower(comp1[i]) == Character::ToLower(comp2[i]))
3072                 {
3073                         return false;
3074                 }
3075
3076                 i++;
3077                 if (Character::ToLower(comp1[i]) == Character::ToLower(comp2[i]))
3078                 {
3079                         return false;
3080                 }
3081
3082                 i++;
3083         }
3084
3085         return true;
3086 }
3087
3088 bool
3089 Uri::IsEncoded(const Tizen::Base::String& str) const
3090 {
3091         int strLen = str.GetLength();
3092         for (int i = 0; i < strLen; i++)
3093         {
3094                 wchar_t ch = str[i];
3095                 if (ch >= 0x0080 || ch == L' ' || IsControlChar(ch))
3096                 {
3097                         return false;
3098                 }
3099         }
3100         return true;
3101 }
3102
3103 void
3104 Uri::Clear(void)
3105 {
3106         // Component
3107         __scheme.Clear();
3108         __ssp.Clear();
3109         __authority.Clear();
3110         __host.Clear();
3111         __fragment.Clear();
3112         __path.Clear();
3113         __userInfo.Clear();
3114         __query.Clear();
3115         __ipv4.Clear();
3116         __ipv6.Clear();
3117         __port = -1;
3118
3119         // Encoded Component
3120         __encodedAuth.Clear();
3121         __encodedFragment.Clear();
3122         __encodedPath.Clear();
3123         __encodedQuery.Clear();
3124         __encodedSsp.Clear();
3125 }
3126 }}} // Tizen::Base::Utility