yaffs: Cache object xattrib state.
[yaffs2.git] / yaffs_nameval.c
index 88ee25bfd6c87d8c0ea4324abcdc529955bae7f8..2081f21dacd3a3e21e666c00fcecc0d3c59400d6 100644 (file)
@@ -21,6 +21,8 @@
  *  nbytes    value.
  *  ----------
  *  total size  stored in record size 
+ *
+ * This code has not been tested with unicode yet.
  */
 
 
 
 #include "yportenv.h"
  
-static int nval_find(const char *xb, int xb_size, const char *name)
+static int nval_find(const char *xb, int xb_size, const YCHAR *name,
+               int *exist_size)
 {
        int pos=0;
        int size;
 
        memcpy(&size,xb,sizeof(int));
        while(size > 0 && (size < xb_size) && (pos + size < xb_size)){
-               if(strncmp(xb+pos+sizeof(int),name,size) == 0)
+               if(yaffs_strncmp((YCHAR *)(xb+pos+sizeof(int)),name,size) == 0){
+                       if(exist_size)
+                               *exist_size = size;
                        return pos;
+               }
                pos += size;
                if(pos < xb_size -sizeof(int))
                        memcpy(&size,xb + pos,sizeof(int));
                else
                        size = 0;
        }
+       if(exist_size)
+               *exist_size = 0;
        return -1;
 }
 
@@ -62,9 +70,9 @@ static int nval_used(const char *xb, int xb_size)
        return pos;
 }
 
-int nval_del(char *xb, int xb_size, const char *name)
+int nval_del(char *xb, int xb_size, const YCHAR *name)
 {
-       int pos  = nval_find(xb, xb_size, name);
+       int pos  = nval_find(xb, xb_size, name, NULL);
        int size;
        
        if(pos >= 0 && pos < xb_size){
@@ -74,42 +82,51 @@ int nval_del(char *xb, int xb_size, const char *name)
                memset(xb + (xb_size - size),0,size);
                return 0;
        } else
-               return -ENOENT;
+               return -ENODATA;
 }
 
-int nval_set(char *xb, int xb_size, const char *name, const char *buf, int bsize, int flags)
+int nval_set(char *xb, int xb_size, const YCHAR *name, const char *buf, int bsize, int flags)
 {
-       int pos = nval_find(xb,xb_size,name);
-       int namelen = strnlen(name,xb_size);
+       int pos;
+       int namelen = yaffs_strnlen(name,xb_size);
        int reclen;
+       int size_exist = 0;
+       int space;
+       int start;
 
-       if(flags & NVAL_CREATE && pos >= 0)
+       pos = nval_find(xb,xb_size,name, &size_exist);
+
+       if(flags & XATTR_CREATE && pos >= 0)
                return -EEXIST;
-       if(flags & NVAL_REPLACE && pos < 0)
-               return -ENOENT;
+       if(flags & XATTR_REPLACE && pos < 0)
+               return -ENODATA;
 
-       nval_del(xb,xb_size,name);
+       start = nval_used(xb,xb_size);
+       space = xb_size - start + size_exist;
 
-       pos = nval_used(xb, xb_size);
-       
-       if(pos < xb_size && bsize < xb_size && namelen < xb_size){
-               reclen = (sizeof(int) + namelen + 1 + bsize);
-               if( pos + reclen < xb_size){
-                       memcpy(xb + pos,&reclen,sizeof(int));
-                       pos +=sizeof(int);
-                       strncpy(xb + pos, name, reclen);
-                       pos+= (namelen+1);
-                       memcpy(xb + pos,buf,bsize);
-                       pos+= bsize;
-                       return 0;
-               }
+       reclen = (sizeof(int) + namelen + 1 + bsize);
+
+       if(reclen > space)
+               return -ENOSPC;
+
+       if(pos >= 0){
+               nval_del(xb,xb_size,name);
+               start = nval_used(xb, xb_size);
        }
-       return -ENOSPC;
+
+       pos = start;
+
+       memcpy(xb + pos,&reclen,sizeof(int));
+       pos +=sizeof(int);
+       yaffs_strncpy((YCHAR *)(xb + pos), name, reclen);
+       pos+= (namelen+1);
+       memcpy(xb + pos,buf,bsize);
+       return 0;
 }
 
-int nval_get(const char *xb, int xb_size, const char *name, char *buf, int bsize)
+int nval_get(const char *xb, int xb_size, const YCHAR *name, char *buf, int bsize)
 {
-       int pos = nval_find(xb,xb_size,name);
+       int pos = nval_find(xb,xb_size,name,NULL);
        int size;
        
        if(pos >= 0 && pos< xb_size){
@@ -133,7 +150,10 @@ int nval_get(const char *xb, int xb_size, const char *name, char *buf, int bsize
                }
                
        }
-       return -ENOENT;
+       if(pos >= 0)
+               return -ERANGE;
+       else
+               return -ENODATA;
 }
 
 int nval_list(const char *xb, int xb_size, char *buf, int bsize)
@@ -148,12 +168,16 @@ int nval_list(const char *xb, int xb_size, char *buf, int bsize)
        while(size > sizeof(int) && size <= xb_size && (pos + size) < xb_size && !filled){
                pos+= sizeof(int);
                size-=sizeof(int);
-               name_len = strnlen(xb + pos, size);
+               name_len = yaffs_strnlen((YCHAR *)(xb + pos), size);
                if(ncopied + name_len + 1 < bsize){
-                       memcpy(buf,xb+pos,name_len);
+                       memcpy(buf,xb+pos,name_len * sizeof(YCHAR));
                        buf+= name_len;
                        *buf = '\0';
                        buf++;
+                       if(sizeof(YCHAR) > 1){
+                               *buf = '\0';
+                               buf++;
+                       }
                        ncopied += (name_len+1);
                } else
                        filled = 1;
@@ -166,6 +190,7 @@ int nval_list(const char *xb, int xb_size, char *buf, int bsize)
        return ncopied;
 }
 
+#if 0
 int nval_load(char *xb, int xb_size, const char *src, int src_size)
 {
        int tx_size;
@@ -194,3 +219,10 @@ int nval_save(const char *xb, int xb_size, char *dest, int dest_size)
        memcpy(dest,xb,tx_size);
        return tx_size;
 }
+#endif
+
+
+int nval_hasvalues(const char *xb, int xb_size)
+{
+       return nval_used(xb, xb_size) > 0;
+}