NOTE: This parser is not even close to rfc2396 but good enough for our purposes
| 43 | |
| 44 | // NOTE: This parser is not even close to rfc2396 but good enough for our purposes |
| 45 | Result Parse(const char* uri, Parts* parts) |
| 46 | { |
| 47 | parts->m_Scheme[0] = '\0'; |
| 48 | parts->m_Location[0] = '\0'; |
| 49 | parts->m_Hostname[0] = '\0'; |
| 50 | parts->m_Port = -1; |
| 51 | parts->m_Path[0] = '\0'; |
| 52 | |
| 53 | const char* scheme_end = strchr(uri, ':'); |
| 54 | if (!scheme_end || !IsValidScheme(uri, scheme_end)) |
| 55 | { |
| 56 | // Assume file:/// scheme |
| 57 | dmStrlCpy(parts->m_Scheme, "file", sizeof(parts->m_Scheme)); |
| 58 | dmStrlCpy(parts->m_Path, uri, sizeof(parts->m_Path)); |
| 59 | return RESULT_OK; |
| 60 | } |
| 61 | else |
| 62 | { |
| 63 | size_t n = dmMath::Min(sizeof(parts->m_Scheme), (size_t) (scheme_end-uri) + 1); |
| 64 | dmStrlCpy(parts->m_Scheme, uri, n); |
| 65 | |
| 66 | if (strcmp(parts->m_Scheme, "http") == 0 || strcmp(parts->m_Scheme, "ws") == 0) |
| 67 | { |
| 68 | // Default to port 80 for http |
| 69 | parts->m_Port = 80; |
| 70 | } |
| 71 | else if (strcmp(parts->m_Scheme, "https") == 0 || strcmp(parts->m_Scheme, "wss") == 0) |
| 72 | { |
| 73 | // Default to port 443 for https |
| 74 | parts->m_Port = 443; |
| 75 | } |
| 76 | |
| 77 | const char* slash_slash = strstr(uri, "//"); |
| 78 | if (slash_slash) |
| 79 | { |
| 80 | const char* location = slash_slash + 2; |
| 81 | const char* path = strchr(location, '/'); |
| 82 | if (path) |
| 83 | { |
| 84 | dmStrlCpy(parts->m_Location, location, dmMath::Min(sizeof(parts->m_Location), (size_t) (path - location) + 1)); |
| 85 | dmStrlCpy(parts->m_Path, path, sizeof(parts->m_Path)); |
| 86 | } |
| 87 | else |
| 88 | { |
| 89 | dmStrlCpy(parts->m_Location, location, sizeof(parts->m_Location)); |
| 90 | } |
| 91 | dmStrlCpy(parts->m_Hostname, parts->m_Location, sizeof(parts->m_Hostname)); |
| 92 | char* port = strchr(parts->m_Hostname, ':'); |
| 93 | if (port) |
| 94 | { |
| 95 | parts->m_Port = strtol(port + 1, 0, 10); |
| 96 | *port = '\0'; |
| 97 | } |
| 98 | } |
| 99 | else |
| 100 | { |
| 101 | dmStrlCpy(parts->m_Path, scheme_end+1, sizeof(parts->m_Path)); |
| 102 | } |