Start of 'fileheader' implementation

Lumiera will create and use some files on its own (caches, indices). This
lies the foundation for identifying this files.
This commit is contained in:
Christian Thaeter 2010-03-10 17:53:51 +01:00
parent 51e5b8a90c
commit c908cf4807
7 changed files with 322 additions and 1 deletions

View file

@ -30,6 +30,7 @@ liblumierabackend_la_SOURCES = \
$(liblumierabackend_la_srcdir)/filedescriptorregistry.c \
$(liblumierabackend_la_srcdir)/filehandle.c \
$(liblumierabackend_la_srcdir)/filehandlecache.c \
$(liblumierabackend_la_srcdir)/fileheader.c \
$(liblumierabackend_la_srcdir)/mediaaccessfacade.cpp \
$(liblumierabackend_la_srcdir)/mmap.c \
$(liblumierabackend_la_srcdir)/mmapcache.c \
@ -49,10 +50,12 @@ noinst_HEADERS += \
$(liblumierabackend_la_srcdir)/filedescriptorregistry.h \
$(liblumierabackend_la_srcdir)/filehandle.h \
$(liblumierabackend_la_srcdir)/filehandlecache.h \
$(liblumierabackend_la_srcdir)/fileheader.h \
$(liblumierabackend_la_srcdir)/mmap.h \
$(liblumierabackend_la_srcdir)/mmapcache.h \
$(liblumierabackend_la_srcdir)/mmapings.h \
$(liblumierabackend_la_srcdir)/resourcecollector.h \
$(liblumierabackend_la_srcdir)/resourcecollector.h \
$(liblumierabackend_la_srcdir)/threadpool.h \
$(liblumierabackend_la_srcdir)/threads.h

View file

@ -166,7 +166,6 @@ lumiera_fileheader_version (LumieraFileheader self)
/**
* check if all flags given from some sets are either set or not.
*/

156
src/backend/fileheader.h Normal file
View file

@ -0,0 +1,156 @@
/*
fileheader.h - Definitions of generic lumiera fileheaders and identification
Copyright (C) Lumiera.org
2010, Christian Thaeter <ct@pipapo.org>
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 2 of the
License, 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.
*/
#ifndef LUMIERA_FILEHEADER_H
#define LUMIERA_FILEHEADER_H
#include "lib/error.h"
LUMIERA_ERROR_DECLARE (FILEHEADER_NOWRITE);
LUMIERA_ERROR_DECLARE (FILEHEADER_HEADER);
typedef struct lumiera_fileheader_struct lumiera_fileheader;
typedef lumiera_fileheader* LumieraFileheader;
typedef struct lumiera_fileheader_raw_struct lumiera_fileheader_raw;
typedef lumiera_fileheader_raw* LumieraFileheaderRaw;
typedef struct lumiera_fileheaderext_struct lumiera_fileheaderext;
typedef lumiera_fileheaderext* LumieraFileheaderext;
typedef struct lumiera_fileheaderext_raw_struct lumiera_fileheaderext_raw;
typedef lumiera_fileheaderext_raw* LumieraFileheaderextRaw;
#include "backend/file.h"
#include <nobug.h>
#include <semaphore.h>
/**
* @file
*
* Lumiera creates some files on itself, caches, indexes and so on.
* Here we define a unified header format for identifying and handling these files.
*
* Most of this files store binary data in host order for performance reasons an are not yet
* intended to be transfered between computers. While the transferability depends on the
* concrete implementation later and is not contstrained here.
*
*/
#ifndef LUMIERA_PACKED
#define LUMIERA_PACKED __attribute__((__packed__))
#endif
/**
* A basic fileheader
* On-Disk representation starts with 32 bytes identifying the file.
* The first 32 bytes are human readable text.
*/
struct LUMIERA_PACKED lumiera_fileheader_raw_struct
{
/** four character codes identifying this file type */
char fourcc[4];
/** decimal digits, right bound space filled, denoting the file version, 0 is reserved for experimental things */
char version[3];
/** always '\n' */
char newline1;
/** freeform string, comment or so on, initialized to spaces */
char meta[22];
/** always '\n' */
char newline2;
/** always '\0' */
char null;
};
/**
* A fileheader object encapsulates the underlying mmap object which keeps the
* raw header data in memory and and the dereferenced thereof.
*/
struct lumiera_fileheader_struct
{
LumieraFileheaderRaw header;
LumieraMMap map;
};
/**
* Create a fileheader on a file open for writing.
* This overwrites any existing date, take care. The created fileheader is mmaped into memory
* and must be closed after use. The File should be locked for operations on the fileheader.
* @param file The file on which to create the header.
* @param fourcc pointer to a string of length 4
* @param version version number for the header (should be incremented after changes)
* the value '0' is reserved for experimental versions.
* @param size The actual size of all header data, including following format specific data.
* @return A lumiera_fileheader object by value, .header and .map are set to NULL on error.
*/
lumiera_fileheader
lumiera_fileheader_create (LumieraFile file, char* fourcc, int version, size_t size);
/**
* Open an existing fileheader.
* The underlying file might be readonly. The opened fileheader is mmaped into memory
* and must be closed after use. The File should be locked for operations on the fileheader.
* @param file The file on which to open the header.
* @param fourcc pointer to a string of length 4 with the expected identifier for the file
* @param size The actual size of all header data, including following format specific data.
* @return A lumiera_fileheader object by value, .header and .map are set to NULL on error.
*/
lumiera_fileheader
lumiera_fileheader_open (LumieraFile file, char* fourcc, size_t size);
/**
* Closes a previously created or opened fileheader.
* @param self the fileheader to close.
* no errors, no nothing returned
*/
void
lumiera_fileheader_close (LumieraFileheader self);
/**
* Queries the version of a fileheader.
* @param self the fileheader to query
* @return the version stored in the fileheader or -1 on error.
*/
int
lumiera_fileheader_version (LumieraFileheader self);
#endif
/*
// Local Variables:
// mode: C
// c-file-style: "gnu"
// indent-tabs-mode: nil
// End:
*/

