blob: af4e1735986eb1160766fafd35067a3a74f55ef6 [file] [log] [blame]
// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libipp/ipp_package.h"
#include "libipp/ipp_attribute.h"
namespace ipp {
// Methods for Package
Group* Package::GetGroup(GroupTag gn) {
const std::vector<Group*> groups = GetKnownGroups();
for (auto g : groups)
if (g->GetName() == gn)
return g;
for (auto g : unknown_groups_)
if (g->GetName() == gn)
return g;
return nullptr;
}
Group* Package::AddUnknownGroup(GroupTag gn, bool is_a_set) {
if (GetGroup(gn) != nullptr)
return nullptr;
unknown_groups_.push_back(new UnknownGroup(gn, is_a_set));
return unknown_groups_.back();
}
std::vector<Group*> Package::GetAllGroups() {
std::vector<Group*> groups = GetKnownGroups();
groups.insert(groups.end(), unknown_groups_.begin(), unknown_groups_.end());
return groups;
}
Package::~Package() {
for (auto g : unknown_groups_)
delete g;
}
// Methods for UnknownGroup
UnknownGroup::UnknownGroup(GroupTag name, bool is_a_set)
: Group(name, is_a_set), groups_(is_a_set ? 0 : 1) {}
UnknownGroup::~UnknownGroup() {
for (auto g : groups_)
delete g;
}
void UnknownGroup::Resize(size_t new_size) {
if (!IsASet())
return;
while (groups_.size() > new_size) {
delete groups_.back();
groups_.pop_back();
}
while (groups_.size() < new_size)
groups_.push_back(new Collection);
}
// Methods for Collection
Collection::~Collection() {
for (const auto& kv : unknown_attrs_) {
delete kv.second;
}
}
Attribute* Collection::GetAttribute(AttrName an) {
const std::vector<Attribute*> known_attr = GetKnownAttributes();
for (auto a : known_attr)
if (a->GetNameAsEnum() == an)
return a;
auto it2 = unknown_attrs_.find(ToString(an));
if (it2 != unknown_attrs_.end())
return it2->second;
return nullptr;
}
Attribute* Collection::GetAttribute(const std::string& name) {
auto it = unknown_attrs_.find(name);
if (it != unknown_attrs_.end())
return it->second;
AttrName an;
if (FromString(name, &an)) {
const std::vector<Attribute*> known_attr = GetKnownAttributes();
for (auto a : known_attr)
if (a->GetNameAsEnum() == an)
return a;
}
return nullptr;
}
Attribute* Collection::AddUnknownAttribute(const std::string& name,
bool is_a_set,
AttrType type) {
// name cannot be empty
if (name.empty())
return nullptr;
// type must be correct
if (ToString(type) == "")
return nullptr;
// check, if given name is not used
if (unknown_attrs_.count(name))
return nullptr;
AttrName an;
if (FromString(name, &an)) {
const std::vector<Attribute*> known_attr = GetKnownAttributes();
for (auto a : known_attr)
if (a->GetNameAsEnum() == an)
return nullptr;
}
// add new attribute
Attribute* attr = nullptr;
if (type == AttrType::collection)
attr = new UnknownCollectionAttribute(name, is_a_set);
else
attr = new UnknownValueAttribute(name, is_a_set, type);
unknown_attrs_names_.push_back(name);
unknown_attrs_[name] = attr;
return attr;
}
void Collection::ResetAllAttributes() {
const std::vector<Attribute*> attrs = GetAllAttributes();
for (auto a : attrs) {
a->Resize(0);
a->SetState(AttrState::unset);
if (a->GetCollection() != nullptr)
a->GetCollection()->ResetAllAttributes();
}
}
std::vector<Attribute*> Collection::GetAllAttributes() {
std::vector<Attribute*> attrs = GetKnownAttributes();
attrs.reserve(attrs.size() + unknown_attrs_names_.size());
for (auto an : unknown_attrs_names_)
attrs.push_back(unknown_attrs_[an]);
return attrs;
}
} // namespace ipp