MHEG5  18.9.0
MHEG5 Documentation
mh5nvm.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2012 Ocean Blue Software Ltd
4  *
5  * This file is part of a DTVKit Software Component
6  * You are permitted to copy, modify or distribute this file subject to the terms
7  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
8  *
9  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
10  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
11  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * If you or your organisation is not a member of DTVKit then you have access
14  * to this source code outside of the terms of the licence agreement
15  * and you are expected to delete this and any associated files immediately.
16  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
17  *******************************************************************************/
25 /*---includes for this file--------------------------------------------------*/
26 #include "mh5memory.h"
27 #include "mh5debug.h"
28 #include "mh5profile.h"
29 #include "mh5nvm.h"
30 #include "mheg5_nvm.h"
31 #include "stb_nvm.h"
32 
33 /*---constant definitions for this file--------------------------------------*/
34 #define MAX_NAME_LENGTH 8
35 
36 #define NVM_STORE_FILENAME "NVMFILELIST.dat"
37 
38 
39 /*---local typedef structs for this file-------------------------------------*/
40 
41 typedef struct sNvmFile
42 {
44  struct sNvmFile *next;
45  struct sNvmFile *previous;
48 } MHEG5NvmFile;
49 
50 
51 /*---local (static) variable declarations for this file----------------------*/
52 
53 static MHEG5NvmFile *file_list_oldest = NULL;
54 static MHEG5NvmFile *file_list_newest = NULL;
55 static U32BIT total_filesize = 0;
56 static U32BIT nvm_store_size = 0;
57 static MHEG5Bool init = MHEG5FALSE;
58 
59 /*---local function definitions----------------------------------------------*/
60 
61 /*---global function definitions---------------------------------------------*/
62 static void CreateFileList(U8BIT *encoded_list, U32BIT list_len);
63 static MHEG5Boolean WriteChanges();
64 static void DeleteNvmFile(MHEG5NvmFile *file);
65 
66 
72 void MHEG5nvmInitialise( U32BIT nvmSize )
73 {
74  U32BIT size;
75  U8BIT *buffer;
76  void *file;
77 
78  if(init)
79  {
80  MHEG5nvmReset();
81  }
82 
83  nvm_store_size = nvmSize;
84  if (STB_NVMFileSize( (U8BIT *) NVM_STORE_FILENAME, &size ))
85  {
87  if (file != NULL)
88  {
89  buffer = STB_MemAlloc(size);
90  if (STB_NVMReadFile(file, buffer, size) == size)
91  {
92  CreateFileList(buffer, size);
93  }
94  STB_MemFree(buffer);
95  STB_NVMCloseFile( file );
96  }
97  }
98  init = MHEG5TRUE;
99 }
100 
110 {
111  MHEG5NvmFile *file = file_list_newest;
112  MHEG5Bool success = MHEG5FALSE;
113  void *fp;
114 
115  INFO_PRINT(("BEGIN: MHEG5nvmRead - File [%.*s].\n", fn.len, fn.data));
116  if (buf == 0 || len == 0)
117  {
118  DEBUG_PRINT(("ERROR: MHEG5nvmRead - Bad data variable pointer passed.\n"));
119  }
120 #ifdef INVALIDATE_LONG_NAME
121  else if (fn.len > MAX_NAME_LENGTH)
122  {
123  TRACE(TERROR, ("filename [%.*s] is too long %d ", fn.len, fn.data, fn.len))
124  }
125 #endif
126  else
127  {
128 #ifndef INVALIDATE_LONG_NAME
129  if (fn.len > MAX_NAME_LENGTH)
130  {
131  TRACE(TERROR, ("filename too long %d - clipping to \"%.*s\"", fn.len, MAX_NAME_LENGTH, fn.data))
132  fn.len = MAX_NAME_LENGTH;
133  }
134 #endif
135 
136 
137  while (file)
138  {
139  if (file->name_length == fn.len &&
140  memcmp(file->name, fn.data, fn.len) == 0)
141  {
142  *len = file->file_size;
143  *buf = STB_MemAlloc(file->file_size);
144 
146  if (fp)
147  {
148  STB_NVMReadFile( fp, *buf, *len );
149  STB_NVMCloseFile(fp);
150  success = MHEG5TRUE;
151  }
152  INFO_PRINT(("SUCCESS: MHEG5nvmRead - Found file [%.*s] in list.\n", fn.len, fn.data));
153 
154  break;
155  }
156  file = file->previous;
157  }
158  }
159  INFO_PRINT(("WARNING: MHEG5nvmRead - Unable to find file [%.*s] in list.\n", fn.len, fn.data));
160  return success;
161 }
162 
172 {
173  MHEG5NvmFile *file = file_list_oldest;
174  MHEG5NvmFile *new_file;
175  MHEG5Bool success;
176  U32BIT size = (U32BIT)len;
177  void *fp;
178  /* Check that input file not bigger than the total nvm space. */
179  if (size > nvm_store_size)
180  {
181  TRACE(TERROR, ("File [%.*s] too big [0x%x]", fn.len, fn.data, size));
182  success = MHEG5FALSE;
183  }
184  #ifdef INVALIDATE_LONG_NAME
185  else if (fn.len > MAX_NAME_LENGTH)
186  {
187  TRACE(TERROR, ("filename [%.*s] is too long %d ", fn.len, fn.data, fn.len))
188  success = MHEG5FALSE;
189  }
190  #endif
191  else
192  {
193  #ifndef INVALIDATE_LONG_NAME
194  if (fn.len > MAX_NAME_LENGTH)
195  {
196  TRACE(TERROR, ("filename too long %d - clipping to \"%.*s\"", fn.len, MAX_NAME_LENGTH, fn.data))
197  fn.len = MAX_NAME_LENGTH;
198  }
199  #endif
200 
201  INFO_PRINT(("BEGIN: MHEG5nvmWrite - File [%.*s], Length [0x%x].\n", fn.len, fn.data, size));
202 
203  /* Find duplicate file names, and remove. */
204 
205  while (file)
206  {
207  if (file->name_length == fn.len &&
208  memcmp(file->name, fn.data, fn.len) == 0)
209  {
210  MHEG5NvmFile *to_delete = file;
211  file = file->next;
212  INFO_PRINT(("WARNING: MHEG5nvmWrite - Found duplicate file name [%.*s] in list.\n", fn.len, fn.data));
213  /* Remove file from list. */
214  DeleteNvmFile(to_delete);
215  }
216  else
217  {
218  file = file->next;
219  }
220  }
221 
222  /* Check enough space in list for new file. */
223  while ((total_filesize + size > nvm_store_size)
224  && file_list_oldest != NULL
225  && total_filesize > 0)
226  {
227  INFO_PRINT(("WARNING: MHEG5nvmWrite - Not enough space in list, deleting files.\n"));
228  DeleteNvmFile(file_list_oldest);
229  }
230  new_file = STB_MemAlloc(sizeof(MHEG5NvmFile));
231  if (new_file == NULL)
232  {
233  success = MHEG5FALSE;
234  }
235  else
236  {
237  new_file->file_size = size;
238  new_file->name_length = (U8BIT)fn.len;
239  memcpy(new_file->name, fn.data, fn.len);
240  new_file->name[fn.len] = 0;
241  new_file->next = NULL;
242 
244  if (fp)
245  {
246  STB_NVMWriteFile(fp, buf, size);
247  STB_NVMCloseFile(fp);
248 
249  new_file->previous = file_list_newest;
250  if (file_list_newest)
251  {
252  file_list_newest->next = new_file;
253  }
254  file_list_newest = new_file;
255  if (!file_list_oldest)
256  {
257  file_list_oldest = new_file;
258  }
259  total_filesize += size;
260 
261  success = MHEG5TRUE;
262  }
263  else
264  {
265  STB_MemFree( new_file );
266  success = MHEG5FALSE;
267  }
268  }
269  /* Remove deleted files and add new file*/
270  WriteChanges();
271 
272  INFO_PRINT(("SUCCESS: MHEG5nvmWrite - File [%.*s] added to list.\n", fn.len, fn.data));
273  }
274  return success;
275 }
276 
277 static void DeleteNvmFile(MHEG5NvmFile *file)
278 {
279  if (file->previous)
280  {
281  file->previous->next = file->next;
282  }
283  else
284  {
285  file_list_oldest = file->next;
286  }
287  if (file->next)
288  {
289  file->next->previous = file->previous;
290  }
291  else
292  {
293  file_list_newest = file->previous;
294  }
295  STB_NVMDeleteFile(file->name);
296  total_filesize -= file->file_size;
297 
298  STB_MemFree(file);
299 }
300 
301 static void CreateFileList(U8BIT *encoded_list, U32BIT list_len)
302 {
303  U32BIT offset = 0;
304  U8BIT name_len;
306  MHEG5NvmFile *new_file;
307  while (offset < list_len)
308  {
309  name_len = encoded_list[offset];
310  offset++;
311 
312  file_size = encoded_list[offset];
313  offset++;
314  file_size += encoded_list[offset] << 8;
315  offset++;
316  file_size += encoded_list[offset] << 16;
317  offset++;
318  file_size += encoded_list[offset] << 24;
319  offset++;
320 
321  new_file = STB_MemAlloc(sizeof(MHEG5NvmFile));
322  if (new_file)
323  {
324  new_file->name_length = name_len;
325  new_file->file_size = file_size;
326 
327  total_filesize += file_size;
328 
329  memcpy(new_file->name, encoded_list + offset, name_len);
330  new_file->name[name_len] = '\0';
331  offset += name_len;
332 
333  new_file->next = NULL;
334  new_file->previous = file_list_newest;
335  if (file_list_newest)
336  {
337  file_list_newest->next = new_file;
338  }
339  if (!file_list_oldest)
340  {
341  file_list_oldest = new_file;
342  }
343  file_list_newest = new_file;
344  }
345  }
346 }
347 
348 static MHEG5Boolean WriteChanges(void)
349 {
350  MHEG5NvmFile *current_file = file_list_oldest;
351  void *file;
352  MHEG5Bool success = MHEG5FALSE;
354  if (file != NULL)
355  {
356  while (current_file)
357  {
358  U8BIT buffer[5];
359  buffer[0] = current_file->name_length;
360 
361  buffer[1] = current_file->file_size & 0xFF;
362  buffer[2] = (current_file->file_size >> 8) & 0xFF;
363  buffer[3] = (current_file->file_size >> 16) & 0xFF;
364  buffer[4] = (current_file->file_size >> 24) & 0xFF;
365  STB_NVMWriteFile(file, buffer, 5);
366  STB_NVMWriteFile(file, current_file->name, current_file->name_length);
367 
368  current_file = current_file->next;
369  }
370  success = MHEG5TRUE;
371  STB_NVMCloseFile( file );
372  }
373  return success;
374 }
375 
380 void MHEG5nvmReset(void)
381 {
382  MHEG5NvmFile *current_file = file_list_oldest;
383  MHEG5NvmFile *next_file;
384  while (current_file)
385  {
386  next_file = current_file->next;
387  STB_MemFree(current_file);
388  current_file = next_file;
389  }
390  file_list_oldest = NULL;
391  file_list_newest = NULL;
392  total_filesize = 0;
393  init = MHEG5FALSE;
394 
395 }
396 
#define MAX_NAME_LENGTH
Definition: mh5nvm.c:34
void * STB_NVMOpenFile(U8BIT *name, E_STB_DSK_FILE_MODE mode)
Opens an existing file or creates a new one.
#define NVM_STORE_FILENAME
Definition: mh5nvm.c:36
U8BIT name_length
Definition: mh5nvm.c:46
void MHEG5nvmInitialise(U32BIT nvmSize)
Initialise NVM Storage.
Definition: mh5nvm.c:72
#define INFO_PRINT(x)
Definition: mh5debug.h:69
void STB_MemFree(void *ptr)
Releases previously allocated memory.
struct sNvmFile * next
Definition: mh5nvm.c:44
void STB_NVMCloseFile(void *file)
Flushes and closes an open file.
U32BIT file_size
Definition: mh5nvm.c:43
BOOLEAN STB_NVMFileSize(U8BIT *filename, U32BIT *filesize)
Returns the size in KB of the given file.
uint8_t U8BIT
Definition: techtype.h:82
long MHEG5Int
Definition: mh5base.h:73
struct sNvmFile MHEG5NvmFile
struct sNvmFile * previous
Definition: mh5nvm.c:45
Persistent storage module. The engine provides a persistent storage for 1024 bytes of data...
void * STB_MemAlloc(U32BIT memSize)
Allocates the specified number of bytes.
This file defines the profile for the MHEG engine.
void MHEG5nvmReset(void)
Clear all NVM data from the persistent store.
Definition: mh5nvm.c:380
short MHEG5Bool
Definition: mh5base.h:71
MHEG5Bool MHEG5nvmRead(MHEG5String fn, void **buf, MHEG5Int *len)
Read a file from the nvm store.
Definition: mh5nvm.c:109
U32BIT STB_NVMReadFile(void *file, U8BIT *data, U32BIT size)
Reads data from an open file.
MHEG5Byte * data
Definition: mh5base.h:85
int len
Definition: mh5gate.c:57
#define MHEG5TRUE
Definition: mh5base.h:49
File System types.
Mheg5 logging and debug printing.
MHEG5Bool MHEG5Boolean
Definition: mh5base.h:145
redirection include
Definition: mg_png.c:52
U32BIT STB_NVMWriteFile(void *file, U8BIT *data, U32BIT size)
Writes data to an open file.
Non-Volatile Memory functions and file access for caching files during power cycles. All file/path names are relative to some implementation dependent root path for MHEG&#39;s NVM storage area. So a path of "" (i.e. zero length name), is the root directory of storage area.
MHEG5Int len
Definition: mh5base.h:84
MHEG5Bool MHEG5nvmWrite(MHEG5String fn, void *buf, MHEG5Int len)
Write a file to the nvm store.
Definition: mh5nvm.c:171
U8BIT name[MAX_NAME_LENGTH+1]
Definition: mh5nvm.c:47
#define MHEG5FALSE
Definition: mh5base.h:48
uint32_t U32BIT
Definition: techtype.h:86
BOOLEAN STB_NVMDeleteFile(U8BIT *filename)
Deletes the file.
#define DEBUG_PRINT(x)
Definition: mh5debug.h:70
#define TRACE(t, x)
Definition: glue_debug.h:118