454f67b3bc
Clamps insertSuffix's underflow, floors uniqueEntryName's validity guard, suppresses the redundant overwrite confirm via a picker out-param, adds a PayloadBuffer high-water mark, and corrects stale CLAUDE.md/CMake claims.
96 lines
4.1 KiB
C++
96 lines
4.1 KiB
C++
// shell/package/export_bank — the promptless bank-export verb: survey, digest,
|
|
// stream, commit. No prompts and no message boxes (shell/actions/
|
|
// package_export_action is the skin). The session arrives CONST, which is how "an
|
|
// export writes no ext state, opens no undo point and never bumps the bank
|
|
// generation" is enforced rather than remembered — those three acts
|
|
// (saveToActiveProject, bumpBankGeneration, writeAssignmentRequest) are exactly the
|
|
// session members that are non-const (session.h:113,108,147). Constness does not
|
|
// block every mutation, though: pruneReclaim (session.h:140-141) is const and is
|
|
// the system's sole file-deletion path — irrelevant to export, but not something a
|
|
// const session forbids in general. Blocking I/O: UI-thread actions only.
|
|
|
|
#pragma once
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "core/package/bank_package.h"
|
|
#include "core/package/export_plan.h"
|
|
|
|
namespace reasampler {
|
|
|
|
class ReaSamplerSession;
|
|
|
|
struct ExportRequest {
|
|
std::string projectDir; // absolute; the root the index's relative paths hang off
|
|
std::string bankId;
|
|
std::string destAbsPath; // the .rsbank to write
|
|
std::int64_t exportTimestamp = 0; // manifest envelope; the caller's clock read
|
|
// Both default false and are set ONLY after the skin's explicit confirm: one
|
|
// lists what is absent, the other names the destination being replaced.
|
|
bool allowIncomplete = false;
|
|
bool allowOverwrite = false;
|
|
};
|
|
|
|
enum class ExportStatus {
|
|
Written,
|
|
NoSuchBank,
|
|
NoProjectDir,
|
|
RefusedIncomplete,
|
|
RefusedUnrepresentable,
|
|
RefusedDestinationExists,
|
|
SourceReadFailed, // a file the plan classified Present would not read, or is empty
|
|
SourceChanged, // a payload's bytes moved between the digest pass and the stream pass
|
|
EncodeFailed,
|
|
WriteFailed,
|
|
};
|
|
|
|
struct ExportOutcome {
|
|
ExportStatus status = ExportStatus::WriteFailed;
|
|
std::size_t entriesWritten = 0;
|
|
std::uint64_t bytesWritten = 0;
|
|
std::string bankDisplayName;
|
|
std::vector<package::ExcludedEntry> excluded;
|
|
std::string offendingName; // the entry a SourceReadFailed / SourceChanged names
|
|
};
|
|
|
|
struct ExportSurvey {
|
|
bool bankFound = false;
|
|
package::ExportPlan plan;
|
|
};
|
|
|
|
// Report-before-acting: the same plan exportBank recomputes, with nothing written.
|
|
// Read-only against both the project and the filesystem.
|
|
ExportSurvey surveyBankExport(const ReaSamplerSession& session,
|
|
const std::string& projectDir,
|
|
const std::string& bankId);
|
|
|
|
// Fills each manifest entry's byteLength and byteHash from its source file — the
|
|
// digest pass, one payload in memory at a time. False with `outFailedName` set when a
|
|
// source will not read or is empty; a zero-length entry cannot round-trip the
|
|
// format's own seam, so it is a failure here rather than an entry.
|
|
bool digestSources(package::PackageManifest& manifest,
|
|
const std::vector<std::string>& sourceAbsPaths,
|
|
std::string& outFailedName);
|
|
|
|
// Streams one package to `destAbsPath`: the encoded prefix, then each payload re-read
|
|
// from `sourceAbsPaths` (parallel to `manifest.entries`) and re-checked against the
|
|
// length and digest recorded for it before it is appended — so the digest the
|
|
// manifest claims describes the bytes actually written, not the bytes a concurrent
|
|
// edit replaced. Any failure abandons the writer, leaving the destination absent or
|
|
// holding its prior contents.
|
|
//
|
|
// Public because that atomicity is this function's property: proving it needs a
|
|
// failure injected mid-stream, which is a call to this seam, not to exportBank.
|
|
ExportOutcome writePackageFile(const package::EncodedPackage& encoded,
|
|
const package::PackageManifest& manifest,
|
|
const std::vector<std::string>& sourceAbsPaths,
|
|
const std::string& destAbsPath);
|
|
|
|
// The verb: plan, gate on the verdict and the destination, digest, encode, stream.
|
|
ExportOutcome exportBank(const ReaSamplerSession& session, const ExportRequest& req);
|
|
|
|
} // namespace reasampler
|