Commit 628f508c authored by DanmeiChen's avatar DanmeiChen
Browse files

use bctbx_vfs_file for File_Class

Showing with 424 additions and 1 deletion
......@@ -45,6 +45,8 @@ endif()
configure_file(config.h.cmake ${CMAKE_BINARY_DIR}/config.h)
find_package(bctoolbox REQUIRED CONFIG)
include_directories(
${CMAKE_BINARY_DIR}
corec
......
......@@ -21,6 +21,8 @@ License: BSD-3
Source0: %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
Requires: %{pkg_prefix}bctoolbox
%description
A libary to parse Matroska files (.mkv and .mka).
......
......@@ -53,6 +53,7 @@ else()
list(APPEND COREC_SOURCES
helpers/date/date_libc.c
helpers/file/file_libc.c
helpers/file/file_bctbx.c
multithread/multithread_pthread.c
)
if (NOT IOS)
......@@ -91,6 +92,7 @@ endif()
add_library(corec-objects OBJECT ${COREC_SOURCES})
set_target_properties(corec-objects PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
target_link_libraries(corec-objects bctoolbox)
install(FILES
banned.h
......
......@@ -11,7 +11,7 @@ GROUP file
SOURCE streams.c {class Streams_Class:1}
SOURCE tools.c
SOURCE(TARGET_LINUX || TARGET_OSX || TARGET_ANDROID) file_libc.c {class File_Class:1}
SOURCE(TARGET_LINUX || TARGET_OSX || TARGET_ANDROID) file_bctbx.c {class File_Class:1}
SOURCE(TARGET_PALMOS) file_palmos.c {class File_Class:1}
SOURCE(TARGET_PALMOS) filedb_palmos.c {class FileDb_Class:1}
SOURCE(TARGET_PALMOS) filevfs_palmos.c {class VFS_Class:1}
......
/*****************************************************************************
*
* Copyright (c) 2008-2010, CoreCodec, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of CoreCodec, Inc. nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY CoreCodec, Inc. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL CoreCodec, Inc. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#include "config.h"
#ifdef CONFIG_FILEPOS_64
#define __USE_FILE_OFFSET64
#endif
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#define bool_t bctbx_bool_t
#include <bctoolbox/vfs.h>
#undef bool_t
// Do not move. Define TARGET_*.
#include "file.h"
#if defined(TARGET_OSX)
#include <sys/mount.h>
#elif defined(TARGET_QNX)
#include <sys/statvfs.h>
#else
#include <sys/vfs.h>
#endif
#if defined(O_ACCMODE)
#define _RW_ACCESS_FILE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
#define _RW_ACCESS_DIR (S_IRWXU|S_IRWXG|S_IRWXO)
#elif defined(S_IREAD) && defined(S_IWRITE)
#define _RW_ACCESS_FILE (S_IREAD|S_IWRITE)
#define _RW_ACCESS_DIR (S_IREAD|S_IWRITE|S_IEXEC)
#endif
typedef struct filestream
{
stream Stream;
bctbx_vfs_file_t *fp;
tchar_t URL[MAXPATH]; // TODO: turn into a dynamic data
filepos_t Length;
int Flags;
tchar_t DirPath[MAXPATH]; // TODO: turn into a dynamic data
DIR *FindDir;
} filestream;
static err_t Open(filestream* p, const tchar_t* URL, int Flags)
{
if (p->fp != -1)
bctbx_file_close(p->fp);
p->Length = INVALID_FILEPOS_T;
p->fp = NULL;
if (URL && URL[0])
{
struct stat file_stats;
int mode = 0;
if (Flags & SFLAG_WRONLY && !(Flags & SFLAG_RDONLY))
mode = O_WRONLY;
else if (Flags & SFLAG_RDONLY && !(Flags & SFLAG_WRONLY))
mode = O_RDONLY;
else
mode = O_RDWR;
if (Flags & SFLAG_CREATE)
mode |= O_CREAT|O_TRUNC;
//TODO: verify it works with Unicode files too
p->fp = bctbx_file_open2(bctbx_vfs_get_default(), URL, mode);
if (p->fp == NULL)
{
if ((Flags & (SFLAG_REOPEN|SFLAG_SILENT))==0)
NodeReportError(p,NULL,ERR_ID,ERR_FILE_NOT_FOUND,URL);
return ERR_FILE_NOT_FOUND;
}
tcscpy_s(p->URL,TSIZEOF(p->URL),URL);
if (stat(URL, &file_stats) == 0)
p->Length = file_stats.st_size;
}
return ERR_NONE;
}
static err_t Read(filestream* p,void* Data,size_t Size,size_t* Readed)
{
err_t Err;
int n = bctbx_file_read2(p->fp, Data, (unsigned int)Size);
if (n<0)
{
n=0;
Err = ERR_READ;
}
else
Err = ((size_t)n != Size) ? ERR_END_OF_FILE:ERR_NONE;
if (Readed)
*Readed = n;
return Err;
}
static err_t ReadBlock(filestream* p,block* Block,size_t Ofs,size_t Size,size_t* Readed)
{
return Read(p,(void*)(Block->Ptr+Ofs),Size,Readed);
}
static err_t Write(filestream* p,const void* Data,size_t Size,size_t* Written)
{
err_t Err;
int n = bctbx_file_write2(p->fp, Data, (unsigned int)Size);
if (n<0)
{
n=0;
Err = ERR_WRITE;
}
else
Err = (n != Size) ? ERR_WRITE:ERR_NONE;
if (Written)
*Written = n;
return Err;
}
static filepos_t Seek(filestream* p,filepos_t Pos,int SeekMode)
{
off_t NewPos = bctbx_file_seek(p->fp, Pos, SeekMode);
if (NewPos<0)
return INVALID_FILEPOS_T;
return NewPos;
}
static err_t SetLength(filestream* p,dataid Id,const filepos_t* Data,size_t Size)
{
if (Size != sizeof(filepos_t))
return ERR_INVALID_DATA;
if (bctbx_file_truncate(p->fp, *Data)!=0)
return ERR_BUFFER_FULL;
return ERR_NONE;
}
static err_t OpenDir(filestream* p,const tchar_t* Path,int UNUSED_PARAM(Flags))
{
if (p->FindDir)
closedir(p->FindDir);
if (Path[0]==0)
Path = T("/");
p->FindDir = opendir(Path);
if (!p->FindDir)
{
if (errno == ENOTDIR)
return ERR_NOT_DIRECTORY;
else
return ERR_FILE_NOT_FOUND;
}
tcscpy_s(p->DirPath,TSIZEOF(p->DirPath),Path);
AddPathDelimiter(p->DirPath,TSIZEOF(p->DirPath));
return ERR_NONE;
}
extern datetime_t LinuxToDateTime(time_t);
static err_t EnumDir(filestream* p,const tchar_t* Exts,bool_t ExtFilter,streamdir* Item)
{
struct dirent *Dirent;
if (!p->FindDir)
return ERR_END_OF_FILE;
Item->FileName[0] = 0;
Item->Size = INVALID_FILEPOS_T;
while (!Item->FileName[0] && (Dirent = readdir(p->FindDir)) != NULL)
{
tchar_t FilePath[MAXPATH];
struct stat file_stats;
if (Dirent->d_name[0]=='.') // skip hidden files and current directory
continue;
tcscpy_s(FilePath, TSIZEOF(FilePath), p->DirPath);
tcscat_s(FilePath, TSIZEOF(FilePath), Dirent->d_name);
tcscpy_s(Item->FileName,TSIZEOF(Item->FileName), Dirent->d_name);
stat(FilePath, &file_stats);
Item->ModifiedDate = LinuxToDateTime(file_stats.st_mtime);
if (S_ISDIR(file_stats.st_mode))
{
Item->Type = FTYPE_DIR;
Item->Size = INVALID_FILEPOS_T;
}
else
{
Item->Size = file_stats.st_size;
Item->Type = CheckExts(Item->FileName,Exts);
if (!Item->Type && ExtFilter)
Item->FileName[0] = 0; // skip
}
}
if (!Item->FileName[0])
{
closedir(p->FindDir);
p->FindDir = NULL;
return ERR_END_OF_FILE;
}
return ERR_NONE;
}
static void Delete(filestream* p)
{
if (p->fp != NULL)
{
bctbx_file_close(p->fp);
p->fp = NULL;
}
if (p->FindDir)
closedir(p->FindDir);
}
META_START(File_Class,FILE_CLASS)
META_CLASS(SIZE,sizeof(filestream))
META_CLASS(PRIORITY,PRI_MINIMUM)
META_CLASS(DELETE,Delete)
META_VMT(TYPE_FUNC,stream_vmt,Open,Open)
META_VMT(TYPE_FUNC,stream_vmt,Read,Read)
META_VMT(TYPE_FUNC,stream_vmt,ReadBlock,ReadBlock)
META_VMT(TYPE_FUNC,stream_vmt,Write,Write)
META_VMT(TYPE_FUNC,stream_vmt,Seek,Seek)
META_VMT(TYPE_FUNC,stream_vmt,OpenDir,OpenDir)
META_VMT(TYPE_FUNC,stream_vmt,EnumDir,EnumDir)
META_CONST(TYPE_INT,filestream,fp,NULL)
META_DATA_RDONLY(TYPE_INT,STREAM_FLAGS,filestream,Flags)
META_DATA_RDONLY(TYPE_STRING,STREAM_URL,filestream,URL)
META_DATA_RDONLY(TYPE_STRING,STREAM_ENUM_BASE,filestream,DirPath)
META_PARAM(SET,STREAM_LENGTH,SetLength)
META_DATA(TYPE_FILEPOS,STREAM_LENGTH,filestream,Length)
META_PARAM(STRING,NODE_PROTOCOL,T("file"))
META_END(STREAM_CLASS)
bool_t FileExists(nodecontext *p,const tchar_t* Path)
{
struct stat file_stats;
return stat(Path, &file_stats) == 0;
}
bool_t FileErase(nodecontext *p,const tchar_t* Path, bool_t Force, bool_t Safe)
{
if (Force)
{
struct stat file_stats;
if (stat(Path, &file_stats) == 0)
{
if ((file_stats.st_mode & S_IWUSR)==0)
{
file_stats.st_mode |= S_IWUSR;
chmod(Path,file_stats.st_mode);
}
}
}
return unlink(Path) == 0;
}
bool_t FolderErase(nodecontext *p,const tchar_t* Path, bool_t Force, bool_t Safe)
{
if (Force)
{
struct stat file_stats;
if (stat(Path, &file_stats) == 0)
{
if ((file_stats.st_mode & S_IWUSR)==0)
{
file_stats.st_mode |= S_IWUSR;
chmod(Path,file_stats.st_mode);
}
}
}
return rmdir(Path) == 0;
}
bool_t PathIsFolder(nodecontext *p,const tchar_t* Path)
{
struct stat file_stats;
if (stat(Path, &file_stats) == 0)
{
return (file_stats.st_mode & S_IFDIR) == S_IFDIR;
}
return 0;
}
datetime_t FileDateTime(nodecontext *p,const tchar_t* Path)
{
datetime_t Date = INVALID_DATETIME_T;
struct stat file_stats;
if (stat(Path, &file_stats) == 0)
Date = LinuxToDateTime(file_stats.st_mtime);
return Date;
}
bool_t FileMove(nodecontext *p,const tchar_t* In,const tchar_t* Out)
{
return rename(In,Out) == 0;
}
bool_t FolderCreate(nodecontext *p,const tchar_t* Path)
{
return mkdir(Path,_RW_ACCESS_DIR) == 0;
}
void FindFiles(nodecontext *p,const tchar_t* Path, const tchar_t* Mask,void(*Process)(const tchar_t*,void*),void* Param)
{
DIR* Directory;
struct dirent* DirectoryInfo;
tchar_t TPathToFile[MAXPATH];
Directory = opendir(Path);
if (Directory)
{
while ( (DirectoryInfo = readdir(Directory)) != NULL )
{
char* FileExtension = 0;
FileExtension = strrchr(DirectoryInfo->d_name, '.');
if(FileExtension)
{
if (strcmp(Mask, FileExtension ) == 0 )
{
tcscpy_s(TPathToFile, TSIZEOF(TPathToFile), Path);
tcscat_s(TPathToFile, TSIZEOF(TPathToFile), DirectoryInfo->d_name);
Process(TPathToFile, Param);
}
}
}
closedir(Directory);
}
}
stream *FileTemp(anynode *Any)
{
#ifndef TODO
assert(NULL); // not supported yet
#endif
return NULL;
}
bool_t FileTempName(anynode *Any,tchar_t *Out, size_t OutLen)
{
#ifndef TODO
assert(NULL); // not supported yet
#endif
return 0;
}
int64_t GetPathFreeSpace(nodecontext* UNUSED_PARAM(p), const tchar_t* Path)
{
#ifndef TODO
// need to an include (see at includes)
#if defined(TARGET_QNX)
struct statvfs st;
if (statvfs(Path, &st) < 0)
#else
struct statfs st;
if (statfs(Path, &st) < 0)
#endif
return -1;
return (int64_t)st.f_bsize * (int64_t)st.f_bavail;
#else
return -1;
#endif
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment