* @brief Appends one directory's children to the listing, recursing within the depth cap. */
| 331 | * @brief Appends one directory's children to the listing, recursing within the depth cap. |
| 332 | */ |
| 333 | static void collectEntries(const QString& dir, |
| 334 | const QString& root, |
| 335 | bool recursive, |
| 336 | int depth, |
| 337 | QJsonArray& rows, |
| 338 | bool& truncated) |
| 339 | { |
| 340 | if (depth > AI::FileSandbox::kMaxRecurseDepth || truncated) |
| 341 | return; |
| 342 | |
| 343 | const auto flags = QDir::AllEntries | QDir::NoDotAndDotDot | QDir::Hidden | QDir::NoSymLinks; |
| 344 | const auto infos = QDir(dir).entryInfoList(flags, QDir::Name | QDir::DirsFirst); |
| 345 | for (const auto& info : infos) { |
| 346 | if (rows.size() >= AI::FileSandbox::kMaxListEntries) { |
| 347 | truncated = true; |
| 348 | return; |
| 349 | } |
| 350 | |
| 351 | QJsonObject row; |
| 352 | row[QStringLiteral("path")] = displayPath(info.absoluteFilePath(), root); |
| 353 | row[QStringLiteral("type")] = info.isDir() ? QStringLiteral("dir") : QStringLiteral("file"); |
| 354 | if (info.isFile()) |
| 355 | row[QStringLiteral("sizeBytes")] = static_cast<double>(info.size()); |
| 356 | |
| 357 | row[QStringLiteral("modified")] = info.lastModified().toString(Qt::ISODate); |
| 358 | rows.append(row); |
| 359 | |
| 360 | if (recursive && info.isDir()) |
| 361 | collectEntries(info.absoluteFilePath(), root, true, depth + 1, rows, truncated); |
| 362 | } |
| 363 | } |
| 364 | |
| 365 | /** |
| 366 | * @brief Lists a directory under the read roots; supports bounded recursion. |
no test coverage detected