-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathipp_package.h
188 lines (157 loc) · 6.15 KB
/
ipp_package.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
// 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.
#ifndef LIBIPP_IPP_PACKAGE_H_
#define LIBIPP_IPP_PACKAGE_H_
#include "ipp_attribute.h" // NOLINT(build/include)
#include "ipp_enums.h" // NOLINT(build/include)
#include "ipp_export.h" // NOLINT(build/include)
#include <cstdint>
#include <map>
#include <string>
#include <vector>
namespace ipp {
class Group;
// This class represents IPP frame. It is container for Groups that represent
// IPP attributes groups (like operation-attributes). Groups in a single Package
// must have unique tags (names).
class IPP_EXPORT Package {
public:
// destructor
virtual ~Package();
// Returns vector of all groups in the package, all pointers are != nullptr.
// Returned vector = GetKnownGroups() + vector with unknown groups.
std::vector<Group*> GetAllGroups();
std::vector<const Group*> GetAllGroups() const;
// Returns pointer to the group with given tag.
// Returns nullptr if there is no group with given tag in the package.
Group* GetGroup(GroupTag);
const Group* GetGroup(GroupTag) const;
// Adds a new group to the package and returns pointer to it or nullptr if
// a group with given tag already exists in the package.
Group* AddUnknownGroup(GroupTag, bool is_a_set);
// Returns reference to payload (e.g. document to print), empty vector means
// no payload.
std::vector<uint8_t>& Data() { return data_; }
const std::vector<uint8_t>& Data() const { return data_; }
protected:
Package() = default;
private:
// Copy/move/assign constructors/operators are not available.
Package(const Package&) = delete;
Package(Package&&) = delete;
Package& operator=(const Package&) = delete;
Package& operator=(Package&&) = delete;
// Returns vector with groups in the schema, all pointers are != nullptr.
// This method must be overloaded in derived classes with schema.
virtual std::vector<Group*> GetKnownGroups() { return {}; }
virtual std::vector<const Group*> GetKnownGroups() const { return {}; }
std::vector<Group*> unknown_groups_;
std::vector<uint8_t> data_;
};
// Defined later in this file.
class Collection;
// Base class represents single IPP attribute group or a sequence of the
// same IPP attribute groups. Single instance of IPP attribute groups is
// represented by Collection object.
class IPP_EXPORT Group {
public:
virtual ~Group() { Resize(0); }
// Returns tag of the group.
GroupTag GetName() const { return name_; }
// Returns true if it is a sequence of IPP groups (Collections) or false
// if it is a single IPP group (one Collection).
bool IsASet() const { return is_a_set_; }
// Returns the current number of elements (IPP groups) in the Group.
// (IsASet() == false) => always returns 1.
size_t GetSize() const { return groups_.size(); }
// Resizes a sequence of IPP groups.
// Does nothing if (IsASet() == false) and (|new_size| > 0).
void Resize(size_t new_size) {
if (!is_a_set_ && new_size > 1)
return;
while (new_size < groups_.size()) {
delete groups_.back();
groups_.pop_back();
}
while (new_size > groups_.size()) {
groups_.push_back(CreateCollection());
}
}
// Returns a pointer to underlying collection, representing one of the IPP
// groups. Returns nullptr <=> (index >= GetSize()).
Collection* GetCollection(size_t index = 0) {
if (index >= groups_.size())
return nullptr;
return groups_[index];
}
const Collection* GetCollection(size_t index = 0) const {
if (index >= groups_.size())
return nullptr;
return groups_.at(index);
}
protected:
Group(GroupTag name, bool is_a_set) : name_(name), is_a_set_(is_a_set) {}
private:
virtual Collection* CreateCollection() = 0;
GroupTag name_;
bool is_a_set_;
std::vector<Collection*> groups_;
};
// Final class for Groups, represents Group with single IPP attribute group
// defined in the schema. Template parameter TCollection must be a class
// derived from Collection and defines the structure of the group.
template <class TCollection>
class SingleGroup : public Group {
public:
explicit SingleGroup(GroupTag name) : Group(name, false) {}
// Allows to refer to fields in the underlying collection.
// Creates the collection if it not exists.
TCollection* operator->() {
Resize(1);
return dynamic_cast<TCollection*>(GetCollection());
}
// Returns reference to the underlying collection. If the group is empty
// (GetSize() == 0) returns a reference to an empty static collection.
const TCollection& Get() const {
const Collection* coll = GetCollection();
if (coll == nullptr)
return TCollection::empty;
return *(dynamic_cast<const TCollection*>(coll));
}
private:
Collection* CreateCollection() override { return new TCollection; }
};
// Final class for Group, represents sequence of IPP attribute groups with
// the same tag and defined in the schema. Template parameter TCollection is
// a class derived from Collection and defines the structure of a single group.
template <class TCollection>
class SetOfGroups : public Group {
public:
explicit SetOfGroups(GroupTag name) : Group(name, true) {}
// If |index| is out of range, the vector is resized to (index+1).
TCollection& operator[](size_t index) {
if (GetSize() <= index)
Resize(index + 1);
return *(dynamic_cast<TCollection*>(GetCollection(index)));
}
// Const version of the method above. If |index| is out of range,
// a reference to an empty static collection is returned.
const TCollection& At(size_t index) const {
const Collection* coll = GetCollection(index);
if (coll == nullptr)
return TCollection::empty;
return *(dynamic_cast<const TCollection*>(coll));
}
private:
Collection* CreateCollection() override { return new TCollection; }
};
// Final class for Group, represents Group not defined in the schema.
class UnknownGroup : public Group {
public:
UnknownGroup(GroupTag name, bool is_a_set) : Group(name, is_a_set) {}
private:
Collection* CreateCollection() override { return new EmptyCollection; }
};
} // namespace ipp
#endif // LIBIPP_IPP_PACKAGE_H_