131 oam.push_back({getAlias(i++, L"qr_xml"), STRING}); |
137 oam.push_back({getAlias(i++, L"qr_xml"), STRING}); |
132 return oam; |
138 return oam; |
133 } |
139 } |
134 |
140 |
135 std::vector<OutputAttribute> getOutputAttributes() override { |
141 std::vector<OutputAttribute> getOutputAttributes() override { |
|
142 bool matchedFile = false; |
136 bool validInput = false; |
143 bool validInput = false; |
137 bool hasSymbols = false; |
144 bool matchedFirst = false; |
138 std::wstring first; |
145 std::wstring first; |
139 std::stringstream xml; |
146 std::stringstream xml; |
140 |
147 |
|
148 std::vector<std::wregex> filePatterns = getOptionsAsPatterns(L"file-pattern"); |
|
149 matchedFile = filePatterns.size() == 0 || matchesAny(getCurrentFile(), filePatterns); |
|
150 |
141 std::vector<Symbol> symbols; |
151 std::vector<Symbol> symbols; |
142 try { |
152 if (matchedFile) { |
143 symbols = findSymbols(getCurrentFile()); |
153 try { |
144 validInput = true; |
154 symbols = findSymbols(getCurrentFile()); |
145 } catch (...) { |
155 validInput = true; |
146 // just ignore the errors; |
156 } catch (...) { |
147 // the file is probably not an image or we do not have read permissions |
157 // just ignore the errors; |
148 validInput = false; |
158 // the file is probably not an image or we do not have read permissions |
|
159 validInput = false; |
|
160 } |
|
161 |
|
162 std::vector<std::wregex> valuePatterns = getOptionsAsPatterns(L"value-pattern"); |
|
163 |
|
164 for (Symbol s : symbols) { |
|
165 if (valuePatterns.size() == 0 || matchesAny(s.value, valuePatterns)) { |
|
166 first = s.value; |
|
167 matchedFirst = true; |
|
168 break; |
|
169 } |
|
170 } |
|
171 |
|
172 relpipe::xmlwriter::XMLWriter xmlWriter(xml); |
|
173 xmlWriter.writeStartElement(L"qr",{L"xmlns", XMLNS}); |
|
174 |
|
175 // TODO: common metadata |
|
176 // xmlWriter.writeStartElement(L"source"); |
|
177 // xmlWriter.writeTextElement(L"height",{}, std::to_wstring(...)); |
|
178 // xmlWriter.writeTextElement(L"width",{}, std::to_wstring(...)); |
|
179 // xmlWriter.writeEndElement(); |
|
180 |
|
181 for (Symbol s : symbols) { |
|
182 xmlWriter.writeStartElement(L"symbol"); |
|
183 xmlWriter.writeTextElement(L"value",{}, s.value); |
|
184 |
|
185 // TODO: well-designed XML schema |
|
186 // TODO: synchronize/share common XML parts with relpipe-in-qr |
|
187 xmlWriter.writeStartElement(L"rectangular-box"); |
|
188 xmlWriter.writeTextElement(L"x",{}, std::to_wstring(s.x)); |
|
189 xmlWriter.writeTextElement(L"y",{}, std::to_wstring(s.y)); |
|
190 xmlWriter.writeTextElement(L"height",{}, std::to_wstring(s.height)); |
|
191 xmlWriter.writeTextElement(L"width",{}, std::to_wstring(s.width)); |
|
192 xmlWriter.writeEndElement(); |
|
193 |
|
194 xmlWriter.writeStartElement(L"polygon"); |
|
195 for (Point p : s.polygon) xmlWriter.writeEmptyElement(L"point",{L"x", std::to_wstring(p.x), L"y", std::to_wstring(p.y)}); |
|
196 xmlWriter.writeEndElement(); |
|
197 |
|
198 xmlWriter.writeEndElement(); |
|
199 } |
|
200 |
|
201 xmlWriter.writeEndElement(); |
|
202 |
149 } |
203 } |
150 |
204 |
151 std::vector<Option> valuePatternOptions = getOptions(L"value-pattern"); |
|
152 std::vector<std::wregex> valuePatterns; |
|
153 for (Option o : valuePatternOptions) valuePatterns.push_back(std::wregex(o.value)); |
|
154 |
|
155 for (Symbol s : symbols) { |
|
156 if (valuePatterns.size() == 0 || matchesAny(s.value, valuePatterns)) { |
|
157 first = s.value; |
|
158 hasSymbols = true; |
|
159 break; |
|
160 } |
|
161 } |
|
162 |
|
163 relpipe::xmlwriter::XMLWriter xmlWriter(xml); |
|
164 xmlWriter.writeStartElement(L"qr",{L"xmlns", XMLNS}); |
|
165 |
|
166 // TODO: common metadata |
|
167 // xmlWriter.writeStartElement(L"source"); |
|
168 // xmlWriter.writeTextElement(L"height",{}, std::to_wstring(...)); |
|
169 // xmlWriter.writeTextElement(L"width",{}, std::to_wstring(...)); |
|
170 // xmlWriter.writeEndElement(); |
|
171 |
|
172 for (Symbol s : symbols) { |
|
173 xmlWriter.writeStartElement(L"symbol"); |
|
174 xmlWriter.writeTextElement(L"value",{}, s.value); |
|
175 |
|
176 // TODO: well-designed XML schema |
|
177 // TODO: synchronize/share common XML parts with relpipe-in-qr |
|
178 xmlWriter.writeStartElement(L"rectangular-box"); |
|
179 xmlWriter.writeTextElement(L"x",{}, std::to_wstring(s.x)); |
|
180 xmlWriter.writeTextElement(L"y",{}, std::to_wstring(s.y)); |
|
181 xmlWriter.writeTextElement(L"height",{}, std::to_wstring(s.height)); |
|
182 xmlWriter.writeTextElement(L"width",{}, std::to_wstring(s.width)); |
|
183 xmlWriter.writeEndElement(); |
|
184 |
|
185 xmlWriter.writeStartElement(L"polygon"); |
|
186 for (Point p : s.polygon) xmlWriter.writeEmptyElement(L"point",{L"x", std::to_wstring(p.x), L"y", std::to_wstring(p.y)}); |
|
187 xmlWriter.writeEndElement(); |
|
188 |
|
189 xmlWriter.writeEndElement(); |
|
190 } |
|
191 |
|
192 xmlWriter.writeEndElement(); |
|
193 |
|
194 std::vector<OutputAttribute> oa; |
205 std::vector<OutputAttribute> oa; |
195 // TODO: report also validInput (distinguish it from hasSymbols) |
206 // TODO: report also validInput and matchedFile (distinguish them from matchedFirst)? |
196 oa.push_back({first, !hasSymbols}); |
207 oa.push_back({first, !matchedFirst}); |
197 oa.push_back({std::to_wstring(symbols.size()), false}); |
208 oa.push_back({std::to_wstring(symbols.size()), !matchedFile}); |
198 oa.push_back({fromBytes(xml.str()), false}); |
209 oa.push_back({fromBytes(xml.str()), !matchedFile}); |
199 return oa; |
210 return oa; |
200 } |
211 } |
201 }; |
212 }; |
202 |
213 |
203 STREAMLET_RUN(QRStreamlet) |
214 STREAMLET_RUN(QRStreamlet) |