mirror of
https://gitlab.com/c3d/db48x.git
synced 2024-09-29 05:36:58 +02:00
Move DMCP file operations to separate file.h / file.cc
This will be useful if we want to do more than just reading the on-line help. Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
This commit is contained in:
parent
1d58abd64c
commit
39be6cc0c2
6 changed files with 315 additions and 223 deletions
1
Makefile
1
Makefile
|
@ -99,6 +99,7 @@ CXX_SOURCES += \
|
|||
src/dm42/sysmenu.cc \
|
||||
src/dm42/main.cc \
|
||||
src/input.cc \
|
||||
src/file.cc \
|
||||
src/stack.cc \
|
||||
src/util.cc \
|
||||
src/renderer.cc \
|
||||
|
|
|
@ -39,6 +39,7 @@ SOURCES += \
|
|||
../src/util.cc \
|
||||
../src/renderer.cc \
|
||||
../src/input.cc \
|
||||
../src/file.cc \
|
||||
../src/stack.cc \
|
||||
../src/settings.cc \
|
||||
../src/object.cc \
|
||||
|
|
150
src/file.cc
Normal file
150
src/file.cc
Normal file
|
@ -0,0 +1,150 @@
|
|||
// ****************************************************************************
|
||||
// file.cc DB48X project
|
||||
// ****************************************************************************
|
||||
//
|
||||
// File Description:
|
||||
//
|
||||
// Abstract interface for the zany DMCP filesystem
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// ****************************************************************************
|
||||
// (C) 2023 Christophe de Dinechin <christophe@dinechin.org>
|
||||
// This software is licensed under the terms outlined in LICENSE.txt
|
||||
// ****************************************************************************
|
||||
// This file is part of DB48X.
|
||||
//
|
||||
// DB48X is free software: you can redistribute it and/or modify
|
||||
// it under the terms outlined in the LICENSE.txt file
|
||||
//
|
||||
// DB48X 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.
|
||||
// ****************************************************************************
|
||||
|
||||
#include "file.h"
|
||||
#include "recorder.h"
|
||||
|
||||
RECORDER(file, 16, "File operations");
|
||||
RECORDER(file_error, 16, "File errors");
|
||||
|
||||
|
||||
file::file()
|
||||
// ----------------------------------------------------------------------------
|
||||
// Construct a file object
|
||||
// ----------------------------------------------------------------------------
|
||||
: data()
|
||||
{}
|
||||
|
||||
|
||||
file::~file()
|
||||
// ----------------------------------------------------------------------------
|
||||
// Close the help file
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void file::open(cstring path)
|
||||
// ----------------------------------------------------------------------------
|
||||
// Open a help file
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
#if SIMULATOR
|
||||
data = fopen(path, "r");
|
||||
if (!data)
|
||||
{
|
||||
record(file_error, "Error %s opening %s", strerror(errno), path);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
FRESULT ok = f_open(&data, path, FA_READ);
|
||||
if (ok != FR_OK)
|
||||
{
|
||||
data.obj.objsize = 0;
|
||||
return;
|
||||
}
|
||||
#endif // SIMULATOR
|
||||
}
|
||||
|
||||
|
||||
void file::close()
|
||||
// ----------------------------------------------------------------------------
|
||||
// Close the help file
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
if (valid())
|
||||
fclose(data);
|
||||
}
|
||||
|
||||
|
||||
unicode file::get()
|
||||
// ----------------------------------------------------------------------------
|
||||
// Read UTF8 code at offset
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
unicode code = valid() ? fgetc(data) : unicode(EOF);
|
||||
if (code == unicode(EOF))
|
||||
return 0;
|
||||
|
||||
if (code & 0x80)
|
||||
{
|
||||
// Reference: Wikipedia UTF-8 description
|
||||
if ((code & 0xE0) == 0xC0)
|
||||
code = ((code & 0x1F) << 6)
|
||||
| (fgetc(data) & 0x3F);
|
||||
else if ((code & 0xF0) == 0xE0)
|
||||
code = ((code & 0xF) << 12)
|
||||
| ((fgetc(data) & 0x3F) << 6)
|
||||
| (fgetc(data) & 0x3F);
|
||||
else if ((code & 0xF8) == 0xF0)
|
||||
code = ((code & 0xF) << 18)
|
||||
| ((fgetc(data) & 0x3F) << 12)
|
||||
| ((fgetc(data) & 0x3F) << 6)
|
||||
| (fgetc(data) & 0x3F);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
uint file::find(unicode cp)
|
||||
// ----------------------------------------------------------------------------
|
||||
// Find a given code point in file looking forward
|
||||
// ----------------------------------------------------------------------------
|
||||
// Return position right before code point, position file right after it
|
||||
{
|
||||
unicode c;
|
||||
uint off;
|
||||
do
|
||||
{
|
||||
off = ftell(data);
|
||||
c = get();
|
||||
} while (c && c != cp);
|
||||
return off;
|
||||
}
|
||||
|
||||
|
||||
uint file::rfind(unicode cp)
|
||||
// ----------------------------------------------------------------------------
|
||||
// Find a given code point in file looking backward
|
||||
// ----------------------------------------------------------------------------
|
||||
// Return position right before code point, position file right after it
|
||||
{
|
||||
uint off = ftell(data);
|
||||
unicode c;
|
||||
do
|
||||
{
|
||||
if (off == 0)
|
||||
break;
|
||||
fseek(data, --off, SEEK_SET);
|
||||
c = get();
|
||||
}
|
||||
while (c != cp);
|
||||
return off;
|
||||
}
|
152
src/file.h
Normal file
152
src/file.h
Normal file
|
@ -0,0 +1,152 @@
|
|||
#ifndef FILE_H
|
||||
# define FILE_H
|
||||
// ****************************************************************************
|
||||
// file.h DB48X project
|
||||
// ****************************************************************************
|
||||
//
|
||||
// File Description:
|
||||
//
|
||||
// Abstract the DMCP zany filesystem interface
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// ****************************************************************************
|
||||
// (C) 2023 Christophe de Dinechin <christophe@dinechin.org>
|
||||
// This software is licensed under the terms outlined in LICENSE.txt
|
||||
// ****************************************************************************
|
||||
// This file is part of DB48X.
|
||||
//
|
||||
// DB48X is free software: you can redistribute it and/or modify
|
||||
// it under the terms outlined in the LICENSE.txt file
|
||||
//
|
||||
// DB48X 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.
|
||||
// ****************************************************************************
|
||||
|
||||
#include "dmcp.h"
|
||||
|
||||
#include "types.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
struct file
|
||||
// ----------------------------------------------------------------------------
|
||||
// Direct access to the help file
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
file();
|
||||
~file();
|
||||
|
||||
void open(cstring path);
|
||||
bool valid();
|
||||
void close();
|
||||
unicode get();
|
||||
unicode get(uint offset);
|
||||
void seek(uint offset);
|
||||
unicode peek();
|
||||
uint position();
|
||||
uint find(unicode cp);
|
||||
uint rfind(unicode cp);
|
||||
|
||||
protected:
|
||||
#if SIMULATOR
|
||||
FILE *data;
|
||||
#else
|
||||
FIL data;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
// ============================================================================
|
||||
//
|
||||
// DMCP wrappers
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
#ifndef SIMULATOR
|
||||
#define ftell(f) f_tell(&f)
|
||||
#define fseek(f,o,w) f_lseek(&f,o)
|
||||
#define fclose(f) f_close(&f)
|
||||
|
||||
static inline int fgetc(FIL &f)
|
||||
// ----------------------------------------------------------------------------
|
||||
// Read one character from a file - Wrapper for DMCP filesystem
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
UINT br = 0;
|
||||
char c = 0;
|
||||
if (f_read(&f, &c, 1, &br) != FR_OK || br != 1)
|
||||
return EOF;
|
||||
return c;
|
||||
}
|
||||
#endif // SIMULATOR
|
||||
|
||||
|
||||
|
||||
|
||||
// ============================================================================
|
||||
//
|
||||
// Inline functions for simple stuff
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
inline bool file::valid()
|
||||
// ----------------------------------------------------------------------------
|
||||
// Return true if the input file is OK
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
#if SIMULATOR
|
||||
return data != 0;
|
||||
#else
|
||||
return f_size(&data) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline void file::seek(uint off)
|
||||
// ----------------------------------------------------------------------------
|
||||
// Move the read position in the data file
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
fseek(data, off, SEEK_SET);
|
||||
}
|
||||
|
||||
|
||||
inline unicode file::peek()
|
||||
// ----------------------------------------------------------------------------
|
||||
// Look at what is as current position without moving it
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
uint off = ftell(data);
|
||||
unicode result = get();
|
||||
seek(off);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
inline unicode file::get(uint off)
|
||||
// ----------------------------------------------------------------------------
|
||||
// Get code point at given offset
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
seek(off);
|
||||
return get();
|
||||
}
|
||||
|
||||
|
||||
inline uint file::position()
|
||||
// ----------------------------------------------------------------------------
|
||||
// Return current position in help file
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
return ftell(data);
|
||||
}
|
||||
|
||||
#endif // FILE_H
|
186
src/input.cc
186
src/input.cc
|
@ -1175,192 +1175,6 @@ void input::draw_error()
|
|||
}
|
||||
|
||||
|
||||
input::file::file()
|
||||
// ----------------------------------------------------------------------------
|
||||
// Construct a file object
|
||||
// ----------------------------------------------------------------------------
|
||||
: data()
|
||||
{}
|
||||
|
||||
|
||||
input::file::~file()
|
||||
// ----------------------------------------------------------------------------
|
||||
// Close the help file
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void input::file::open(cstring path)
|
||||
// ----------------------------------------------------------------------------
|
||||
// Open a help file
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
#if SIMULATOR
|
||||
data = fopen(path, "r");
|
||||
if (!data)
|
||||
{
|
||||
record(help, "Error %s opening %s", strerror(errno), path);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
FRESULT ok = f_open(&data, path, FA_READ);
|
||||
if (ok != FR_OK)
|
||||
{
|
||||
data.obj.objsize = 0;
|
||||
return;
|
||||
}
|
||||
#define ftell(f) f_tell(&f)
|
||||
#define fseek(f,o,w) f_lseek(&f,o)
|
||||
#define fclose(f) f_close(&f)
|
||||
#endif // SIMULATOR
|
||||
}
|
||||
|
||||
|
||||
void input::file::close()
|
||||
// ----------------------------------------------------------------------------
|
||||
// Close the help file
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
if (valid())
|
||||
fclose(data);
|
||||
}
|
||||
|
||||
|
||||
inline bool input::file::valid()
|
||||
// ----------------------------------------------------------------------------
|
||||
// Return true if the input file is OK
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
#if SIMULATOR
|
||||
return data != 0;
|
||||
#else
|
||||
return f_size(&data) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifndef SIMULATOR
|
||||
static inline int fgetc(FIL &f)
|
||||
// ----------------------------------------------------------------------------
|
||||
// Read one character from a file - Wrapper for DMCP filesystem
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
UINT br = 0;
|
||||
char c = 0;
|
||||
if (f_read(&f, &c, 1, &br) != FR_OK || br != 1)
|
||||
return EOF;
|
||||
return c;
|
||||
}
|
||||
#endif // SIMULATOR
|
||||
|
||||
|
||||
unicode input::file::get()
|
||||
// ----------------------------------------------------------------------------
|
||||
// Read UTF8 code at offset
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
unicode code = valid() ? fgetc(data) : unicode(EOF);
|
||||
if (code == unicode(EOF))
|
||||
return 0;
|
||||
|
||||
if (code & 0x80)
|
||||
{
|
||||
// Reference: Wikipedia UTF-8 description
|
||||
if ((code & 0xE0) == 0xC0)
|
||||
code = ((code & 0x1F) << 6)
|
||||
| (fgetc(data) & 0x3F);
|
||||
else if ((code & 0xF0) == 0xE0)
|
||||
code = ((code & 0xF) << 12)
|
||||
| ((fgetc(data) & 0x3F) << 6)
|
||||
| (fgetc(data) & 0x3F);
|
||||
else if ((code & 0xF8) == 0xF0)
|
||||
code = ((code & 0xF) << 18)
|
||||
| ((fgetc(data) & 0x3F) << 12)
|
||||
| ((fgetc(data) & 0x3F) << 6)
|
||||
| (fgetc(data) & 0x3F);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
inline void input::file::seek(uint off)
|
||||
// ----------------------------------------------------------------------------
|
||||
// Move the read position in the data file
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
fseek(data, off, SEEK_SET);
|
||||
}
|
||||
|
||||
|
||||
inline unicode input::file::peek()
|
||||
// ----------------------------------------------------------------------------
|
||||
// Look at what is as current position without moving it
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
uint off = ftell(data);
|
||||
unicode result = get();
|
||||
seek(off);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
inline unicode input::file::get(uint off)
|
||||
// ----------------------------------------------------------------------------
|
||||
// Get code point at given offset
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
seek(off);
|
||||
return get();
|
||||
}
|
||||
|
||||
|
||||
inline uint input::file::position()
|
||||
// ----------------------------------------------------------------------------
|
||||
// Return current position in help file
|
||||
// ----------------------------------------------------------------------------
|
||||
{
|
||||
return ftell(data);
|
||||
}
|
||||
|
||||
|
||||
inline uint input::file::find(unicode cp)
|
||||
// ----------------------------------------------------------------------------
|
||||
// Find a given code point in file looking forward
|
||||
// ----------------------------------------------------------------------------
|
||||
// Return position right before code point, position file right after it
|
||||
{
|
||||
unicode c;
|
||||
uint off;
|
||||
do
|
||||
{
|
||||
off = ftell(data);
|
||||
c = get();
|
||||
} while (c && c != cp);
|
||||
return off;
|
||||
}
|
||||
|
||||
|
||||
inline uint input::file::rfind(unicode cp)
|
||||
// ----------------------------------------------------------------------------
|
||||
// Find a given code point in file looking backward
|
||||
// ----------------------------------------------------------------------------
|
||||
// Return position right before code point, position file right after it
|
||||
{
|
||||
uint off = ftell(data);
|
||||
unicode c;
|
||||
do
|
||||
{
|
||||
if (off == 0)
|
||||
break;
|
||||
fseek(data, --off, SEEK_SET);
|
||||
c = get();
|
||||
}
|
||||
while (c != cp);
|
||||
return off;
|
||||
}
|
||||
|
||||
|
||||
void input::load_help(utf8 topic)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
48
src/input.h
48
src/input.h
|
@ -29,10 +29,11 @@
|
|||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// ****************************************************************************
|
||||
|
||||
#include "dmcp.h"
|
||||
#include "file.h"
|
||||
#include "graphics.h"
|
||||
#include "object.h"
|
||||
#include "types.h"
|
||||
#include "dmcp.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -177,42 +178,15 @@ protected:
|
|||
bool autoComplete : 1; // Menu is auto-complete
|
||||
|
||||
protected:
|
||||
// Key mappings
|
||||
object_p function[NUM_PLANES][NUM_KEYS];
|
||||
cstring menu_label[NUM_PLANES][NUM_SOFTKEYS];
|
||||
uint16_t menu_marker[NUM_PLANES][NUM_SOFTKEYS];
|
||||
bool menu_marker_align[NUM_PLANES][NUM_SOFTKEYS];
|
||||
static runtime &RT;
|
||||
friend struct tests;
|
||||
friend struct runtime;
|
||||
|
||||
protected:
|
||||
struct file
|
||||
// ------------------------------------------------------------------------
|
||||
// Direct access to the help file
|
||||
// ------------------------------------------------------------------------
|
||||
{
|
||||
file();
|
||||
~file();
|
||||
|
||||
void open(cstring path);
|
||||
bool valid();
|
||||
void close();
|
||||
unicode get();
|
||||
unicode get(uint offset);
|
||||
void seek(uint offset);
|
||||
unicode peek();
|
||||
uint position();
|
||||
uint find(unicode cp);
|
||||
uint rfind(unicode cp);
|
||||
|
||||
protected:
|
||||
#ifdef SIMULATOR
|
||||
FILE *data;
|
||||
#else
|
||||
FIL data;
|
||||
#endif
|
||||
} helpfile;
|
||||
// Key mappings
|
||||
object_p function[NUM_PLANES][NUM_KEYS];
|
||||
cstring menu_label[NUM_PLANES][NUM_SOFTKEYS];
|
||||
uint16_t menu_marker[NUM_PLANES][NUM_SOFTKEYS];
|
||||
bool menu_marker_align[NUM_PLANES][NUM_SOFTKEYS];
|
||||
file helpfile;
|
||||
static runtime &RT;
|
||||
friend struct tests;
|
||||
friend struct runtime;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue