2 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
4 * Copyright (C) 2002-2010 Aleph One Ltd.
5 * for Toby Churchill Ltd and Brightstar Engineering
7 * Created by Charles Manning <charles@aleph1.co.uk>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
15 * This simple implementation of a name-value store assumes a small number of values and fits
16 * into a small finite buffer.
18 * Each attribute is stored as a record:
19 * sizeof(int) bytes record size.
20 * strnlen+1 bytes name null terminated.
23 * total size stored in record size
25 * This code has not been tested with unicode yet.
29 #include "yaffs_nameval.h"
33 static int nval_find(const char *xb
, int xb_size
, const YCHAR
*name
,
39 memcpy(&size
,xb
,sizeof(int));
40 while(size
> 0 && (size
< xb_size
) && (pos
+ size
< xb_size
)){
41 if(yaffs_strncmp((YCHAR
*)(xb
+pos
+sizeof(int)),name
,size
) == 0){
47 if(pos
< xb_size
-sizeof(int))
48 memcpy(&size
,xb
+ pos
,sizeof(int));
57 static int nval_used(const char *xb
, int xb_size
)
62 memcpy(&size
,xb
+ pos
,sizeof(int));
63 while(size
> 0 && (size
< xb_size
) && (pos
+ size
< xb_size
)){
65 if(pos
< xb_size
-sizeof(int))
66 memcpy(&size
,xb
+ pos
,sizeof(int));
73 int nval_del(char *xb
, int xb_size
, const YCHAR
*name
)
75 int pos
= nval_find(xb
, xb_size
, name
, NULL
);
78 if(pos
>= 0 && pos
< xb_size
){
79 /* Find size, shift rest over this record, then zero out the rest of buffer */
80 memcpy(&size
,xb
+pos
,sizeof(int));
81 memcpy(xb
+ pos
, xb
+ pos
+ size
, xb_size
- (pos
+ size
));
82 memset(xb
+ (xb_size
- size
),0,size
);
88 int nval_set(char *xb
, int xb_size
, const YCHAR
*name
, const char *buf
, int bsize
, int flags
)
91 int namelen
= yaffs_strnlen(name
,xb_size
);
97 pos
= nval_find(xb
,xb_size
,name
, &size_exist
);
99 if(flags
& XATTR_CREATE
&& pos
>= 0)
101 if(flags
& XATTR_REPLACE
&& pos
< 0)
104 start
= nval_used(xb
,xb_size
);
105 space
= xb_size
- start
+ size_exist
;
107 reclen
= (sizeof(int) + namelen
+ 1 + bsize
);
113 nval_del(xb
,xb_size
,name
);
114 start
= nval_used(xb
, xb_size
);
119 memcpy(xb
+ pos
,&reclen
,sizeof(int));
121 yaffs_strncpy((YCHAR
*)(xb
+ pos
), name
, reclen
);
123 memcpy(xb
+ pos
,buf
,bsize
);
127 int nval_get(const char *xb
, int xb_size
, const YCHAR
*name
, char *buf
, int bsize
)
129 int pos
= nval_find(xb
,xb_size
,name
,NULL
);
132 if(pos
>= 0 && pos
< xb_size
){
134 memcpy(&size
,xb
+pos
,sizeof(int));
135 pos
+=sizeof(int); /* advance past record length */
138 /* Advance over name string */
139 while(xb
[pos
] && size
> 0 && pos
< xb_size
){
143 /*Advance over NUL */
148 memcpy(buf
,xb
+ pos
,size
);
159 int nval_list(const char *xb
, int xb_size
, char *buf
, int bsize
)
167 memcpy(&size
,xb
+ pos
,sizeof(int));
168 while(size
> sizeof(int) && size
<= xb_size
&& (pos
+ size
) < xb_size
&& !filled
){
171 name_len
= yaffs_strnlen((YCHAR
*)(xb
+ pos
), size
);
172 if(ncopied
+ name_len
+ 1 < bsize
){
173 memcpy(buf
,xb
+pos
,name_len
* sizeof(YCHAR
));
177 if(sizeof(YCHAR
) > 1){
181 ncopied
+= (name_len
+1);
185 if(pos
< xb_size
-sizeof(int))
186 memcpy(&size
,xb
+ pos
,sizeof(int));
194 int nval_hasvalues(const char *xb
, int xb_size
)
196 return nval_used(xb
, xb_size
) > 0;