3 * exFAT file system implementation library.
5 * Created by Andrew Nayenko on 02.09.09.
6 * This software is distributed under the GNU General Public License
7 * version 3 or any later.
15 int exfat_opendir(struct exfat* ef, struct exfat_node* dir,
16 struct exfat_iterator* it)
23 rc = exfat_cache_directory(ef, dir);
25 exfat_put_node(ef, dir);
29 void exfat_closedir(struct exfat* ef, struct exfat_iterator* it)
31 exfat_put_node(ef, it->parent);
36 struct exfat_node* exfat_readdir(struct exfat* ef, struct exfat_iterator* it)
38 if (it->current == NULL)
39 it->current = it->parent->child;
41 it->current = it->current->next;
43 if (it->current != NULL)
44 return exfat_get_node(it->current);
49 static int compare_char(struct exfat* ef, uint16_t a, uint16_t b)
51 if (a >= ef->upcase_chars || b >= ef->upcase_chars)
52 return (int) a - (int) b;
54 return (int) le16_to_cpu(ef->upcase[a]) - (int) le16_to_cpu(ef->upcase[b]);
57 static int compare_name(struct exfat* ef, const le16_t* a, const le16_t* b)
59 while (le16_to_cpu(*a) && le16_to_cpu(*b))
61 int rc = compare_char(ef, le16_to_cpu(*a), le16_to_cpu(*b));
67 return compare_char(ef, le16_to_cpu(*a), le16_to_cpu(*b));
70 static int lookup_name(struct exfat* ef, struct exfat_node* parent,
71 struct exfat_node** node, const char* name, size_t n)
73 struct exfat_iterator it;
74 le16_t buffer[EXFAT_NAME_MAX + 1];
77 rc = utf8_to_utf16(buffer, name, EXFAT_NAME_MAX, n);
81 rc = exfat_opendir(ef, parent, &it);
84 while ((*node = exfat_readdir(ef, &it)))
86 if (compare_name(ef, buffer, (*node)->name) == 0)
88 exfat_closedir(ef, &it);
91 exfat_put_node(ef, *node);
93 exfat_closedir(ef, &it);
97 static size_t get_comp(const char* path, const char** comp)
101 *comp = path + strspn(path, "/"); /* skip leading slashes */
102 end = strchr(*comp, '/');
104 return strlen(*comp);
109 int exfat_lookup(struct exfat* ef, struct exfat_node** node,
112 struct exfat_node* parent;
116 /* start from the root directory */
117 parent = *node = exfat_get_node(ef->root);
118 for (p = path; (n = get_comp(p, &p)); p += n)
120 if (n == 1 && *p == '.') /* skip "." component */
122 if (lookup_name(ef, parent, node, p, n) != 0)
124 exfat_put_node(ef, parent);
127 exfat_put_node(ef, parent);