Lumiera  0.pre.03
»edityourfreedom«
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
fileheader.c
Go to the documentation of this file.
1 /*
2  Fileheader - Definitions of generic lumiera file headers and identification
3 
4  Copyright (C) Lumiera.org
5  2010, Christian Thaeter <ct@pipapo.org>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
23 
31 #include "lib/tmpbuf.h"
32 
33 #include "backend/fileheader.h"
34 #include "backend/file.h"
35 #include "include/logging.h"
36 
37 #include <errno.h>
38 
39 
40 
41 
42 LUMIERA_ERROR_DEFINE (FILEHEADER_NOWRITE, "File is not writable");
43 LUMIERA_ERROR_DEFINE (FILEHEADER_HEADER, "Error in header");
44 LUMIERA_ERROR_DEFINE (FILEHEADER_FLAGS, "Inconsistent Flags");
45 LUMIERA_ERROR_DEFINE (FILEHEADER_FLAGSPACE, "No more space for flags left");
46 LUMIERA_ERROR_DEFINE (FILEHEADER_ENDIANESS, "Unsupported Endianess");
47 
48 
49 
50 lumiera_fileheader
51 lumiera_fileheader_create (LumieraFile file, char* fourcc, int version, size_t size, const char* flags)
52 {
53  lumiera_fileheader self = {NULL, NULL};
54 
55  REQUIRE (fourcc && strlen (fourcc) == 4, "fourcc must be of size 4 and nothing else: %s", fourcc);
56  REQUIRE_IF (flags, strlen (flags) <= sizeof(self.header->flags), "to much flags given");
57 
58  if (file)
59  {
60  if (lumiera_file_checkflags (file, O_RDWR))
61  {
62  WARN_IF (version == 0, fileheader, "Experimental version 0 given for file %s, %s", file->name, fourcc);
63 
64  if ((self.map = lumiera_mmap_new_exact (file, 0, size)))
65  {
66  self.header = lumiera_mmap_address (self.map, 0);
67 
68  memcpy (self.header->fourcc, fourcc, 4);
69  snprintf (self.header->version, 4, "%3u", version);
70  self.header->newline1 = '\n';
71  for (size_t i = 0; i < sizeof(self.header->meta); ++i)
72  self.header->meta[i] = ' ';
73  self.header->newline2 = '\n';
74  for (size_t i = 0; i < sizeof(self.header->flags); ++i)
75  self.header->flags[i] = ' ';
76  self.header->newline3 = '\n';
77  self.header->null = '\0';
78  self.header->endianess_mark = LUMIERA_FILEHEADER_ENDIANMAGIC;
79 
80  lumiera_fileheader_flags_set (&self, flags);
81  }
82  }
83  else
84  LUMIERA_ERROR_SET_CRITICAL(fileheader, FILEHEADER_NOWRITE, file->name);
85  }
86 
87  return self;
88 }
89 
90 
91 lumiera_fileheader
92 lumiera_fileheader_open (LumieraFile file, char* fourcc, size_t size, const char* flags_expected, const char* flags_remove)
93 {
94  lumiera_fileheader self = {NULL, NULL};
95 
96  REQUIRE (fourcc && strlen (fourcc) == 4, "fourcc must be of size 4 and nothing else: %s", fourcc);
97 
98  if (file)
99  {
100  if ((self.map = lumiera_mmap_new_exact (file, 0, size)))
101  {
102  self.header = lumiera_mmap_address (self.map, 0);
103 
104  if (memcmp (self.header->fourcc, fourcc, 4))
105  {
106  LUMIERA_ERROR_SET_WARNING (fileheader, FILEHEADER_HEADER, file->name);
107  goto err;
108  }
109 
110  if (!lumiera_fileheader_flags_validate (&self, flags_expected, NULL))
111  {
112  LUMIERA_ERROR_SET_WARNING (fileheader, FILEHEADER_FLAGS, self.header->flags);
113  goto err;
114  }
115 
117  lumiera_fileheader_flags_clear (&self, flags_remove);
118 
119  static uint64_t endianess_mark = LUMIERA_FILEHEADER_ENDIANMAGIC;
120 
122  memcmp (&self.header->endianess_mark, (char*)&endianess_mark, sizeof (endianess_mark)))
123  {
124  LUMIERA_ERROR_SET_CRITICAL (fileheader, FILEHEADER_ENDIANESS, NULL);
125  goto err;
126  }
127  }
128  }
129 
130  return self;
131 
132  err:
133  lumiera_mmap_delete (self.map);
134  self.map = NULL;
135  self.header = NULL;
136  return self;
137 }
138 
139 
140 void
141 lumiera_fileheader_close (LumieraFileheader self, const char* flags_add)
142 {
143  if (self && self->header)
144  {
145  lumiera_fileheader_flags_set (self, flags_add);
146  self->header = NULL;
147  lumiera_mmap_delete (self->map);
148  }
149 }
150 
151 
152 int
154 {
155  int ret = -1;
156  if (self && self->header)
157  {
158  errno = 0;
159  ret = (int) strtol(self->header->version, NULL, 10);
160  if (errno)
161  {
162  ret = -1;
163  LUMIERA_ERROR_SET_WARNING (fileheader, FILEHEADER_HEADER, lumiera_tmpbuf_snprintf (32, "%s", self->header->fourcc));
164  }
165  }
166  return ret;
167 }
168 
169 
170 
171 
175 int
176 lumiera_fileheader_flags_validate (LumieraFileheader self, const char* expected, const char* unexpected)
177 {
178  for (; expected && *expected; ++expected)
179  if (!strchr (self->header->flags, *expected))
180  return 0;
181 
182  for (; unexpected && *unexpected; ++unexpected)
183  if (strchr (self->header->flags, *unexpected))
184  return 0;
185 
186  return 1;
187 }
188 
189 
195 {
196  for (; flags && *flags; ++flags)
197  if (!strchr(self->header->flags, *flags))
198  {
199  char* pos = strchr (self->header->flags, ' ');
200  if (!pos)
201  {
202  LUMIERA_ERROR_SET_CRITICAL (fileheader, FILEHEADER_FLAGSPACE, flags);
203  return NULL;
204  }
205  *pos = *flags;
206  }
207 
208  return self;
209 }
210 
211 
217 {
218  char* pos;
219 
220  for (; flags && *flags; ++flags)
221  if ((pos = strchr (self->header->flags, *flags)))
222  *pos = ' ';
223 
224  return self;
225 }
226 
227 
228 
229 /*
230 // Local Variables:
231 // mode: C
232 // c-file-style: "gnu"
233 // indent-tabs-mode: nil
234 // End:
235 */
int lumiera_fileheader_flags_validate(LumieraFileheader self, const char *expected, const char *unexpected)
check if all flags given from some sets are either set or not.
Definition: fileheader.c:176
#define LUMIERA_ERROR_SET_WARNING(flag, err, extra)
Helper macro to raise an error for the current thread.
Definition: error.h:136
lumiera_fileheader lumiera_fileheader_open(LumieraFile file, char *fourcc, size_t size, const char *flags_expected, const char *flags_remove)
Open an existing file header.
Definition: fileheader.c:92
lumiera_file * LumieraFile
Definition: file.h:49
void lumiera_fileheader_close(LumieraFileheader self, const char *flags_add)
Closes a previously created or opened file header.
Definition: fileheader.c:141
LumieraMMap lumiera_mmap_new_exact(LumieraFile file, off_t start, size_t size)
Definition: mmap.c:297
File management.
This header is for including and configuring NoBug.
LumieraFileheader lumiera_fileheader_flags_clear(LumieraFileheader self, const char *flags)
Clear flags if present.
Definition: fileheader.c:216
Round robin temporary buffers.
for(int kind=0;kind< LUMIERA_THREADCLASS_COUNT;++kind)
int lumiera_file_checkflags(LumieraFile self, int flags)
Query the flags effective for a file.
LUMIERA_ERROR_DEFINE(FILEHEADER_NOWRITE,"File is not writable")
#define LUMIERA_FILEHEADER_ENDIANMAGIC
Definition: fileheader.h:48
return NULL
Definition: llist.h:596
#define LUMIERA_ERROR_SET_CRITICAL(flag, err, extra)
Helper macro to raise an error for the current thread.
Definition: error.h:121
int lumiera_fileheader_version(LumieraFileheader self)
Queries the version of a file header.
Definition: fileheader.c:153
#define LUMIERA_FILEHEADER_FLAG_ENDIANESS
check for host order endianess
Definition: fileheader.h:108
LumieraFileheader lumiera_fileheader_flags_set(LumieraFileheader self, const char *flags)
Sets flags if not already set.
Definition: fileheader.c:194
Common header format to identify various kinds of files.
lumiera_fileheader * LumieraFileheader
Definition: fileheader.h:51
lumiera_fileheader lumiera_fileheader_create(LumieraFile file, char *fourcc, int version, size_t size, const char *flags)
Create a file header on a file open for writing.
Definition: fileheader.c:51
void lumiera_mmap_delete(LumieraMMap self)
Definition: mmap.c:314
static void * lumiera_mmap_address(LumieraMMap self, off_t offset)
Translate a 'external' offset to a address in memory.
Definition: mmap.h:113
char * lumiera_tmpbuf_snprintf(size_t size, const char *fmt,...)
Construct a string in a tmpbuf.
Definition: tmpbuf.c:125