| |
1 |
1 |
#pragma once |
| |
|
2 |
#include "../libchcore/TCoreException.h" |
| |
|
3 |
#include "../libchcore/ErrorCodes.h" |
| |
2 |
4 |
|
| |
3 |
5 |
namespace serializer |
| |
4 |
6 |
{ |
| |
5 |
7 |
template<class T> |
| |
6 |
8 |
class SerializableContainer |
| |
7 |
9 |
{ |
| |
8 |
10 |
public: |
| |
|
11 |
SerializableContainer() = default; |
| |
9 |
12 |
|
| |
|
13 |
SerializableContainer(const SerializableContainer<T>& rSrc) |
| |
|
14 |
{ |
| |
|
15 |
for(const T& item : rSrc.m_vEntries) |
| |
|
16 |
{ |
| |
|
17 |
|
| |
|
18 |
Add(item); |
| |
|
19 |
} |
| |
|
20 |
} |
| |
|
21 |
|
| |
|
22 |
SerializableContainer<T>& operator=(const SerializableContainer<T>& rSrc) |
| |
|
23 |
{ |
| |
|
24 |
if(this != &rSrc) |
| |
|
25 |
{ |
| |
|
26 |
Clear(); |
| |
|
27 |
for(const T& item : rSrc.m_vEntries) |
| |
|
28 |
{ |
| |
|
29 |
|
| |
|
30 |
Add(item); |
| |
|
31 |
} |
| |
|
32 |
} |
| |
|
33 |
|
| |
|
34 |
return *this; |
| |
|
35 |
} |
| |
|
36 |
|
| |
|
37 |
virtual ~SerializableContainer() = default; |
| |
|
38 |
|
| |
10 |
39 |
void Store(const serializer::ISerializerContainerPtr& spContainer) const |
| |
11 |
40 |
{ |
| |
|
41 |
if(!spContainer) |
| |
|
42 |
throw chcore::TCoreException(chcore::eErr_InvalidPointer, L"spContainer", LOCATION); |
| |
|
43 |
|
| |
12 |
44 |
InitColumns(spContainer); |
| |
13 |
45 |
|
| |
14 |
46 |
spContainer->DeleteRows(m_setRemovedObjects); |
| |
15 |
47 |
m_setRemovedObjects.Clear(); |
| |
16 |
48 |
|
| |
17 |
49 |
for(const T& rEntry : m_vEntries) |
| |
18 |
50 |
{ |
| |
19 |
51 |
rEntry.Store(spContainer); |
| |
20 |
52 |
} |
| |
21 |
53 |
} |
| |
22 |
54 |
|
| |
23 |
55 |
void Load(const serializer::ISerializerContainerPtr& spContainer) |
| |
24 |
56 |
{ |
| |
|
57 |
if(!spContainer) |
| |
|
58 |
throw chcore::TCoreException(chcore::eErr_InvalidPointer, L"spContainer", LOCATION); |
| |
|
59 |
|
| |
|
60 |
m_setRemovedObjects.Clear(); |
| |
|
61 |
m_vEntries.clear(); |
| |
|
62 |
|
| |
25 |
63 |
InitColumns(spContainer); |
| |
26 |
64 |
|
| |
27 |
65 |
ISerializerRowReaderPtr spRowReader = spContainer->GetRowReader(); |
| |
28 |
66 |
while(spRowReader->Next()) |
| |
29 |
67 |
{ |
| |
30 |
68 |
T tEntry; |
| |
31 |
69 |
tEntry.Load(spRowReader); |
| |
32 |
70 |
|
| |
33 |
|
tEntry.ResetModifications(); |
| |
34 |
|
|
| |
35 |
71 |
m_vEntries.push_back(tEntry); |
| |
36 |
72 |
} |
| |
|
73 |
|
| |
|
74 |
|
| |
|
75 |
|
| |
|
76 |
for(T& rItem : m_vEntries) |
| |
|
77 |
{ |
| |
|
78 |
rItem.ResetModifications(); |
| |
37 |
79 |
} |
| |
|
80 |
} |
| |
38 |
81 |
|
| |
39 |
82 |
virtual void InitColumns(const serializer::ISerializerContainerPtr& spContainer) const = 0; |
| |
40 |
83 |
|
| |
41 |
84 |
bool IsEmpty() const |
| |
42 |
85 |
{ |
| |
43 |
86 |
return m_vEntries.empty(); |
| |
44 |
87 |
} |
| |
45 |
88 |
|
| |
46 |
89 |
void Add(const T& rEntry) |
| |
47 |
90 |
{ |
| |
48 |
|
m_vEntries.push_back(rEntry); |
| |
|
91 |
auto iterResult = m_vEntries.insert(m_vEntries.end(), rEntry); |
| |
|
92 |
iterResult->SetObjectID(++m_oidLastObjectID); |
| |
49 |
93 |
} |
| |
50 |
94 |
|
| |
51 |
95 |
bool SetAt(size_t stIndex, const T& rNewEntry) |
| |
52 |
96 |
{ |
| |
53 |
97 |
BOOST_ASSERT(stIndex < m_vEntries.size()); |
| |
54 |
98 |
if(stIndex < m_vEntries.size()) |
| |
55 |
99 |
{ |
| |
56 |
100 |
T& rEntry = m_vEntries.at(stIndex); |
| |
57 |
101 |
|
| |
|
102 |
|
| |
58 |
103 |
rEntry.SetData(rNewEntry); |
| |
59 |
104 |
return true; |
| |
60 |
105 |
} |
| |
61 |
106 |
|
| |
62 |
107 |
return false; |
| |
63 |
108 |
} |
| |
64 |
109 |
|
| |
65 |
110 |
bool InsertAt(size_t stIndex, const T& rNewEntry) |
| |
66 |
111 |
{ |
| |
67 |
112 |
BOOST_ASSERT(stIndex <= m_vEntries.size()); |
| |
68 |
113 |
if(stIndex <= m_vEntries.size()) |
| |
69 |
114 |
{ |
| |
70 |
|
m_vEntries.insert(m_vEntries.begin() + stIndex, rNewEntry); |
| |
|
115 |
auto iterResult = m_vEntries.insert(m_vEntries.begin() + stIndex, rNewEntry); |
| |
|
116 |
iterResult->SetObjectID(++m_oidLastObjectID); |
| |
71 |
117 |
return true; |
| |
72 |
118 |
} |
| |
73 |
119 |
|
| |
74 |
120 |
return false; |
| |
75 |
121 |
} |
| |
76 |
122 |
|
| |
77 |
123 |
const T& GetAt(size_t stIndex) const |
| |
78 |
124 |
{ |
| |
79 |
125 |
if(stIndex >= m_vEntries.size()) |
| |
80 |
126 |
throw std::out_of_range("stIndex is out of range"); |
| |
81 |
127 |
|
| |
82 |
128 |
return m_vEntries.at(stIndex); |
| |
83 |
129 |
} |
| |
84 |
130 |
|
| |
85 |
131 |
T& GetAt(size_t stIndex) |
| |
86 |
132 |
{ |
| |
87 |
133 |
if(stIndex >= m_vEntries.size()) |
| |
88 |
134 |
throw std::out_of_range("stIndex is out of range"); |
| |
89 |
135 |
|
| |
90 |
136 |
return m_vEntries.at(stIndex); |
|
| |
102 |
148 |
} |
| |
103 |
149 |
|
| |
104 |
150 |
return false; |
| |
105 |
151 |
} |
| |
106 |
152 |
|
| |
107 |
153 |
size_t GetCount() const |
| |
108 |
154 |
{ |
| |
109 |
155 |
return m_vEntries.size(); |
| |
110 |
156 |
} |
| |
111 |
157 |
|
| |
112 |
158 |
void Clear() |
| |
113 |
159 |
{ |
| |
114 |
160 |
for(const T& rEntry : m_vEntries) |
| |
115 |
161 |
{ |
| |
116 |
162 |
m_setRemovedObjects.Add(rEntry.GetObjectID()); |
| |
117 |
163 |
} |
| |
118 |
164 |
m_vEntries.clear(); |
| |
119 |
165 |
} |
| |
120 |
166 |
|
| |
121 |
167 |
protected: |
| |
|
168 |
serializer::object_id_t m_oidLastObjectID = 0; |
| |
122 |
169 |
std::vector<T> m_vEntries; |
| |
123 |
170 |
mutable serializer::TRemovedObjects m_setRemovedObjects; |
| |
124 |
171 |
}; |
| |
125 |
172 |
} |