View file

@ -85,6 +85,7 @@ NOBUG_CPP_DEFINE_FLAG_PARENT ( mmapings_dbg, backend_dbg);
NOBUG_CPP_DEFINE_FLAG_PARENT ( thread_dbg, backend_dbg);
NOBUG_CPP_DEFINE_FLAG_PARENT ( threads_dbg, thread_dbg);
NOBUG_CPP_DEFINE_FLAG_PARENT ( threadpool_dbg, thread_dbg);
NOBUG_CPP_DEFINE_FLAG_PARENT ( fileheader_dbg, backend_dbg);
/** base of debug logging for the proc layer */
NOBUG_CPP_DEFINE_FLAG_PARENT ( proc_dbg, debugging);
@ -124,6 +125,7 @@ NOBUG_CPP_DEFINE_FLAG_PARENT ( mmap, backend);
NOBUG_CPP_DEFINE_FLAG_PARENT ( thread, backend); //starting/stopping threads
NOBUG_CPP_DEFINE_FLAG_PARENT ( threads, thread);
NOBUG_CPP_DEFINE_FLAG_PARENT ( threadpool, thread);
NOBUG_CPP_DEFINE_FLAG_PARENT ( fileheader, backend);
/** progress log for the proc layer */
NOBUG_CPP_DEFINE_FLAG_PARENT ( proc, progress);
/** progress log for proc-layer command dispatch */

31
tests/31fileheader.tests Normal file
View file

@ -0,0 +1,31 @@
TESTING "fileheader access" ./test-fileheader
TEST "fileheader, basic creation" create_basic <<END
err: ECHO: .*: fileheader: TEST 0
err: ECHO: .*: .* $
err: ECHO: .*: :
END
TEST "fileheader, create on readlonly fails" create_nowrite <<END
return: 0
END
TEST "fileheader, fourcc mismatch" acquire_wrongheader <<END
return: 0
END
TEST "fileheader, reopen" acquire_basic <<END
err: ECHO: .*: fileheader: TEST 0
err: ECHO: .*: .* $
err: ECHO: .*: :
END
#TEST "fileheader, " <<END
#END
rm ,tmp-fileheader 2>/dev/null

