static int mpjpeg_read_packet(AVFormatContext *s, AVPacket *pkt) { int ret; int size = parse_multipart_header(s); if (size < 0) return size; ret = av_get_packet(s->pb, pkt, size); if (ret < 0) return ret; // trailing empty line avio_skip(s->pb, 2); return 0; }
static int mpjpeg_read_probe(AVProbeData *p) { AVIOContext *pb; int ret = 0; if (p->buf_size < 2 || p->buf[0] != '-' || p->buf[1] != '-') return 0; pb = avio_alloc_context(p->buf, p->buf_size, 0, NULL, NULL, NULL, NULL); if (!pb) return AVERROR(ENOMEM); ret = (parse_multipart_header(pb, NULL)>0)?AVPROBE_SCORE_MAX:0; av_free(pb); return ret; }
void request_parser::parse_multipart_content(request& req, const std::string& data) { std::string end = "\r\n\r\n"; std::string::size_type head_limit = data.find(end, 0); if (head_limit == std::string::npos) { throw std::runtime_error("invalid part header"); } std::string::size_type value_start = head_limit + end.size(); std::string value = data.substr(value_start, data.size() - value_start - 2); multipart_header head = parse_multipart_header(req, data.substr(0, value_start)); if (head.filename.empty()) { req.params.push_back(name_value(head.name, value)); } else { req.uploads.push_back(multipart_content(head.name, head.filename, head.filetype, value)); } }
static int mpjpeg_read_packet(AVFormatContext *s, AVPacket *pkt) { int size; int ret; MPJPEGDemuxContext *mpjpeg = s->priv_data; if (mpjpeg->boundary == NULL) { uint8_t* boundary = NULL; if (mpjpeg->strict_mime_boundary) { boundary = mpjpeg_get_boundary(s->pb); } if (boundary != NULL) { mpjpeg->boundary = boundary; mpjpeg->searchstr = av_asprintf( "\r\n%s\r\n", boundary ); } else { mpjpeg->boundary = av_strdup("--"); mpjpeg->searchstr = av_strdup("\r\n--"); } if (!mpjpeg->boundary || !mpjpeg->searchstr) { av_freep(&mpjpeg->boundary); av_freep(&mpjpeg->searchstr); return AVERROR(ENOMEM); } mpjpeg->searchstr_len = strlen(mpjpeg->searchstr); } ret = parse_multipart_header(s->pb, &size, mpjpeg->boundary, s); if (ret < 0) return ret; if (size > 0) { /* size has been provided to us in MIME header */ ret = av_get_packet(s->pb, pkt, size); } else { /* no size was given -- we read until the next boundary or end-of-file */ int remaining = 0, len; const int read_chunk = 2048; av_init_packet(pkt); pkt->data = NULL; pkt->size = 0; pkt->pos = avio_tell(s->pb); /* we may need to return as much as all we've read back to the buffer */ ffio_ensure_seekback(s->pb, read_chunk); while ((ret = av_append_packet(s->pb, pkt, read_chunk - remaining)) >= 0) { /* scan the new data */ char *start; len = ret + remaining; start = pkt->data + pkt->size - len; do { if (!memcmp(start, mpjpeg->searchstr, mpjpeg->searchstr_len)) { // got the boundary! rewind the stream avio_seek(s->pb, -(len-2), SEEK_CUR); pkt->size -= (len-2); return pkt->size; } len--; start++; } while (len >= mpjpeg->searchstr_len); remaining = len; } /* error or EOF occurred */ if (ret == AVERROR_EOF) { ret = pkt->size > 0 ? pkt->size : AVERROR_EOF; } else { av_packet_unref(pkt); } } return ret; }