From 3b9750ee495be05809f7784981433c74f36d4748 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Tue, 4 Jun 2013 01:24:49 +0200 Subject: [PATCH] Fix a race condition in downloader, some ui style stuff --- base/buffer.cpp | 27 +++++++++++++++------------ base/buffer.h | 2 +- net/http_client.cpp | 9 +++++---- ui/view.cpp | 14 +++++++------- ui/view.h | 5 ++--- 5 files changed, 30 insertions(+), 27 deletions(-) diff --git a/base/buffer.cpp b/base/buffer.cpp index 55b9e11015..9d0c160fcf 100644 --- a/base/buffer.cpp +++ b/base/buffer.cpp @@ -159,19 +159,22 @@ bool Buffer::ReadAll(int fd) { return true; } -void Buffer::Read(int fd, size_t sz) { - char buf[1024]; - int retval; - while ((retval = recv(fd, buf, std::min(sz, sizeof(buf)), 0)) > 0) { - char *p = Append((size_t)retval); - memcpy(p, buf, retval); - sz -= retval; - if (sz == 0) - break; - } +size_t Buffer::Read(int fd, size_t sz) { + char buf[1024]; + int retval; + size_t received = 0; + while ((retval = recv(fd, buf, std::min(sz, sizeof(buf)), 0)) > 0) { + char *p = Append((size_t)retval); + memcpy(p, buf, retval); + sz -= retval; + received += retval; + if (sz == 0) + return 0; + } + return received; } void Buffer::PeekAll(std::string *dest) { - dest->resize(data_.size()); - memcpy(&(*dest)[0], &data_[0], data_.size()); + dest->resize(data_.size()); + memcpy(&(*dest)[0], &data_[0], data_.size()); } \ No newline at end of file diff --git a/base/buffer.h b/base/buffer.h index ead85cb450..ff6fa9e1ab 100644 --- a/base/buffer.h +++ b/base/buffer.h @@ -65,7 +65,7 @@ class Buffer { bool FlushSocket(uintptr_t sock); // Windows portability bool ReadAll(int fd); - void Read(int fd, size_t sz); + size_t Read(int fd, size_t sz); // Utilities. Try to avoid checking for size. size_t size() const { return data_.size(); } diff --git a/net/http_client.cpp b/net/http_client.cpp index 5a520a9048..4963fc01d2 100644 --- a/net/http_client.cpp +++ b/net/http_client.cpp @@ -127,7 +127,6 @@ int Client::GET(const char *resource, Buffer *output) { CHECK_GT(output->TakeLineCRLF(&firstline), 0); int code = atoi(&firstline[9]); - while (output->SkipLineCRLF() > 0) ; @@ -181,7 +180,6 @@ int Client::POST(const char *resource, const std::string &data, Buffer *output) Download::Download(const std::string &url, const std::string &outfile) : url_(url), outfile_(outfile), progress_(0.0f), failed_(false), resultCode_(0) { - std::thread th(std::bind(&Download::Do, this)); th.detach(); } @@ -191,9 +189,12 @@ Download::~Download() { } void Download::Do() { + resultCode_ = 0; + Url fileUrl(url_); if (!fileUrl.Valid()) { failed_ = true; + progress_ = 1.0f; return; } net::Init(); @@ -202,22 +203,22 @@ void Download::Do() { if (!client.Resolve(fileUrl.Host().c_str(), 80)) { ELOG("Failed resolving %s", url_.c_str()); failed_ = true; + progress_ = 1.0f; return; } client.Connect(); int resultCode = client.GET(fileUrl.Resource().c_str(), &buffer_); if (resultCode == 200) { - progress_ = 1.0f; ILOG("Completed downloading %s to %s", url_.c_str(), outfile_.c_str()); if (!outfile_.empty() && !buffer_.FlushToFile(outfile_.c_str())) { ELOG("Failed writing download to %s", outfile_.c_str()); } } else { - progress_ = 1.0f; ELOG("Error downloading %s to %s: %i", url_.c_str(), outfile_.c_str(), resultCode); } resultCode_ = resultCode; net::Shutdown(); + progress_ = 1.0f; } std::shared_ptr Downloader::StartDownload(const std::string &url, const std::string &outfile) { diff --git a/ui/view.cpp b/ui/view.cpp index 366333e6e0..2a73699012 100644 --- a/ui/view.cpp +++ b/ui/view.cpp @@ -189,11 +189,13 @@ void ItemHeader::Draw(UIContext &dc) { void CheckBox::Draw(UIContext &dc) { ClickableItem::Draw(dc); - int paddingX = 80; + int paddingX = 4; int paddingY = 4; - dc.Draw()->DrawImage(dc.theme->checkOn, bounds_.x + 30, bounds_.centerY(), 0xFFFFFFFF, ALIGN_VCENTER); + + int image = *toggle_ ? dc.theme->checkOn : dc.theme->checkOff; + dc.Draw()->DrawText(dc.theme->uiFont, text_.c_str(), bounds_.x + paddingX, bounds_.centerY(), 0xFFFFFFFF, ALIGN_VCENTER); - // dc.draw->DrawText(dc.theme->uiFontSmaller, text_.c_str(), paddingX, paddingY, 0xFFFFFFFF, ALIGN_TOPLEFT); + dc.Draw()->DrawImage(image, bounds_.x2() - 4, bounds_.centerY(), 0xFFFFFFFF, ALIGN_RIGHT | ALIGN_VCENTER); } void Button::GetContentDimensions(const UIContext &dc, float &w, float &h) const { @@ -201,14 +203,12 @@ void Button::GetContentDimensions(const UIContext &dc, float &w, float &h) const } void Button::Draw(UIContext &dc) { - int image = down_ ? dc.theme->buttonImage : dc.theme->buttonSelected; - Style style = dc.theme->buttonStyle; if (HasFocus()) style = dc.theme->buttonFocusedStyle; if (down_) style = dc.theme->buttonDownStyle; if (!enabled_) style = dc.theme->buttonDisabledStyle; - dc.Draw()->DrawImage4Grid(dc.theme->buttonImage, bounds_.x, bounds_.y, bounds_.x2(), bounds_.y2(), style.bgColor); + dc.Draw()->DrawImage4Grid(style.image, bounds_.x, bounds_.y, bounds_.x2(), bounds_.y2(), style.bgColor); dc.Draw()->DrawText(dc.theme->uiFont, text_.c_str(), bounds_.centerX(), bounds_.centerY(), style.fgColor, ALIGN_CENTER); } @@ -243,7 +243,7 @@ void ProgressBar::GetContentDimensions(const UIContext &dc, float &w, float &h) void ProgressBar::Draw(UIContext &dc) { char temp[32]; sprintf(temp, "%i%%", (int)(progress_ * 100.0f)); - dc.Draw()->DrawImageStretch(dc.theme->whiteImage, bounds_.x, bounds_.y, bounds_.x + bounds_.w * progress_, bounds_.h); + dc.Draw()->DrawImageStretch(dc.theme->whiteImage, bounds_.x, bounds_.y, bounds_.x + bounds_.w * progress_, bounds_.y2(), 0xc0c0c0c0); dc.Draw()->DrawTextRect(dc.theme->uiFont, temp, bounds_.x, bounds_.y, bounds_.w, bounds_.h, 0xFFFFFFFF, ALIGN_CENTER); } diff --git a/ui/view.h b/ui/view.h index c882c1a7ce..02b017342c 100644 --- a/ui/view.h +++ b/ui/view.h @@ -58,10 +58,11 @@ struct Drawable { }; struct Style { - Style() : fgColor(0xFFFFFFFF), bgColor(0xFF303030) {} + Style() : fgColor(0xFFFFFFFF), bgColor(0xFF303030), image(-1) {} uint32_t fgColor; uint32_t bgColor; + int image; // where applicable. }; // To use with an UI atlas. @@ -69,8 +70,6 @@ struct Theme { int uiFont; int uiFontSmall; int uiFontSmaller; - int buttonImage; - int buttonSelected; int checkOn; int checkOff; int whiteImage;