View file

@ -76,6 +76,13 @@ test_filemmap_LDADD = $(LUMIERA_LIBS) liblumierabackend.la liblumieracommon.la l
#test_resourcecollector_SOURCES = $(tests_srcdir)/backend/test-resourcecollector.c
#test_resourcecollector_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/
#test_resourcecollector_LDADD = $(LUMIERA_LIBS) liblumiera.la liblumierabackend.la liblumieraproc.la liblumieracommon.la
check_PROGRAMS += test-fileheader
test_fileheader_SOURCES = $(tests_srcdir)/backend/test-fileheader.c
test_fileheader_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/
test_fileheader_LDADD = $(LUMIERA_LIBS) liblumierabackend.la liblumieracommon.la liblumieraproc.la
# FIXME stray dependencies on proc
# FIXME stray dependencies on proc
check_PROGRAMS += test-slist

View file

@ -0,0 +1,123 @@
/*
test-fileheader.c - File identification
Copyright (C) Lumiera.org
2010, Christian Thaeter <ct@pipapo.org>
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 2 of the
License, 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.
*/
#include "backend/backend.h"
#include "backend/fileheader.h"
#include "tests/test.h"
#include "backend/filehandlecache.h"
extern LumieraFilehandlecache lumiera_fhcache;
TESTS_BEGIN
TEST (create_basic)
{
lumiera_backend_init ();
LumieraFile file = lumiera_file_new (",tmp-fileheader", LUMIERA_FILE_RECREATE);
LUMIERA_FILE_WRLOCK_SECTION (NOBUG_ON, file)
{
lumiera_fileheader header = lumiera_fileheader_create (file, "TEST", 0, sizeof (lumiera_fileheader_raw));
CHECK (lumiera_error_peek() == NULL);
ECHO ("fileheader: %s:", (char*)header.header);
lumiera_fileheader_close (&header);
}
lumiera_file_delete (file);
lumiera_backend_destroy ();
}
TEST (create_nowrite)
{
lumiera_backend_init ();
LumieraFile file = lumiera_file_new (",tmp-fileheader", LUMIERA_FILE_READONLY);
REQUIRE(file);
LUMIERA_FILE_RDLOCK_SECTION (NOBUG_ON, file)
{
lumiera_fileheader header = lumiera_fileheader_create (file, "TEST", 0, sizeof (lumiera_fileheader));
CHECK(lumiera_error() == LUMIERA_ERROR_FILEHEADER_NOWRITE);
lumiera_fileheader_close (&header);
}
lumiera_file_delete (file);
lumiera_backend_destroy ();
}
TEST (acquire_wrongheader)
{
lumiera_backend_init ();
LumieraFile file = lumiera_file_new (",tmp-fileheader", LUMIERA_FILE_READONLY);
LUMIERA_FILE_RDLOCK_SECTION (NOBUG_ON, file)
{
lumiera_fileheader header = lumiera_fileheader_open (file, "BADH", sizeof (lumiera_fileheader));
CHECK(!header.header);
CHECK(lumiera_error() == LUMIERA_ERROR_FILEHEADER_HEADER);
lumiera_fileheader_close (&header);
}
lumiera_file_delete (file);
lumiera_backend_destroy ();
}
TEST (acquire_basic)
{
lumiera_backend_init ();
LumieraFile file = lumiera_file_new (",tmp-fileheader", LUMIERA_FILE_READONLY);
LUMIERA_FILE_RDLOCK_SECTION (NOBUG_ON, file)
{
lumiera_fileheader header = lumiera_fileheader_open (file, "TEST", sizeof (lumiera_fileheader));
CHECK(header.header);
CHECK(!lumiera_error());
CHECK (lumiera_fileheader_version (&header) == 0);
ECHO ("fileheader: %s:", (char*)header.header);
lumiera_fileheader_close (&header);
}
lumiera_file_delete (file);
lumiera_backend_destroy ();
}
TESTS_END