Set file last modified time.

PiperOrigin-RevId: 791926107
This commit is contained in:
Francis Tsui
2025-08-06 18:25:42 -07:00
committed by Copybara-Service
parent 4826e79e0c
commit ae015665cd
8 changed files with 67 additions and 44 deletions
+1
View File
@@ -96,6 +96,7 @@ cc_library(
"//proto:connections_enums_cc_proto",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/random",
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:variant",
],
)
@@ -16,7 +16,9 @@
#define CORE_INTERNAL_INTERNAL_PAYLOAD_H_
#include <cstdint>
#include <string>
#include "absl/time/time.h"
#include "connections/implementation/proto/offline_wire_formats.pb.h"
#include "connections/payload.h"
#include "internal/platform/byte_array.h"
@@ -41,8 +43,13 @@ class InternalPayload {
Payload::Id GetId() const;
const std::string& GetParentFolder() { return payload_.GetParentFolder(); }
const std::string& GetFileName() { return payload_.GetFileName(); }
const std::string& GetParentFolder() const {
return payload_.GetParentFolder();
}
const std::string& GetFileName() const { return payload_.GetFileName(); }
absl::Time GetLastModifiedTime() const {
return payload_.GetLastModifiedTime();
}
// Returns the PayloadType of the Payload to which this object is bound.
//
@@ -21,6 +21,8 @@
#include <utility>
#include "absl/strings/str_cat.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "connections/implementation/internal_payload.h"
#include "connections/implementation/proto/offline_wire_formats.pb.h"
#include "connections/payload.h"
@@ -265,9 +267,11 @@ class OutgoingFileInternalPayload : public InternalPayload {
class IncomingFileInternalPayload : public InternalPayload {
public:
IncomingFileInternalPayload(Payload payload, OutputFile output_file,
absl::Time last_modified_time,
std::int64_t total_size)
: InternalPayload(std::move(payload)),
output_file_(std::move(output_file)),
last_modified_time_(last_modified_time),
total_size_(total_size) {}
location::nearby::connections::PayloadTransferFrame::PayloadHeader::
@@ -284,7 +288,7 @@ class IncomingFileInternalPayload : public InternalPayload {
Exception AttachNextChunk(const ByteArray& chunk) override {
if (chunk.Empty()) {
// Received null last chunk for incoming payload.
output_file_.Close();
Close();
return {Exception::kSuccess};
}
@@ -296,10 +300,14 @@ class IncomingFileInternalPayload : public InternalPayload {
return {Exception::kIo};
}
void Close() override { output_file_.Close(); }
void Close() override {
output_file_.SetLastModifiedTime(last_modified_time_);
output_file_.Close();
}
private:
OutputFile output_file_;
absl::Time last_modified_time_;
const std::int64_t total_size_;
};
@@ -405,6 +413,13 @@ ErrorOr<std::unique_ptr<InternalPayload>> CreateIncomingInternalPayload(
if (frame.payload_header().has_total_size()) {
total_size = frame.payload_header().total_size();
}
absl::Time last_modified_time = absl::Now();
if (frame.payload_header().has_last_modified_timestamp_millis()) {
last_modified_time = absl::FromUnixMillis(
frame.payload_header().last_modified_timestamp_millis());
VLOG(1) << "Received last modified time: " << last_modified_time
<< " for file: " << file_name;
}
// These are ordered, the output file must be created first otherwise
// there will be no input file to open.
@@ -417,7 +432,7 @@ ErrorOr<std::unique_ptr<InternalPayload>> CreateIncomingInternalPayload(
}
return {std::make_unique<IncomingFileInternalPayload>(
Payload(payload_id, InputFile(payload_id, total_size)),
std::move(output_file), total_size)};
std::move(output_file), last_modified_time, total_size)};
} else {
OutputFile output_file(file_path);
if (!output_file.IsValid()) {
@@ -427,7 +442,7 @@ ErrorOr<std::unique_ptr<InternalPayload>> CreateIncomingInternalPayload(
return {std::make_unique<IncomingFileInternalPayload>(
Payload(payload_id, parent_folder, file_name,
InputFile(file_path, total_size)),
std::move(output_file), total_size)};
std::move(output_file), last_modified_time, total_size)};
}
}
default:
@@ -475,9 +475,8 @@ void PayloadManager::SendPayload(ClientProxy* client,
payload_type, resume_offset,
internal_payload->GetTotalSize());
PayloadTransferFrame::PayloadHeader payload_header{CreatePayloadHeader(
*internal_payload, resume_offset, internal_payload->GetParentFolder(),
internal_payload->GetFileName())};
PayloadTransferFrame::PayloadHeader payload_header{
CreatePayloadHeader(*internal_payload, resume_offset)};
bool should_continue = true;
std::int64_t next_chunk_offset = 0;
@@ -754,8 +753,7 @@ int PayloadManager::GetOptimalChunkSize(EndpointIds endpoint_ids) {
}
PayloadTransferFrame::PayloadHeader PayloadManager::CreatePayloadHeader(
const InternalPayload& internal_payload, size_t offset,
const std::string& parent_folder, const std::string& file_name) {
const InternalPayload& internal_payload, size_t offset) {
PayloadTransferFrame::PayloadHeader payload_header;
size_t payload_size = internal_payload.GetTotalSize();
@@ -764,14 +762,15 @@ PayloadTransferFrame::PayloadHeader PayloadManager::CreatePayloadHeader(
if (internal_payload.GetType() ==
nearby::connections::PayloadTransferFrame::PayloadTransferFrame::
PayloadHeader::FILE) {
payload_header.set_file_name(file_name);
payload_header.set_parent_folder(parent_folder);
payload_header.set_file_name(internal_payload.GetFileName());
payload_header.set_parent_folder(internal_payload.GetParentFolder());
payload_header.set_last_modified_timestamp_millis(
absl::ToUnixMillis(internal_payload.GetLastModifiedTime()));
}
payload_header.set_total_size(payload_size ==
InternalPayload::kIndeterminateSize
? InternalPayload::kIndeterminateSize
: payload_size - offset);
return payload_header;
}
+1 -3
View File
@@ -311,9 +311,7 @@ class PayloadManager : public EndpointManager::FrameProcessor {
int GetOptimalChunkSize(EndpointIds endpoint_ids);
location::nearby::connections::PayloadTransferFrame::PayloadHeader
CreatePayloadHeader(const InternalPayload& internal_payload, size_t offset,
const std::string& parent_folder,
const std::string& file_name);
CreatePayloadHeader(const InternalPayload& internal_payload, size_t offset);
location::nearby::connections::PayloadTransferFrame::PayloadChunk
CreatePayloadChunk(std::int64_t offset, ByteArray body, int index);
+21 -23
View File
@@ -64,19 +64,11 @@ Payload::Payload(ByteArray&& bytes)
Payload::Payload(const ByteArray& bytes)
: type_(PayloadType::kBytes), content_(bytes) {}
Payload::Payload(InputFile input_file)
: id_(std::hash<std::string>()(input_file.GetFilePath())),
file_name_(FormatFileName(input_file.GetFilePath())),
type_(PayloadType::kFile),
content_(std::move(input_file)) {}
Payload::Payload(std::string parent_folder, std::string file_name,
InputFile input_file)
: id_(std::hash<std::string>()(input_file.GetFilePath())),
parent_folder_(parent_folder),
file_name_(file_name),
type_(PayloadType::kFile),
content_(std::move(input_file)) {}
InputFile input_file) {
Id id = std::hash<std::string>()(input_file.GetFilePath());
InitFilePayload(id, parent_folder, file_name, std::move(input_file));
}
Payload::Payload(std::unique_ptr<InputStream> stream)
: type_(PayloadType::kStream), content_(std::move(stream)) {}
@@ -88,23 +80,29 @@ Payload::Payload(Id id, ByteArray&& bytes)
Payload::Payload(Id id, const ByteArray& bytes)
: id_(id), type_(PayloadType::kBytes), content_(bytes) {}
Payload::Payload(Id id, InputFile input_file)
: id_(id),
file_name_(FormatFileName(input_file.GetFilePath())),
type_(PayloadType::kFile),
content_(std::move(input_file)) {}
Payload::Payload(Id id, InputFile input_file) {
std::string file_path = input_file.GetFilePath();
InitFilePayload(id, /*parent_folder=*/"", file_path, std::move(input_file));
}
Payload::Payload(Id id, std::string parent_folder, std::string file_name,
InputFile input_file)
: id_(id),
parent_folder_(parent_folder),
file_name_(file_name),
type_(PayloadType::kFile),
content_(std::move(input_file)) {}
InputFile input_file) {
InitFilePayload(id, parent_folder, file_name, std::move(input_file));
}
Payload::Payload(Id id, std::unique_ptr<InputStream> stream)
: id_(id), type_(PayloadType::kStream), content_(std::move(stream)) {}
void Payload::InitFilePayload(Id id, std::string parent_folder,
std::string file_name, InputFile input_file) {
id_ = id;
parent_folder_ = parent_folder;
file_name_ = FormatFileName(file_name);
last_modified_time_ = input_file.GetLastModifiedTime();
type_ = PayloadType::kFile;
content_ = std::move(input_file);
}
// Returns ByteArray payload, if it has been defined, or empty ByteArray.
const ByteArray& Payload::AsBytes() const& {
static const ByteArray empty; // NOLINT: function-level static is OK.
+7 -2
View File
@@ -18,9 +18,12 @@
#include <cstdint>
#include <functional>
#include <memory>
#include <string>
#include <utility>
#include <variant>
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "absl/types/variant.h"
#include "connections/payload_type.h"
#include "internal/platform/byte_array.h"
@@ -53,9 +56,7 @@ class Payload {
// Constructors for outgoing payloads.
explicit Payload(ByteArray&& bytes);
explicit Payload(const ByteArray& bytes);
explicit Payload(InputFile input_file);
// InputFile is just "a pointer to a file on your disc", a wrapper around a
// file name or file descriptor. It has no understanding that Nearby is going
@@ -105,8 +106,11 @@ class Payload {
const std::string& GetFileName() const;
const std::string& GetParentFolder() const;
absl::Time GetLastModifiedTime() const { return last_modified_time_; }
private:
void InitFilePayload(Id id, std::string parent_folder, std::string file_name,
InputFile input_file);
PayloadType FindType() const;
Id id_{GenerateId()};
@@ -114,6 +118,7 @@ class Payload {
std::string parent_folder_;
std::string file_name_;
absl::Time last_modified_time_ = absl::Now();
PayloadType type_{FindType()};
Content content_;
+2 -2
View File
@@ -76,7 +76,7 @@ TEST(PayloadTest, SupportsMultiDotNamedFileType) {
constexpr char expected[] = "this.is.a.multidot.file";
InputFile file(expected, 0);
Payload payload(std::move(file));
Payload payload(/*parent_folder=*/"", expected, std::move(file));
EXPECT_EQ(payload.GetFileName(), expected);
}
@@ -89,7 +89,7 @@ TEST(PayloadTest,
"this.is.a.multidot.backslash.folder.separated.file";
InputFile file(file_name, 0);
Payload payload(std::move(file));
Payload payload(/*parent_folder=*/"", file_name, std::move(file));
EXPECT_EQ(payload.GetFileName(), expected);
}