streams.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:8k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: streams.c 585 2006-01-16 09:48:55Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "common.h"
  24. static const datatable StreamParams[] = 
  25. {
  26. { STREAM_URL, TYPE_STRING },
  27. { STREAM_LENGTH, TYPE_INT, DF_HIDDEN },
  28. { STREAM_SILENT, TYPE_BOOL, DF_HIDDEN },
  29. { STREAM_CREATE, TYPE_BOOL, DF_HIDDEN },
  30. { STREAM_CONTENTTYPE, TYPE_STRING, DF_HIDDEN|DF_RDONLY },
  31. { STREAM_PRAGMA_SEND, TYPE_STRING, DF_HIDDEN|DF_RDONLY },
  32. { STREAM_PRAGMA_GET, TYPE_STRING, DF_HIDDEN|DF_RDONLY },
  33. { STREAM_COMMENT, TYPE_COMMENT, DF_OUTPUT },
  34. { STREAM_METAPROCESSOR, TYPE_INT, DF_HIDDEN },
  35. DATATABLE_END(STREAM_CLASS)
  36. };
  37. int StreamEnum(void* p, int* No, datadef* Param)
  38. {
  39. return NodeEnumTable(No,Param,StreamParams);
  40. }
  41. static int DummyRead(void* This,void* Data,int Size) { return -1; }
  42. static int DummyReadBlock(void* This,block* Block,int Ofs,int Size) { return -1; }
  43. static filepos_t DummySeek(void* This,filepos_t Pos,int SeekMode) { return -1; }
  44. static int DummyWrite(void* This,const void* Data,int Size) { return -1; }
  45. static int DummyEnumDir(void* This,const tchar_t* URL,const tchar_t* Exts,
  46. bool_t ExtFilter,streamdir* Item) { return ERR_FILE_NOT_FOUND; }
  47. static int StreamCreate(stream* p)
  48. {
  49. p->Enum = StreamEnum;
  50. p->Read = DummyRead;
  51. p->ReadBlock = DummyReadBlock;
  52. p->Write = DummyWrite;
  53. p->EnumDir = DummyEnumDir;
  54. p->Seek = DummySeek;
  55. return ERR_NONE;
  56. }
  57. static const nodedef Stream =
  58. {
  59. sizeof(stream)|CF_ABSTRACT,
  60. STREAM_CLASS,
  61. NODE_CLASS,
  62. PRI_DEFAULT,
  63. (nodecreate)StreamCreate,
  64. };
  65. static const datatable StreamProcessParams[] = 
  66. {
  67. { STREAMPROCESS_INPUT, TYPE_NODE, DF_HIDDEN, STREAM_CLASS },
  68. DATATABLE_END(STREAMPROCESS_CLASS)
  69. };
  70. static int StreamProcessEnum(void* p, int* No, datadef* Param)
  71. {
  72. if (StreamEnum(p,No,Param)==ERR_NONE)
  73. return ERR_NONE;
  74. return NodeEnumTable(No,Param,StreamProcessParams);
  75. }
  76. typedef struct memstream
  77. {
  78. stream s;
  79. int Pos;
  80. const uint8_t* Data;
  81. int Size;
  82. } memstream;
  83. static int MemRead(memstream* p,void* Data,int Size)
  84. {
  85. int Pos = p->Pos;
  86. p->Pos += Size;
  87. if (p->Pos > p->Size)
  88. {
  89. Size -= p->Pos - p->Size;
  90. p->Pos = p->Size;
  91. }
  92. if (Size<0)
  93. Size=0;
  94. if (Size>0)
  95. memcpy(Data,p->Data+Pos,Size);
  96. return Size;
  97. }
  98. static int MemReadBlock(memstream* p,block* Block,int Ofs,int Size)
  99. {
  100. int Pos = p->Pos;
  101. p->Pos += Size;
  102. if (p->Pos > p->Size)
  103. {
  104. Size -= p->Pos - p->Size;
  105. p->Pos = p->Size;
  106. }
  107. if (Size<0)
  108. Size=0;
  109. if (Size>0)
  110. WriteBlock(Block,Ofs,p->Data+Pos,Size);
  111. return Size;
  112. }
  113. static int MemSeek(memstream* p,int Pos,int SeekMode)
  114. {
  115. switch (SeekMode)
  116. {
  117. default:
  118. case SEEK_SET: break;
  119. case SEEK_CUR: Pos += p->Pos; break;
  120. case SEEK_END: Pos += p->Size; break;
  121. }
  122. if (Pos<0)
  123. Pos=0;
  124. return p->Pos = Pos;
  125. }
  126. static int MemGet(memstream* p, int No, void* Data, int Size)
  127. {
  128. int Result = ERR_INVALID_PARAM;
  129. switch (No)
  130. {
  131. case STREAM_LENGTH: GETVALUE(p->Size,int); break;
  132. }
  133. return Result;
  134. }
  135. static int MemSet(memstream* p, int No, const void* Data, int Size)
  136. {
  137. int Result = ERR_INVALID_PARAM;
  138. switch (No)
  139. {
  140. case MEMSTREAM_DATA: 
  141. p->Data = Data;
  142. p->Size = Size;
  143. return ERR_NONE;
  144. }
  145. return Result;
  146. }
  147. static int MemCreate(memstream* p)
  148. {
  149. p->s.Set = (nodeset)MemSet;
  150. p->s.Get = (nodeget)MemGet;
  151. p->s.Read = (streamread)MemRead;
  152. p->s.ReadBlock = (streamreadblock)MemReadBlock;
  153. p->s.Seek = (streamseek)MemSeek;
  154. return ERR_NONE;
  155. }
  156. static int StreamProcessCreate(stream* p)
  157. {
  158. p->Enum = StreamProcessEnum;
  159. return ERR_NONE;
  160. }
  161. static const nodedef StreamProcess =
  162. {
  163. sizeof(stream)|CF_ABSTRACT,
  164. STREAMPROCESS_CLASS,
  165. MEDIA_CLASS, // can't use STREAM_CLASS, because it can have NODE_EXTS and such...
  166. PRI_DEFAULT,
  167. (nodecreate)StreamProcessCreate,
  168. };
  169. static const nodedef MemStream =
  170. {
  171. sizeof(memstream),
  172. MEMSTREAM_ID,
  173. STREAM_CLASS,
  174. PRI_DEFAULT,
  175. (nodecreate)MemCreate,
  176. };
  177. void Stream_Init()
  178. {
  179. NodeRegisterClass(&Stream);
  180. NodeRegisterClass(&MemStream);
  181. NodeRegisterClass(&StreamProcess);
  182. }
  183. void Stream_Done()
  184. {
  185. NodeUnRegisterClass(STREAMPROCESS_CLASS);
  186. NodeUnRegisterClass(MEMSTREAM_ID);
  187. NodeUnRegisterClass(STREAM_CLASS);
  188. }
  189. const tchar_t* GetMime(const tchar_t* URL, tchar_t* Mime, int MimeLen, bool_t* HasHost)
  190. {
  191. const tchar_t* s = tcschr(URL,':');
  192. if (s && s[1] == '/' && s[2] == '/')
  193. {
  194. if (Mime)
  195. tcsncpy_s(Mime,MimeLen,URL,s-URL);
  196. if (HasHost)
  197. *HasHost = tcsnicmp(URL,T("file"),4)!=0 &&
  198.            tcsnicmp(URL,T("mem"),3)!=0 &&
  199.            tcsnicmp(URL,T("pose"),4)!=0 &&
  200.            tcsnicmp(URL,T("vol"),3)!=0 &&
  201.            tcsnicmp(URL,T("slot"),4)!=0 &&
  202.    tcsnicmp(URL,T("simu"),4)!=0;
  203. s += 3;
  204. }
  205. else
  206. {
  207. if (HasHost)
  208. *HasHost = 0;
  209. if (Mime)
  210. tcscpy_s(Mime,MimeLen,T("file"));
  211. s = URL;
  212. }
  213. return s;
  214. }
  215. stream* GetStream(const tchar_t* URL, bool_t Silent)
  216. {
  217. tchar_t Mime[MAXPATH];
  218. stream* Stream;
  219. GetMime(URL,Mime,TSIZEOF(Mime),NULL);
  220. Stream = (stream*)NodeCreate(NodeEnumClassEx(NULL,STREAM_CLASS,Mime,NULL,NULL,0));
  221. if (!Stream && !Silent)
  222. {
  223. tcsupr(Mime);
  224. ShowError(0,ERR_ID,ERR_MIME_NOT_FOUND,Mime);
  225. }
  226. return Stream;
  227. }
  228. void StreamPrintfEx(stream* Stream, bool_t UTF8, const tchar_t* Msg,...)
  229. {
  230. tchar_t s[512];
  231. va_list Arg;
  232. va_start(Arg,Msg);
  233. vstprintf_s(s,TSIZEOF(s),Msg,Arg);
  234. va_end(Arg);
  235. StreamText(Stream,s,UTF8);
  236. }
  237. void StreamPrintf(stream* Stream, const tchar_t* Msg,...)
  238. {
  239. tchar_t s[512];
  240. va_list Arg;
  241. va_start(Arg,Msg);
  242. vstprintf_s(s,TSIZEOF(s),Msg,Arg);
  243. va_end(Arg);
  244. StreamText(Stream,s,0);
  245. }
  246. void StreamText(stream* Stream, const tchar_t* Msg, bool_t UTF8)
  247. {
  248. int i,n = tcslen(Msg)*2+1;
  249. char* s = malloc(n);
  250. if (s)
  251. {
  252. if (UTF8)
  253. TcsToUTF8(s,n,Msg);
  254. else
  255. TcsToStr(s,n,Msg);
  256. i = strlen(s);
  257. #if defined(TARGET_WINCE) || defined(TARGET_WIN32)
  258. {
  259. char* nl = s;
  260. while (i+1<n && (nl = strchr(nl,10))!=NULL)
  261. {
  262. memmove(nl+1,nl,i+1-(nl-s));
  263. *nl = 13;
  264. nl += 2;
  265. ++i;
  266. }
  267. }
  268. #endif
  269. Stream->Write(Stream,s,i);
  270. free(s);
  271. }
  272. }
  273. extern stream* FileCreate(const tchar_t*);
  274. extern void FileRelease(stream*);
  275. stream* StreamOpen(const tchar_t* Path, bool_t Write)
  276. {
  277. stream* File = FileCreate(Path);
  278. if (File)
  279. {
  280. bool_t One = 1;
  281. File->Set(File,STREAM_SILENT,&One,sizeof(One));
  282. File->Set(File,STREAM_CREATE,&Write,sizeof(Write));
  283. if (File->Set(File,STREAM_URL,Path,(tcslen(Path)+1)*sizeof(tchar_t)) != ERR_NONE)
  284. {
  285. FileRelease(File);
  286. File = NULL;
  287. }
  288. }
  289. return File;
  290. }
  291. stream* StreamOpenMem(const void* Data,int Length)
  292. {
  293. memstream* p = (memstream*)malloc(sizeof(memstream));
  294. if (p)
  295. {
  296. memset(p,0,sizeof(memstream));
  297. p->s.Class = MEMSTREAM_ID;
  298. MemCreate(p);
  299. p->s.Set(&p->s,MEMSTREAM_DATA,Data,Length);
  300. }
  301. return &p->s;
  302. }
  303. int StreamCloseMem(stream* p)
  304. {
  305. //MemDelete(p);
  306. free(p);
  307. return 0;
  308. }
  309. filepos_t StreamSeek(stream* File, filepos_t Ofs, int Mode)
  310. {
  311. return File->Seek(File,Ofs,Mode);
  312. }
  313. int StreamRead(stream* File, void* p, int n)
  314. {
  315. return File->Read(File,p,n);
  316. }
  317. int StreamWrite(stream* File, const void* p, int n)
  318. {
  319. return File->Write(File,p,n);
  320. }
  321. int StreamClose(stream* File)
  322. {
  323. File->Set(File,STREAM_URL,NULL,0);
  324. FileRelease(File);
  325. return 0;
  326. }