📄 gbx_c_file.c
字号:
/*************************************************************************** CFile.c The native File class (c) 2000-2004 Beno顃 Minisini <gambas@users.sourceforge.net> 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************************/#define __GBX_C_FILE_C#include <stdio.h>#include <pwd.h>#include <grp.h>#include <sys/stat.h>#include "gb_common.h"#include "gbx_api.h"#include "gambas.h"#include "gbx_class.h"#include "gb_file.h"#include "gbx_stream.h"#include "gbx_exec.h"#include "gbx_string.h"#include "gbx_date.h"#include "gbx_c_file.h"PUBLIC CFILE CFILE_in, CFILE_out, CFILE_err;DECLARE_EVENT(EVENT_Read);DECLARE_EVENT(EVENT_Write);static char _buffer[16];PRIVATE void init(CFILE *_object, FILE *file){ THIS->ob.ob.class = CLASS_File; THIS->ob.ob.ref = 1; THIS->ob.stream.type = &STREAM_buffer; THIS->ob.stream.buffer.file = file; THIS->ob.stream.buffer.size = 0;}PUBLIC void CFILE_init(void){ init(&CFILE_in, stdin); init(&CFILE_out, stdout); init(&CFILE_err, stderr);}PRIVATE void callback_read(int fd, int type, CFILE *file){ GB_Raise(file, EVENT_Read, 0);}PRIVATE void callback_write(int fd, int type, CFILE *file){ GB_Raise(file, EVENT_Write, 0);}PUBLIC CFILE *CFILE_create(STREAM *stream, int mode){ int fd; CFILE *file; OBJECT_new((void **)&file, CLASS_File, NULL, NULL); OBJECT_UNREF_KEEP((void **)&file, "CFILE_new"); if (stream) { *CSTREAM_stream(file) = *stream; file->watch_fd = -1; if (mode & ST_WATCH) { fd = STREAM_handle(&file->ob.stream); file->watch_fd = fd; if (mode & ST_READ) GB_Watch(fd, GB_WATCH_READ, (void *)callback_read, (long)file); if (mode & ST_WRITE) GB_Watch(fd, GB_WATCH_WRITE, (void *)callback_write, (long)file); OBJECT_attach((OBJECT *)file, OP ? (OBJECT *)OP : (OBJECT *)CP, "File"); } } return file;}BEGIN_METHOD_VOID(CFILE_free) STREAM_close(&THIS->ob.stream); if (THIS->watch_fd >= 0) GB_Watch(THIS->watch_fd, GB_WATCH_NONE, NULL, 0);END_METHODBEGIN_PROPERTY(CFILE_get_in) GB_ReturnObject(&CFILE_in);END_PROPERTYBEGIN_PROPERTY(CFILE_get_out) GB_ReturnObject(&CFILE_out);END_PROPERTYBEGIN_PROPERTY(CFILE_get_err) GB_ReturnObject(&CFILE_err);END_PROPERTYBEGIN_PROPERTY(CFILE_type) GB_ReturnInt(THIS->info.type);END_PROPERTYBEGIN_PROPERTY(CFILE_mode) GB_ReturnInt(THIS->info.mode);END_PROPERTYBEGIN_PROPERTY(CFILE_hidden) GB_ReturnBoolean(THIS->info.hidden);END_PROPERTYBEGIN_PROPERTY(CFILE_size) GB_ReturnInt(THIS->info.size);END_PROPERTYBEGIN_PROPERTY(CFILE_atime) GB_DATE date; DATE_from_time(THIS->info.atime, 0, (VALUE *)&date); GB_ReturnDate(&date);END_PROPERTYBEGIN_PROPERTY(CFILE_ctime) GB_DATE date; DATE_from_time(THIS->info.ctime, 0, (VALUE *)&date); GB_ReturnDate(&date);END_PROPERTYBEGIN_PROPERTY(CFILE_mtime) GB_DATE date; DATE_from_time(THIS->info.mtime, 0, (VALUE *)&date); GB_ReturnDate(&date);END_PROPERTYstatic char *get_file_user(CFILE *_object){ struct passwd *pwd; uid_t uid = THIS->info.uid; if (uid == 0) return "root"; else { pwd = getpwuid(uid); if (!pwd) { sprintf(_buffer, "%d", uid); return _buffer; } else return pwd->pw_name; }}BEGIN_PROPERTY(CFILE_user) GB_ReturnNewZeroString(get_file_user(THIS));END_PROPERTYstatic char *get_file_group(CFILE *_object){ struct group *grp; gid_t gid = THIS->info.gid; if (gid == 0) return "root"; else { grp = getgrgid(gid); if (!grp) { sprintf(_buffer, "%d", gid); return _buffer; } else return grp->gr_name; }}BEGIN_PROPERTY(CFILE_group) GB_ReturnNewZeroString(get_file_group(THIS));END_PROPERTYBEGIN_PROPERTY(CFILE_setuid) GB_ReturnBoolean(THIS->info.mode & S_ISUID);END_PROPERTYBEGIN_PROPERTY(CFILE_setgid) GB_ReturnBoolean(THIS->info.mode & S_ISGID);END_PROPERTYBEGIN_PROPERTY(CFILE_sticky) GB_ReturnBoolean(THIS->info.mode & S_ISVTX);END_PROPERTY#if 0BEGIN_METHOD(CFILE_access, GB_INTEGER who; GB_INTEGER access) bool ret; int access = VARGOPT(access, GB_STAT_READ); int who = VARG(who); int mode = THIS->info.mode; if ((access & GB_STAT_READ) == 0) mode &= ~(S_IRUSR | S_IRGRP | S_IROTH); if ((access & GB_STAT_WRITE) == 0) mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); if ((access & GB_STAT_EXEC) == 0) mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH); switch(who) { case GB_STAT_USER: ret = mode & S_IRWXU; break; case GB_STAT_GROUP: ret = mode & S_IRWXG; break; case GB_STAT_OTHER: ret = mode & S_IRWXO; break; default: ret = FALSE; break; } GB_ReturnBoolean(ret);END_METHOD#endifstatic void return_perm(CFILE *_object, int rf, int wf, int xf){ char perm[4]; char *p; int mode = THIS->info.mode; p = perm; if (mode & rf) *p++ = 'r'; if (mode & wf) *p++ = 'w'; if (mode & xf) *p++ = 'x'; *p = 0; GB_ReturnNewZeroString(perm);}BEGIN_PROPERTY(CFILE_perm_user) return_perm(THIS, S_IRUSR, S_IWUSR, S_IXUSR);END_PROPERTYBEGIN_PROPERTY(CFILE_perm_group) return_perm(THIS, S_IRGRP, S_IWGRP, S_IXGRP);END_PROPERTYBEGIN_PROPERTY(CFILE_perm_other) return_perm(THIS, S_IROTH, S_IWOTH, S_IXOTH);END_PROPERTYBEGIN_METHOD(CFILE_perm_get, GB_STRING user) char *who; char *user = GB_ToZeroString(ARG(user)); who = get_file_user(THIS); if (strcmp(user, who) == 0) { return_perm(THIS, S_IRUSR, S_IWUSR, S_IWUSR); return; } who = get_file_group(THIS); if (strlen(user) > 2 && user[0] == '*' && user[1] == '.' && strcmp(&user[2], who) == 0) { return_perm(THIS, S_IRGRP, S_IWGRP, S_IWGRP); return; } return_perm(THIS, S_IROTH, S_IWOTH, S_IWOTH);END_METHODBEGIN_PROPERTY(CFILE_separator) GB_ReturnConstZeroString("/");END_PROPERTYBEGIN_METHOD(CFILE_dir, GB_STRING path) const char *path = GB_ToZeroString(ARG(path)); if (path) GB_ReturnNewZeroString(FILE_get_dir(path)); else GB_ReturnNull();/* char *path = PARAM(path).addr; int len = PARAM(path).len; if (len == 0) { GB_ReturnNull(); return; } if (len == 1) { if (*path == '/') GB_ReturnCopyString(path, len); else GB_ReturnNull(); return; } for(;;) { len--; if ((len == 0) || (path[len] == '/')) { GB_ReturnCopyString(path, len); return; } }*/END_METHODBEGIN_METHOD(CFILE_name, GB_STRING path) if (LENGTH(path) && STRING(path)[LENGTH(path) - 1] == '/') LENGTH(path)--; GB_ReturnNewString(FILE_get_name(GB_ToZeroString(ARG(path))), -1);END_METHODBEGIN_METHOD(CFILE_ext, GB_STRING path) const char *path = GB_ToZeroString(ARG(path)); if (path) GB_ReturnNewZeroString(FILE_get_ext(path)); else GB_ReturnNull();END_METHODBEGIN_METHOD(CFILE_basename, GB_STRING path) const char *path = GB_ToZeroString(ARG(path)); if (path) GB_ReturnNewZeroString(FILE_get_basename(path)); else GB_ReturnNull();END_METHODBEGIN_METHOD(CFILE_load, GB_STRING path) STREAM stream; long len; char *str; boolean opened = FALSE; TRY { STREAM_open(&stream, STRING_conv_file_name(STRING(path), LENGTH(path)), ST_READ); opened = TRUE; STREAM_lof(&stream, &len); STRING_new_temp(&str, NULL, len); STREAM_read(&stream, str, len); STREAM_close(&stream); GB_ReturnString(str); } CATCH { if (opened) STREAM_close(&stream); PROPAGATE(); } END_TRYEND_METHODBEGIN_METHOD(CFILE_save, GB_STRING path; GB_STRING data) STREAM stream; boolean opened = FALSE; TRY { STREAM_open(&stream, STRING_conv_file_name(STRING(path), LENGTH(path)), ST_CREATE); opened = TRUE; STREAM_write(&stream, STRING(data), LENGTH(data)); STREAM_close(&stream); } CATCH { if (opened) STREAM_close(&stream); PROPAGATE(); } END_TRYEND_METHODPUBLIC GB_DESC NATIVE_Stream[] ={ GB_DECLARE(".Stream", sizeof(CSTREAM)), GB_NOT_CREATABLE(), GB_END_DECLARE};PUBLIC GB_DESC NATIVE_FilePerm[] ={ GB_DECLARE(".FilePerm", 0), GB_VIRTUAL_CLASS(), GB_METHOD("_get", "s", CFILE_perm_get, "(UserOrGroup)s"), GB_PROPERTY_READ("User", "s", CFILE_perm_user), GB_PROPERTY_READ("Group", "s", CFILE_perm_group), GB_PROPERTY_READ("Other", "s", CFILE_perm_other), GB_END_DECLARE};PUBLIC GB_DESC NATIVE_File[] ={ GB_DECLARE("File", sizeof(CFILE)), GB_INHERITS(".Stream"), GB_NOT_CREATABLE(), GB_METHOD("_free", NULL, CFILE_free, NULL), GB_STATIC_PROPERTY_READ("Separator", "s", CFILE_separator), GB_STATIC_PROPERTY_READ("In", "File", CFILE_get_in), GB_STATIC_PROPERTY_READ("Out", "File", CFILE_get_out), GB_STATIC_PROPERTY_READ("Err", "File", CFILE_get_err), GB_PROPERTY_READ("Type", "i", CFILE_type), GB_PROPERTY_READ("Mode", "i", CFILE_mode), GB_PROPERTY_READ("Hidden", "b", CFILE_hidden), GB_PROPERTY_READ("Size", "i", CFILE_size), GB_PROPERTY_READ("Time", "d", CFILE_mtime), GB_PROPERTY_READ("LastAccess", "d", CFILE_atime), GB_PROPERTY_READ("LastUpdate", "d", CFILE_mtime), GB_PROPERTY_READ("LastChange", "d", CFILE_ctime), GB_PROPERTY_READ("User", "s", CFILE_user), GB_PROPERTY_READ("Group", "s", CFILE_group), GB_PROPERTY_SELF("Perm", ".FilePerm"), GB_PROPERTY_READ("SetGID", "b", CFILE_setgid), GB_PROPERTY_READ("SetUID", "b", CFILE_setuid), GB_PROPERTY_READ("Sticky", "b", CFILE_sticky), //GB_METHOD("Access", "b", CFILE_access, "(Who)i[(Mode)i]"), GB_STATIC_METHOD("Dir", "s", CFILE_dir, "(FileName)s"), GB_STATIC_METHOD("Name", "s", CFILE_name, "(FileName)s"), GB_STATIC_METHOD("Ext", "s", CFILE_ext, "(FileName)s"), GB_STATIC_METHOD("BaseName", "s", CFILE_basename, "(FileName)s"), GB_STATIC_METHOD("Load", "s", CFILE_load, "(FileName)s"), GB_STATIC_METHOD("Save", NULL, CFILE_save, "(FileName)s(Data)s"), GB_EVENT("Read", NULL, NULL, &EVENT_Read), GB_EVENT("Write", NULL, NULL, &EVENT_Write), GB_END_DECLARE};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -