GCC Code Coverage Report


Directory: libimgdoc2/
File: libimgdoc2/src/doc/documentWrite2d.cpp
Date: 2025-02-03 12:41:04
Exec Total Coverage
Lines: 113 116 97.4%
Functions: 11 11 100.0%
Branches: 151 296 51.0%

Line Branch Exec Source
1 // SPDX-FileCopyrightText: 2023 Carl Zeiss Microscopy GmbH
2 //
3 // SPDX-License-Identifier: MIT
4
5 #include <sstream>
6 #include <vector>
7 #include <gsl/gsl>
8 #include "documentWrite2d.h"
9 #include "transactionHelper.h"
10
11 using namespace std;
12 using namespace imgdoc2;
13
14 3270 /*virtual*/imgdoc2::dbIndex DocumentWrite2d::AddTile(
15 const imgdoc2::ITileCoordinate* coordinate,
16 const imgdoc2::LogicalPositionInfo* info,
17 const imgdoc2::TileBaseInfo* tileInfo,
18 imgdoc2::DataTypes datatype,
19 imgdoc2::TileDataStorageType storage_type,
20 const imgdoc2::IDataObjBase* data)
21 {
22 TransactionHelper<dbIndex> transaction{
23 3270 this->document_->GetDatabase_connection(),
24 [&]()->dbIndex
25 {
26 3270 return this->AddTileInternal(coordinate, info, tileInfo, datatype, storage_type, data);
27 }
28
1/2
✓ Branch 4 taken 3270 times.
✗ Branch 5 not taken.
3270 };
29
30
1/2
✓ Branch 1 taken 3270 times.
✗ Branch 2 not taken.
6540 return transaction.Execute();
31 3270 }
32
33 6 /*virtual*/void DocumentWrite2d::BeginTransaction()
34 {
35 6 this->document_->GetDatabase_connection()->BeginTransaction();
36 4 }
37
38 8 /*virtual*/void DocumentWrite2d::CommitTransaction()
39 {
40 8 this->document_->GetDatabase_connection()->EndTransaction(true);
41 2 }
42
43 4 /*virtual*/void DocumentWrite2d::RollbackTransaction()
44 {
45 4 this->document_->GetDatabase_connection()->EndTransaction(false);
46 2 }
47
48 3270 imgdoc2::dbIndex DocumentWrite2d::AddTileInternal(
49 const imgdoc2::ITileCoordinate* coordinate,
50 const imgdoc2::LogicalPositionInfo* info,
51 const imgdoc2::TileBaseInfo* tileInfo,
52 imgdoc2::DataTypes datatype,
53 imgdoc2::TileDataStorageType storage_type,
54 const imgdoc2::IDataObjBase* data)
55 {
56
1/2
✓ Branch 1 taken 3270 times.
✗ Branch 2 not taken.
3270 const auto tiles_data_id = this->AddTileData(tileInfo, datatype, storage_type, data);
57
58
1/2
✓ Branch 1 taken 3270 times.
✗ Branch 2 not taken.
3270 ostringstream string_stream;
59
1/2
✓ Branch 3 taken 3270 times.
✗ Branch 4 not taken.
3270 string_stream << "INSERT INTO [" << this->document_->GetDataBaseConfiguration2d()->GetTableNameForTilesInfoOrThrow() << "] ("
60
1/2
✓ Branch 3 taken 3270 times.
✗ Branch 4 not taken.
6540 << "[" << this->document_->GetDataBaseConfiguration2d()->GetColumnNameOfTilesInfoTableOrThrow(DatabaseConfiguration2D::kTilesInfoTable_Column_TileX) << "],"
61
1/2
✓ Branch 3 taken 3270 times.
✗ Branch 4 not taken.
6540 << "[" << this->document_->GetDataBaseConfiguration2d()->GetColumnNameOfTilesInfoTableOrThrow(DatabaseConfiguration2D::kTilesInfoTable_Column_TileY) << "],"
62
1/2
✓ Branch 3 taken 3270 times.
✗ Branch 4 not taken.
6540 << "[" << this->document_->GetDataBaseConfiguration2d()->GetColumnNameOfTilesInfoTableOrThrow(DatabaseConfiguration2D::kTilesInfoTable_Column_TileW) << "],"
63
1/2
✓ Branch 3 taken 3270 times.
✗ Branch 4 not taken.
6540 << "[" << this->document_->GetDataBaseConfiguration2d()->GetColumnNameOfTilesInfoTableOrThrow(DatabaseConfiguration2D::kTilesInfoTable_Column_TileH) << "],"
64
1/2
✓ Branch 3 taken 3270 times.
✗ Branch 4 not taken.
6540 << "[" << this->document_->GetDataBaseConfiguration2d()->GetColumnNameOfTilesInfoTableOrThrow(DatabaseConfiguration2D::kTilesInfoTable_Column_PyramidLevel) << "],"
65
22/44
✓ Branch 1 taken 3270 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 3270 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 3270 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 3270 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 3270 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 3270 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 3270 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 3270 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 3270 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 3270 times.
✗ Branch 32 not taken.
✓ Branch 35 taken 3270 times.
✗ Branch 36 not taken.
✓ Branch 38 taken 3270 times.
✗ Branch 39 not taken.
✓ Branch 41 taken 3270 times.
✗ Branch 42 not taken.
✓ Branch 45 taken 3270 times.
✗ Branch 46 not taken.
✓ Branch 48 taken 3270 times.
✗ Branch 49 not taken.
✓ Branch 51 taken 3270 times.
✗ Branch 52 not taken.
✓ Branch 55 taken 3270 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 3270 times.
✗ Branch 59 not taken.
✓ Branch 61 taken 3270 times.
✗ Branch 62 not taken.
✓ Branch 67 taken 3270 times.
✗ Branch 68 not taken.
✓ Branch 70 taken 3270 times.
✗ Branch 71 not taken.
✓ Branch 73 taken 3270 times.
✗ Branch 74 not taken.
22890 << "[" << this->document_->GetDataBaseConfiguration2d()->GetColumnNameOfTilesInfoTableOrThrow(DatabaseConfiguration2D::kTilesInfoTable_Column_TileDataId) << "]";
66
67 3270 vector<int> coordinate_values;
68
1/2
✓ Branch 1 taken 3270 times.
✗ Branch 2 not taken.
3270 coordinate->EnumCoordinates(
69
1/2
✓ Branch 1 taken 3270 times.
✗ Branch 2 not taken.
3270 [&](Dimension dimension, int value)->bool
70 {
71 3486 string_stream << ", [" << this->document_->GetDataBaseConfiguration2d()->GetDimensionsColumnPrefix() << dimension << ']';
72 3486 coordinate_values.push_back(value);
73 3486 return true;
74 });
75
76
1/2
✓ Branch 1 taken 3270 times.
✗ Branch 2 not taken.
3270 string_stream << ") VALUES( ?, ?, ?, ?, ?, ?";
77
2/2
✓ Branch 1 taken 3486 times.
✓ Branch 2 taken 3270 times.
6756 for (size_t i = 0; i < coordinate_values.size(); ++i)
78 {
79
1/2
✓ Branch 1 taken 3486 times.
✗ Branch 2 not taken.
3486 string_stream << ", ?";
80 }
81
82
1/2
✓ Branch 1 taken 3270 times.
✗ Branch 2 not taken.
3270 string_stream << ");";
83
84
2/4
✓ Branch 4 taken 3270 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3270 times.
✗ Branch 8 not taken.
3270 const auto statement = this->document_->GetDatabase_connection()->PrepareStatement(string_stream.str());
85 3270 int binding_index = 1;
86
1/2
✓ Branch 2 taken 3270 times.
✗ Branch 3 not taken.
3270 statement->BindDouble(binding_index++, info->posX);
87
1/2
✓ Branch 2 taken 3270 times.
✗ Branch 3 not taken.
3270 statement->BindDouble(binding_index++, info->posY);
88
1/2
✓ Branch 2 taken 3270 times.
✗ Branch 3 not taken.
3270 statement->BindDouble(binding_index++, info->width);
89
1/2
✓ Branch 2 taken 3270 times.
✗ Branch 3 not taken.
3270 statement->BindDouble(binding_index++, info->height);
90
1/2
✓ Branch 2 taken 3270 times.
✗ Branch 3 not taken.
3270 statement->BindInt32(binding_index++, info->pyrLvl);
91
1/2
✓ Branch 2 taken 3270 times.
✗ Branch 3 not taken.
3270 statement->BindInt64(binding_index++, tiles_data_id);
92
93
2/2
✓ Branch 5 taken 3486 times.
✓ Branch 6 taken 3270 times.
6756 for (const int coordinate_value : coordinate_values)
94 {
95
1/2
✓ Branch 2 taken 3486 times.
✗ Branch 3 not taken.
3486 statement->BindInt32(binding_index++, coordinate_value);
96 }
97
98
1/2
✓ Branch 5 taken 3270 times.
✗ Branch 6 not taken.
3270 const auto row_id = this->document_->GetDatabase_connection()->ExecuteAndGetLastRowId(statement.get());
99
100
3/4
✓ Branch 4 taken 3270 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 600 times.
✓ Branch 7 taken 2670 times.
3270 if (this->document_->GetDataBaseConfiguration2d()->GetIsUsingSpatialIndex())
101 {
102
1/2
✓ Branch 1 taken 600 times.
✗ Branch 2 not taken.
600 this->AddToSpatialIndex(row_id, *info);
103 }
104
105 3270 return row_id;
106 3270 }
107
108 3270 imgdoc2::dbIndex DocumentWrite2d::AddTileData(const imgdoc2::TileBaseInfo* tile_info, imgdoc2::DataTypes datatype, imgdoc2::TileDataStorageType storage_type, const imgdoc2::IDataObjBase* data)
109 {
110 // first, add the blob data
111 3270 dbIndex blob_db_index = 0;
112
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 3266 times.
3270 if (data != nullptr)
113 {
114
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 blob_db_index = this->AddBlobData(storage_type, data);
115 }
116
117
1/2
✓ Branch 1 taken 3270 times.
✗ Branch 2 not taken.
3270 ostringstream string_stream;
118
1/2
✓ Branch 3 taken 3270 times.
✗ Branch 4 not taken.
3270 string_stream << "INSERT INTO " << this->document_->GetDataBaseConfiguration2d()->GetTableNameForTilesDataOrThrow() << " ("
119
1/2
✓ Branch 3 taken 3270 times.
✗ Branch 4 not taken.
6540 << "[" << this->document_->GetDataBaseConfiguration2d()->GetColumnNameOfTilesDataTableOrThrow(DatabaseConfiguration2D::kTilesDataTable_Column_PixelWidth) << "],"
120
1/2
✓ Branch 3 taken 3270 times.
✗ Branch 4 not taken.
6540 << "[" << this->document_->GetDataBaseConfiguration2d()->GetColumnNameOfTilesDataTableOrThrow(DatabaseConfiguration2D::kTilesDataTable_Column_PixelHeight) << "],"
121
1/2
✓ Branch 3 taken 3270 times.
✗ Branch 4 not taken.
6540 << "[" << this->document_->GetDataBaseConfiguration2d()->GetColumnNameOfTilesDataTableOrThrow(DatabaseConfiguration2D::kTilesDataTable_Column_PixelType) << "],"
122
1/2
✓ Branch 3 taken 3270 times.
✗ Branch 4 not taken.
6540 << "[" << this->document_->GetDataBaseConfiguration2d()->GetColumnNameOfTilesDataTableOrThrow(DatabaseConfiguration2D::kTilesDataTable_Column_TileDataType) << "],"
123
1/2
✓ Branch 3 taken 3270 times.
✗ Branch 4 not taken.
6540 << "[" << this->document_->GetDataBaseConfiguration2d()->GetColumnNameOfTilesDataTableOrThrow(DatabaseConfiguration2D::kTilesDataTable_Column_BinDataStorageType) << "],"
124
1/2
✓ Branch 3 taken 3270 times.
✗ Branch 4 not taken.
6540 << "[" << this->document_->GetDataBaseConfiguration2d()->GetColumnNameOfTilesDataTableOrThrow(DatabaseConfiguration2D::kTilesDataTable_Column_BinDataId) << "]"
125
21/42
✓ Branch 1 taken 3270 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 3270 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 3270 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 3270 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 3270 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 3270 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 3270 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 3270 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 3270 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 3270 times.
✗ Branch 32 not taken.
✓ Branch 35 taken 3270 times.
✗ Branch 36 not taken.
✓ Branch 38 taken 3270 times.
✗ Branch 39 not taken.
✓ Branch 41 taken 3270 times.
✗ Branch 42 not taken.
✓ Branch 45 taken 3270 times.
✗ Branch 46 not taken.
✓ Branch 48 taken 3270 times.
✗ Branch 49 not taken.
✓ Branch 51 taken 3270 times.
✗ Branch 52 not taken.
✓ Branch 55 taken 3270 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 3270 times.
✗ Branch 59 not taken.
✓ Branch 61 taken 3270 times.
✗ Branch 62 not taken.
✓ Branch 65 taken 3270 times.
✗ Branch 66 not taken.
✓ Branch 68 taken 3270 times.
✗ Branch 69 not taken.
26160 ") VALUES( ?1, ?2, ?3, ?4, ?5, ?6);";
126
127
2/4
✓ Branch 4 taken 3270 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3270 times.
✗ Branch 8 not taken.
3270 const auto statement = this->document_->GetDatabase_connection()->PrepareStatement(string_stream.str());
128
129 3270 int binding_index = 1;
130
1/2
✓ Branch 2 taken 3270 times.
✗ Branch 3 not taken.
3270 statement->BindInt32(binding_index++, tile_info->pixelWidth);
131
1/2
✓ Branch 2 taken 3270 times.
✗ Branch 3 not taken.
3270 statement->BindInt32(binding_index++, tile_info->pixelHeight);
132
1/2
✓ Branch 2 taken 3270 times.
✗ Branch 3 not taken.
3270 statement->BindInt32(binding_index++, tile_info->pixelType);
133
1/2
✓ Branch 2 taken 3270 times.
✗ Branch 3 not taken.
3270 statement->BindInt32(binding_index++, static_cast<underlying_type_t<decltype(datatype)>>(datatype));
134
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 3266 times.
3270 if (data != nullptr)
135 {
136 // for data-type "zero"
137
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 statement->BindInt32(binding_index++, static_cast<underlying_type_t<decltype(storage_type)>>(storage_type));
138
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 statement->BindInt64(binding_index++, blob_db_index);
139 }
140
141
1/2
✓ Branch 5 taken 3270 times.
✗ Branch 6 not taken.
3270 const auto row_id = this->document_->GetDatabase_connection()->ExecuteAndGetLastRowId(statement.get());
142 3270 return row_id;
143 3270 }
144
145 4 imgdoc2::dbIndex DocumentWrite2d::AddBlobData(imgdoc2::TileDataStorageType storage_type, const imgdoc2::IDataObjBase* data)
146 {
147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 Expects(data != nullptr);
148
149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (storage_type != TileDataStorageType::BlobInDatabase)
150 {
151 throw invalid_operation_exception("Storage-types other than 'blob-in-database' are not implemented.");
152 }
153
154
2/4
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
4 if (!this->document_->GetDataBaseConfiguration2d()->GetHasBlobsTable())
155 {
156 throw invalid_operation_exception("The database does not have a blob-table.");
157 }
158
159
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 const auto insert_data_statement = this->CreateInsertDataStatement(data);
160
161
1/2
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 const auto row_id = this->document_->GetDatabase_connection()->ExecuteAndGetLastRowId(insert_data_statement.get());
162 4 return row_id;
163 4 }
164
165 4 std::shared_ptr<IDbStatement> DocumentWrite2d::CreateInsertDataStatement(const imgdoc2::IDataObjBase* data)
166 {
167
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 ostringstream string_stream;
168
1/2
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
4 string_stream << "INSERT INTO [" << this->document_->GetDataBaseConfiguration2d()->GetTableNameForBlobTableOrThrow() << "] ("
169
1/2
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
8 << "[" << this->document_->GetDataBaseConfiguration2d()->GetColumnNameOfBlobTableOrThrow(DatabaseConfigurationCommon::kBlobTable_Column_Data) << "]"
170
7/14
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 4 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 4 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 4 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 4 times.
✗ Branch 22 not taken.
12 << ") VALUES( ?1 );";
171
172
2/4
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
4 auto statement = this->document_->GetDatabase_connection()->PrepareStatement(string_stream.str());
173 4 const void* ptr_data = nullptr;
174 4 size_t size_data = 0;
175
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 data->GetData(&ptr_data, &size_data);
176
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 statement->BindBlob_Static(1, ptr_data, size_data);
177 8 return statement;
178 4 }
179
180 600 void DocumentWrite2d::AddToSpatialIndex(imgdoc2::dbIndex index, const imgdoc2::LogicalPositionInfo& logical_position_info)
181 {
182
1/2
✓ Branch 1 taken 600 times.
✗ Branch 2 not taken.
600 ostringstream string_stream;
183
1/2
✓ Branch 3 taken 600 times.
✗ Branch 4 not taken.
600 string_stream << "INSERT INTO " << this->document_->GetDataBaseConfiguration2d()->GetTableNameForTilesSpatialIndexTableOrThrow() << " ("
184
1/2
✓ Branch 3 taken 600 times.
✗ Branch 4 not taken.
1200 << "[" << this->document_->GetDataBaseConfiguration2d()->GetColumnNameOfTilesSpatialIndexTableOrThrow(DatabaseConfiguration2D::kTilesSpatialIndexTable_Column_Pk) << "],"
185
1/2
✓ Branch 3 taken 600 times.
✗ Branch 4 not taken.
1200 << "[" << this->document_->GetDataBaseConfiguration2d()->GetColumnNameOfTilesSpatialIndexTableOrThrow(DatabaseConfiguration2D::kTilesSpatialIndexTable_Column_MinX) << "],"
186
1/2
✓ Branch 3 taken 600 times.
✗ Branch 4 not taken.
1200 << "[" << this->document_->GetDataBaseConfiguration2d()->GetColumnNameOfTilesSpatialIndexTableOrThrow(DatabaseConfiguration2D::kTilesSpatialIndexTable_Column_MaxX) << "],"
187
1/2
✓ Branch 3 taken 600 times.
✗ Branch 4 not taken.
1200 << "[" << this->document_->GetDataBaseConfiguration2d()->GetColumnNameOfTilesSpatialIndexTableOrThrow(DatabaseConfiguration2D::kTilesSpatialIndexTable_Column_MinY) << "],"
188
1/2
✓ Branch 3 taken 600 times.
✗ Branch 4 not taken.
1200 << "[" << this->document_->GetDataBaseConfiguration2d()->GetColumnNameOfTilesSpatialIndexTableOrThrow(DatabaseConfiguration2D::kTilesSpatialIndexTable_Column_MaxY) << "]"
189
18/36
✓ Branch 1 taken 600 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 600 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 600 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 600 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 600 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 600 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 600 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 600 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 600 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 600 times.
✗ Branch 32 not taken.
✓ Branch 35 taken 600 times.
✗ Branch 36 not taken.
✓ Branch 38 taken 600 times.
✗ Branch 39 not taken.
✓ Branch 41 taken 600 times.
✗ Branch 42 not taken.
✓ Branch 45 taken 600 times.
✗ Branch 46 not taken.
✓ Branch 48 taken 600 times.
✗ Branch 49 not taken.
✓ Branch 51 taken 600 times.
✗ Branch 52 not taken.
✓ Branch 55 taken 600 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 600 times.
✗ Branch 59 not taken.
4200 ") VALUES(?1,?2,?3,?4,?5);";
190
191
2/4
✓ Branch 4 taken 600 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 600 times.
✗ Branch 8 not taken.
600 const auto statement = this->document_->GetDatabase_connection()->PrepareStatement(string_stream.str());
192
193 600 int binding_index = 1;
194
1/2
✓ Branch 2 taken 600 times.
✗ Branch 3 not taken.
600 statement->BindInt64(binding_index++, index);
195
1/2
✓ Branch 2 taken 600 times.
✗ Branch 3 not taken.
600 statement->BindDouble(binding_index++, logical_position_info.posX);
196
1/2
✓ Branch 2 taken 600 times.
✗ Branch 3 not taken.
600 statement->BindDouble(binding_index++, logical_position_info.posX + logical_position_info.width);
197
1/2
✓ Branch 2 taken 600 times.
✗ Branch 3 not taken.
600 statement->BindDouble(binding_index++, logical_position_info.posY);
198
1/2
✓ Branch 2 taken 600 times.
✗ Branch 3 not taken.
600 statement->BindDouble(binding_index++, logical_position_info.posY + logical_position_info.height);
199
200
1/2
✓ Branch 5 taken 600 times.
✗ Branch 6 not taken.
600 this->document_->GetDatabase_connection()->ExecuteAndGetLastRowId(statement.get());
201 600 }
202
203