Files

176 lines
4.1 KiB
C

#include "file.h"
#include "viewer.h"
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
file_view_area_t view_area;
static int _file_get_size_of_first_line()
{
int res = 0;
for (int i = view_area.start; i < view_area.data_len; i++) {
res++;
if (view_area.buffer[i] == '\n') {
return res;
}
}
return view_area.data_len - view_area.start;
}
static void _file_find_start(uint32_t old_offset)
{
old_offset -= 2;
while (old_offset > view_area.offset) {
if (view_area.buffer[old_offset - view_area.offset] == '\n') {
view_area.start = old_offset - view_area.offset + 1;
return;
}
old_offset--;
}
view_area.start = 0;
}
static inline int _file_remaining_size()
{
return view_area.data_len - view_area.start;
}
static inline int _file_is_last_line_in_buf()
{
return 1;
}
int _file_buf_flush()
{
/* FIXME: for now we think that we have all file in our buffer */
lseek(view_area.fd, view_area.offset, SEEK_SET);
view_area.data_len = write(view_area.fd, view_area.buffer, view_area.data_len);
return 0;
}
int _file_buf_reload(int offset_in_file)
{
/* TODO: Get real file size */
view_area.buf_len = 4000;
view_area.buffer = (char*)malloc(view_area.buf_len);
view_area.start = 0;
view_area.offset = offset_in_file;
view_area.was_changed = 0;
lseek(view_area.fd, view_area.offset, SEEK_SET);
view_area.data_len = read(view_area.fd, view_area.buffer, view_area.buf_len);
if (view_area.data_len < 0) {
return -1;
}
return 0;
}
int file_line_len(int offset)
{
int res = 0;
for (int i = offset; i < view_area.data_len; i++) {
res++;
if (view_area.buffer[i] == '\n') {
return res;
}
}
return view_area.data_len - view_area.start;
}
int file_line_len_backwards(int offset)
{
int res = 1;
for (int i = offset - 1; i >= view_area.offset; i--) {
if (view_area.buffer[i] == '\n') {
return res;
}
res++;
}
return offset;
}
int file_open(char* path)
{
int n;
if ((view_area.fd = open(path, O_RDWR)) < 0) {
return -1;
}
_file_buf_reload(0);
if (view_area.data_len < 0) {
return -1;
}
viewer_display(view_area.buffer, view_area.start, _file_remaining_size());
return view_area.fd;
}
void file_exit()
{
close(view_area.fd);
}
/**
* file_paste_char pastes and flush updates to disk.
*/
int file_paste_char(char c, int offset)
{
view_area.was_changed = 1;
view_area.data_len++;
memmove(view_area.buffer + offset + 1, view_area.buffer + offset, view_area.data_len - offset - 1);
view_area.buffer[offset] = c;
viewer_cursor_next();
viewer_display(view_area.buffer, view_area.start, _file_remaining_size());
}
/**
* file_paste_char pastes and flush updates to disk.
*/
int file_save()
{
if (view_area.was_changed) {
_file_buf_flush();
}
}
/**
* Scroll functions update file buffer, to contain line scrolled to.
*/
int file_scroll_up()
{
if (view_area.line == 0 || view_area.start == 0) {
return -1;
}
view_area.line--;
int old_offset_in_file = view_area.offset + view_area.start;
int offset_in_file = view_area.offset + view_area.start - SCREEN_X;
if (offset_in_file < 0) {
offset_in_file = 0;
}
if (offset_in_file >= view_area.offset) {
view_area.start = offset_in_file - view_area.offset;
_file_find_start(old_offset_in_file);
viewer_display(view_area.buffer, view_area.start, _file_remaining_size());
} else {
_file_buf_reload(offset_in_file);
_file_find_start(old_offset_in_file);
viewer_display(view_area.buffer, view_area.start, _file_remaining_size());
}
}
int file_scroll_down()
{
int line_size = _file_get_size_of_first_line();
view_area.start += line_size;
if (!_file_is_last_line_in_buf()) {
_file_buf_reload(view_area.offset + view_area.start);
}
viewer_display(view_area.buffer, view_area.start, _file_remaining_size());
view_area.line++;
}