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; }
stream* StreamOpen(anynode *AnyNode, const tchar_t* Path, int Flags) { stream* File = GetStream(AnyNode,Path,Flags); if (File) { err_t Err = Stream_Open(File,Path,Flags); if (Err != ERR_NONE && Err != ERR_NEED_MORE_DATA) { NodeDelete((node*)File); File = NULL; } else { stream* Buf; if ((Flags & SFLAG_BUFFERED) && (Buf = (stream*)NodeCreate(AnyNode,BUFSTREAM_CLASS)) != NULL) { Node_SET(Buf,BUFSTREAM_STREAM,&File); File = Buf; } } } return File; }
void OpenConsole() { Console = Stream_Open(ConsoleProtocol, streamFlags_CanRead | streamFlags_CanWrite); }