21 intptr_t
len = strlen(str) + 1;
29 for (intptr_t
i = 0;
i <
len;
i++) {
87 if ((digit >=
'0' && digit <=
'9')) {
90 if ((digit >=
'A' && digit <=
'F')) {
91 return digit -
'A' + 10;
93 if ((digit >=
'a' && digit <=
'f')) {
94 return digit -
'a' + 10;
105 if (str[
pos] !=
'%') {
110 char digit1 = str[
pos + 1];
111 char digit2 = str[
pos + 2];
128 intptr_t buffer_pos = 0;
132 if (escaped_value >= 0) {
137 buffer[buffer_pos] = escaped_value;
160 buffer[buffer_pos] =
'\0';
166 const intptr_t
len = strlen(str);
170 if (escaped_value >= 0) {
177 if (c >=
'A' && c <=
'Z') {
178 str[
i] = c + (
'a' -
'A');
186 const char* current = authority;
189 size_t userinfo_len = strcspn(current,
"@/");
190 if (current[userinfo_len] ==
'@') {
193 current += userinfo_len + 1;
194 len += userinfo_len + 1;
197 size_t host_len = strcspn(current,
":/");
203 if (current[host_len] ==
':') {
205 const char* port_start = current + host_len + 1;
206 size_t port_len = strcspn(port_start,
"/");
215std::unique_ptr<ParsedUri>
ParseUri(
const char* uri) {
216 auto parsed_uri = std::make_unique<ParsedUri>();
220 size_t scheme_len = strcspn(uri,
":/");
221 const char* rest = uri;
222 if (uri[scheme_len] ==
':') {
225 parsed_uri->scheme = std::move(scheme);
226 rest = uri + scheme_len + 1;
230 const char* hash_pos = rest + strcspn(rest,
"#");
231 if (*hash_pos ==
'#') {
233 const char* fragment_start = hash_pos + 1;
234 parsed_uri->fragment =
240 const char* question_pos = rest + strcspn(rest,
"?#");
241 if (*question_pos ==
'?') {
243 const char* query_start = question_pos + 1;
244 parsed_uri->query =
NormalizeEscapes(query_start, (hash_pos - query_start));
247 const char* path_start = rest;
248 if (rest[0] ==
'/' && rest[1] ==
'/') {
250 const char* authority_start = rest + 2;
252 intptr_t authority_len =
ParseAuthority(authority_start, *parsed_uri.get());
253 if (authority_len < 0) {
254 return std::unique_ptr<ParsedUri>();
256 path_start = authority_start + authority_len;
260 parsed_uri->path =
NormalizeEscapes(path_start, (question_pos - path_start));
265 if (current ==
base) {
269 for (current--; current >
base; current--) {
270 if (*current ==
'/') {
280 const char* cp = input;
288 cp += strcspn(cp,
"/");
294 const char* input =
path;
302 while (*input !=
'\0') {
303 if (strncmp(
"../", input, 3) == 0) {
307 }
else if (strncmp(
"./", input, 3) == 0) {
311 }
else if (strncmp(
"/./", input, 3) == 0) {
315 }
else if (strcmp(
"/.", input) == 0) {
319 }
else if (strncmp(
"/../", input, 4) == 0) {
325 }
else if (strcmp(
"/..", input) == 0) {
331 }
else if (strcmp(
"..", input) == 0) {
335 }
else if (strcmp(
".", input) == 0) {
345 strncpy(
output, input, segment_len);
347 input += segment_len;
356 if (base_path[0] ==
'\0') {
362 const char* last_slash = strrchr(base_path,
'/');
363 if (last_slash ==
nullptr) {
370 intptr_t truncated_base_len = last_slash - base_path;
371 intptr_t ref_path_len = strlen(ref_path);
372 intptr_t
len = truncated_base_len + ref_path_len + 1;
376 strncpy(
buffer, base_path, truncated_base_len);
379 buffer[truncated_base_len] =
'/';
382 strncpy((
buffer + truncated_base_len + 1), ref_path, ref_path_len + 1);
391 const char* fragment_separator = uri.
fragment ==
nullptr ?
"" :
"#";
392 const char* query = uri.
query ==
nullptr ?
"" : uri.
query.get();
393 const char* query_separator = uri.
query ==
nullptr ?
"" :
"?";
398 if (uri.
scheme ==
nullptr) {
400 uri.
port ==
nullptr);
402 fragment_separator, fragment);
406 if (uri.
host ==
nullptr) {
409 query_separator, query, fragment_separator, fragment);
413 const char* user_separator = uri.
userinfo ==
nullptr ?
"" :
"@";
414 const char*
port = uri.
port ==
nullptr ?
"" : uri.
port.get();
415 const char* port_separator = uri.
port ==
nullptr ?
"" :
":";
419 const char* path_separator =
420 ((uri.
path.get()[0] ==
'\0' || uri.
path.get()[0] ==
'/') ?
"" :
"/");
425 "%s://%s%s%s%s%s%s%s%s%s%s%s",
426 uri.
scheme.get(), user, user_separator, uri.
host.get(), port_separator,
427 port, path_separator, uri.
path.get(), query_separator, query,
428 fragment_separator, fragment);
434 std::unique_ptr<ParsedUri> ref =
ParseUri(ref_uri);
440 if (ref->scheme !=
nullptr) {
441 if (strcmp(ref->scheme.get(),
"dart") == 0) {
446 target.scheme = std::move(ref->scheme);
447 target.userinfo = std::move(ref->userinfo);
448 target.host = std::move(ref->host);
449 target.port = std::move(ref->port);
450 target.path = std::move(ref->path);
451 target.query = std::move(ref->query);
452 target.fragment = std::move(ref->fragment);
462 if ((
base->scheme !=
nullptr) && strcmp(
base->scheme.get(),
"dart") == 0) {
466 if (ref->host !=
nullptr) {
469 target.userinfo = std::move(ref->userinfo);
470 target.host = std::move(ref->host);
471 target.port = std::move(ref->port);
473 target.query = std::move(ref->query);
474 target.fragment = std::move(ref->fragment);
478 if (ref->path.get()[0] ==
'\0') {
485 target.query = ((ref->query ==
nullptr) ? std::move(
base->query)
486 : std::move(ref->query));
487 target.fragment = std::move(ref->fragment);
490 }
else if (ref->path.get()[0] ==
'/') {
497 target.query = std::move(ref->query);
498 target.fragment = std::move(ref->fragment);
504 if (
base->scheme ==
nullptr &&
base->host ==
nullptr &&
505 base->path.get()[0] !=
'/') {
521 target.query = std::move(ref->query);
522 target.fragment = std::move(ref->fragment);
CStringUniquePtr fragment
CStringUniquePtr userinfo
static int SNPrint(char *str, size_t size, const char *format,...) PRINTF_ATTRIBUTE(3
static char static char * VSCreate(const char *format, va_list args)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
uint32_t uint32_t * format
CStringUniquePtr BuildUri(const ParsedUri &uri)
static int GetEscapedValue(const char *str, intptr_t pos, intptr_t len)
CAllocUniquePtr< char > CStringUniquePtr
static CStringUniquePtr MakeCopyOfString(const char *str)
void * malloc(size_t size)
static intptr_t ParseAuthority(const char *authority, ParsedUri &parsed_uri)
std::unique_ptr< ParsedUri > ParseUri(const char *uri)
static bool IsHexDigit(char value)
static CStringUniquePtr PrintToString(const char *format,...)
static bool IsDelimiter(intptr_t value)
static CStringUniquePtr MakeCopyOfStringN(const char *str, intptr_t len)
static void StringLower(char *str)
static bool IsUnreservedChar(intptr_t value)
CStringUniquePtr ResolveUri(const char *ref_uri, const char *base_uri)
static int HexValue(char digit)
static char * RemoveLastSegment(char *current, char *base)
CStringUniquePtr MergePaths(const char *base_path, const char *ref_path)
static intptr_t SegmentLength(const char *input)
CStringUniquePtr NormalizeEscapes(const char *str, intptr_t len)
CStringUniquePtr RemoveDotSegments(const char *path)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service port
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service host
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer