mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[escher] Change name: File --> Record, FileSystem --> Kallax
This commit is contained in:
committed by
EmilieNumworks
parent
338ee4e0b0
commit
b9a852a9d1
@@ -11,7 +11,7 @@ EditorController::EditorController(MenuController * menuController) :
|
||||
ViewController(nullptr),
|
||||
m_textArea(this),
|
||||
m_areaBuffer(nullptr),
|
||||
m_script(File()),
|
||||
m_script(Record()),
|
||||
m_menuController(menuController)
|
||||
{
|
||||
m_textArea.setDelegate(this);
|
||||
@@ -26,7 +26,7 @@ void EditorController::setScript(Script script) {
|
||||
m_script = script;
|
||||
const char * scriptBody = m_script.readContent();
|
||||
size_t scriptBodySize = strlen(scriptBody)+1;
|
||||
size_t availableScriptSize = scriptBodySize + FileSystem::sharedFileSystem()->availableSize();
|
||||
size_t availableScriptSize = scriptBodySize + Kallax::sharedKallax()->availableSize();
|
||||
assert(m_areaBuffer == nullptr);
|
||||
m_areaBuffer = new char[availableScriptSize];
|
||||
strlcpy(m_areaBuffer, scriptBody, scriptBodySize);
|
||||
@@ -36,9 +36,9 @@ void EditorController::setScript(Script script) {
|
||||
// TODO: this should be done in textAreaDidFinishEditing maybe??
|
||||
bool EditorController::handleEvent(Ion::Events::Event event) {
|
||||
if (event == Ion::Events::OK || event == Ion::Events::Back) {
|
||||
File::ErrorStatus err = m_script.writeContent(m_areaBuffer, strlen(m_areaBuffer)+1);
|
||||
if (err == File::ErrorStatus::NoEnoughSpaceAvailable) {
|
||||
assert(false); // This should not happen as we set the text area according to the available space in the File System
|
||||
Record::ErrorStatus err = m_script.writeContent(m_areaBuffer, strlen(m_areaBuffer)+1);
|
||||
if (err == Record::ErrorStatus::NoEnoughSpaceAvailable) {
|
||||
assert(false); // This should not happen as we set the text area according to the available space in the Kallax
|
||||
} else {
|
||||
stackController()->pop();
|
||||
}
|
||||
|
||||
@@ -302,8 +302,8 @@ bool MenuController::textFieldDidFinishEditing(TextField * textField, const char
|
||||
} else {
|
||||
newName = text;
|
||||
}
|
||||
File::ErrorStatus error = m_scriptStore->scriptAtIndex(m_selectableTableView.selectedRow()).rename(newName);
|
||||
if (error == File::ErrorStatus::None) {
|
||||
Record::ErrorStatus error = m_scriptStore->scriptAtIndex(m_selectableTableView.selectedRow()).rename(newName);
|
||||
if (error == Record::ErrorStatus::None) {
|
||||
updateAddScriptRowDisplay();
|
||||
textField->setText(newName);
|
||||
int currentRow = m_selectableTableView.selectedRow();
|
||||
@@ -318,7 +318,7 @@ bool MenuController::textFieldDidFinishEditing(TextField * textField, const char
|
||||
static_cast<AppsContainer *>(const_cast<Container *>(app()->container()))->setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::Default);
|
||||
return true;
|
||||
} else {
|
||||
assert(error == File::ErrorStatus::NameTaken);
|
||||
assert(error == Record::ErrorStatus::NameTaken);
|
||||
// The name cannot be to long as the text field size was set accordingly
|
||||
|
||||
// TODO:
|
||||
@@ -337,8 +337,8 @@ bool MenuController::textFieldDidAbortEditing(TextField * textField, const char
|
||||
// The previous text was an empty name. Use a numbered default script name.
|
||||
char numberedDefaultName[k_defaultScriptNameMaxSize];
|
||||
numberedDefaultScriptName(numberedDefaultName);
|
||||
File::ErrorStatus error = m_scriptStore->scriptAtIndex(m_selectableTableView.selectedRow()).rename(numberedDefaultName);
|
||||
assert(error == File::ErrorStatus::None);
|
||||
Record::ErrorStatus error = m_scriptStore->scriptAtIndex(m_selectableTableView.selectedRow()).rename(numberedDefaultName);
|
||||
assert(error == Record::ErrorStatus::None);
|
||||
updateAddScriptRowDisplay();
|
||||
m_selectableTableView.reloadData();
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace Code {
|
||||
|
||||
Script::Script(File f) :
|
||||
File(f)
|
||||
Script::Script(Record f) :
|
||||
Record(f)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -23,9 +23,9 @@ const char * Script::readContent() const {
|
||||
return body+k_importationStatusSize;
|
||||
}
|
||||
|
||||
File::ErrorStatus Script::writeContent(const char * data, size_t size) {
|
||||
Record::ErrorStatus Script::writeContent(const char * data, size_t size) {
|
||||
int deltaSize = (int)size+k_importationStatusSize - (int)bodySize();
|
||||
if (FileSystem::sharedFileSystem()->moveNextFile(start(), deltaSize)) {
|
||||
if (Kallax::sharedKallax()->moveNextRecord(start(), deltaSize)) {
|
||||
*m_size += deltaSize;
|
||||
strlcpy(m_body+k_importationStatusSize, data, size);
|
||||
return ErrorStatus::None;
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
namespace Code {
|
||||
|
||||
/* File : | Total Size | Type | Name | Body |
|
||||
* Script: | AutoImportationStatus | Content |*/
|
||||
/* Record : | Total Size | Type | Name | Body |
|
||||
* Script: | AutoImportationStatus | Content |*/
|
||||
|
||||
class Script : public File {
|
||||
class Script : public Record {
|
||||
friend class ScriptStore;
|
||||
public:
|
||||
Script(File f);
|
||||
Script(Record f);
|
||||
|
||||
bool importationStatus() const;
|
||||
void toggleImportationStatus();
|
||||
|
||||
@@ -12,7 +12,7 @@ ScriptParameterController::ScriptParameterController(Responder * parentResponder
|
||||
m_deleteScript(I18n::Message::DeleteScript),
|
||||
m_selectableTableView(this, this, 0, 1, Metric::CommonTopMargin, Metric::CommonRightMargin,
|
||||
Metric::CommonBottomMargin, Metric::CommonLeftMargin, this),
|
||||
m_script(File()),
|
||||
m_script(Record()),
|
||||
m_menuController(menuController)
|
||||
{
|
||||
}
|
||||
@@ -22,7 +22,7 @@ void ScriptParameterController::setScript(Script script){
|
||||
}
|
||||
|
||||
void ScriptParameterController::dismissScriptParameterController() {
|
||||
m_script = Script(File());
|
||||
m_script = Script(Record());
|
||||
stackViewController()->pop();
|
||||
}
|
||||
|
||||
|
||||
@@ -20,17 +20,17 @@ ScriptStore::ScriptStore()
|
||||
}
|
||||
|
||||
Script ScriptStore::scriptAtIndex(int index) {
|
||||
File f = FileSystem::sharedFileSystem()->fileOfTypeAtIndex(File::Type::Script, index);
|
||||
Record f = Kallax::sharedKallax()->recordOfTypeAtIndex(Record::Type::Script, index);
|
||||
return Script(f);
|
||||
}
|
||||
|
||||
Script ScriptStore::scriptNamed(const char * name) {
|
||||
File f = FileSystem::sharedFileSystem()->getFile(File::Type::Script, name);
|
||||
Record f = Kallax::sharedKallax()->getRecord(Record::Type::Script, name);
|
||||
return Script(f);
|
||||
}
|
||||
|
||||
int ScriptStore::numberOfScripts() {
|
||||
return FileSystem::sharedFileSystem()->numberOfFileOfType(File::Type::Script);
|
||||
return Kallax::sharedKallax()->numberOfRecordOfType(Record::Type::Script);
|
||||
}
|
||||
|
||||
bool ScriptStore::addNewScript() {
|
||||
@@ -44,7 +44,7 @@ void ScriptStore::deleteAllScripts() {
|
||||
}
|
||||
|
||||
bool ScriptStore::isFull() {
|
||||
return (numberOfScripts() >= k_maxNumberOfScripts || FileSystem::sharedFileSystem()->availableSize() < k_fullFreeSpaceSizeLimit);
|
||||
return (numberOfScripts() >= k_maxNumberOfScripts || Kallax::sharedKallax()->availableSize() < k_fullFreeSpaceSizeLimit);
|
||||
}
|
||||
|
||||
void ScriptStore::scanScriptsForFunctionsAndVariables(void * context, ScanCallback storeFunction, ScanCallback storeVariable) {
|
||||
@@ -143,8 +143,8 @@ bool ScriptStore::addScriptFromTemplate(const ScriptTemplate * scriptTemplate) {
|
||||
body[0] = 1;
|
||||
strlcpy(body+1, scriptTemplate->content(), scriptSize);
|
||||
bool result = false;
|
||||
if (FileSystem::sharedFileSystem()->sizeOfFileWithBody(body) <= FileSystem::sharedFileSystem()->availableSize()) {
|
||||
FileSystem::sharedFileSystem()->addFile(scriptTemplate->name(), File::Type::Script, body);
|
||||
if (Kallax::sharedKallax()->sizeOfRecordWithBody(body) <= Kallax::sharedKallax()->availableSize()) {
|
||||
Kallax::sharedKallax()->addRecord(scriptTemplate->name(), Record::Type::Script, body);
|
||||
result = true;
|
||||
}
|
||||
delete[] body;
|
||||
|
||||
@@ -33,9 +33,9 @@ public:
|
||||
|
||||
bool addScriptFromTemplate(const ScriptTemplate * scriptTemplate);
|
||||
private:
|
||||
// If the system file free space has a size smaller than
|
||||
// If the kallax free space has a size smaller than
|
||||
// k_fullFreeSpaceSizeLimit, we consider the script store as full.
|
||||
static constexpr int k_fullFreeSpaceSizeLimit = File::k_sizeSize+File::k_nameSize+File::k_typeSize+10;
|
||||
static constexpr int k_fullFreeSpaceSizeLimit = Record::k_sizeSize+Record::k_nameSize+Record::k_typeSize+10;
|
||||
static constexpr size_t k_fileInput2ParseNodeStructKind = 1;
|
||||
static constexpr size_t k_functionDefinitionParseNodeStructKind = 3;
|
||||
static constexpr size_t k_expressionStatementParseNodeStructKind = 5;
|
||||
|
||||
@@ -21,13 +21,12 @@ objs += $(addprefix escher/src/,\
|
||||
expression_table_cell.o\
|
||||
expression_table_cell_with_pointer.o\
|
||||
expression_view.o\
|
||||
file.o\
|
||||
file_system.o\
|
||||
highlight_cell.o\
|
||||
gauge_view.o\
|
||||
image_view.o\
|
||||
invocation.o\
|
||||
input_view_controller.o\
|
||||
kallax.o\
|
||||
key_view.o\
|
||||
list_view_data_source.o\
|
||||
message_table_cell.o\
|
||||
@@ -44,6 +43,7 @@ objs += $(addprefix escher/src/,\
|
||||
modal_view_controller.o\
|
||||
palette.o\
|
||||
pointer_text_view.o\
|
||||
record.o\
|
||||
responder.o\
|
||||
run_loop.o\
|
||||
scroll_view.o\
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
#include <escher/expression_table_cell.h>
|
||||
#include <escher/expression_table_cell_with_pointer.h>
|
||||
#include <escher/expression_view.h>
|
||||
#include <escher/file.h>
|
||||
#include <escher/file_system.h>
|
||||
#include <escher/gauge_view.h>
|
||||
#include <escher/highlight_cell.h>
|
||||
#include <escher/image.h>
|
||||
@@ -31,6 +29,7 @@
|
||||
#include <escher/input_view_controller.h>
|
||||
#include <escher/invocation.h>
|
||||
#include <escher/i18n.h>
|
||||
#include <escher/kallax.h>
|
||||
#include <escher/key_view.h>
|
||||
#include <escher/list_view_data_source.h>
|
||||
#include <escher/message_table_cell.h>
|
||||
@@ -48,6 +47,7 @@
|
||||
#include <escher/modal_view_controller.h>
|
||||
#include <escher/palette.h>
|
||||
#include <escher/pointer_text_view.h>
|
||||
#include <escher/record.h>
|
||||
#include <escher/responder.h>
|
||||
#include <escher/scroll_view.h>
|
||||
#include <escher/scroll_view_data_source.h>
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
#ifndef ESCHER_FILE_SYSTEM_H
|
||||
#define ESCHER_FILE_SYSTEM_H
|
||||
|
||||
/* FileSystem : | Magic | File1 | File2 | ... | Magic |
|
||||
* | Magic | Size1 | Type1 | Name1 | BodySize1 | Body1 | Size2 | Type2 | Name2 | BodySize2 | Body2 | ... | Magic */
|
||||
|
||||
class FileSystem {
|
||||
public:
|
||||
FileSystem();
|
||||
static FileSystem * sharedFileSystem();
|
||||
int numberOfFileOfType(File::Type type);
|
||||
File fileOfTypeAtIndex(File::Type type, int index);
|
||||
File getFile(File::Type type, const char * name);
|
||||
|
||||
File addFile(const char * name, File::Type type, const char * content);
|
||||
|
||||
// availableSize takes into account the the size of the last File must be 0.
|
||||
size_t availableSize();
|
||||
|
||||
bool isNameTaken(const char * name, File::Type type);
|
||||
bool moveNextFile(char * start, int delta);
|
||||
size_t sizeOfFileWithBody(const char * body) const;
|
||||
private:
|
||||
// lastUsedData takes into account the the size of the last File must be 0.
|
||||
char * lastUsedData();
|
||||
size_t * sizeAddressOfFileStarting(char * start) const;
|
||||
size_t sizeOfFileStarting(char * start) const;
|
||||
File::Type typeOfFileStarting(char * start) const;
|
||||
char * nameOfFileStarting(char * start);
|
||||
char * bodyOfFileStarting(char * start);
|
||||
constexpr static size_t k_totalSize = 4096;
|
||||
constexpr static uint32_t Magic = 0xDECA0DF0;
|
||||
uint32_t m_dataHeader;
|
||||
char m_data[k_totalSize];
|
||||
uint32_t m_dataFooter;
|
||||
};
|
||||
|
||||
class FileSystemInfo {
|
||||
public:
|
||||
constexpr FileSystemInfo(uint32_t address) :
|
||||
m_header(Magic),
|
||||
m_address(address),
|
||||
m_footer(Magic) { }
|
||||
private:
|
||||
constexpr static uint32_t Magic = 0xDECB0DF0;
|
||||
uint32_t m_header;
|
||||
uint32_t m_address;
|
||||
uint32_t m_footer;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
54
escher/include/escher/kallax.h
Normal file
54
escher/include/escher/kallax.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef ESCHER_KALLAX_H
|
||||
#define ESCHER_KALLAX_H
|
||||
|
||||
#include <escher/record.h>
|
||||
|
||||
/* Kallax : | Magic | Record1 | Record2 | ... | Magic |
|
||||
* | Magic | Size1 | Type1 | Name1 | BodySize1 | Body1 | Size2 | Type2 | Name2 | BodySize2 | Body2 | ... | Magic */
|
||||
|
||||
class Kallax {
|
||||
public:
|
||||
Kallax();
|
||||
static Kallax * sharedKallax();
|
||||
int numberOfRecordOfType(Record::Type type);
|
||||
Record recordOfTypeAtIndex(Record::Type type, int index);
|
||||
Record getRecord(Record::Type type, const char * name);
|
||||
|
||||
Record addRecord(const char * name, Record::Type type, const char * content);
|
||||
|
||||
// availableSize takes into account the the size of the last Record must be 0.
|
||||
size_t availableSize();
|
||||
|
||||
bool isNameTaken(const char * name, Record::Type type);
|
||||
bool moveNextRecord(char * start, int delta);
|
||||
size_t sizeOfRecordWithBody(const char * body) const;
|
||||
private:
|
||||
// lastUsedData takes into account the the size of the last Record must be 0.
|
||||
char * lastUsedData();
|
||||
size_t * sizeAddressOfRecordStarting(char * start) const;
|
||||
size_t sizeOfRecordStarting(char * start) const;
|
||||
Record::Type typeOfRecordStarting(char * start) const;
|
||||
char * nameOfRecordStarting(char * start);
|
||||
char * bodyOfRecordStarting(char * start);
|
||||
constexpr static size_t k_totalSize = 4096;
|
||||
constexpr static uint32_t Magic = 0xDECA0DF0;
|
||||
uint32_t m_dataHeader;
|
||||
char m_data[k_totalSize];
|
||||
uint32_t m_dataFooter;
|
||||
};
|
||||
|
||||
class KallaxInfo {
|
||||
public:
|
||||
constexpr KallaxInfo(uint32_t address) :
|
||||
m_header(Magic),
|
||||
m_address(address),
|
||||
m_footer(Magic) { }
|
||||
private:
|
||||
constexpr static uint32_t Magic = 0xDECB0DF0;
|
||||
uint32_t m_header;
|
||||
uint32_t m_address;
|
||||
uint32_t m_footer;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#ifndef ESCHER_FILE_H
|
||||
#define ESCHER_FILE_H
|
||||
#ifndef ESCHER_RECORD_H
|
||||
#define ESCHER_RECORD_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* File : | Total Size | Type | Name | Body | */
|
||||
/* Record : | Total Size | Type | Name | Body | */
|
||||
|
||||
class File {
|
||||
class Record {
|
||||
public:
|
||||
enum class Type : uint8_t {
|
||||
Null,
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
NameTooLong = 2,
|
||||
NoEnoughSpaceAvailable = 3
|
||||
};
|
||||
File(size_t * totalSize = nullptr, char * name = nullptr, Type type = Type::Null, char * body = nullptr);
|
||||
Record(size_t * totalSize = nullptr, char * name = nullptr, Type type = Type::Null, char * body = nullptr);
|
||||
|
||||
bool isNull() const;
|
||||
|
||||
@@ -1,162 +0,0 @@
|
||||
#include <escher/file.h>
|
||||
#include <escher/file_system.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef HEADER_SECTION
|
||||
#define HEADER_SECTION
|
||||
#endif
|
||||
|
||||
#ifndef FORCE_LINK
|
||||
#define FORCE_LINK
|
||||
#endif
|
||||
|
||||
FileSystem f;
|
||||
constexpr FileSystemInfo HEADER_SECTION FORCE_LINK file_system_infos((uint32_t)(&f));
|
||||
|
||||
FileSystem::FileSystem() :
|
||||
m_dataHeader(Magic),
|
||||
m_data(),
|
||||
m_dataFooter(Magic)
|
||||
{
|
||||
size_t * p = (size_t *)m_data;
|
||||
p[0] = 0;
|
||||
}
|
||||
|
||||
FileSystem * FileSystem::sharedFileSystem() {
|
||||
return &f;
|
||||
}
|
||||
|
||||
int FileSystem::numberOfFileOfType(File::Type type) {
|
||||
assert(m_dataHeader == Magic);
|
||||
assert(m_dataFooter == Magic);
|
||||
int count = 0;
|
||||
char * currentPointer = m_data;
|
||||
size_t size = sizeOfFileStarting(currentPointer);
|
||||
while (size != 0 && currentPointer < m_data + k_totalSize) {
|
||||
if (typeOfFileStarting(currentPointer) == type) {
|
||||
count++;
|
||||
}
|
||||
currentPointer += size;
|
||||
size = sizeOfFileStarting(currentPointer);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
File FileSystem::fileOfTypeAtIndex(File::Type type, int index) {
|
||||
int currentIndex = -1;
|
||||
char * currentPointer = m_data;
|
||||
size_t size = sizeOfFileStarting(currentPointer);
|
||||
while (size != 0 && currentPointer < m_data + k_totalSize) {
|
||||
if (typeOfFileStarting(currentPointer) == type) {
|
||||
currentIndex++;
|
||||
if (currentIndex == index) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
currentPointer += size;
|
||||
size = sizeOfFileStarting(currentPointer);
|
||||
}
|
||||
return File(sizeAddressOfFileStarting(currentPointer), nameOfFileStarting(currentPointer), type, bodyOfFileStarting(currentPointer));
|
||||
}
|
||||
|
||||
File FileSystem::getFile(File::Type type, const char * name) {
|
||||
for (int i = 0; i < numberOfFileOfType(type); i++) {
|
||||
File currentFile = fileOfTypeAtIndex(type, i);
|
||||
if (strcmp(currentFile.name(), name) == 0) {
|
||||
return currentFile;
|
||||
}
|
||||
}
|
||||
return File();
|
||||
}
|
||||
|
||||
File FileSystem::addFile(const char * name, File::Type type, const char * body) {
|
||||
// assert name is short enough and there is enough space to add the file
|
||||
assert(strlen(name) < File::k_nameSize);
|
||||
assert(availableSize() >= sizeOfFileWithBody(body));
|
||||
// Find the end of data
|
||||
char * currentPointer = m_data;
|
||||
size_t size = sizeOfFileStarting(currentPointer);
|
||||
while (size != 0 && currentPointer < m_data + k_totalSize) {
|
||||
currentPointer += size;
|
||||
size = sizeOfFileStarting(currentPointer);
|
||||
}
|
||||
size_t fileSize = sizeOfFileWithBody(body);
|
||||
// Fill totalSize
|
||||
*((size_t *)currentPointer) = fileSize;
|
||||
// Fill type
|
||||
*(currentPointer+File::k_sizeSize) = (uint8_t)type;
|
||||
// Fill name
|
||||
strlcpy(currentPointer+File::k_sizeSize+File::k_typeSize, name, File::k_nameSize);
|
||||
// Fill body
|
||||
strlcpy(currentPointer+File::k_sizeSize+File::k_typeSize+File::k_nameSize, body, strlen(body)+1);
|
||||
char * nextPointer = currentPointer + fileSize;
|
||||
*((size_t *)nextPointer) = 0;
|
||||
return File(sizeAddressOfFileStarting(currentPointer), nameOfFileStarting(currentPointer), type, bodyOfFileStarting(currentPointer));
|
||||
}
|
||||
|
||||
char * FileSystem::lastUsedData() {
|
||||
size_t usedSize = 0;
|
||||
char * currentPointer = m_data;
|
||||
size_t size = sizeOfFileStarting(currentPointer);
|
||||
while (size != 0 && currentPointer < m_data + k_totalSize) {
|
||||
usedSize += size;
|
||||
currentPointer += size;
|
||||
size = sizeOfFileStarting(currentPointer);
|
||||
}
|
||||
return currentPointer + File::k_sizeSize;
|
||||
}
|
||||
|
||||
|
||||
size_t FileSystem::availableSize() {
|
||||
return k_totalSize-(lastUsedData()-m_data);
|
||||
}
|
||||
|
||||
bool FileSystem::isNameTaken(const char * name, File::Type type) {
|
||||
char * currentPointer = m_data;
|
||||
size_t size = sizeOfFileStarting(currentPointer);
|
||||
while (size != 0 && currentPointer < m_data + k_totalSize) {
|
||||
if (typeOfFileStarting(currentPointer) == type && strcmp(nameOfFileStarting(currentPointer), name) == 0) {
|
||||
return true;
|
||||
}
|
||||
currentPointer += size;
|
||||
size = sizeOfFileStarting(currentPointer);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FileSystem::moveNextFile(char * start, int delta) {
|
||||
if (delta > (int)availableSize()) {
|
||||
return false;
|
||||
}
|
||||
char * nextFile = start + sizeOfFileStarting(start);
|
||||
memmove(nextFile+delta, nextFile, lastUsedData()-nextFile);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t * FileSystem::sizeAddressOfFileStarting(char * start) const {
|
||||
return (size_t *)start;
|
||||
}
|
||||
|
||||
size_t FileSystem::sizeOfFileStarting(char * start) const {
|
||||
if (start >= m_data + k_totalSize) {
|
||||
return 0;
|
||||
}
|
||||
return *(sizeAddressOfFileStarting(start));
|
||||
}
|
||||
|
||||
File::Type FileSystem::typeOfFileStarting(char * start) const {
|
||||
return (File::Type)*((uint8_t *)start+File::k_sizeSize);
|
||||
}
|
||||
|
||||
char * FileSystem::nameOfFileStarting(char * start) {
|
||||
return start+File::k_sizeSize+File::k_typeSize;
|
||||
}
|
||||
|
||||
char * FileSystem::bodyOfFileStarting(char * start) {
|
||||
return start+File::k_sizeSize+File::k_typeSize+File::k_nameSize;
|
||||
}
|
||||
|
||||
size_t FileSystem::sizeOfFileWithBody(const char * body) const {
|
||||
return File::k_sizeSize+File::k_typeSize+File::k_nameSize+strlen(body)+1;
|
||||
}
|
||||
161
escher/src/kallax.cpp
Normal file
161
escher/src/kallax.cpp
Normal file
@@ -0,0 +1,161 @@
|
||||
#include <escher/kallax.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef HEADER_SECTION
|
||||
#define HEADER_SECTION
|
||||
#endif
|
||||
|
||||
#ifndef FORCE_LINK
|
||||
#define FORCE_LINK
|
||||
#endif
|
||||
|
||||
Kallax f;
|
||||
constexpr KallaxInfo HEADER_SECTION FORCE_LINK kallax_infos((uint32_t)(&f));
|
||||
|
||||
Kallax::Kallax() :
|
||||
m_dataHeader(Magic),
|
||||
m_data(),
|
||||
m_dataFooter(Magic)
|
||||
{
|
||||
size_t * p = (size_t *)m_data;
|
||||
p[0] = 0;
|
||||
}
|
||||
|
||||
Kallax * Kallax::sharedKallax() {
|
||||
return &f;
|
||||
}
|
||||
|
||||
int Kallax::numberOfRecordOfType(Record::Type type) {
|
||||
assert(m_dataHeader == Magic);
|
||||
assert(m_dataFooter == Magic);
|
||||
int count = 0;
|
||||
char * currentPointer = m_data;
|
||||
size_t size = sizeOfRecordStarting(currentPointer);
|
||||
while (size != 0 && currentPointer < m_data + k_totalSize) {
|
||||
if (typeOfRecordStarting(currentPointer) == type) {
|
||||
count++;
|
||||
}
|
||||
currentPointer += size;
|
||||
size = sizeOfRecordStarting(currentPointer);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
Record Kallax::recordOfTypeAtIndex(Record::Type type, int index) {
|
||||
int currentIndex = -1;
|
||||
char * currentPointer = m_data;
|
||||
size_t size = sizeOfRecordStarting(currentPointer);
|
||||
while (size != 0 && currentPointer < m_data + k_totalSize) {
|
||||
if (typeOfRecordStarting(currentPointer) == type) {
|
||||
currentIndex++;
|
||||
if (currentIndex == index) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
currentPointer += size;
|
||||
size = sizeOfRecordStarting(currentPointer);
|
||||
}
|
||||
return Record(sizeAddressOfRecordStarting(currentPointer), nameOfRecordStarting(currentPointer), type, bodyOfRecordStarting(currentPointer));
|
||||
}
|
||||
|
||||
Record Kallax::getRecord(Record::Type type, const char * name) {
|
||||
for (int i = 0; i < numberOfRecordOfType(type); i++) {
|
||||
Record currentRecord = recordOfTypeAtIndex(type, i);
|
||||
if (strcmp(currentRecord.name(), name) == 0) {
|
||||
return currentRecord;
|
||||
}
|
||||
}
|
||||
return Record();
|
||||
}
|
||||
|
||||
Record Kallax::addRecord(const char * name, Record::Type type, const char * body) {
|
||||
// assert name is short enough and there is enough space to add the record
|
||||
assert(strlen(name) < Record::k_nameSize);
|
||||
assert(availableSize() >= sizeOfRecordWithBody(body));
|
||||
// Find the end of data
|
||||
char * currentPointer = m_data;
|
||||
size_t size = sizeOfRecordStarting(currentPointer);
|
||||
while (size != 0 && currentPointer < m_data + k_totalSize) {
|
||||
currentPointer += size;
|
||||
size = sizeOfRecordStarting(currentPointer);
|
||||
}
|
||||
size_t recordSize = sizeOfRecordWithBody(body);
|
||||
// Fill totalSize
|
||||
*((size_t *)currentPointer) = recordSize;
|
||||
// Fill type
|
||||
*(currentPointer+Record::k_sizeSize) = (uint8_t)type;
|
||||
// Fill name
|
||||
strlcpy(currentPointer+Record::k_sizeSize+Record::k_typeSize, name, Record::k_nameSize);
|
||||
// Fill body
|
||||
strlcpy(currentPointer+Record::k_sizeSize+Record::k_typeSize+Record::k_nameSize, body, strlen(body)+1);
|
||||
char * nextPointer = currentPointer + recordSize;
|
||||
*((size_t *)nextPointer) = 0;
|
||||
return Record(sizeAddressOfRecordStarting(currentPointer), nameOfRecordStarting(currentPointer), type, bodyOfRecordStarting(currentPointer));
|
||||
}
|
||||
|
||||
char * Kallax::lastUsedData() {
|
||||
size_t usedSize = 0;
|
||||
char * currentPointer = m_data;
|
||||
size_t size = sizeOfRecordStarting(currentPointer);
|
||||
while (size != 0 && currentPointer < m_data + k_totalSize) {
|
||||
usedSize += size;
|
||||
currentPointer += size;
|
||||
size = sizeOfRecordStarting(currentPointer);
|
||||
}
|
||||
return currentPointer + Record::k_sizeSize;
|
||||
}
|
||||
|
||||
|
||||
size_t Kallax::availableSize() {
|
||||
return k_totalSize-(lastUsedData()-m_data);
|
||||
}
|
||||
|
||||
bool Kallax::isNameTaken(const char * name, Record::Type type) {
|
||||
char * currentPointer = m_data;
|
||||
size_t size = sizeOfRecordStarting(currentPointer);
|
||||
while (size != 0 && currentPointer < m_data + k_totalSize) {
|
||||
if (typeOfRecordStarting(currentPointer) == type && strcmp(nameOfRecordStarting(currentPointer), name) == 0) {
|
||||
return true;
|
||||
}
|
||||
currentPointer += size;
|
||||
size = sizeOfRecordStarting(currentPointer);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Kallax::moveNextRecord(char * start, int delta) {
|
||||
if (delta > (int)availableSize()) {
|
||||
return false;
|
||||
}
|
||||
char * nextRecord = start + sizeOfRecordStarting(start);
|
||||
memmove(nextRecord+delta, nextRecord, lastUsedData()-nextRecord);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t * Kallax::sizeAddressOfRecordStarting(char * start) const {
|
||||
return (size_t *)start;
|
||||
}
|
||||
|
||||
size_t Kallax::sizeOfRecordStarting(char * start) const {
|
||||
if (start >= m_data + k_totalSize) {
|
||||
return 0;
|
||||
}
|
||||
return *(sizeAddressOfRecordStarting(start));
|
||||
}
|
||||
|
||||
Record::Type Kallax::typeOfRecordStarting(char * start) const {
|
||||
return (Record::Type)*((uint8_t *)start+Record::k_sizeSize);
|
||||
}
|
||||
|
||||
char * Kallax::nameOfRecordStarting(char * start) {
|
||||
return start+Record::k_sizeSize+Record::k_typeSize;
|
||||
}
|
||||
|
||||
char * Kallax::bodyOfRecordStarting(char * start) {
|
||||
return start+Record::k_sizeSize+Record::k_typeSize+Record::k_nameSize;
|
||||
}
|
||||
|
||||
size_t Kallax::sizeOfRecordWithBody(const char * body) const {
|
||||
return Record::k_sizeSize+Record::k_typeSize+Record::k_nameSize+strlen(body)+1;
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
#include <escher/file.h>
|
||||
#include <escher/file_system.h>
|
||||
#include <escher/record.h>
|
||||
#include <escher/kallax.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
File::File(size_t * size, char * name, Type type, char * body) :
|
||||
Record::Record(size_t * size, char * name, Type type, char * body) :
|
||||
m_body(body),
|
||||
m_size(size),
|
||||
m_name(name),
|
||||
@@ -11,7 +11,7 @@ File::File(size_t * size, char * name, Type type, char * body) :
|
||||
{
|
||||
}
|
||||
|
||||
bool File::isNull() const {
|
||||
bool Record::isNull() const {
|
||||
if (m_type == Type::Null) {
|
||||
assert(m_size == nullptr);
|
||||
return true;
|
||||
@@ -20,12 +20,12 @@ bool File::isNull() const {
|
||||
}
|
||||
|
||||
|
||||
const char * File::name() const {
|
||||
const char * Record::name() const {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
File::ErrorStatus File::rename(const char * newName) {
|
||||
if (FileSystem::sharedFileSystem()->isNameTaken(newName, m_type)) {
|
||||
Record::ErrorStatus Record::rename(const char * newName) {
|
||||
if (Kallax::sharedKallax()->isNameTaken(newName, m_type)) {
|
||||
return ErrorStatus::NameTaken;
|
||||
}
|
||||
if (strlen(newName) >= k_nameSize) {
|
||||
@@ -35,14 +35,14 @@ File::ErrorStatus File::rename(const char * newName) {
|
||||
return ErrorStatus::None;
|
||||
}
|
||||
|
||||
const char * File::read() const {
|
||||
const char * Record::read() const {
|
||||
return m_body;
|
||||
}
|
||||
|
||||
File::ErrorStatus File::write(const char * data, size_t size) {
|
||||
Record::ErrorStatus Record::write(const char * data, size_t size) {
|
||||
int deltaSize = (int)size - (int)bodySize();
|
||||
// TODO: if this fails because deltaSize is too big, return an error?
|
||||
if (FileSystem::sharedFileSystem()->moveNextFile(start(), deltaSize)) {
|
||||
if (Kallax::sharedKallax()->moveNextRecord(start(), deltaSize)) {
|
||||
*m_size += deltaSize;
|
||||
strlcpy(m_body, data, size);
|
||||
return ErrorStatus::None;
|
||||
@@ -50,18 +50,18 @@ File::ErrorStatus File::write(const char * data, size_t size) {
|
||||
return ErrorStatus::NoEnoughSpaceAvailable;
|
||||
}
|
||||
|
||||
File::Type File::type() {
|
||||
Record::Type Record::type() {
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void File::remove() {
|
||||
FileSystem::sharedFileSystem()->moveNextFile(start(), -*(m_size));
|
||||
void Record::remove() {
|
||||
Kallax::sharedKallax()->moveNextRecord(start(), -*(m_size));
|
||||
}
|
||||
|
||||
char * File::start() {
|
||||
char * Record::start() {
|
||||
return m_name - k_typeSize - k_sizeSize;
|
||||
}
|
||||
|
||||
size_t File::bodySize() const {
|
||||
size_t Record::bodySize() const {
|
||||
return *m_size - k_nameSize - k_typeSize - k_sizeSize;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
include ion/src/device/boot/Makefile
|
||||
include ion/src/device/bench/Makefile
|
||||
|
||||
escher/src/file_system.o: SFLAGS += -DHEADER_SECTION="__attribute__((section(\".header\")))" -DFORCE_LINK="__attribute__((used))"
|
||||
escher/src/kallax.o: SFLAGS += -DHEADER_SECTION="__attribute__((section(\".header\")))" -DFORCE_LINK="__attribute__((used))"
|
||||
|
||||
ion/src/shared/software_version.o: SFLAGS += -DHEADER_SECTION="__attribute__((section(\".header\")))"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user