static flatten_result flatten( BufferSequence const& buffers, std::size_t limit) { flatten_result result{0, false}; auto first = net::buffer_sequence_begin(buffers); auto last = net::buffer_sequence_end(buffers); if(first != last) { result.size = buffer_bytes(*first); if(result.size < limit) { auto it = first; auto prev = first; while(++it != last) { auto const n = buffer_bytes(*it); if(result.size + n > limit) break; result.size += n; prev = it; } result.flatten = prev != first; } } return result; }
std::size_t put(ConstBufferSequence const& buffers, error_code& ec) { auto const n = buffer_bytes(buffers); if(body_.size() > body_.max_size() - n) { ec = error::buffer_overflow; return 0; } auto const mb = beast::detail::dynamic_buffer_prepare( body_, (std::min)(n, body_.max_size() - body_.size()), ec, error::buffer_overflow); if(ec) return 0; auto const bytes_transferred = net::buffer_copy(*mb, buffers); body_.commit(bytes_transferred); return bytes_transferred; }
void serializer<isRequest, Body, Fields>:: next(error_code& ec, Visit&& visit) { switch(s_) { case do_construct: { fwrinit(std::integral_constant<bool, isRequest>{}); if(m_.chunked()) goto go_init_c; s_ = do_init; BOOST_FALLTHROUGH; } case do_init: { wr_.init(ec); if(ec) return; if(split_) goto go_header_only; auto result = wr_.get(ec); if(ec == error::need_more) goto go_header_only; if(ec) return; if(! result) goto go_header_only; more_ = result->second; v_.template emplace<2>( boost::in_place_init, fwr_->get(), result->first); s_ = do_header; BOOST_FALLTHROUGH; } case do_header: do_visit<2>(ec, visit); break; go_header_only: v_.template emplace<1>(fwr_->get()); s_ = do_header_only; BOOST_FALLTHROUGH; case do_header_only: do_visit<1>(ec, visit); break; case do_body: s_ = do_body + 1; BOOST_FALLTHROUGH; case do_body + 1: { auto result = wr_.get(ec); if(ec) return; if(! result) goto go_complete; more_ = result->second; v_.template emplace<3>(result->first); s_ = do_body + 2; BOOST_FALLTHROUGH; } case do_body + 2: do_visit<3>(ec, visit); break; //---------------------------------------------------------------------- go_init_c: s_ = do_init_c; BOOST_FALLTHROUGH; case do_init_c: { wr_.init(ec); if(ec) return; if(split_) goto go_header_only_c; auto result = wr_.get(ec); if(ec == error::need_more) goto go_header_only_c; if(ec) return; if(! result) goto go_header_only_c; more_ = result->second; if(! more_) { // do it all in one buffer v_.template emplace<7>( boost::in_place_init, fwr_->get(), buffer_bytes(result->first), net::const_buffer{nullptr, 0}, chunk_crlf{}, result->first, chunk_crlf{}, detail::chunk_last(), net::const_buffer{nullptr, 0}, chunk_crlf{}); goto go_all_c; } v_.template emplace<4>( boost::in_place_init, fwr_->get(), buffer_bytes(result->first), net::const_buffer{nullptr, 0}, chunk_crlf{}, result->first, chunk_crlf{}); s_ = do_header_c; BOOST_FALLTHROUGH; } case do_header_c: do_visit<4>(ec, visit); break; go_header_only_c: v_.template emplace<1>(fwr_->get()); s_ = do_header_only_c; BOOST_FALLTHROUGH; case do_header_only_c: do_visit<1>(ec, visit); break; case do_body_c: s_ = do_body_c + 1; BOOST_FALLTHROUGH; case do_body_c + 1: { auto result = wr_.get(ec); if(ec) return; if(! result) goto go_final_c; more_ = result->second; if(! more_) { // do it all in one buffer v_.template emplace<6>( boost::in_place_init, buffer_bytes(result->first), net::const_buffer{nullptr, 0}, chunk_crlf{}, result->first, chunk_crlf{}, detail::chunk_last(), net::const_buffer{nullptr, 0}, chunk_crlf{}); goto go_body_final_c; } v_.template emplace<5>( boost::in_place_init, buffer_bytes(result->first), net::const_buffer{nullptr, 0}, chunk_crlf{}, result->first, chunk_crlf{}); s_ = do_body_c + 2; BOOST_FALLTHROUGH; } case do_body_c + 2: do_visit<5>(ec, visit); break; go_body_final_c: s_ = do_body_final_c; BOOST_FALLTHROUGH; case do_body_final_c: do_visit<6>(ec, visit); break; go_all_c: s_ = do_all_c; BOOST_FALLTHROUGH; case do_all_c: do_visit<7>(ec, visit); break; go_final_c: case do_final_c: v_.template emplace<8>( boost::in_place_init, detail::chunk_last(), net::const_buffer{nullptr, 0}, chunk_crlf{}); s_ = do_final_c + 1; BOOST_FALLTHROUGH; case do_final_c + 1: do_visit<8>(ec, visit); break; //---------------------------------------------------------------------- default: case do_complete: BOOST_ASSERT(false); break; go_complete: s_ = do_complete; break; } }
void serializer<isRequest, Body, Fields>:: consume(std::size_t n) { switch(s_) { case do_header: BOOST_ASSERT( n <= buffer_bytes(v_.template get<2>())); v_.template get<2>().consume(n); if(buffer_bytes(v_.template get<2>()) > 0) break; header_done_ = true; v_.reset(); if(! more_) goto go_complete; s_ = do_body + 1; break; case do_header_only: BOOST_ASSERT( n <= buffer_bytes(v_.template get<1>())); v_.template get<1>().consume(n); if(buffer_bytes(v_.template get<1>()) > 0) break; fwr_ = boost::none; header_done_ = true; if(! split_) goto go_complete; s_ = do_body; break; case do_body + 2: { BOOST_ASSERT( n <= buffer_bytes(v_.template get<3>())); v_.template get<3>().consume(n); if(buffer_bytes(v_.template get<3>()) > 0) break; v_.reset(); if(! more_) goto go_complete; s_ = do_body + 1; break; } //---------------------------------------------------------------------- case do_header_c: BOOST_ASSERT( n <= buffer_bytes(v_.template get<4>())); v_.template get<4>().consume(n); if(buffer_bytes(v_.template get<4>()) > 0) break; header_done_ = true; v_.reset(); if(more_) s_ = do_body_c + 1; else s_ = do_final_c; break; case do_header_only_c: { BOOST_ASSERT( n <= buffer_bytes(v_.template get<1>())); v_.template get<1>().consume(n); if(buffer_bytes(v_.template get<1>()) > 0) break; fwr_ = boost::none; header_done_ = true; if(! split_) { s_ = do_final_c; break; } s_ = do_body_c; break; } case do_body_c + 2: BOOST_ASSERT( n <= buffer_bytes(v_.template get<5>())); v_.template get<5>().consume(n); if(buffer_bytes(v_.template get<5>()) > 0) break; v_.reset(); if(more_) s_ = do_body_c + 1; else s_ = do_final_c; break; case do_body_final_c: { BOOST_ASSERT( n <= buffer_bytes(v_.template get<6>())); v_.template get<6>().consume(n); if(buffer_bytes(v_.template get<6>()) > 0) break; v_.reset(); s_ = do_complete; break; } case do_all_c: { BOOST_ASSERT( n <= buffer_bytes(v_.template get<7>())); v_.template get<7>().consume(n); if(buffer_bytes(v_.template get<7>()) > 0) break; header_done_ = true; v_.reset(); s_ = do_complete; break; } case do_final_c + 1: BOOST_ASSERT(buffer_bytes(v_.template get<8>())); v_.template get<8>().consume(n); if(buffer_bytes(v_.template get<8>()) > 0) break; v_.reset(); goto go_complete; //---------------------------------------------------------------------- default: BOOST_ASSERT(false); case do_complete: break; go_complete: s_ = do_complete; break; } }
struct view *view_open(const char *path0) { struct view *view; struct text *text; struct stat statbuf; char *path = fix_path(path0); if (!path) return NULL; for (text = text_list; text; text = text->next) if (text->path && !strcmp(text->path, path)) { for (view = text->views; view; view = view->next) if (!view->window) goto done; view = view_create(text); goto done; } view = text_create(path, 0); text = view->text; errno = 0; if (stat(path, &statbuf)) { if (errno != ENOENT) { message("%s: can't stat", path_format(path)); goto fail; } if (read_only) { message("%s: can't create in read-only mode", path_format(path)); goto fail; } errno = 0; text->fd = open(path, O_CREAT|O_TRUNC|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if (text->fd < 0) { message("%s: can't create", path_format(path)); goto fail; } text->flags |= TEXT_CREATED; } else { if (!S_ISREG(statbuf.st_mode)) { message("%s: not a regular file", path_format(path)); goto fail; } if (!read_only) text->fd = open(path, O_RDWR); if (text->fd < 0) { errno = 0; text->flags |= TEXT_RDONLY; text->fd = open(path, O_RDONLY); if (text->fd < 0) { message("%s: can't open", path_format(path)); goto fail; } } clean_mmap(text, statbuf.st_size, PROT_READ); if (!text->clean) { text->buffer = buffer_create(path); if (old_fashioned_read(text) < 0) goto fail; grab_mtime(text); } view->bytes = text->buffer ? buffer_bytes(text->buffer) : text->clean_bytes; scan(view); text_forget_undo(text); } goto done; fail: view_close(view); view = NULL; done: RELEASE(path); return view; }