1 /******************************************************************************
2
3 This source file is part of the Avogadro project.
4
5 Copyright 2013 Kitware, Inc.
6
7 This source code is released under the New BSD License, (the "License").
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14
15 ******************************************************************************/
16
17 #include "moleculedeserializer.h"
18
19 #include "matrixserialization.h"
20 #include <avogadro/io/fileformatmanager.h>
21 #include <google/protobuf/io/coded_stream.h>
22 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
23
24 #include <iostream>
25
26 using Avogadro::Core::Molecule;
27 using Avogadro::Io::FileFormat;
28 using Avogadro::Io::FileFormatManager;
29
30 using google::protobuf::io::ArrayOutputStream;
31 using google::protobuf::io::CodedOutputStream;
32 using google::protobuf::io::ArrayInputStream;
33 using google::protobuf::io::CodedInputStream;
34 using google::protobuf::uint32;
35 using google::protobuf::uint8;
36
37 namespace Avogadro {
38 namespace Core {
39
MoleculeDeserializer(Molecule * molecule)40 MoleculeDeserializer::MoleculeDeserializer(Molecule* molecule)
41 : m_molecule(molecule)
42 {
43 }
44
deserialize(const void * data,size_t size)45 bool MoleculeDeserializer::deserialize(const void* data, size_t size)
46 {
47 ArrayInputStream ais(data, size);
48 CodedInputStream cis(&ais);
49
50 // Read the atoms
51 if (!this->deserializeAtomicNumbers(&cis))
52 return false;
53
54 // Read the positions2d
55 if (!this->deserializePositions2d(&cis))
56 return false;
57
58 // Read the positions3d
59 if (!this->deserializePostions3d(&cis))
60 return false;
61
62 // Read bond pairs
63 if (!this->deserializeBondPairs(&cis))
64 return false;
65
66 // Read bond orders
67 if (!this->deserializeBondOrders(&cis))
68 return false;
69
70 return true;
71 }
72
deserializeAtomicNumbers(google::protobuf::io::CodedInputStream * stream)73 bool MoleculeDeserializer::deserializeAtomicNumbers(
74 google::protobuf::io::CodedInputStream* stream)
75 {
76 // Read the atoms
77 m_molecule->clearAtoms();
78 uint32 numberOfAtoms;
79 if (!stream->ReadLittleEndian32(&numberOfAtoms))
80 return false;
81 for (uint32 i = 0; i < numberOfAtoms; i++) {
82 unsigned char atom;
83 if (!stream->ReadRaw(&atom, sizeof(unsigned char)))
84 return false;
85 m_molecule->addAtom(atom);
86 }
87
88 return true;
89 }
90
deserializePositions2d(google::protobuf::io::CodedInputStream * stream)91 bool MoleculeDeserializer::deserializePositions2d(
92 google::protobuf::io::CodedInputStream* stream)
93 {
94 // Get the count
95 uint32 posCount;
96 if (!stream->ReadLittleEndian32(&posCount))
97 return false;
98 // Clear an current positions
99 m_molecule->atomPositions2d().clear();
100 for (uint32 i = 0; i < posCount; i++) {
101 Avogadro::Vector2 vec2;
102 if (!ProtoCall::MatrixSerialization::deserialize(vec2, stream))
103 return false;
104 m_molecule->atomPositions2d().push_back(vec2);
105 }
106
107 return true;
108 }
109
deserializePostions3d(google::protobuf::io::CodedInputStream * stream)110 bool MoleculeDeserializer::deserializePostions3d(
111 google::protobuf::io::CodedInputStream* stream)
112 {
113 // Get the count
114 uint32 posCount;
115 if (!stream->ReadLittleEndian32(&posCount))
116 return false;
117 // Clear an current positions
118 m_molecule->atomPositions3d().clear();
119 for (uint32 i = 0; i < posCount; i++) {
120 Avogadro::Vector3 vec3;
121 if (!ProtoCall::MatrixSerialization::deserialize(vec3, stream))
122 return false;
123 m_molecule->atomPositions3d().push_back(vec3);
124 }
125
126 return true;
127 }
128
deserializeBondPairs(google::protobuf::io::CodedInputStream * stream)129 bool MoleculeDeserializer::deserializeBondPairs(
130 google::protobuf::io::CodedInputStream* stream)
131 {
132 uint32 bondCount;
133 if (!stream->ReadLittleEndian32(&bondCount))
134 return false;
135
136 // Clear and bond pairs
137 m_molecule->bondPairs().clear();
138
139 for (uint32 i = 0; i < bondCount; i++) {
140 uint32 from, to;
141 if (!stream->ReadLittleEndian32(&from))
142 return false;
143 if (!stream->ReadLittleEndian32(&to))
144 return false;
145 std::pair<size_t, size_t> bond;
146 bond.first = from;
147 bond.second = to;
148 m_molecule->bondPairs().push_back(bond);
149 }
150
151 return true;
152 }
153
deserializeBondOrders(google::protobuf::io::CodedInputStream * stream)154 bool MoleculeDeserializer::deserializeBondOrders(
155 google::protobuf::io::CodedInputStream* stream)
156 {
157 uint32 bondOrderCount;
158 if (!stream->ReadLittleEndian32(&bondOrderCount))
159 return false;
160
161 // Clear bond order
162 m_molecule->bondOrders().clear();
163
164 for (uint32 i = 0; i < bondOrderCount; i++) {
165 unsigned char bond;
166 if (!stream->ReadRaw(&bond, sizeof(unsigned char)))
167 return false;
168
169 m_molecule->bondOrders().push_back(bond);
170 }
171
172 return true;
173 }
174
175 } // namespace Core
176 } // namespace Avogadro
177