/** * find the matched mount point from a given full absolute path. * * \param[in] path full path * \return the length of mount point. */ int uffs_GetMatchedMountPointSize(const char *path) { int pos; uffs_Device *dev; if (path[0] != '/') return 0; pos = strlen(path); while (pos > 0) { if ((dev = uffs_GetDeviceFromMountPointEx(path, pos)) != NULL ) { uffs_PutDevice(dev); return pos; } else { if (path[pos-1] == '/') pos--; //back forward search the next '/' for (; pos > 0 && path[pos-1] != '/'; pos--) ; } } return pos; }
/** * Parse the full path name, initialize obj. * * \param[out] obj object to be initialize. * \param[in] name full path name. * * \return U_SUCC if the name is parsed correctly, * U_FAIL if failed, and obj->err is set. * * \note the following fields in obj will be initialized: * obj->dev * obj->parent * obj->name * obj->name_len */ URET uffs_ParseObject(uffs_Object *obj, const char *name) { int len, m_len, d_len; uffs_Device *dev; const char *start, *p, *dname; u16 dir; TreeNode *node; u16 sum; if (uffs_ReInitObject(obj) == U_FAIL) return U_FAIL; len = strlen(name); m_len = uffs_GetMatchedMountPointSize(name); dev = uffs_GetDeviceFromMountPointEx(name, m_len); if (dev) { start = name + m_len; d_len = GetDirLengthFromPath(start, len - m_len); p = start; obj->dev = dev; if (m_len == len) { obj->parent = PARENT_OF_ROOT; obj->name = NULL; obj->name_len = 0; } else { dir = ROOT_DIR_SERIAL; dname = start; while (p - start < d_len) { while (*p != '/') p++; sum = uffs_MakeSum16(dname, p - dname); node = uffs_TreeFindDirNodeByName(dev, dname, p - dname, sum, dir); if (node == NULL) { obj->err = UENOENT; break; } else { dir = node->u.dir.serial; p++; // skip the '/' dname = p; } } obj->parent = dir; obj->name = start + (d_len > 0 ? d_len + 1 : 0); obj->name_len = len - (d_len > 0 ? d_len + 1 : 0) - m_len; } if (obj->err != UENOERR) { uffs_PutDevice(obj->dev); obj->dev = NULL; } } else { obj->err = UENOENT; } return (obj->err == UENOERR ? U_SUCC : U_FAIL); }