| 1242 | |
| 1243 | |
| 1244 | class MPBodyMarkup: |
| 1245 | def __init__(self, boundary): |
| 1246 | self.markups = [] |
| 1247 | self.error = None |
| 1248 | if CR in boundary: |
| 1249 | raise HTTPError(422, 'The `CR` must not be in the boundary: %s' % boundary) |
| 1250 | boundary = HYPHENx2 + boundary |
| 1251 | self.boundary = boundary |
| 1252 | token = CRLF + boundary |
| 1253 | self.tlen = len(token) |
| 1254 | self.token = token |
| 1255 | self.trest = self.trest_len = None |
| 1256 | self.abspos = 0 |
| 1257 | self.abs_start_section = 0 |
| 1258 | self.headers_eater = MPHeadersEaeter() |
| 1259 | self.cur_meth = self._eat_start_boundary |
| 1260 | self._eat_headers = self.headers_eater.eat |
| 1261 | self.stopped = False |
| 1262 | self.idx = idx = defaultdict(list) # 1-based indices for each token symbol |
| 1263 | for i, c in enumerate(token, start=1): |
| 1264 | idx[c].append([i, token[:i]]) |
| 1265 | |
| 1266 | def _match_tail(self, s, start, end): |
| 1267 | idxs = self.idx.get(s[end - 1]) |
| 1268 | if idxs is None: return |
| 1269 | slen = end - start |
| 1270 | assert slen <= self.tlen |
| 1271 | for i, thead in idxs: # idxs is 1-based index |
| 1272 | search_pos = slen - i |
| 1273 | if search_pos < 0: return |
| 1274 | if s[start + search_pos:end] == thead: return i # if s_tail == token_head |
| 1275 | |
| 1276 | def _iter_markup(self, chunk): |
| 1277 | if self.stopped: |
| 1278 | raise StopMarkupException() |
| 1279 | cur_meth = self.cur_meth |
| 1280 | abs_start_section = self.abs_start_section |
| 1281 | start_next_sec = 0 |
| 1282 | skip_start = 0 |
| 1283 | tlen = self.tlen |
| 1284 | eat_data, eat_headers = self._eat_data, self._eat_headers |
| 1285 | while True: |
| 1286 | try: |
| 1287 | end_section = cur_meth(chunk, start_next_sec) |
| 1288 | except StopMarkupException: |
| 1289 | self.stopped = True |
| 1290 | return |
| 1291 | if end_section is None: break |
| 1292 | if cur_meth == eat_headers: |
| 1293 | sec_name = 'headers' |
| 1294 | start_next_sec = end_section + CRLFx2_LEN |
| 1295 | cur_meth = eat_data |
| 1296 | skip_start = 0 |
| 1297 | elif cur_meth == eat_data: |
| 1298 | sec_name = 'data' |
| 1299 | start_next_sec = end_section + tlen |
| 1300 | skip_start = CRLF_LEN |
| 1301 | cur_meth = eat_headers |
no outgoing calls
no test coverage detected
searching dependent graphs…