char *URL_GetAbsoluteFilePath(const char *pathName, const char *parentPath) { char *outPath; u32 prot_type; prot_type = URL_GetProtocolType(pathName); /*abs path name*/ if (prot_type == URL_TYPE_FILE) { u32 offset = URL_SEP_LENGTH + 4; if (!strstr(pathName, "://") && !strstr(pathName, "|//")) return strdup(pathName); /*not sure if "file:///C:\..." is std, but let's handle it anyway*/ if (strstr(pathName, ":///") || strstr(pathName, "|///")) { if (pathName[offset+2]==':') offset += 1; } outPath = (char *) malloc(strlen(pathName) - offset + 1); strcpy(outPath, pathName + offset); return outPath; } if (prot_type==URL_TYPE_ANY) return NULL; if (!parentPath) return strdup(pathName); /*try with the parent URL*/ prot_type = URL_GetProtocolType(parentPath); /*if abs parent path concatenate*/ if (prot_type == URL_TYPE_FILE) return URL_Concatenate(parentPath, pathName); if (prot_type != URL_TYPE_RELATIVE) return NULL; /*if we are here, parentPath is also relative... return the original PathName*/ return strdup(pathName); }
char *gf_url_get_absolute_path(const char *pathName, const char *parentPath) { u32 prot_type = URL_GetProtocolType(pathName); /*abs path name*/ if (prot_type == GF_URL_TYPE_FILE) { /*abs path*/ if (!strstr(pathName, "://") && !strstr(pathName, "|//")) return gf_strdup(pathName); pathName += 6; /*not sure if "file:///C:\..." is std, but let's handle it anyway*/ if ((pathName[0]=='/') && (pathName[2]==':')) pathName += 1; return gf_strdup(pathName); } if (prot_type==GF_URL_TYPE_ANY) return NULL; if (!parentPath) return gf_strdup(pathName); /*try with the parent URL*/ prot_type = URL_GetProtocolType(parentPath); /*if abs parent path concatenate*/ if (prot_type == GF_URL_TYPE_FILE) return gf_url_concatenate(parentPath, pathName); if (prot_type != GF_URL_TYPE_RELATIVE) return NULL; /*if we are here, parentPath is also relative... return the original PathName*/ return gf_strdup(pathName); }
GF_EXPORT char *gf_url_concatenate(const char *parentName, const char *pathName) { u32 pathSepCount, i, prot_type; char *outPath, *name, *rad; char tmp[GF_MAX_PATH]; if (!pathName && !parentName) return NULL; if (!pathName) return gf_strdup(parentName); if (!parentName) return gf_strdup(pathName); if ( (strlen(parentName) > GF_MAX_PATH) || (strlen(pathName) > GF_MAX_PATH) ) return NULL; prot_type = URL_GetProtocolType(pathName); if (prot_type != GF_URL_TYPE_RELATIVE) { char *sep = NULL; if (pathName[0]=='/') sep = strstr(parentName, "://"); if (sep) sep = strchr(sep+3, '/'); if (sep) { u32 len; sep[0] = 0; len = (u32) strlen(parentName); outPath = (char*)gf_malloc(sizeof(char)*(len+1+strlen(pathName))); strcpy(outPath, parentName); strcat(outPath, pathName); sep[0] = '/'; } else { outPath = gf_strdup(pathName); } goto check_spaces; } /*old upnp addressing a la Platinum*/ rad = strstr(parentName, "%3fpath="); if (!rad) rad = strstr(parentName, "%3Fpath="); if (!rad) rad = strstr(parentName, "?path="); if (rad) { char *the_path; rad = strchr(rad, '='); rad[0] = 0; the_path = gf_strdup(rad+1); i=0; while (1) { if (the_path[i]==0) break; if (!strnicmp(the_path+i, "%5c", 3) || !strnicmp(the_path+i, "%2f", 3) ) { the_path[i] = '/'; memmove(the_path+i+1, the_path+i+3, strlen(the_path+i+3)+1); } else if (!strnicmp(the_path+i, "%05c", 4) || !strnicmp(the_path+i, "%02f", 4) ) { the_path[i] = '/'; memmove(the_path+i+1, the_path+i+4, strlen(the_path+i+4)+1); } i++; } name = gf_url_concatenate(the_path, pathName); outPath = gf_malloc(strlen(parentName) + strlen(name) + 2); sprintf(outPath, "%s=%s", parentName, name); rad[0] = '='; gf_free(name); gf_free(the_path); return outPath; } /*rewrite path to use / not % encoding*/ rad = strchr(parentName, '%'); if (rad && (!strnicmp(rad, "%5c", 3) || !strnicmp(rad, "%05c", 4) || !strnicmp(rad, "%2f", 3) || !strnicmp(rad, "%02f", 4))) { char *the_path = gf_strdup(parentName); i=0; while (1) { if (the_path[i]==0) break; if (!strnicmp(the_path+i, "%5c", 3) || !strnicmp(the_path+i, "%2f", 3) ) { the_path[i] = '/'; memmove(the_path+i+1, the_path+i+3, strlen(the_path+i+3)+1); } else if (!strnicmp(the_path+i, "%05c", 4) || !strnicmp(the_path+i, "%02f", 4) ) { the_path[i] = '/'; memmove(the_path+i+1, the_path+i+4, strlen(the_path+i+4)+1); } i++; } name = gf_url_concatenate(the_path, pathName); gf_free(the_path); return name; } pathSepCount = 0; name = NULL; if (pathName[0] == '.') { if (!strcmp(pathName, "..")) { pathSepCount = 1; name = ""; } if (!strcmp(pathName, "./")) { pathSepCount = 0; name = ""; } for (i = 0; i< strlen(pathName) - 2; i++) { /*current dir*/ if ( (pathName[i] == '.') && ( (pathName[i+1] == GF_PATH_SEPARATOR) || (pathName[i+1] == '/') ) ) { i++; continue; } /*parent dir*/ if ( (pathName[i] == '.') && (pathName[i+1] == '.') && ( (pathName[i+2] == GF_PATH_SEPARATOR) || (pathName[i+2] == '/') ) ) { pathSepCount ++; i+=2; name = (char *) &pathName[i+1]; } else { name = (char *) &pathName[i]; break; } } } if (!name) name = (char *) pathName; strcpy(tmp, parentName); while (strchr(" \r\n\t", tmp[strlen(tmp)-1])) { tmp[strlen(tmp)-1] = 0; } /*remove the last /*/ for (i = (u32) strlen(parentName); i > 0; i--) { //break our path at each separator if ((parentName[i-1] == GF_PATH_SEPARATOR) || (parentName[i-1] == '/')) { tmp[i-1] = 0; if (!pathSepCount) break; pathSepCount--; } } //if i==0, the parent path was relative, just return the pathName if (!i) { tmp[i] = 0; while (pathSepCount) { strcat(tmp, "../"); pathSepCount--; } } else { strcat(tmp, "/"); } i = (u32) strlen(tmp); outPath = (char *) gf_malloc(i + strlen(name) + 1); sprintf(outPath, "%s%s", tmp, name); /*cleanup paths sep for win32*/ for (i = 0; i<strlen(outPath); i++) if (outPath[i]=='\\') outPath[i] = '/'; check_spaces: i=0; while (outPath[i]) { if (outPath[i] == '?') break; if (outPath[i] != '%') { i++; continue; } if (!strnicmp(outPath+i, "%3f", 3)) break; if (!strnicmp(outPath+i, "%20", 3)) { outPath[i]=' '; memmove(outPath + i+1, outPath+i+3, strlen(outPath+i)-2); } i++; } return outPath; }
/*gets protocol type*/ Bool gf_url_is_local(const char *pathName) { u32 mode = URL_GetProtocolType(pathName); return (mode==GF_URL_TYPE_ANY) ? 0 : 1; }
char *URL_Concatenate(const char *parentName, const char *pathName) { u32 pathSepCount, i, prot_type; char psep; char *outPath, *name; char tmp[M4_MAX_PATH]; if (!pathName || !parentName) return NULL; if ( (strlen(parentName) > M4_MAX_PATH) || (strlen(pathName) > M4_MAX_PATH) ) return NULL; prot_type = URL_GetProtocolType(pathName); if (prot_type != URL_TYPE_RELATIVE) return strdup(pathName); /*we need abs path for parent*/ prot_type = URL_GetProtocolType(parentName); if (prot_type == URL_TYPE_RELATIVE) return strdup(pathName); pathSepCount = 0; name = NULL; if (pathName[0] == '.') { for (i = 0; i< strlen(pathName) - 2; i++) { /*current dir*/ if ( (pathName[i] == '.') && ( (pathName[i+1] == M4_PATH_SEPARATOR) || (pathName[i+1] == '/') ) ) continue; /*parent dir*/ if ( (pathName[i] == '.') && (pathName[i+1] == '.') && ( (pathName[i+2] == M4_PATH_SEPARATOR) || (pathName[i+2] == '/') ) ) { pathSepCount ++; i+=2; } else { name = (char *) &pathName[i]; break; } } } if (!name) name = (char *) pathName; strcpy(tmp, parentName); for (i = strlen(parentName); i > 0; i--) { //break our path at each separator if ((parentName[i-1] == M4_PATH_SEPARATOR) || (parentName[i-1] == '/')) { tmp[i-1] = 0; if (!pathSepCount) break; pathSepCount--; } } //if i==0, the parent path was relative, just return the pathName if (!i) return strdup(pathName); psep = (prot_type == URL_TYPE_FILE) ? M4_PATH_SEPARATOR : '/'; outPath = (char *) malloc(strlen(tmp) + strlen(name) + 2); sprintf(outPath, "%s%c%s", tmp, psep, name); /*cleanup paths sep for win32*/ if ((prot_type == URL_TYPE_FILE) && (M4_PATH_SEPARATOR != '/')) { for (i = 0; i<strlen(outPath); i++) if (outPath[i]=='/') outPath[i] = M4_PATH_SEPARATOR; } return outPath; }
char *gf_url_concatenate(const char *parentName, const char *pathName) { u32 pathSepCount, i, prot_type; char psep; char *outPath, *name; char tmp[GF_MAX_PATH]; if (!pathName || !parentName) return NULL; if ( (strlen(parentName) > GF_MAX_PATH) || (strlen(pathName) > GF_MAX_PATH) ) return NULL; prot_type = URL_GetProtocolType(pathName); if (prot_type != GF_URL_TYPE_RELATIVE) { outPath = strdup(pathName); goto check_spaces; } pathSepCount = 0; name = NULL; if (pathName[0] == '.') { for (i = 0; i< strlen(pathName) - 2; i++) { /*current dir*/ if ( (pathName[i] == '.') && ( (pathName[i+1] == GF_PATH_SEPARATOR) || (pathName[i+1] == '/') ) ) { i++; continue; } /*parent dir*/ if ( (pathName[i] == '.') && (pathName[i+1] == '.') && ( (pathName[i+2] == GF_PATH_SEPARATOR) || (pathName[i+2] == '/') ) ) { pathSepCount ++; i+=2; } else { name = (char *) &pathName[i]; break; } } } if (!name) name = (char *) pathName; strcpy(tmp, parentName); for (i = strlen(parentName); i > 0; i--) { //break our path at each separator if ((parentName[i-1] == GF_PATH_SEPARATOR) || (parentName[i-1] == '/')) { tmp[i-1] = 0; if (!pathSepCount) break; pathSepCount--; } } //if i==0, the parent path was relative, just return the pathName if (!i) { outPath = strdup(pathName); goto check_spaces; } prot_type = URL_GetProtocolType(parentName); psep = (prot_type == GF_URL_TYPE_FILE) ? GF_PATH_SEPARATOR : '/'; outPath = (char *) malloc(strlen(tmp) + strlen(name) + 2); sprintf(outPath, "%s%c%s", tmp, psep, name); /*cleanup paths sep for win32*/ if ((prot_type == GF_URL_TYPE_FILE) && (GF_PATH_SEPARATOR != '/')) { for (i = 0; i<strlen(outPath); i++) if (outPath[i]=='/') outPath[i] = GF_PATH_SEPARATOR; } check_spaces: while (1) { char *str = strstr(outPath, "%20"); if (!str) break; str[0] = ' '; memmove(str+1, str+3, strlen(str)-2); } return outPath; }