MCPcopy Create free account
hub / github.com/Serial-Studio/Serial-Studio / read

Method read

app/src/AI/FileSandbox.cpp:405–453  ·  view source on GitHub ↗

* @brief Reads a byte slice of a file under the read roots, paged via offset/limit. */

Source from the content-addressed store, hash-verified

403 * @brief Reads a byte slice of a file under the read roots, paged via offset/limit.
404 */
405QJsonObject AI::FileSandbox::read(const QJsonObject& args) const
406{
407 const auto resolved = resolveRead(args.value(QStringLiteral("path")).toString());
408 if (!resolved.ok)
409 return failure(resolved.error, resolved.hint);
410
411 QFileInfo info(resolved.path);
412 if (!info.isFile())
413 return failure(QStringLiteral("not_a_file"),
414 QStringLiteral("Use fs.list for directories; fs.read expects a file."));
415
416 QFile file(resolved.path);
417 if (!file.open(QIODevice::ReadOnly))
418 return failure(QStringLiteral("open_failed"), file.errorString());
419
420 if (info.isSymLink() || !openedPathWithinRoots(file.fileName(), readRoots()))
421 return failure(QStringLiteral("outside_sandbox"),
422 QStringLiteral("Refusing to read a symlinked or sandbox-escaping path."));
423
424 const qint64 total = file.size();
425 const qint64 offset = qBound<qint64>(0, args.value(QStringLiteral("offset")).toInteger(0), total);
426 const qint64 want = args.value(QStringLiteral("limit")).toInt(kMaxReadSlice);
427 const qint64 limit = qBound<qint64>(1, want, kMaxReadSlice);
428
429 if (!file.seek(offset))
430 return failure(QStringLiteral("seek_failed"), file.errorString());
431
432 const QByteArray sniff = file.peek(qMin<qint64>(limit, kBinarySniffBytes));
433 if (looksBinary(sniff))
434 return failure(QStringLiteral("binary_file"),
435 QStringLiteral("File appears binary. fs.read returns text only; request a "
436 "different file or a known text range."));
437
438 const QByteArray chunk = file.read(limit);
439 const qint64 next = offset + chunk.size();
440
441 QJsonObject out;
442 out[QStringLiteral("ok")] = true;
443 out[QStringLiteral("path")] = displayPath(resolved.path, workspaceRoot());
444 out[QStringLiteral("content")] = QString::fromUtf8(chunk);
445 out[QStringLiteral("offset")] = static_cast<double>(offset);
446 out[QStringLiteral("bytesReturned")] = static_cast<double>(chunk.size());
447 out[QStringLiteral("totalBytes")] = static_cast<double>(total);
448 out[QStringLiteral("eof")] = (next >= total);
449 if (next < total)
450 out[QStringLiteral("nextOffset")] = static_cast<double>(next);
451
452 return out;
453}
454
455//--------------------------------------------------------------------------------------------------
456// search

Callers 2

executeFsToolFunction · 0.45

Calls 10

failureFunction · 0.85
openedPathWithinRootsFunction · 0.85
looksBinaryFunction · 0.85
displayPathFunction · 0.85
errorStringMethod · 0.80
valueMethod · 0.45
openMethod · 0.45
fileNameMethod · 0.45
sizeMethod · 0.45
peekMethod · 0.45

Tested by

no test coverage detected