@@ -55,6 +55,31 @@ class CDCParseBuffer final {
55
55
uint32_t offset = 0 ;
56
56
};
57
57
58
+ /*
59
+ Helper to read a string
60
+ returns Done when the string is ready (in buf.get_ptr())
61
+ returns Error when we've reached the max length without a terminator
62
+ returns Continue when there is currently no more data to read
63
+ */
64
+ static CDCCommand::Status cdc_read_string (CDCParseBuffer &buf, uint32_t max_len) {
65
+ while (true ) {
66
+ auto buf_ptr = buf.get_current_ptr ();
67
+
68
+ if (!usb_cdc_read (buf_ptr, 1 ))
69
+ return CDCCommand::Status::Continue;
70
+
71
+ // end of string
72
+ if (*buf_ptr == 0 )
73
+ return CDCCommand::Status::Done;
74
+
75
+ buf.add_read (1 );
76
+
77
+ // too long
78
+ if (buf.get_offset () == max_len)
79
+ return CDCCommand::Status::Error;
80
+ }
81
+ }
82
+
58
83
class CDCProgCommand final : public CDCCommand {
59
84
public:
60
85
CDCProgCommand (CDCParseBuffer &buf) : buf(buf) {}
@@ -69,33 +94,19 @@ class CDCProgCommand final : public CDCCommand {
69
94
while (true ) {
70
95
switch (parse_state) {
71
96
case ParseState::Filename: {
72
- auto buf_ptr = buf.get_current_ptr ();
73
- if (!usb_cdc_read (buf_ptr, 1 ))
74
- return Status::Continue;
75
-
76
- // end of string
77
- if (*buf_ptr == 0 ) {
97
+ auto status = cdc_read_string (buf, MAX_FILENAME);
98
+ if (status == Status::Done) {
78
99
parse_state = ParseState::Length;
79
100
buf.reset ();
80
101
continue ;
81
102
}
82
103
83
- buf.add_read (1 );
84
-
85
- // too long
86
- if (buf.get_offset () == MAX_FILENAME)
87
- return Status::Error;
88
-
89
- break ;
104
+ return status;
90
105
}
91
106
92
107
case ParseState::Length: {
93
- auto buf_ptr = buf.get_current_ptr ();
94
- if (!usb_cdc_read (buf_ptr, 1 ))
95
- return Status::Continue;
96
-
97
- // end of string
98
- if (*buf_ptr == 0 ) {
108
+ auto status = cdc_read_string (buf, MAX_FILELEN);
109
+ if (status == Status::Done) {
99
110
auto file_len = strtoul ((const char *)buf.get_data (), nullptr , 10 );
100
111
parse_state = ParseState::Data;
101
112
buf.reset ();
@@ -104,13 +115,7 @@ class CDCProgCommand final : public CDCCommand {
104
115
continue ;
105
116
}
106
117
107
- buf.add_read (1 );
108
-
109
- // too long
110
- if (buf.get_offset () == MAX_FILELEN)
111
- return Status::Error;
112
-
113
- break ;
118
+ return status;
114
119
}
115
120
116
121
case ParseState::Data: {
@@ -211,25 +216,12 @@ class CDCLaunchCommand final : public CDCCommand {
211
216
}
212
217
213
218
Status update () override {
214
- while (true ) {
215
- auto buf_ptr = buf.get_current_ptr ();
216
- if (!usb_cdc_read (buf_ptr, 1 ))
217
- return Status::Continue;
218
-
219
- // end of string
220
- if (*buf_ptr == 0 ) {
221
- blit::api.launch ((const char *)buf.get_data ());
222
- return Status::Done;
223
- }
224
-
225
- buf.add_read (1 );
219
+ auto status = cdc_read_string (buf, MAX_FILENAME);
226
220
227
- // too long
228
- if (buf.get_offset () == MAX_FILENAME)
229
- return Status::Error;
230
- }
221
+ if (status == Status::Done)
222
+ blit::api.launch ((const char *)buf.get_data ());
231
223
232
- return Status::Continue ;
224
+ return status ;
233
225
}
234
226
235
227
CDCParseBuffer &buf;
0 commit comments