2 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
4 * Copyright (C) 2002-2011 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
16 * values and fits into a small finite buffer.
18 * Each attribute is stored as a record:
19 * sizeof(int) bytes record size.
20 * yaffs_strnlen+1 bytes name null terminated.
23 * total size stored in record size
25 * This code has not been tested with unicode yet.
28 #include "yaffs_nameval.h"
32 static int nval_find(const char *xb
, int xb_size
, const YCHAR
*name
,
38 memcpy(&size
, xb
, sizeof(int));
39 while (size
> 0 && (size
< xb_size
) && (pos
+ size
< xb_size
)) {
40 if (!yaffs_strncmp((YCHAR
*) (xb
+ pos
+ sizeof(int)),
47 if (pos
< xb_size
- (int)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
- (int)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
)
81 /* Find size, shift rest over this record,
82 * then zero out the rest of buffer */
83 memcpy(&size
, xb
+ pos
, sizeof(int));
84 memcpy(xb
+ pos
, xb
+ pos
+ size
, xb_size
- (pos
+ size
));
85 memset(xb
+ (xb_size
- size
), 0, size
);
89 int nval_set(char *xb
, int xb_size
, const YCHAR
*name
, const char *buf
,
93 int namelen
= yaffs_strnlen(name
, xb_size
);
99 pos
= nval_find(xb
, xb_size
, name
, &size_exist
);
101 if (flags
& XATTR_CREATE
&& pos
>= 0)
103 if (flags
& XATTR_REPLACE
&& pos
< 0)
106 start
= nval_used(xb
, xb_size
);
107 space
= xb_size
- start
+ size_exist
;
109 reclen
= (sizeof(int) + namelen
+ 1 + bsize
);
115 nval_del(xb
, xb_size
, name
);
116 start
= nval_used(xb
, xb_size
);
121 memcpy(xb
+ pos
, &reclen
, sizeof(int));
123 yaffs_strncpy((YCHAR
*) (xb
+ pos
), name
, reclen
);
124 pos
+= (namelen
+ 1);
125 memcpy(xb
+ pos
, buf
, bsize
);
129 int nval_get(const char *xb
, int xb_size
, const YCHAR
* name
, char *buf
,
132 int pos
= nval_find(xb
, xb_size
, name
, NULL
);
135 if (pos
>= 0 && pos
< xb_size
) {
137 memcpy(&size
, xb
+ pos
, sizeof(int));
138 pos
+= sizeof(int); /* advance past record length */
141 /* Advance over name string */
142 while (xb
[pos
] && size
> 0 && pos
< xb_size
) {
146 /*Advance over NUL */
150 /* If bsize is zero then this is a size query.
151 * Return the size, but don't copy.
157 memcpy(buf
, xb
+ pos
, size
);
167 int nval_list(const char *xb
, int xb_size
, char *buf
, int bsize
)
175 memcpy(&size
, xb
+ pos
, sizeof(int));
176 while (size
> (int)sizeof(int) &&
178 (pos
+ size
) < xb_size
&&
182 name_len
= yaffs_strnlen((YCHAR
*) (xb
+ pos
), size
);
183 if (ncopied
+ name_len
+ 1 < bsize
) {
184 memcpy(buf
, xb
+ pos
, name_len
* sizeof(YCHAR
));
188 if (sizeof(YCHAR
) > 1) {
192 ncopied
+= (name_len
+ 1);
197 if (pos
< xb_size
- (int)sizeof(int))
198 memcpy(&size
, xb
+ pos
, sizeof(int));
205 int nval_hasvalues(const char *xb
, int xb_size
)
207 return nval_used(xb
, xb_size
) > 0;