From f4aedad02e8994f89a4137d175dba2666a7005bc Mon Sep 17 00:00:00 2001 From: Eugenio Favalli Date: Sat, 16 Jul 2005 16:25:47 +0000 Subject: Phew, now news.txt and resources.txt are read directly from memory --- src/gui/updatewindow.cpp | 144 +++++++++++++++++++++++++++++++---------------- src/gui/updatewindow.h | 2 +- 2 files changed, 96 insertions(+), 50 deletions(-) (limited to 'src/gui') diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp index 0dd34854..66839451 100644 --- a/src/gui/updatewindow.cpp +++ b/src/gui/updatewindow.cpp @@ -40,6 +40,10 @@ std::string currentFile = "news.txt"; bool downloadComplete = true; int downloadStatus = UPDATE_NEWS; std::string basePath = ""; +bool memoryTransfer = true; +int downloadedBytes = 0; +char *memoryBuffer = NULL; +int fileIndex = 0; UpdaterWindow::UpdaterWindow() : Window("Updating...") @@ -125,16 +129,31 @@ void UpdaterWindow::action(const std::string& eventId) void UpdaterWindow::loadNews() { - ResourceManager *resman = ResourceManager::getInstance(); - std::vector lines = resman->loadTextFile("news.txt"); + int contentsLength = downloadedBytes; + char *fileContents = memoryBuffer; + if (!fileContents) + { + logger->log("Couldn't load news"); + return; + } + + // Reallocate and include terminating 0 character + fileContents = (char*)realloc(fileContents, contentsLength + 1); + fileContents[contentsLength] = '\0'; + browserBox->clearRows(); - for (unsigned int i = 0; i < lines.size(); ++i) + // Tokenize and add each line separately + char *line = strtok(fileContents, "\n"); + while (line != NULL) { - browserBox->addRow(lines[i]); + browserBox->addRow(line); + line = strtok(NULL, "\n"); } + free(fileContents); + scrollArea->setVerticalScrollAmount(0); setVisible(true); } @@ -145,13 +164,9 @@ void UpdaterWindow::setText(std::string row) { scrollArea->getVerticalMaxScroll()); } -int updateProgress(void *ptr, - double t, /* dltotal */ - double d, /* dlnow */ - double ultotal, - double ulnow) +int updateProgress(void *ptr, double dt, double dn, double ut, double un) { - float progress = d/t; + float progress = dn/dt; if (progress < 0) { progress = 0.0f; @@ -169,11 +184,26 @@ int updateProgress(void *ptr, return 0; } +size_t memoryWrite(void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + if (memoryTransfer) { + memoryBuffer = (char *)realloc(memoryBuffer, downloadedBytes + nmemb + 1); + if (memoryBuffer) { + memcpy(&(memoryBuffer[downloadedBytes]), ptr, nmemb); + downloadedBytes += nmemb; + memoryBuffer[downloadedBytes] = 0; + } + return nmemb; + } + return fwrite(ptr, size, nmemb, stream); +} + int downloadThread(void *ptr) { CURL *curl; CURLcode res; FILE *outfile; + std::string outFilename; std::string url(updateHost + "/" + currentFile); curl = curl_easy_init(); @@ -183,27 +213,34 @@ int downloadThread(void *ptr) logger->log("Downloading: %s", url.c_str()); // Download in the proper folder : ./data under win, // /home/user/.tmw/data for unices - std::string outFilename = basePath + "/data/download.temp"; - outfile = fopen(outFilename.c_str(), "wb"); + if (memoryTransfer) + { + downloadedBytes = 0; + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memoryWrite); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL); + } + else { + outFilename = basePath + "/data/download.temp"; + outfile = fopen(outFilename.c_str(), "wb"); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile); + } curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, updateProgress); curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, NULL); res = curl_easy_perform(curl); - fclose(outfile); curl_easy_cleanup(curl); downloadComplete = true; if (res != 0) { downloadStatus = UPDATE_ERROR; } - else { + else if (!memoryTransfer) { + fclose(outfile); // If the download was successful give the file the proper name // else it will be deleted later std::string newName(basePath + "/data/" + currentFile.c_str()); - logger->log("Renaming: %s -> %s", outFilename.c_str(), newName.c_str()); rename(outFilename.c_str(), newName.c_str()); } } @@ -242,15 +279,17 @@ void checkFile(std::ifstream &in) { void updateData() { + std::ifstream in; + std::vector files; updaterWindow = new UpdaterWindow(); state = UPDATE; updateHost = config.getValue("updatehost", "themanaworld.org/files"); basePath = config.getValue("homeDir", "."); + // Try to download the updates list download(); - std::ifstream in; while (state == UPDATE) { @@ -276,7 +315,6 @@ void updateData() switch (downloadStatus) { case UPDATE_ERROR: SDL_WaitThread(thread, NULL); - //cancellare tutto, rimettere browser box protected, creare metodi per aggiungere linee e cancellare tutto updaterWindow->setText(""); updaterWindow->setText("##1 The update process is incomplete."); updaterWindow->setText("##1 It is strongly recommended that"); @@ -284,55 +322,62 @@ void updateData() downloadStatus = UPDATE_COMPLETE; break; case UPDATE_NEWS: - // If not already downloading another file if (downloadComplete) { // Try to open news.txt updaterWindow->loadNews(); // Doesn't matter if it couldn't find news.txt, // go to the next step currentFile = "resources.txt"; + if (memoryBuffer != NULL) + { + free(memoryBuffer); + memoryBuffer = NULL; + } download(); - downloadStatus = UPDATE_RESOURCES; + downloadStatus = UPDATE_LIST; } break; - case UPDATE_RESOURCES: - // If not already downloading another file + case UPDATE_LIST: if (downloadComplete) { - // Check if the list was already accessed - if (!in.is_open()) + if (memoryBuffer != NULL && memoryBuffer[0] != '<') { - // Try to open resources.txt - in.open((basePath + "/data/resources.txt").c_str(), std::ifstream::in); - if (!in.is_open()) + // Tokenize and add each line separately + char *line = strtok(memoryBuffer, "\n"); + while (line != NULL) { - logger->log("Unable to open resources.txt"); - downloadStatus = UPDATE_ERROR; - } - else { - checkFile(in); + files.push_back(line); + std::cout << line << std::endl; + line = strtok(NULL, "\n"); } + memoryTransfer = false; + downloadStatus = UPDATE_RESOURCES; } else { - SDL_WaitThread(thread, NULL); - if (in.is_open() && !in.eof()) - { - // Download each update - std::string line(""); - getline(in, line); - currentFile = line; - std::ifstream temp((basePath + "/data" + line).c_str(), std::ifstream::in); - if (temp.is_open()) { - temp.close(); - download(); - } - else { - logger->log("%s is already here", line.c_str()); - } + logger->log("Unable to download resources.txt"); + downloadStatus = UPDATE_ERROR; + } + } + break; + case UPDATE_RESOURCES: + if (downloadComplete) { + SDL_WaitThread(thread, NULL); + if (fileIndex < files.size()) + { + currentFile = files[fileIndex]; + std::ifstream temp( + (basePath + "/data/" + currentFile).c_str()); + if (!temp.is_open()) { + temp.close(); + download(); } else { - // Download of updates completed - downloadStatus = UPDATE_COMPLETE; + logger->log("%s already here", currentFile.c_str()); } + fileIndex++; + } + else { + // Download of updates completed + downloadStatus = UPDATE_COMPLETE; } } break; @@ -351,6 +396,7 @@ void updateData() guiGraphics->updateScreen(); } + free(memoryBuffer); in.close(); // Remove downloaded files remove((basePath + "/data/news.txt").c_str()); diff --git a/src/gui/updatewindow.h b/src/gui/updatewindow.h index 6c807611..f1d460a2 100644 --- a/src/gui/updatewindow.h +++ b/src/gui/updatewindow.h @@ -34,7 +34,7 @@ enum { UPDATE_ERROR, UPDATE_IDLE, - UPDATE_RUN, + UPDATE_LIST, UPDATE_COMPLETE, UPDATE_NEWS, UPDATE_RESOURCES -- cgit v1.2.3-60-g2f50