tchar_t* FirstSepar(const tchar_t *Path) { tchar_t *s1, *s2; s1 = tcschr(Path, '\\'); s2 = tcschr(Path, '/'); if (!s1 || (s2 && s2 < s1)) s1 = s2; return s1; }
static err_t Open(urlpart* p, const tchar_t* URL, int Flags) { err_t Result; const tchar_t *String, *Equal; tchar_t Value[MAXPATHFULL]; datetime_t Date = INVALID_DATETIME_T; String = tcsrchr(URL,URLPART_SEP_CHAR); if (!String) return ERR_INVALID_DATA; Clear(p); Node_SetData((node*)p,STREAM_URL,TYPE_STRING,URL); Equal = GetProtocol(URL,NULL,0,NULL); tcsncpy_s(Value,TSIZEOF(Value),Equal,String-Equal); tcsreplace(Value,TSIZEOF(Value),URLPART_SEP_ESCAPE,URLPART_SEPARATOR); Node_SetData((node*)p,URLPART_URL,TYPE_STRING,Value); while (String++ && *String) { Equal = tcschr(String,T('=')); if (Equal) { tchar_t *Sep = tcschr(Equal,T('#')); if (Sep) tcsncpy_s(Value,TSIZEOF(Value),Equal+1,Sep-Equal-1); else tcscpy_s(Value,TSIZEOF(Value),Equal+1); if (tcsncmp(String,T("ofs"),Equal-String)==0) p->Pos = StringToInt(Value,0); else if (tcsncmp(String,T("len"),Equal-String)==0) p->Length = StringToInt(Value,0); else if (tcsncmp(String,T("mime"),Equal-String)==0) Node_SetData((node*)p,URLPART_MIME,TYPE_STRING,Value); else if (tcsncmp(String,T("date"),Equal-String)==0) Date = StringToInt(Value,0); } String = tcschr(String,'#'); } if (Date!=INVALID_DATETIME_T && Date != FileDateTime(Node_Context(p),Node_GetDataStr((node*)p,URLPART_URL))) return ERR_INVALID_DATA; p->Input = GetStream(p,Node_GetDataStr((node*)p,URLPART_URL),Flags); if (!p->Input) return ERR_NOT_SUPPORTED; Stream_Blocking(p->Input,p->Blocking); Result = Stream_Open(p->Input,Node_GetDataStr((node*)p,URLPART_URL),Flags); if (Result == ERR_NONE && p->Pos!=INVALID_FILEPOS_T) // TODO: support asynchronous stream opening { if (Stream_Seek(p->Input,p->Pos,SEEK_SET)!=p->Pos) return ERR_INVALID_DATA; } return Result; }
void SplitURL(const tchar_t* URL, tchar_t* Protocol, int ProtocolLen, tchar_t* Host, int HostLen, int* Port, tchar_t* Path, int PathLen) { bool_t HasHost; URL = GetProtocol(URL,Protocol,ProtocolLen,&HasHost); if (HasHost) { const tchar_t* p; const tchar_t* p2; p = tcschr(URL,'\\'); p2 = tcschr(URL,'/'); if (!p || (p2 && p2>p)) p=p2; if (!p) p = URL+tcslen(URL); p2 = tcschr(URL,':'); if (p2 && p2<p) { if (Port) stscanf(p2+1,T("%d"),Port); } else p2 = p; if (Host) tcsncpy_s(Host,HostLen,URL,p2-URL); URL = p; } else { if (Host && HostLen>0) *Host = 0; } if (Path) { if (URL[0]) { tchar_t* p; tcscpy_s(Path,PathLen,URL); for (p=Path;*p;++p) if (*p == '\\') *p = '/'; } else tcscpy_s(Path,PathLen,T("/")); } }
void AbsPath(tchar_t* Abs, int AbsLen, const tchar_t* Path, const tchar_t* Base) { if (Base && GetProtocol(Base,NULL,0,NULL)!=Base && (Path[0] == '/' || Path[0] == '\\') && (Path[1] != '/' && Path[1] != '\\')) { tchar_t* s; bool_t HasHost; tcscpy_s(Abs,AbsLen,Base); s = (tchar_t*)GetProtocol(Abs,NULL,0,&HasHost); if (!HasHost) { // keep "mime://" from Base ++Path; *s = 0; } else { // keep "mime://host" from Base tchar_t *a,*b; a = tcschr(s,'\\'); b = tcschr(s,'/'); if (!a || (b && b<a)) a=b; if (a) *a=0; } } else if (Base && GetProtocol(Path,NULL,0,NULL)==Path && Path[0] != '/' && Path[0] != '\\' && !(Path[0] && Path[1]==':' && (Path[2]=='\\' || Path[2]=='\0'))) { // doesn't have mime or drive letter or pathdelimiter at the start const tchar_t* MimeEnd = GetProtocol(Base,NULL,0,NULL); tcscpy_s(Abs,AbsLen,Base); #if defined(TARGET_WIN) || defined(TARGET_SYMBIAN) if (MimeEnd==Base) AddPathDelimiter(Abs,AbsLen); else #endif if (MimeEnd[0]) AddPathDelimiter(Abs,AbsLen); } else Abs[0] = 0; tcscat_s(Abs,AbsLen,Path); AbsPathNormalize(Abs,AbsLen); }
static int ReadList(playlist* p,tchar_t* Path,int PathLen,tchar_t* DispName,int DispNameLen,tick_t* Length) { tchar_t s[MAXLINE]; DispName[0] = 0; *Length = -1; while (ParserLine(&p->Parser,s,MAXLINE)) { if (s[0]=='#') { tcsuprto(s,':'); if (stscanf(s,T("#EXTINF: %d ,"),Length)==1) { tchar_t* p = tcschr(s,','); if (p++) { while (IsSpace(*p)) ++p; tcscpy_s(DispName,DispNameLen,p); } if (*Length >= 0) *Length *= TICKSPERSEC; } } else if (s[0]) { tcscpy_s(Path,PathLen,s); return ERR_NONE; } } return ERR_END_OF_FILE; }
char StreamExtType(anynode* AnyNode, fourcc_t ClassFilter, const tchar_t *Ext) { char Result = FTYPE_UNDEFINED; tchar_t *s; size_t i; array List; StreamGenExts(AnyNode,&List,ClassFilter,NULL); for (s=ARRAYBEGIN(List,tchar_t);s;) { for (i=0;s[i] && s[i]==Ext[i];i++) {} if (!Ext[i] && s[i] == ':') { Result = (char)s[i+1]; break; } s = tcschr(s,';'); if (s) ++s; } ArrayClear(&List); return Result; }
static NOINLINE void AddField(pin* Pin,int Id,tchar_t* Value) { tchar_t* p; if (Id == COMMENT_GENRE) { int Genre; p = tcschr(Value,'='); if (p && stscanf(p,T("=(%d)"),&Genre)==1 && Genre<GENRE_COUNT) { tchar_t* q=++p; while (*q && *q!=')') ++q; if (q[0]==')' && q[1]) // custom name while ((*(p++)=*(++q))!=0); else { AddGenre(Pin,Genre); return; } } } if (Id != COMMENT_COMMENT) for (p=Value;*p;++p) if (*p==10) *p=' '; Pin->Node->Set(Pin->Node,Pin->No,Value,(tcslen(Value)+1)*sizeof(tchar_t)); }
bool_t UpperPath(tchar_t* Path, tchar_t* Last, size_t LastLen) { tchar_t *a,*b,*c; bool_t HasHost; tchar_t Mime[32]; if (!*Path) return 0; RemovePathDelimiter(Path); c = (tchar_t*)GetProtocol(Path,Mime,TSIZEOF(Mime),&HasHost); a = tcsrchr(c,'\\'); b = tcsrchr(c,'/'); if (!a || (b && b>a)) a=b; #ifdef TARGET_PS2SDK if (!a && (a = tcschr(c,':'))!=NULL) if (a[1]==0) a = NULL; #endif if (!a) { if (tcsicmp(Mime, T("smb")) == 0) { *c = 0; tcscpy_s(Last, LastLen, Path); return 1; } if (HasHost && tcsicmp(Mime, T("upnp"))!=0) return 0; a=c; if (!a[0]) // only mime left a=c=Path; } else ++a; if (Last) tcscpy_s(Last,LastLen,a); if (a==c) *a = 0; #ifdef TARGET_PS2SDK if (a>c && a[-1]==':') *a = 0; #endif while (--a>=c && (*a=='\\' || *a=='/')) *a = 0; return 1; }
bool_t StreamGenExts(anynode* AnyNode,array* Exts, fourcc_t ClassFilter, const tchar_t* TypeFilter) { fourcc_t* i; array List; ArrayInit(Exts); if (TypeFilter && !TypeFilter[0]) TypeFilter = NULL; NodeEnumClass(AnyNode,&List,ClassFilter); for (i=ARRAYBEGIN(List,fourcc_t);i!=ARRAYEND(List,fourcc_t);++i) { const tchar_t* s = NodeStr2(AnyNode,*i,NODE_EXTS); while (s && s[0]) { size_t n; for (n=0;s[n] && s[n]!=';' && s[n]!=':';++n) {} if (!TypeFilter || (s[n]==':' && tcschr(TypeFilter,s[n+1])!=NULL)) { while (s[n] && s[n]!=';') ++n; if (n) { if (!ARRAYEMPTY(*Exts)) ArrayAppend(Exts,T(";"),sizeof(tchar_t),64); ArrayAppend(Exts,s,n*sizeof(tchar_t),64); } } s = tcschr(s,';'); if (s) ++s; } } ArrayClear(&List); if (!ARRAYEMPTY(*Exts) && !ArrayAppend(Exts,T("\0"),sizeof(tchar_t),64)) ArrayClear(Exts); return !ARRAYEMPTY(*Exts); }
int CheckExts(const tchar_t* URL, const tchar_t* Exts) { tchar_t Ext[MAXPATH]; tchar_t* Tail; intptr_t ExtLen; SplitPath(URL,NULL,0,NULL,0,Ext,TSIZEOF(Ext)); Tail = tcschr(Ext,'?'); if (Tail) *Tail = 0; ExtLen = tcslen(Ext); while (Exts) { const tchar_t* p = tcschr(Exts,':'); if (p && (ExtLen == p-Exts) && tcsnicmp(Ext,Exts,p-Exts)==0) return p[1]; // return type char Exts = tcschr(Exts,';'); if (Exts) ++Exts; } return 0; }
static int ReadList(pls* p,tchar_t* Path,int PathLen,tchar_t* DispName,int DispNameLen,tick_t* Length) { tchar_t s[MAXLINE]; int No,Len; int Result = ERR_END_OF_FILE; while (Result==ERR_END_OF_FILE && ParserLine(&p->Playlist.Parser,s,MAXLINE)) { tcsuprto(s,'='); if (stscanf(s,T("FILE%d ="),&No)==1) { if (No != p->Playlist.No && Fill(p,Path,PathLen,DispName,DispNameLen,Length)) Result = ERR_NONE; p->Playlist.No = No; tcscpy_s(p->File,TSIZEOF(p->File),tcschr(s,'=')+1); } else if (stscanf(s,T("TITLE%d ="),&No)==1) { if (No != p->Playlist.No && Fill(p,Path,PathLen,DispName,DispNameLen,Length)) Result = ERR_NONE; p->Playlist.No = No; tcscpy_s(p->Title,TSIZEOF(p->Title),tcschr(s,'=')+1); } else if (stscanf(s,T("LENGTH%d = %d"),&No,&Len)==2) { if (No != p->Playlist.No && Fill(p,Path,PathLen,DispName,DispNameLen,Length)) Result = ERR_NONE; p->Playlist.No = No; p->Length = Len; } } if (Result==ERR_END_OF_FILE && Fill(p,Path,PathLen,DispName,DispNameLen,Length)) Result = ERR_NONE; return Result; }
bool_t SplitAddr(const tchar_t* URL, tchar_t* Peer, int PeerLen, tchar_t* Local, int LocalLen) { const tchar_t* p = NULL; const tchar_t* p2; const tchar_t* Addr; bool_t HasHost; bool_t Result = 0; Addr = GetProtocol(URL,NULL,0,&HasHost); if (HasHost) { p = tcschr(Addr,'\\'); p2 = tcschr(Addr,'/'); if (!p || (p2 && p2>p)) p=p2; } if (!p) p = Addr+tcslen(Addr); p2 = tcschr(Addr,'@'); if (!p2 || p2>p) p2 = p; else Result = 1; if (Peer) tcsncpy_s(Peer,PeerLen,URL,p2-URL); if (Local) { if (p2<p) ++p2; tcsncpy_s(Local,LocalLen,URL,Addr-URL); tcsncat_s(Local,LocalLen,p2,p-p2); } return Result; }
void StreamLoginInfo(node* p, tchar_t* URL, bool_t Proxy) { tchar_t LoginPass[MAXPATH]; if (SplitAddr(URL,LoginPass,TSIZEOF(LoginPass),NULL,0)) { // extract the login:pass from the URL as there seems to be one tchar_t *s,*t; if (!Proxy) { Node_SetData(p,STREAM_FULL_URL,TYPE_STRING,URL); t = (tchar_t*)GetProtocol(URL,NULL,0,NULL); s = tcschr(t,T('@')); assert(s!=NULL); ++s; memmove(t, s, tcsbytes(s)); } t = (tchar_t*)GetProtocol(LoginPass,NULL,0,NULL); s=tcschr(t,T(':')); if (s) *s++ = 0; if (Proxy) { Node_SetData(p,STREAM_PROXY_PASSWORD,TYPE_STRING,s); Node_SetData(p,STREAM_PROXY_USERNAME,TYPE_STRING,t); } else { Node_SetData(p,STREAM_PASSWORD,TYPE_STRING,s); Node_SetData(p,STREAM_USERNAME,TYPE_STRING,t); } } else Node_RemoveData(p,STREAM_FULL_URL,TYPE_STRING); }
static int next(const tchar *src, const tchar *slim, tchar *dst, tchar *dlim) { const tchar *start = src; if (dst >= dlim) { return 0; } dlim--; while (src < slim && *src && istspace(*src)) { src++; } if (src < slim && tcschr((const char *)ops + 2, *src)) { *dst++ = *src++; } else { while (src < slim && dst < dlim && *src && istspace(*src) == 0 && tcschr((const char *)ops + 2, *src) == NULL) { *dst++ = *src++; } } *dst = _T('\0'); return src - start; }
void RelPath(tchar_t* Rel, int RelLen, const tchar_t* Path, const tchar_t* Base) { size_t n; bool_t HasHost; const tchar_t* p = GetProtocol(Base,NULL,0,&HasHost); if (p != Base) { if (HasHost) { // include host name too tchar_t *a,*b; a = tcschr(p,'\\'); b = tcschr(p,'/'); if (!a || (b && b<a)) a=b; if (a) p=a; else p+=tcslen(p); } // check if mime and host is the same n = p-Base; if (n>0 && n<tcslen(Path) && (Path[n]=='\\' || Path[n]=='/') && tcsnicmp(Path,Base,n)==0) { Base += n; Path += n; } } n = tcslen(Base); if (n>0 && n<tcslen(Path) && (Path[n]=='\\' || Path[n]=='/') && tcsnicmp(Path,Base,n)==0) Path += n+1; tcscpy_s(Rel,RelLen,Path); }
void SplitURLLogin(const tchar_t *URL, tchar_t *UserName, size_t UserNameLen, tchar_t *Password, size_t PasswordLen, tchar_t *URL2, size_t URL2Len) { tchar_t LoginPass[MAXPATH]; if (SplitAddr(URL, LoginPass, TSIZEOF(LoginPass), NULL, 0)) { tchar_t *s,*t; if (URL2) { tcscpy_s(URL2, URL2Len, URL); t = (tchar_t*)GetProtocol(URL2,NULL,0,NULL); s = tcschr(t,T('@')); assert(s!=NULL); ++s; memmove(t, s, tcsbytes(s)); } t = (tchar_t*)GetProtocol(LoginPass,NULL,0,NULL); s=tcschr(t,T(':')); if (s) { *s++ = 0; // missing: resolving escape sequences if (Password) tcscpy_s(Password, PasswordLen, s); } else tcsclr_s(Password, PasswordLen); if (UserName) tcscpy_s(UserName, UserNameLen, t); } else { tcsclr_s(UserName, UserNameLen); tcsclr_s(Password, PasswordLen); if (URL2) tcscpy_s(URL2, URL2Len, URL); } }
/** * @brief return a text that end with one of the `end' chars */ tchar * escm_input_gettext(escm_input *f, const tchar *end) { size_t len = 0; tint c; assert(f != NULL); assert(end != NULL); c = escm_input_getc(f); while (c != TEOF && !tcschr(end, c)) { if (c == T('\\')) { c = escm_input_getc(f); switch (c) { case T('a'): c = T('\a'); break; case T('b'): c = T('\b'); break; case T('f'): c = T('\f'); break; case T('n'): c = T('\n'); break; case T('r'): c = T('\r'); break; case T('t'): c = T('\t'); break; case T('v'): c = T('\v'); break; case T('\\'): case T('"'): break; default: strbuf[len++] = T('\\'); break; /* keep the new character */ } strbuf[len++] = c; } else strbuf[len++] = c; c = escm_input_getc(f); } if (!f->end) escm_input_ungetc(f, c); strbuf[len] = T('\0'); return tcsdup(strbuf); }
const tchar_t* GetProtocol(const tchar_t* URL, tchar_t* Proto, int ProtoLen, bool_t* HasHost) { const tchar_t* s = tcschr(URL,':'); if (s && s[1] == '/' && s[2] == '/') { while (URL<s && IsSpace(*URL)) ++URL; if (Proto) tcsncpy_s(Proto,ProtoLen,URL,s-URL); if (HasHost) { if (tcsnicmp(URL,T("urlpart"),7)==0) // skip this protocol for the Host checking GetProtocol(URL+10,NULL,0,HasHost); else *HasHost = tcsnicmp(URL,T("file"),4)!=0 && tcsnicmp(URL,T("conf"),3)!=0 && tcsnicmp(URL,T("res"),3)!=0 && tcsnicmp(URL,T("root"),4)!=0 && tcsnicmp(URL,T("mem"),3)!=0 && tcsnicmp(URL,T("pose"),4)!=0 && tcsnicmp(URL,T("vol"),3)!=0 && tcsnicmp(URL,T("slot"),4)!=0 && tcsnicmp(URL,T("simu"),4)!=0 && tcsnicmp(URL,T("local"),5)!=0 && tcsnicmp(URL,T("sdcard"),6)!=0; } s += 3; } else { if (HasHost) *HasHost = 0; if (Proto) tcscpy_s(Proto,ProtoLen,T("file")); s = URL; } return s; }
void SplitPath(const tchar_t* URL, tchar_t* Dir, int DirLen, tchar_t* Name, int NameLen, tchar_t* Ext, int ExtLen) { const tchar_t *p,*p2,*p3; bool_t HasHost; tchar_t LocalURL[MAXPATH]; tchar_t Protocol[MAXPATH]; // mime p = GetProtocol(URL,Protocol,TSIZEOF(Protocol),&HasHost); // dir p2 = tcsrchr(p,'\\'); p3 = tcsrchr(p,'/'); if (!p2 || (p3 && p3>p2)) p2 = p3; #ifdef TARGET_PS2SDK // "host:test.elf" -> "host:" // "host:/test.elf" -> "host:/" (keeping end delimiter) if ((p2 && p2>p && p2[-1]==':') || (!p2 && (p2 = tcschr(p,':'))!=NULL)) { if (Dir) tcsncpy_s(Dir,DirLen,URL,p2-URL+1); URL = p2+1; } else #endif if (p2) { if (Dir) tcsncpy_s(Dir,DirLen,URL,p2-URL); URL = p2+1; } else if (HasHost) // no filename, only host { if (Dir) tcscpy_s(Dir,DirLen,URL); URL += tcslen(URL); } else // no directory { if (Dir) tcsncpy_s(Dir,DirLen,URL,p-URL); URL = p; } // name if (tcsicmp(Protocol,T("http"))==0 && tcsrchr(URL,T('#'))) { tchar_t *NulChar; tcscpy_s(LocalURL,TSIZEOF(LocalURL),URL); URL = LocalURL; NulChar = tcsrchr(LocalURL,T('#')); *NulChar = 0; } if (Name && Name == Ext) tcscpy_s(Name,NameLen,URL); else { p = tcsrchr(URL,'.'); if (p) { if (Name) tcsncpy_s(Name,NameLen,URL,p-URL); if (Ext) { if (p[1]) ++p; // remove '.', but only if there is a real extension tcscpy_s(Ext,ExtLen,p); } } else { if (Name) tcscpy_s(Name,NameLen,URL); if (Ext) Ext[0] = 0; } } }