/** * Writes a given LuciStringObj to a LuciFileObj. * * @param args list of args * @param c number of args * @returns LuciNilObj */ LuciObject *luci_fwrite(LuciObject **args, unsigned int c) { if (c < 2) { LUCI_DIE("%s", "Missing parameter to write()\n"); } /* grab the FILE parameter */ LuciObject *fobj = args[0]; if (!fobj || (!ISTYPE(fobj, obj_file_t))) { LUCI_DIE("%s", "Not a file object\n"); } /* grab string parameter */ LuciObject *text_obj = args[1]; if (!text_obj || (!ISTYPE(text_obj, obj_string_t)) ) { LUCI_DIE("%s", "Not a string\n"); } char *text = AS_STRING(text_obj)->s; if (AS_FILE(fobj)->mode == f_read_m) { LUCI_DIE("%s", "Can't write to It is opened for reading.\n"); } fwrite(text, sizeof(char), strlen(text), AS_FILE(fobj)->ptr); return LuciNilObj; }
Folder* folder_open(FileSystem *fs, Inode *inode) { Folder *folder = NULL; char *buffer = NULL; int offset = 0; int i = 0; folder = (Folder *) malloc(sizeof(Folder)); file_init(AS_FILE(folder), fs, inode); buffer = (char *) malloc(inode->filesize); file_get_contents(AS_FILE(folder), buffer); #ifdef DEBUG fprintf(stderr, "folder_open buffer="); for (i = 0; i < inode->filesize; ++i) fprintf(stderr, " %x", buffer[i]); fprintf(stderr, "\n"); #endif folder->nitem = util_readint(buffer, 0); #ifdef DEBUG fprintf(stderr, "folder_open, folder->nitem=%d\n", folder->nitem); #endif folder->items = (FolderItem *) malloc(sizeof(FolderItem) * folder->nitem); offset = 4; for (i = 0; i < folder->nitem; ++i) { int cname_len = 0; cname_len = util_readint(buffer, offset); offset += 4; memcpy(folder->items[i].cname, buffer + offset, cname_len); folder->items[i].cname[cname_len] = 0; // make it a string offset += cname_len; folder->items[i].page_num = util_readint(buffer, offset); offset += 4; } free(buffer); return folder; }
/** * Copies a LuciFileObj * * Marks the copy's 'iscopy' flag to ensure garbage collection * never closes a FILE* that is supposed to be open * * @param o LuciFileObj to copy * @returns copy of LuciFileObj */ LuciObject *LuciFile_copy(LuciObject *o) { LuciFileObj *f = AS_FILE(o); LuciObject *copy = LuciFile_new(f->ptr, f->size, f->mode); AS_FILE(copy)->iscopy = true; /* prevent garbage collector from closing this file */ return copy; }
/** * Reads the contents of a file into a LuciStringObj. * * @param args list of args * @param c number of args * @returns contents of the file from the first arg. */ LuciObject *luci_fread(LuciObject **args, unsigned int c) { if (c < 1) { LUCI_DIE("%s", "Missing parameter to read()\n"); } LuciObject *fobj = args[0]; if (!ISTYPE(fobj, obj_file_t)) { LUCI_DIE("%s", "Not a file object\n"); } if (AS_FILE(fobj)->mode != f_read_m) { LUCI_DIE("%s", "Can't open It is opened for writing.\n"); } /* seek to file start, we're gonna read the whole thing */ /* fseek(fobj->ptr, 0, SEEK_SET); */ long len = AS_FILE(fobj)->size; char *read = alloc(len + 1); fread(read, sizeof(char), len, AS_FILE(fobj)->ptr); read[len] = '\0'; /* fseek(fobj->ptr, 0, SEEK_SET); */ LuciObject *ret = LuciString_new(read); return ret; }
/** * Asserts that a given LuciObject is equivalent to a boolean True * * Currently uses C @code assert @endcode , which will exit a program * mid-execution if the assertion fails. * * @param args list of args * @param c number of args * @returns LuciNilObj */ LuciObject *luci_assert(LuciObject **args, unsigned int c) { if (c < 1) { LUCI_DIE("%s", "Missing condition parameter to assert()\n"); } LuciObject *item = args[0]; if (ISTYPE(item, obj_int_t) && !AS_INT(item)->i) { LUCI_DIE("%s\n", "Assertion failed"); } else if (ISTYPE(item, obj_float_t) && !((long)AS_FLOAT(item)->f)) { LUCI_DIE("%s\n", "Float assertion failed"); } else if (ISTYPE(item, obj_string_t)) { if (strcmp("", AS_STRING(item)->s) == 0) { LUCI_DIE("%s\n", "String assertion failed"); } } else if (ISTYPE(item, obj_list_t) && (AS_LIST(item)->count == 0)) { LUCI_DIE("%s\n", "List assertion failed"); } else if (ISTYPE(item, obj_map_t) && (AS_MAP(item)->count == 0)) { LUCI_DIE("%s\n", "Map assertion failed"); } else if (ISTYPE(item, obj_file_t) && (AS_FILE(item)->ptr)) { LUCI_DIE("%s\n", "File assertion failed"); } return LuciNilObj; }
/** * Finalizes a LuciFileObj * * Closes it's internal C FILE* only if it is not a copy of * the original LuciFileObj * * @param in LuciFileObj */ void LuciFile_finalize(LuciObject *in) { LuciFileObj *f = AS_FILE(in); if (!f->iscopy) { fclose(f->ptr); } }
/** * Returns a boolean representation of a LuciFileObj * * true if the file pointer is not NULL * * @returns LuciIntObj */ LuciObject* LuciFile_asbool(LuciObject *o) { LuciObject *res = LuciNilObj; if (AS_FILE(o)->ptr) { res = LuciInt_new(true); } else { res = LuciInt_new(false); } return res; }
/** * Closes an open LuciFileObj. * * @param args list of args * @param c number of args * @returns LuciNilObj */ LuciObject *luci_fclose(LuciObject **args, unsigned int c) { if (c < 1) { LUCI_DIE("%s", "Missing parameter to close()\n"); } LuciObject *fobj = args[0]; if (!ISTYPE(fobj, obj_file_t)) { LUCI_DIE("%s", "Not a file object\n"); } if (AS_FILE(fobj)->ptr) { close_file(AS_FILE(fobj)->ptr); } /* else, probably already closed (it's NULL) */ LUCI_DEBUG("%s\n", "Closed file object."); return LuciNilObj; }
/** * Reads a line of input from stdin * * @param args first arg is either NULL or a LuciFileObj * @param c if 0, read from stdin. if > 0, read from file. * @returns LuciStringObj containing what was read */ LuciObject *luci_readline(LuciObject **args, unsigned int c) { size_t lenmax = 64, len = 0; int ch; FILE *read_from = NULL; char *input; if (c < 1) { LUCI_DEBUG("%s\n", "readline from stdin"); read_from = stdin; } else { LuciObject *item = args[0]; if (item && (ISTYPE(item, obj_file_t))) { LUCI_DEBUG("%s\n", "readline from file"); read_from = AS_FILE(item)->ptr; } else { LUCI_DIE("args[0]: %p, type: %s\n", args[0], item->type->type_name); LUCI_DIE("%s", "Can't readline from non-file object\n"); } } input = alloc(lenmax * sizeof(char)); if (input == NULL) { LUCI_DIE("%s", "Failed to allocate buffer for reading stdin\n"); } do { ch = fgetc(read_from); if (len >= lenmax) { lenmax *= 2; if ((input = realloc(input, lenmax * sizeof(char))) == NULL) { LUCI_DIE("%s", "Failed to allocate buffer for reading\n"); } } input[len++] = (char)ch; } while (ch != EOF && ch != '\n'); if (ch == EOF) { LUCI_DEBUG("%s\n", "readline at EOF, returning nil"); return LuciNilObj; } /* overwrite the newline or EOF char with a NUL terminator */ input[--len] = '\0'; LuciObject *ret = LuciString_new(input); LUCI_DEBUG("Read line %s\n", AS_STRING(ret)->s); return ret; }
/** * Prints a representation of a LuciFileObj to stdout * * @param in LuciFileObj to print */ void LuciFile_print(LuciObject *in) { switch (AS_FILE(in)->mode) { case f_read_m: printf("<file 'r'>"); break; case f_write_m: printf("<file 'w'>"); break; case f_append_m: printf("<file 'a'>"); break; default: break; } }
void folder_close(Folder **folder) { if (folder && *folder) { int len = 0; int i = 0; char *buffer = NULL; int offset = 0; len = 4; for (i = 0; i < (*folder)->nitem; ++i) { len += 4; len += strlen((*folder)->items[i].cname); len += 4; } buffer = (char *) malloc(len); util_writeint(buffer, 0, (*folder)->nitem); #ifdef DEBUG fprintf(stderr, "folder_close, (*folder)->nitem=%d\n", (*folder)->nitem); #endif offset = 4; for (i = 0; i < (*folder)->nitem; ++i) { int cname_len = 0; cname_len = (int) strlen((*folder)->items[i].cname); util_writeint(buffer, offset, cname_len); offset += 4; memcpy(buffer + offset, (*folder)->items[i].cname, cname_len); offset += cname_len; util_writeint(buffer, offset, (*folder)->items[i].page_num); offset += 4; } #ifdef DEBUG fprintf(stderr, "offset=%d, len=%d\n", offset, len); fprintf(stderr, "folder_close buffer="); for (i = 0; i < len; ++i) fprintf(stderr, " %x", buffer[i]); fprintf(stderr, "\n"); #endif file_put_contents(AS_FILE(*folder), buffer, len); free(buffer); free((*folder)->items); free(*folder); *folder = NULL; } }
int fs_mkdir(FileSystem *fs, const char *d) { int p = 0; Inode *inode = NULL; Folder *fd = NULL; char ppath[4096] = ""; char cname[4096] = ""; Folder *pfd = NULL; int parent_page_num = 0; p = freelist_allocate(fs->freelist); if (p <= 1) return ERROR; inode = inode_new(p); if (!inode) return ERROR; inode->type = INODE_FOLDER; inode->filesize = 0; inode->lastmod = time(NULL); inode->firstpage = 0; fs_save_inode(fs, inode); inode_free(&inode); fs_split_path(d, ppath, cname); #ifdef DEBUG fprintf(stderr, "fs_mkdir, d=`%s`, ppath=`%s`, cname=`%s`\n", d, ppath, cname); #endif pfd = folder_open(fs, folder_lookup(fs, fs->cur, ppath)); parent_page_num = AS_FILE(pfd)->inode->page_num; folder_add_child(pfd, cname, p); folder_close(&pfd); fd = folder_open(fs, fs_load_inode(fs, p)); fs_split_path(d, ppath, cname); folder_add_child(fd, "", ROOT_PAGE_NUM()); folder_add_child(fd, ".", p); folder_add_child(fd, "..", parent_page_num); folder_close(&fd); return OK; }
/** * Produces a LuciStringObj representation of a LuciFileObj * * @param o LuciFileObj to represent * @returns LuciStringObj representation of o */ LuciObject *LuciFile_repr(LuciObject *o) { char *s = alloc(32); snprintf(s, 32, "file @ %p", AS_FILE(o)->ptr); return LuciString_new(s); }
/** * Returns the size of a LuciFileObj in bytes * * @param o LuciFileObj * @returns LuciIntObj size of file in bytes */ LuciObject* LuciFile_len(LuciObject *o) { return LuciInt_new(AS_FILE(o)->size); }