1 /* sane - Scanner Access Now Easy.
2 
3    Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
4 
5    This file is part of the SANE package.
6 
7    This program is free software; you can redistribute it and/or
8    modify it under the terms of the GNU General Public License as
9    published by the Free Software Foundation; either version 2 of the
10    License, or (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <https://www.gnu.org/licenses/>.
19 
20    As a special exception, the authors of SANE give permission for
21    additional uses of the libraries contained in this release of SANE.
22 
23    The exception is that, if you link a SANE library with other files
24    to produce an executable, this does not by itself cause the
25    resulting executable to be covered by the GNU General Public
26    License.  Your use of that executable is in no way restricted on
27    account of linking the SANE library code into it.
28 
29    This exception does not, however, invalidate any other reasons why
30    the executable file might be covered by the GNU General Public
31    License.
32 
33    If you submit changes to SANE to the maintainers to be included in
34    a subsequent release, you agree by submitting the changes that
35    those changes may be distributed with this exception intact.
36 
37    If you write modifications of your own for SANE, it is your choice
38    whether to permit this exception to apply to your modifications.
39    If you do not wish that, delete this exception notice.
40 */
41 
42 #define DEBUG_DECLARE_ONLY
43 
44 #include "enums.h"
45 #include "genesys.h"
46 #include <iomanip>
47 
48 namespace genesys {
49 
scan_method_to_option_string(ScanMethod method)50 const char* scan_method_to_option_string(ScanMethod method)
51 {
52     switch (method) {
53         case ScanMethod::FLATBED: return STR_FLATBED;
54         case ScanMethod::TRANSPARENCY: return STR_TRANSPARENCY_ADAPTER;
55         case ScanMethod::TRANSPARENCY_INFRARED: return STR_TRANSPARENCY_ADAPTER_INFRARED;
56     }
57     throw SaneException("Unknown scan method %d", static_cast<unsigned>(method));
58 }
59 
option_string_to_scan_method(const std::string & str)60 ScanMethod option_string_to_scan_method(const std::string& str)
61 {
62     if (str == STR_FLATBED) {
63         return ScanMethod::FLATBED;
64     } else if (str == STR_TRANSPARENCY_ADAPTER) {
65         return ScanMethod::TRANSPARENCY;
66     } else if (str == STR_TRANSPARENCY_ADAPTER_INFRARED) {
67         return ScanMethod::TRANSPARENCY_INFRARED;
68     }
69     throw SaneException("Unknown scan method option %s", str.c_str());
70 }
71 
scan_color_mode_to_option_string(ScanColorMode mode)72 const char* scan_color_mode_to_option_string(ScanColorMode mode)
73 {
74     switch (mode) {
75         case ScanColorMode::COLOR_SINGLE_PASS: return SANE_VALUE_SCAN_MODE_COLOR;
76         case ScanColorMode::GRAY: return SANE_VALUE_SCAN_MODE_GRAY;
77         case ScanColorMode::HALFTONE: return SANE_VALUE_SCAN_MODE_HALFTONE;
78         case ScanColorMode::LINEART: return SANE_VALUE_SCAN_MODE_LINEART;
79     }
80     throw SaneException("Unknown scan mode %d", static_cast<unsigned>(mode));
81 }
82 
option_string_to_scan_color_mode(const std::string & str)83 ScanColorMode option_string_to_scan_color_mode(const std::string& str)
84 {
85     if (str == SANE_VALUE_SCAN_MODE_COLOR) {
86         return ScanColorMode::COLOR_SINGLE_PASS;
87     } else if (str == SANE_VALUE_SCAN_MODE_GRAY) {
88         return ScanColorMode::GRAY;
89     } else if (str == SANE_VALUE_SCAN_MODE_HALFTONE) {
90         return ScanColorMode::HALFTONE;
91     } else if (str == SANE_VALUE_SCAN_MODE_LINEART) {
92         return ScanColorMode::LINEART;
93     }
94     throw SaneException("Unknown scan color mode %s", str.c_str());
95 }
96 
97 
operator <<(std::ostream & out,ColorFilter mode)98 std::ostream& operator<<(std::ostream& out, ColorFilter mode)
99 {
100     switch (mode) {
101         case ColorFilter::RED: out << "RED"; break;
102         case ColorFilter::GREEN: out << "GREEN"; break;
103         case ColorFilter::BLUE: out << "BLUE"; break;
104         case ColorFilter::NONE: out << "NONE"; break;
105         default: out << static_cast<unsigned>(mode); break;
106     }
107     return out;
108 }
109 
operator <<(std::ostream & out,ModelId id)110 std::ostream& operator<<(std::ostream& out, ModelId id)
111 {
112     switch (id) {
113         case ModelId::UNKNOWN: out << "UNKNOWN"; break;
114         case ModelId::CANON_4400F: out << "CANON_4400F"; break;
115         case ModelId::CANON_5600F: out << "CANON_5600F"; break;
116         case ModelId::CANON_8400F: out << "CANON_8400F"; break;
117         case ModelId::CANON_8600F: out << "CANON_8600F"; break;
118         case ModelId::CANON_IMAGE_FORMULA_101: out << "CANON_IMAGE_FORMULA_101"; break;
119         case ModelId::CANON_LIDE_50: out << "CANON_LIDE_50"; break;
120         case ModelId::CANON_LIDE_60: out << "CANON_LIDE_60"; break;
121         case ModelId::CANON_LIDE_80: out << "CANON_LIDE_80"; break;
122         case ModelId::CANON_LIDE_90: out << "CANON_LIDE_90"; break;
123         case ModelId::CANON_LIDE_100: out << "CANON_LIDE_100"; break;
124         case ModelId::CANON_LIDE_110: out << "CANON_LIDE_110"; break;
125         case ModelId::CANON_LIDE_120: out << "CANON_LIDE_120"; break;
126         case ModelId::CANON_LIDE_200: out << "CANON_LIDE_200"; break;
127         case ModelId::CANON_LIDE_210: out << "CANON_LIDE_210"; break;
128         case ModelId::CANON_LIDE_220: out << "CANON_LIDE_220"; break;
129         case ModelId::CANON_LIDE_700F: out << "CANON_LIDE_700F"; break;
130         case ModelId::DCT_DOCKETPORT_487: out << "DCT_DOCKETPORT_487"; break;
131         case ModelId::HP_SCANJET_2300C: out << "HP_SCANJET_2300C"; break;
132         case ModelId::HP_SCANJET_2400C: out << "HP_SCANJET_2400C"; break;
133         case ModelId::HP_SCANJET_3670: out << "HP_SCANJET_3670"; break;
134         case ModelId::HP_SCANJET_4850C: out << "HP_SCANJET_4850C"; break;
135         case ModelId::HP_SCANJET_G4010: out << "HP_SCANJET_G4010"; break;
136         case ModelId::HP_SCANJET_G4050: out << "HP_SCANJET_G4050"; break;
137         case ModelId::HP_SCANJET_N6310: out << "HP_SCANJET_N6310"; break;
138         case ModelId::MEDION_MD5345: out << "MEDION_MD5345"; break;
139         case ModelId::PANASONIC_KV_SS080: out << "PANASONIC_KV_SS080"; break;
140         case ModelId::PENTAX_DSMOBILE_600: out << "PENTAX_DSMOBILE_600"; break;
141         case ModelId::PLUSTEK_OPTICBOOK_3800: out << "PLUSTEK_OPTICBOOK_3800"; break;
142         case ModelId::PLUSTEK_OPTICFILM_7200: out << "PLUSTEK_OPTICFILM_7200"; break;
143         case ModelId::PLUSTEK_OPTICFILM_7200I: out << "PLUSTEK_OPTICFILM_7200I"; break;
144         case ModelId::PLUSTEK_OPTICFILM_7300: out << "PLUSTEK_OPTICFILM_7300"; break;
145         case ModelId::PLUSTEK_OPTICFILM_7400: out << "PLUSTEK_OPTICFILM_7400"; break;
146         case ModelId::PLUSTEK_OPTICFILM_7500I: out << "PLUSTEK_OPTICFILM_7500I"; break;
147         case ModelId::PLUSTEK_OPTICFILM_8200I: out << "PLUSTEK_OPTICFILM_8200I"; break;
148         case ModelId::PLUSTEK_OPTICPRO_3600: out << "PLUSTEK_OPTICPRO_3600"; break;
149         case ModelId::PLUSTEK_OPTICPRO_ST12: out << "PLUSTEK_OPTICPRO_ST12"; break;
150         case ModelId::PLUSTEK_OPTICPRO_ST24: out << "PLUSTEK_OPTICPRO_ST24"; break;
151         case ModelId::SYSCAN_DOCKETPORT_465: out << "SYSCAN_DOCKETPORT_465"; break;
152         case ModelId::SYSCAN_DOCKETPORT_467: out << "SYSCAN_DOCKETPORT_467"; break;
153         case ModelId::SYSCAN_DOCKETPORT_485: out << "SYSCAN_DOCKETPORT_485"; break;
154         case ModelId::SYSCAN_DOCKETPORT_665: out << "SYSCAN_DOCKETPORT_665"; break;
155         case ModelId::SYSCAN_DOCKETPORT_685: out << "SYSCAN_DOCKETPORT_685"; break;
156         case ModelId::UMAX_ASTRA_4500: out << "UMAX_ASTRA_4500"; break;
157         case ModelId::VISIONEER_7100: out << "VISIONEER_7100"; break;
158         case ModelId::VISIONEER_ROADWARRIOR: out << "VISIONEER_ROADWARRIOR"; break;
159         case ModelId::VISIONEER_STROBE_XP100_REVISION3:
160             out << "VISIONEER_STROBE_XP100_REVISION3"; break;
161         case ModelId::VISIONEER_STROBE_XP200: out << "VISIONEER_STROBE_XP200"; break;
162         case ModelId::VISIONEER_STROBE_XP300: out << "VISIONEER_STROBE_XP300"; break;
163         case ModelId::XEROX_2400: out << "XEROX_2400"; break;
164         case ModelId::XEROX_TRAVELSCANNER_100: out << "XEROX_TRAVELSCANNER_100"; break;
165         default:
166             out << static_cast<unsigned>(id); break;
167     }
168     return out;
169 }
170 
operator <<(std::ostream & out,SensorId id)171 std::ostream& operator<<(std::ostream& out, SensorId id)
172 {
173     switch (id) {
174         case SensorId::CCD_5345: out << "CCD_5345"; break;
175         case SensorId::CCD_CANON_4400F: out << "CCD_CANON_4400F"; break;
176         case SensorId::CCD_CANON_5600F: out << "CCD_CANON_5600F"; break;
177         case SensorId::CCD_CANON_8400F: out << "CCD_CANON_8400F"; break;
178         case SensorId::CCD_CANON_8600F: out << "CCD_CANON_8600F"; break;
179         case SensorId::CCD_DP665: out << "CCD_DP665"; break;
180         case SensorId::CCD_DP685: out << "CCD_DP685"; break;
181         case SensorId::CCD_DSMOBILE600: out << "CCD_DSMOBILE600"; break;
182         case SensorId::CCD_DOCKETPORT_487: out << "CCD_DOCKETPORT_487"; break;
183         case SensorId::CCD_G4050: out << "CCD_G4050"; break;
184         case SensorId::CCD_HP2300: out << "CCD_HP2300"; break;
185         case SensorId::CCD_HP2400: out << "CCD_HP2400"; break;
186         case SensorId::CCD_HP3670: out << "CCD_HP3670"; break;
187         case SensorId::CCD_HP_N6310: out << "CCD_HP_N6310"; break;
188         case SensorId::CCD_HP_4850C: out << "CCD_HP_4850C"; break;
189         case SensorId::CCD_IMG101: out << "CCD_IMG101"; break;
190         case SensorId::CCD_KVSS080: out << "CCD_KVSS080"; break;
191         case SensorId::CCD_PLUSTEK_OPTICBOOK_3800: out << "CCD_PLUSTEK_OPTICBOOK_3800"; break;
192         case SensorId::CCD_PLUSTEK_OPTICFILM_7200: out << "CCD_PLUSTEK_OPTICFILM_7200"; break;
193         case SensorId::CCD_PLUSTEK_OPTICFILM_7200I: out << "CCD_PLUSTEK_OPTICFILM_7200I"; break;
194         case SensorId::CCD_PLUSTEK_OPTICFILM_7300: out << "CCD_PLUSTEK_OPTICFILM_7300"; break;
195         case SensorId::CCD_PLUSTEK_OPTICFILM_7400: out << "CCD_PLUSTEK_OPTICFILM_7400"; break;
196         case SensorId::CCD_PLUSTEK_OPTICFILM_7500I: out << "CCD_PLUSTEK_OPTICFILM_7500I"; break;
197         case SensorId::CCD_PLUSTEK_OPTICFILM_8200I: out << "CCD_PLUSTEK_OPTICFILM_8200I"; break;
198         case SensorId::CCD_PLUSTEK_OPTICPRO_3600: out << "CCD_PLUSTEK_OPTICPRO_3600"; break;
199         case SensorId::CCD_ROADWARRIOR: out << "CCD_ROADWARRIOR"; break;
200         case SensorId::CCD_ST12: out << "CCD_ST12"; break;
201         case SensorId::CCD_ST24: out << "CCD_ST24"; break;
202         case SensorId::CCD_UMAX: out << "CCD_UMAX"; break;
203         case SensorId::CCD_XP300: out << "CCD_XP300"; break;
204         case SensorId::CIS_CANON_LIDE_35: out << "CIS_CANON_LIDE_35"; break;
205         case SensorId::CIS_CANON_LIDE_60: out << "CIS_CANON_LIDE_60"; break;
206         case SensorId::CIS_CANON_LIDE_80: out << "CIS_CANON_LIDE_80"; break;
207         case SensorId::CIS_CANON_LIDE_90: out << "CIS_CANON_LIDE_90"; break;
208         case SensorId::CIS_CANON_LIDE_100: out << "CIS_CANON_LIDE_100"; break;
209         case SensorId::CIS_CANON_LIDE_110: out << "CIS_CANON_LIDE_110"; break;
210         case SensorId::CIS_CANON_LIDE_120: out << "CIS_CANON_LIDE_120"; break;
211         case SensorId::CIS_CANON_LIDE_200: out << "CIS_CANON_LIDE_200"; break;
212         case SensorId::CIS_CANON_LIDE_210: out << "CIS_CANON_LIDE_210"; break;
213         case SensorId::CIS_CANON_LIDE_220: out << "CIS_CANON_LIDE_220"; break;
214         case SensorId::CIS_CANON_LIDE_700F: out << "CIS_CANON_LIDE_700F"; break;
215         case SensorId::CIS_XP200: out << "CIS_XP200"; break;
216         default:
217             out << static_cast<unsigned>(id); break;
218     }
219     return out;
220 }
221 
operator <<(std::ostream & out,AdcId id)222 std::ostream& operator<<(std::ostream& out, AdcId id)
223 {
224     switch (id) {
225         case AdcId::UNKNOWN: out << "UNKNOWN"; break;
226         case AdcId::AD_XP200: out << "AD_XP200"; break;
227         case AdcId::CANON_LIDE_35: out << "CANON_LIDE_35"; break;
228         case AdcId::CANON_LIDE_80: out << "CANON_LIDE_80"; break;
229         case AdcId::CANON_LIDE_90: out << "CANON_LIDE_90"; break;
230         case AdcId::CANON_LIDE_110: out << "CANON_LIDE_110"; break;
231         case AdcId::CANON_LIDE_120: out << "CANON_LIDE_120"; break;
232         case AdcId::CANON_LIDE_200: out << "CANON_LIDE_200"; break;
233         case AdcId::CANON_LIDE_700F: out << "CANON_LIDE_700F"; break;
234         case AdcId::CANON_4400F: out << "CANON_4400F"; break;
235         case AdcId::CANON_5600F: out << "CANON_5600F"; break;
236         case AdcId::CANON_8400F: out << "CANON_8400F"; break;
237         case AdcId::CANON_8600F: out << "CANON_8600F"; break;
238         case AdcId::G4050: out << "G4050"; break;
239         case AdcId::IMG101: out << "IMG101"; break;
240         case AdcId::KVSS080: out << "KVSS080"; break;
241         case AdcId::PLUSTEK_OPTICBOOK_3800: out << "PLUSTEK_OPTICBOOK_3800"; break;
242         case AdcId::PLUSTEK_OPTICFILM_7200: out << "PLUSTEK_OPTICFILM_7200"; break;
243         case AdcId::PLUSTEK_OPTICFILM_7200I: out << "PLUSTEK_OPTICFILM_7200I"; break;
244         case AdcId::PLUSTEK_OPTICFILM_7300: out << "PLUSTEK_OPTICFILM_7300"; break;
245         case AdcId::PLUSTEK_OPTICFILM_7400: out << "PLUSTEK_OPTICFILM_7400"; break;
246         case AdcId::PLUSTEK_OPTICFILM_7500I: out << "PLUSTEK_OPTICFILM_7500I"; break;
247         case AdcId::PLUSTEK_OPTICFILM_8200I: out << "PLUSTEK_OPTICFILM_8200I"; break;
248         case AdcId::PLUSTEK_OPTICPRO_3600: out << "PLUSTEK_OPTICPRO_3600"; break;
249         case AdcId::WOLFSON_5345: out << "WOLFSON_5345"; break;
250         case AdcId::WOLFSON_DSM600: out << "WOLFSON_DSM600"; break;
251         case AdcId::WOLFSON_HP2300: out << "WOLFSON_HP2300"; break;
252         case AdcId::WOLFSON_HP2400: out << "WOLFSON_HP2400"; break;
253         case AdcId::WOLFSON_HP3670: out << "WOLFSON_HP3670"; break;
254         case AdcId::WOLFSON_ST12: out << "WOLFSON_ST12"; break;
255         case AdcId::WOLFSON_ST24: out << "WOLFSON_ST24"; break;
256         case AdcId::WOLFSON_UMAX: out << "WOLFSON_UMAX"; break;
257         case AdcId::WOLFSON_XP300: out << "WOLFSON_XP300"; break;
258         default:
259             out << static_cast<unsigned>(id); break;
260     }
261     return out;
262 }
263 
operator <<(std::ostream & out,GpioId id)264 std::ostream& operator<<(std::ostream& out, GpioId id)
265 {
266     switch (id) {
267         case GpioId::UNKNOWN: out << "UNKNOWN"; break;
268         case GpioId::CANON_LIDE_35: out << "CANON_LIDE_35"; break;
269         case GpioId::CANON_LIDE_80: out << "CANON_LIDE_80"; break;
270         case GpioId::CANON_LIDE_90: out << "CANON_LIDE_90"; break;
271         case GpioId::CANON_LIDE_110: out << "CANON_LIDE_110"; break;
272         case GpioId::CANON_LIDE_120: out << "CANON_LIDE_120"; break;
273         case GpioId::CANON_LIDE_200: out << "CANON_LIDE_200"; break;
274         case GpioId::CANON_LIDE_210: out << "CANON_LIDE_210"; break;
275         case GpioId::CANON_LIDE_700F: out << "CANON_LIDE_700F"; break;
276         case GpioId::CANON_4400F: out << "CANON_4400F"; break;
277         case GpioId::CANON_5600F: out << "CANON_5600F"; break;
278         case GpioId::CANON_8400F: out << "CANON_8400F"; break;
279         case GpioId::CANON_8600F: out << "CANON_8600F"; break;
280         case GpioId::DP665: out << "DP665"; break;
281         case GpioId::DP685: out << "DP685"; break;
282         case GpioId::G4050: out << "G4050"; break;
283         case GpioId::HP2300: out << "HP2300"; break;
284         case GpioId::HP2400: out << "HP2400"; break;
285         case GpioId::HP3670: out << "HP3670"; break;
286         case GpioId::HP_N6310: out << "HP_N6310"; break;
287         case GpioId::IMG101: out << "IMG101"; break;
288         case GpioId::KVSS080: out << "KVSS080"; break;
289         case GpioId::MD_5345: out << "MD_5345"; break;
290         case GpioId::PLUSTEK_OPTICBOOK_3800: out << "PLUSTEK_OPTICBOOK_3800"; break;
291         case GpioId::PLUSTEK_OPTICFILM_7200I: out << "PLUSTEK_OPTICFILM_7200I"; break;
292         case GpioId::PLUSTEK_OPTICFILM_7300: out << "PLUSTEK_OPTICFILM_7300"; break;
293         case GpioId::PLUSTEK_OPTICFILM_7400: out << "PLUSTEK_OPTICFILM_7400"; break;
294         case GpioId::PLUSTEK_OPTICFILM_7500I: out << "PLUSTEK_OPTICFILM_7500I"; break;
295         case GpioId::PLUSTEK_OPTICFILM_8200I: out << "PLUSTEK_OPTICFILM_8200I"; break;
296         case GpioId::PLUSTEK_OPTICPRO_3600: out << "PLUSTEK_OPTICPRO_3600"; break;
297         case GpioId::ST12: out << "ST12"; break;
298         case GpioId::ST24: out << "ST24"; break;
299         case GpioId::UMAX: out << "UMAX"; break;
300         case GpioId::XP200: out << "XP200"; break;
301         case GpioId::XP300: out << "XP300"; break;
302         default: out << static_cast<unsigned>(id); break;
303     }
304     return out;
305 }
306 
operator <<(std::ostream & out,MotorId id)307 std::ostream& operator<<(std::ostream& out, MotorId id)
308 {
309     switch (id) {
310         case MotorId::UNKNOWN: out << "UNKNOWN"; break;
311         case MotorId::CANON_LIDE_90: out << "CANON_LIDE_90"; break;
312         case MotorId::CANON_LIDE_100: out << "CANON_LIDE_100"; break;
313         case MotorId::CANON_LIDE_110: out << "CANON_LIDE_110"; break;
314         case MotorId::CANON_LIDE_120: out << "CANON_LIDE_120"; break;
315         case MotorId::CANON_LIDE_200: out << "CANON_LIDE_200"; break;
316         case MotorId::CANON_LIDE_210: out << "CANON_LIDE_210"; break;
317         case MotorId::CANON_LIDE_35: out << "CANON_LIDE_35"; break;
318         case MotorId::CANON_LIDE_60: out << "CANON_LIDE_60"; break;
319         case MotorId::CANON_LIDE_700: out << "CANON_LIDE_700"; break;
320         case MotorId::CANON_LIDE_80: out << "CANON_LIDE_80"; break;
321         case MotorId::CANON_4400F: out << "CANON_4400F"; break;
322         case MotorId::CANON_5600F: out << "CANON_5600F"; break;
323         case MotorId::CANON_8400F: out << "CANON_8400F"; break;
324         case MotorId::CANON_8600F: out << "CANON_8600F"; break;
325         case MotorId::DP665: out << "DP665"; break;
326         case MotorId::DSMOBILE_600: out << "DSMOBILE_600"; break;
327         case MotorId::G4050: out << "G4050"; break;
328         case MotorId::HP2300: out << "HP2300"; break;
329         case MotorId::HP2400: out << "HP2400"; break;
330         case MotorId::HP3670: out << "HP3670"; break;
331         case MotorId::IMG101: out << "IMG101"; break;
332         case MotorId::KVSS080: out << "KVSS080"; break;
333         case MotorId::MD_5345: out << "MD_5345"; break;
334         case MotorId::PLUSTEK_OPTICBOOK_3800: out << "PLUSTEK_OPTICBOOK_3800"; break;
335         case MotorId::PLUSTEK_OPTICFILM_7200: out << "PLUSTEK_OPTICFILM_7200"; break;
336         case MotorId::PLUSTEK_OPTICFILM_7200I: out << "PLUSTEK_OPTICFILM_7200I"; break;
337         case MotorId::PLUSTEK_OPTICFILM_7300: out << "PLUSTEK_OPTICFILM_7300"; break;
338         case MotorId::PLUSTEK_OPTICFILM_7400: out << "PLUSTEK_OPTICFILM_7400"; break;
339         case MotorId::PLUSTEK_OPTICFILM_7500I: out << "PLUSTEK_OPTICFILM_7500I"; break;
340         case MotorId::PLUSTEK_OPTICFILM_8200I: out << "PLUSTEK_OPTICFILM_8200I"; break;
341         case MotorId::PLUSTEK_OPTICPRO_3600: out << "PLUSTEK_OPTICPRO_3600"; break;
342         case MotorId::ROADWARRIOR: out << "ROADWARRIOR"; break;
343         case MotorId::ST24: out << "ST24"; break;
344         case MotorId::UMAX: out << "UMAX"; break;
345         case MotorId::XP200: out << "XP200"; break;
346         case MotorId::XP300: out << "XP300"; break;
347         default: out << static_cast<unsigned>(id); break;
348     }
349     return out;
350 }
351 
operator <<(std::ostream & out,StepType type)352 std::ostream& operator<<(std::ostream& out, StepType type)
353 {
354     switch (type) {
355         case StepType::FULL: out << "1/1"; break;
356         case StepType::HALF: out << "1/2"; break;
357         case StepType::QUARTER: out << "1/4"; break;
358         case StepType::EIGHTH: out << "1/8"; break;
359         default: out << static_cast<unsigned>(type); break;
360     }
361     return out;
362 }
363 
operator <<(std::ostream & out,ScanFlag flags)364 std::ostream& operator<<(std::ostream& out, ScanFlag flags)
365 {
366     StreamStateSaver state_saver{out};
367     out << "0x" << std::hex << static_cast<unsigned>(flags);
368     return out;
369 }
370 
371 } // namespace genesys
372