| 20 | } |
| 21 | |
| 22 | bool UrlView::parse(const StringView& _url) |
| 23 | { |
| 24 | clear(); |
| 25 | |
| 26 | const char* term = _url.getTerm(); |
| 27 | StringView schemeEnd = strFind(_url, "://"); |
| 28 | const char* hostStart = !schemeEnd.isEmpty() ? schemeEnd.getTerm() : _url.getPtr(); |
| 29 | StringView path = strFind(StringView(hostStart, term), '/'); |
| 30 | |
| 31 | if (schemeEnd.isEmpty() |
| 32 | && path.isEmpty() ) |
| 33 | { |
| 34 | return false; |
| 35 | } |
| 36 | |
| 37 | if (!schemeEnd.isEmpty() |
| 38 | && (path.isEmpty() || path.getPtr() > schemeEnd.getPtr() ) ) |
| 39 | { |
| 40 | const StringView scheme(_url.getPtr(), schemeEnd.getPtr() ); |
| 41 | |
| 42 | if (!isAlpha(scheme) ) |
| 43 | { |
| 44 | return false; |
| 45 | } |
| 46 | |
| 47 | m_tokens[Scheme].set(scheme); |
| 48 | } |
| 49 | |
| 50 | if (!path.isEmpty() ) |
| 51 | { |
| 52 | path.set(path.getPtr(), term); |
| 53 | const StringView query = strFind(path, '?'); |
| 54 | const StringView fragment = strFind(path, '#'); |
| 55 | |
| 56 | if (!fragment.isEmpty() |
| 57 | && fragment.getPtr() < query.getPtr() ) |
| 58 | { |
| 59 | return false; |
| 60 | } |
| 61 | |
| 62 | m_tokens[Path].set(path.getPtr() |
| 63 | , !query.isEmpty() ? query.getPtr() |
| 64 | : !fragment.isEmpty() ? fragment.getPtr() |
| 65 | : term |
| 66 | ); |
| 67 | |
| 68 | if (!query.isEmpty() ) |
| 69 | { |
| 70 | m_tokens[Query].set(query.getPtr()+1 |
| 71 | , !fragment.isEmpty() ? fragment.getPtr() |
| 72 | : term |
| 73 | ); |
| 74 | } |
| 75 | |
| 76 | if (!fragment.isEmpty() ) |
| 77 | { |
| 78 | m_tokens[Fragment].set(fragment.getPtr()+1, term); |
| 79 | } |