equal
deleted
inserted
replaced
29 * |
29 * |
30 * It provides three attributes: |
30 * It provides three attributes: |
31 * - qr: first QR code found (if any) |
31 * - qr: first QR code found (if any) |
32 * - qr_count: number of QR codes found |
32 * - qr_count: number of QR codes found |
33 * - qr_xml: XML containing all QR cpdes found an additional metadata |
33 * - qr_xml: XML containing all QR cpdes found an additional metadata |
34 * |
34 * |
|
35 * Options: |
|
36 * - value-pattern: regular expression describing expected value of QR code; |
|
37 * if one or more options are given, the "qr" attribute will contain first value matching any of these patterns |
|
38 * |
35 */ |
39 */ |
36 class QRStreamlet : public Streamlet { |
40 class QRStreamlet : public Streamlet { |
37 private: |
41 private: |
38 |
42 |
39 const wstring XMLNS = L"tag:globalcode.info,2018:qr:FIXME:final-xmlns"; // FIXME: correct xmlns URI |
43 const wstring XMLNS = L"tag:globalcode.info,2018:qr:FIXME:final-xmlns"; // FIXME: correct xmlns URI |
108 |
112 |
109 |
113 |
110 return result; |
114 return result; |
111 } |
115 } |
112 |
116 |
|
117 bool matchesAny(const std::wstring& value, const std::vector<std::wregex>& valuePatterns) { |
|
118 for (const std::wregex& pattern : valuePatterns) { |
|
119 if (std::regex_match(value, pattern)) return true; |
|
120 } |
|
121 return false; |
|
122 } |
|
123 |
113 protected: |
124 protected: |
114 |
125 |
115 std::vector<AttributeMetadata> getOutputAttributesMetadata() override { |
126 std::vector<AttributeMetadata> getOutputAttributesMetadata() override { |
116 std::vector<AttributeMetadata> oam; |
127 std::vector<AttributeMetadata> oam; |
117 int i = 0; |
128 int i = 0; |
135 // just ignore the errors; |
146 // just ignore the errors; |
136 // the file is probably not an image or we do not have read permissions |
147 // the file is probably not an image or we do not have read permissions |
137 validInput = false; |
148 validInput = false; |
138 } |
149 } |
139 |
150 |
|
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 |
140 for (Symbol s : symbols) { |
155 for (Symbol s : symbols) { |
141 // TODO: match against pattern (if any) |
156 if (valuePatterns.size() == 0 || matchesAny(s.value, valuePatterns)) { |
142 first = s.value; |
157 first = s.value; |
143 hasSymbols = true; |
158 hasSymbols = true; |
144 break; |
159 break; |
|
160 } |
145 } |
161 } |
146 |
162 |
147 relpipe::xmlwriter::XMLWriter xmlWriter(xml); |
163 relpipe::xmlwriter::XMLWriter xmlWriter(xml); |
148 xmlWriter.writeStartElement(L"qr",{L"xmlns", XMLNS}); |
164 xmlWriter.writeStartElement(L"qr",{L"xmlns", XMLNS}); |
149 |
165 |
154 // xmlWriter.writeEndElement(); |
170 // xmlWriter.writeEndElement(); |
155 |
171 |
156 for (Symbol s : symbols) { |
172 for (Symbol s : symbols) { |
157 xmlWriter.writeStartElement(L"symbol"); |
173 xmlWriter.writeStartElement(L"symbol"); |
158 xmlWriter.writeTextElement(L"value",{}, s.value); |
174 xmlWriter.writeTextElement(L"value",{}, s.value); |
159 |
175 |
160 // TODO: well-designed XML schema |
176 // TODO: well-designed XML schema |
161 // TODO: synchronize/share common XML parts with relpipe-in-qr |
177 // TODO: synchronize/share common XML parts with relpipe-in-qr |
162 xmlWriter.writeStartElement(L"rectangular-box"); |
178 xmlWriter.writeStartElement(L"rectangular-box"); |
163 xmlWriter.writeTextElement(L"x",{}, std::to_wstring(s.x)); |
179 xmlWriter.writeTextElement(L"x",{}, std::to_wstring(s.x)); |
164 xmlWriter.writeTextElement(L"y",{}, std::to_wstring(s.y)); |
180 xmlWriter.writeTextElement(L"y",{}, std::to_wstring(s.y)); |