blob: 643b388814a7012332747472ff51cfb91a57b461 [file] [log] [blame]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "frame.h"
#include <cstdint>
#include <memory>
#include <utility>
#include <vector>
#include "builder.h"
#include "ipp_frame.h"
#include "ipp_parser.h"
#include "parser.h"
namespace ipp {
constexpr size_t kMaxPayloadSize = 256 * 1024 * 1024;
namespace {
void SetCharsetAndLanguageAttributes(Frame* frame) {
CollsView::iterator grp;
frame->AddGroup(ipp::GroupTag::operation_attributes, grp);
grp->AddAttr("attributes-charset", ValueTag::charset, "utf-8");
grp->AddAttr("attributes-natural-language", ValueTag::naturalLanguage,
"en-us");
}
} // namespace
Frame::Frame()
: version_(static_cast<ipp::Version>(0)),
operation_id_or_status_code_(0),
request_id_(0) {}
Frame::Frame(Operation operation_id,
Version version_number,
int32_t request_id,
bool set_localization_en_us)
: version_(version_number),
operation_id_or_status_code_(static_cast<uint16_t>(operation_id)),
request_id_(request_id) {
if (set_localization_en_us) {
SetCharsetAndLanguageAttributes(this);
}
}
Frame::Frame(Status status_code,
Version version_number,
int32_t request_id,
bool set_localization_en_us_and_status_message)
: version_(version_number),
operation_id_or_status_code_(static_cast<uint16_t>(status_code)),
request_id_(request_id) {
if (set_localization_en_us_and_status_message) {
SetCharsetAndLanguageAttributes(this);
CollsView::iterator grp = Groups(GroupTag::operation_attributes).begin();
grp->AddAttr("status-message", ValueTag::textWithoutLanguage,
ToString(status_code));
}
}
Frame::~Frame() {
for (std::pair<GroupTag, Collection*>& group : groups_) {
delete group.second;
}
}
Version Frame::VersionNumber() const {
return version_;
}
Version& Frame::VersionNumber() {
return version_;
}
int16_t Frame::OperationIdOrStatusCode() const {
return operation_id_or_status_code_;
}
int16_t& Frame::OperationIdOrStatusCode() {
return operation_id_or_status_code_;
}
Operation Frame::OperationId() const {
return static_cast<Operation>(operation_id_or_status_code_);
}
Status Frame::StatusCode() const {
return static_cast<Status>(operation_id_or_status_code_);
}
int32_t& Frame::RequestId() {
return request_id_;
}
int32_t Frame::RequestId() const {
return request_id_;
}
const std::vector<uint8_t>& Frame::Data() const {
return data_;
}
std::vector<uint8_t> Frame::TakeData() {
std::vector<uint8_t> data;
data.swap(data_);
return data;
}
Code Frame::SetData(std::vector<uint8_t>&& data) {
if (data.size() > kMaxPayloadSize) {
return Code::kDataTooLong;
}
data_ = std::move(data);
return Code::kOK;
}
CollsView Frame::Groups(GroupTag tag) {
if (IsValid(tag)) {
return CollsView(groups_by_tag_[static_cast<size_t>(tag)]);
}
return CollsView();
}
ConstCollsView Frame::Groups(GroupTag tag) const {
if (IsValid(tag)) {
return ConstCollsView(groups_by_tag_[static_cast<size_t>(tag)]);
}
return ConstCollsView();
}
std::vector<std::pair<GroupTag, Collection*>> Frame::GetGroups() {
return groups_;
}
std::vector<std::pair<GroupTag, const Collection*>> Frame::GetGroups() const {
return std::vector<std::pair<GroupTag, const Collection*>>(groups_.begin(),
groups_.end());
}
Code Frame::AddGroup(GroupTag tag, CollsView::iterator& new_group) {
if (!IsValid(tag)) {
return Code::kInvalidGroupTag;
}
if (groups_.size() >= kMaxCountOfAttributeGroups) {
return Code::kTooManyGroups;
}
Collection* coll = new Collection;
groups_.emplace_back(tag, coll);
std::vector<ipp::Collection*>& vg = groups_by_tag_[static_cast<size_t>(tag)];
new_group = CollsView::iterator(vg.insert(vg.end(), coll));
return Code::kOK;
}
} // namespace ipp