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

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************  *  * This program is free software ; you can redistribute it and/or modify  * it under the terms of the GNU General Public License as published by  * the Free Software Foundation; either version 2 of the License, or  * (at your option) any later version.  *  * This program is distributed in the hope that it will be useful,  * but WITHOUT ANY WARRANTY; without even the implied warranty of  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the  * GNU General Public License for more details.  *  * You should have received a copy of the GNU General Public License  * along with this program; if not, write to the Free Software  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA  *  * $Id: vfs_palmos.c 339 2005-11-15 11:22:45Z picard $  *  * The Core Pocket Media Player  * Copyright (c) 2004-2005 Gabor Kovacs  *  ****************************************************************************/ #include "../common.h" #if defined(TARGET_PALMOS) #include "pace.h" typedef struct vfs { stream Stream; tchar_t URL[MAXPATH]; UInt16 Vol; FileRef File; int Length; int Pos; bool_t Silent; bool_t Create; UInt32 Iter; const tchar_t* Exts; bool_t ExtFilter; } vfs; static int Get(vfs* p, int No, void* Data, int Size) { int Result = ERR_INVALID_PARAM; switch (No) { case STREAM_URL: GETSTRING(p->URL); break; case STREAM_SILENT: GETVALUE(p->Silent,bool_t); break; case STREAM_LENGTH: GETVALUECOND(p->Length,int,p->Length>=0); break; case STREAM_CREATE: GETVALUE(p->Create,bool_t); break; } return Result; } static int Open(vfs* p, const tchar_t* URL, bool_t ReOpen); static int Read(vfs* p,void* Data,int Size) { uint32_t Readed = 0;
  2. Err Error = VFSFileRead(p->File,Size,Data,&Readed);
  3. if ((Error==errNone && Readed>0) || Error==vfsErrFileEOF)
  4. { p->Pos += Readed; return Readed; } if (Error == vfsErrFileBadRef)
  5. Open(p,p->URL,1); return -1; } static int ReadBlock(vfs* p,block* Block,int Ofs,int Size) {
  6. uint32_t Readed = 0; 
  7. Err Error;
  8. if (IsHeapStorage(Block))
  9. Error = VFSFileReadData(p->File,Size,(void*)Block->Ptr,Ofs,&Readed);
  10. else
  11. Error = VFSFileRead(p->File,Size,(void*)(Block->Ptr+Ofs),&Readed);
  12. if ((Error==errNone && Readed>0) || Error==vfsErrFileEOF) {
  13. p->Pos += Readed; return Readed; }
  14. if (Error == vfsErrFileBadRef) Open(p,p->URL,1);
  15. return -1; } static int Seek(vfs* p,int Pos,int SeekMode) { FileOrigin Origin; Err Error; switch (SeekMode) { default: case SEEK_SET: Origin = vfsOriginBeginning; break; case SEEK_CUR: Origin = vfsOriginCurrent; break; case SEEK_END: Origin = vfsOriginEnd; break; } Error = VFSFileSeek(p->File,Origin,Pos); if (Error == errNone || Error == vfsErrFileEOF) { UInt32 Pos; if (VFSFileTell(p->File,&Pos) == errNone) p->Pos = Pos; return p->Pos; } return -1; } static UInt16 FindVol(int Slot) { UInt16 Ref; UInt32 Iter = vfsIteratorStart; while (Iter != vfsIteratorStop && VFSVolumeEnumerate(&Ref,&Iter)==errNone) { VolumeInfoType Info; VFSVolumeInfo(Ref,&Info); if (Slot==0 && Info.mediaType == 'pose') return Ref;   if (Slot<0 && Info.mountClass == vfsMountClass_Simulator && Info.slotRefNum==0xFFFF+Slot) return Ref; if (Slot>0 && Info.mountClass == vfsMountClass_SlotDriver && Info.slotRefNum==Slot) return Ref; } return vfsInvalidVolRef; }
  16. const tchar_t* VFSToVol(const tchar_t* URL,uint16_t* Vol)
  17. {
  18. int Slot = 0;
  19. bool_t Found = 0;
  20. tchar_t Mime[MAXPATH];
  21. const tchar_t* Name = GetMime(URL,Mime,TSIZEOF(Mime),NULL);
  22. if (Name != URL)
  23. --Name; // need the '/'
  24. if (tcsncmp(Mime,"pose",4)==0 || stscanf(Mime,"slot%d",&Slot)==1 || stscanf(Mime,"vol%d",&Slot)==1)
  25. Found = 1;
  26. else
  27. if (stscanf(Mime,"simu%d",&Slot)==1)
  28. {
  29. Found = 1;
  30. Slot = -Slot;
  31. }
  32. if (Found && (*Vol=FindVol(Slot))!=vfsInvalidVolRef)
  33. return Name;
  34. return NULL;
  35. }
  36. bool_t VFSFromVol(uint16_t Vol,const tchar_t* Path,tchar_t* URL,int URLLen)
  37. {
  38. int Slot;
  39. VolumeInfoType Info;
  40. VFSVolumeInfo(Vol,&Info);
  41. Slot = Info.slotRefNum;
  42. if (Slot > 0xFFF0)
  43. Slot = 0xFFFF-Slot;
  44. URL[0] = 0;
  45. if (!Path) Path = T("/");
  46. if (Info.mediaType == 'pose')
  47. {
  48. stprintf_s(URL,URLLen,T("pose:/%s"),Path);
  49. return 1;
  50. }
  51. if (Info.mountClass == vfsMountClass_Simulator)
  52. {
  53. stprintf_s(URL,URLLen,T("simu%d:/%s"),Slot,Path);
  54. return 1;
  55. }
  56. if (Info.mountClass == vfsMountClass_SlotDriver)
  57. {
  58. stprintf_s(URL,URLLen,(Info.attributes & vfsVolumeAttrNonRemovable)?T("vol%d:/%s"):T("slot%d:/%s"),Slot,Path);
  59. return 1;
  60. }
  61. return 0;
  62. }
  63. bool_t FileExits(const tchar_t* URL)
  64. {
  65. // open supports VFS
  66. const tchar_t* Name;
  67. UInt16 Vol;
  68. FileRef File = 0;
  69. Name = VFSToVol(URL,&Vol);
  70. if (!Name)
  71. return 0;
  72. VFSFileOpen(Vol,Name,vfsModeRead,&File);
  73. if (!File)
  74. return 0;
  75. VFSFileClose(File);
  76. return 1;
  77. }
  78. static bool_t InternalOpen(vfs* p,const tchar_t* URL) {
  79. const tchar_t* Name;
  80. if (p->File) { VFSFileClose(p->File); p->File = 0; }
  81. Name = VFSToVol(URL,&p->Vol);
  82. if (Name)
  83. VFSFileOpen(p->Vol,Name,vfsModeRead,&p->File); if (!p->File) return 0; tcscpy_s(p->URL,TSIZEOF(p->URL),URL); return 1; } static int Open(vfs* p, const tchar_t* URL, bool_t ReOpen) { if (p->File) { VFSFileClose(p->File); p->File = 0; } p->Length = -1; if (!ReOpen) p->URL[0] = 0; #ifdef MULTITHREAD
  84. else ThreadSleep(GetTimeFreq()/5);
  85. #endif if (URL && URL[0]) { UInt32 Pos = 0; if (!InternalOpen(p,URL)) { if (!ReOpen && !p->Silent) ShowError(0,ERR_ID,ERR_FILE_NOT_FOUND,URL); return ERR_FILE_NOT_FOUND; } if (ReOpen) VFSFileSeek(p->File,vfsOriginBeginning,p->Pos); else { p->Length = -1; if (VFSFileSize(p->File,&Pos)==errNone) p->Length = Pos; } if (VFSFileTell(p->File,&Pos) == errNone) p->Pos = Pos; } return ERR_NONE; } static int EnumDir(vfs* p,const tchar_t* URL,const tchar_t* Exts,bool_t ExtFilter,streamdir* Item) { tchar_t Path[MAXPATH]; FileInfoType Info; if (URL) { UInt32 Attrib = 0; p->Exts = Exts; p->ExtFilter = ExtFilter; if (!InternalOpen(p,URL)) return ERR_FILE_NOT_FOUND; VFSFileGetAttributes(p->File,&Attrib); if (!(Attrib & vfsFileAttrDirectory)) return ERR_NOT_DIRECTORY; p->Iter = vfsIteratorStart; }
  86. Item->DisplayName[0] = 0;
  87. if (p->File) { Info.nameP = Item->FileName; Info.nameBufLen = sizeof(Item->FileName); while (p->Iter != vfsIteratorStop && VFSDirEntryEnumerate(p->File,&p->Iter,&Info)==errNone) { UInt32 Value; FileRef File = 0; if (Item->FileName[0]=='.') // skip unix/mac hidden files continue;   AbsPath(Path,TSIZEOF(Path),Item->FileName,GetMime(p->URL,NULL,0,NULL)); //currently Date and Size is not needed //VFSFileOpen(p->Vol,Path,vfsModeRead,&File); Item->Date = -1; if (File && VFSFileGetDate(File,vfsFileDateModified,&Value)==errNone) Item->Date = Value; if (Info.attributes & vfsFileAttrDirectory) Item->Size = -1; else { if (File && VFSFileSize(File,&Value)==errNone) Item->Size = Value; else Item->Size = 0; Item->Type = CheckExts(Item->FileName,p->Exts); if (!Item->Type && p->ExtFilter) { if (File) VFSFileClose(File); continue; } } if (File) VFSFileClose(File); return ERR_NONE; } VFSFileClose(p->File); p->File = 0; } Item->FileName[0] = 0; return ERR_END_OF_FILE; } static int Set(vfs* p, int No, const void* Data, int Size) { int Result = ERR_INVALID_PARAM; switch (No) { case STREAM_SILENT: SETVALUE(p->Silent,bool_t,ERR_NONE); break; case STREAM_CREATE: SETVALUE(p->Create,bool_t,ERR_NONE); break; case STREAM_URL: Result = Open(p,(const tchar_t*)Data,0); break; } return Result; } static int Create(vfs* p) { p->Stream.Get = (nodeget)Get; p->Stream.Set = (nodeset)Set; p->Stream.Read = (streamread)Read; p->Stream.ReadBlock = (streamreadblock)ReadBlock; p->Stream.Seek = (streamseek)Seek; p->Stream.EnumDir = (streamenumdir)EnumDir; return ERR_NONE; } static void Delete(vfs* p) { Open(p,NULL,0); } static const nodedef VFS =  { sizeof(vfs), VFS_ID, STREAM_CLASS, PRI_MINIMUM, (nodecreate)Create, (nodedelete)Delete, }; void VFS_Init() { UInt32 Version; if (QueryPlatform(PLATFORM_MODEL) == MODEL_PALM_SIMULATOR ||  (FtrGet(sysFileCExpansionMgr, expFtrIDVersion, &Version) == errNone && Version >= 1 &&      FtrGet(sysFileCVFSMgr, vfsFtrIDVersion, &Version) == errNone && Version >= 1)) NodeRegisterClass(&VFS); } void VFS_Done() { NodeUnRegisterClass(VFS_ID); } #endif