Created
August 25, 2016 12:49
-
-
Save dwbuiten/66f007058d27bf04663c362732f9be2a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is pseudocode / example to explain what kind of implementation I mean. | |
// I have not checked it for off-by-one errors, 100% accurate C compliance, etc. | |
// It's just to show what I mean, implementation wise. | |
#define SOME_DEFAULT_SIZE 20 | |
char *vlc_uri_compose(const vlc_url_t *uri) | |
{ | |
char *buf, *enc; | |
size_t len = SOME_DEFAULT_SIZE; | |
size_t pos = 0; | |
buf = calloc(len, 1); | |
if (buf == NULL) | |
return NULL; | |
if (uri->psz_protocol != NULL) { | |
// The following should be made into a function that uses va_list. or a macro. | |
int n = snprintf(buf, "%s:", uri->psz_protocol); | |
if (n + 1 >= len + pos) { | |
char *tmp = realloc(buf, n * 2); //arbitrary, could easily be n + 3, etc. | |
if (tmp != NULL) { | |
buf = tmp; | |
pos = n; | |
len = pos + | |
} else { | |
goto error; | |
} | |
} | |
} | |
if (uri->psz_host != NULL) | |
{ | |
if (pos + 2 + 1 < len) { | |
buf[pos++] = '/'; | |
buf[pos++] = '/'; | |
} else { | |
//realloc stuff or error or whatever | |
} | |
if (uri->psz_username != NULL) | |
{ | |
enc = vlc_uri_encode(uri->psz_username); | |
if (enc == NULL) | |
goto error; | |
if (pos + strlen(enc) + 1 > len) { | |
//realloc here | |
} | |
buf[pos++] = '\0'; | |
strcat(&buf[pos], enc); // Guaranteed to be big enough. Would be better off using memcpy or strncpy or strncat. Just used here for example psuedocode. | |
pos += strlen(enc); | |
free(enc); | |
if (uri->psz_password != NULL) | |
{ | |
enc = vlc_uri_encode(uri->psz_password); | |
if (unlikely(enc == NULL)) | |
goto error; | |
int writ = vlc_snprintf_realloc_thing(&buf, len, pos, ":%s", enc); // Pretend this is the macro/func I alluded to above. Could also be done using normal copies and '=' operators, since it's just %s and one character. | |
if (writ <= 0) { | |
//rrror stuff | |
} | |
pos += writ; | |
free(enc); | |
} | |
if (pos + 1 + 1 < len) { | |
buf[pos++] = '@' | |
} else { | |
//realloc or err stuff | |
} | |
} | |
const char *fmt; | |
if (strchr(uri->psz_host, ':') != NULL) | |
fmt = (uri->i_port != 0) ? "[%s]:%d" : "[%s]"; | |
else | |
fmt = (uri->i_port != 0) ? "%s:%d" : "%s"; | |
/* No IDNA decoding here. Seems unnecessary, dangerous even. */ | |
int writ = vlc_snprintf_realloc_thing(&buf, len, pos, fmt, uri->psz_host, uri->i_port); | |
if (write <= 0) { | |
//error | |
} | |
} | |
if (uri->psz_path != NULL) { | |
if (pos + strlen(uri->psz_path) + 1 < len) { | |
//realloc stuff | |
} | |
strcat(&buf[pos], uri->psz_path); // same comment as last usage | |
pos += strlen(uri->psz_path); | |
} | |
if (uri->psz_option != NULL) { | |
int writ = vlc_snprintf_realloc_thing(&buf, len, pos, "?%s", uri->psz_option); //same comment as the last few | |
if (writ <= 0) { | |
//error | |
} | |
} | |
if (pos + 1 < len) { | |
//realloc | |
} | |
buf[pos] = '\0'; | |
return buf; | |
error: | |
free(buf); | |
return NULL; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment