* Open a directory's parent directory. * * \param[in] dir Parent of this directory will be opened. Must not be root. * * \return true for success, false for failure. */
| 1185 | * \return true for success, false for failure. |
| 1186 | */ |
| 1187 | bool SdBaseFile::openParent(SdBaseFile *dir) { |
| 1188 | dir_t entry; |
| 1189 | SdBaseFile file; |
| 1190 | uint32_t c; |
| 1191 | uint32_t cluster; |
| 1192 | uint32_t lbn; |
| 1193 | // error if already open or dir is root or dir is not a directory |
| 1194 | if (isOpen() || !dir || dir->isRoot() || !dir->isDir()) return false; |
| 1195 | vol_ = dir->vol_; |
| 1196 | // position to '..' |
| 1197 | if (!dir->seekSet(32)) return false; |
| 1198 | // read '..' entry |
| 1199 | if (dir->read(&entry, sizeof(entry)) != 32) return false; |
| 1200 | // verify it is '..' |
| 1201 | if (entry.name[0] != '.' || entry.name[1] != '.') return false; |
| 1202 | // start cluster for '..' |
| 1203 | cluster = entry.firstClusterLow; |
| 1204 | cluster |= (uint32_t)entry.firstClusterHigh << 16; |
| 1205 | if (cluster == 0) return openRoot(vol_); |
| 1206 | // start block for '..' |
| 1207 | lbn = vol_->clusterStartBlock(cluster); |
| 1208 | // first block of parent dir |
| 1209 | if (!vol_->cacheRawBlock(lbn, SdVolume::CACHE_FOR_READ)) return false; |
| 1210 | |
| 1211 | dir_t *p = &vol_->cacheBuffer_.dir[1]; |
| 1212 | // verify name for '../..' |
| 1213 | if (p->name[0] != '.' || p->name[1] != '.') return false; |
| 1214 | // '..' is pointer to first cluster of parent. open '../..' to find parent |
| 1215 | if (p->firstClusterHigh == 0 && p->firstClusterLow == 0) { |
| 1216 | if (!file.openRoot(dir->volume())) return false; |
| 1217 | } |
| 1218 | else if (!file.openCachedEntry(1, O_READ)) |
| 1219 | return false; |
| 1220 | |
| 1221 | // search for parent in '../..' |
| 1222 | do { |
| 1223 | if (file.readDir(&entry, nullptr) != 32) return false; |
| 1224 | c = entry.firstClusterLow; |
| 1225 | c |= (uint32_t)entry.firstClusterHigh << 16; |
| 1226 | } while (c != cluster); |
| 1227 | |
| 1228 | // open parent |
| 1229 | return open(&file, file.curPosition() / 32 - 1, O_READ); |
| 1230 | } |
| 1231 | #endif |
| 1232 | |
| 1233 | /** |
nothing calls this directly
no test coverage detected