Folder* Folder_find_folder(Folder *self, const CharBuf *path) { if (!path || !CB_Get_Size(path)) { return self; } else { ZombieCharBuf *scratch = ZCB_WRAP(path); Folder *enclosing_folder = S_enclosing_folder(self, scratch); if (!enclosing_folder) { return NULL; } else { return Folder_Local_Find_Folder(enclosing_folder, (CharBuf*)scratch); } } }
static Folder* S_enclosing_folder(Folder *self, ZombieCharBuf *path) { size_t path_component_len = 0; uint32_t code_point; // Strip trailing slash. if (ZCB_Code_Point_From(path, 0) == '/') { ZCB_Chop(path, 1); } // Find first component of the file path. ZombieCharBuf *scratch = ZCB_WRAP((CharBuf*)path); ZombieCharBuf *path_component = ZCB_WRAP((CharBuf*)path); while (0 != (code_point = ZCB_Nip_One(scratch))) { if (code_point == '/') { ZCB_Truncate(path_component, path_component_len); ZCB_Nip(path, path_component_len + 1); break; } path_component_len++; } // If we've eaten up the entire filepath, self is enclosing folder. if (ZCB_Get_Size(scratch) == 0) { return self; } Folder *local_folder = Folder_Local_Find_Folder(self, (CharBuf*)path_component); if (!local_folder) { /* This element of the filepath doesn't exist, or it's not a * directory. However, there are filepath characters left over, * implying that this component ought to be a directory -- so the * original file path is invalid. */ return NULL; } // This file path component is a folder. Recurse into it. return S_enclosing_folder(local_folder, path); }
Folder* Folder_enclosing_folder(Folder *self, const CharBuf *path) { ZombieCharBuf *scratch = ZCB_WRAP(path); return S_enclosing_folder(self, scratch); }