Skip to content

Instantly share code, notes, and snippets.

@dwbuiten
Created August 25, 2016 12:49
Show Gist options
  • Save dwbuiten/66f007058d27bf04663c362732f9be2a to your computer and use it in GitHub Desktop.
Save dwbuiten/66f007058d27bf04663c362732f9be2a to your computer and use it in GitHub Desktop.
// 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