diff --git a/src/Format.h b/src/Format.h index b29749bde..85b63c7f1 100644 --- a/src/Format.h +++ b/src/Format.h @@ -9,30 +9,6 @@ namespace format { const static char hex[] = "0123456789ABCDEF"; - template ByteString NumberToByteString(T number) - { - ByteString::Stream ss; - ss << number; - return ss.str(); - } - - template String NumberToString(T number) - { - return String::Build(number); - } - - template T ByteStringToNumber(const ByteString & text) - { - ByteString::Stream ss(text); - T number; - return (ss >> number)?number:0; - } - - template T StringToNumber(const String & text) - { - return text.ToNumber(true); - } - ByteString URLEncode(ByteString value); ByteString UnixtimeToDate(time_t unixtime, ByteString dateFomat = "%d %b %Y"); ByteString UnixtimeToDateMini(time_t unixtime); diff --git a/src/PowderToySDL.cpp b/src/PowderToySDL.cpp index 4fd0bb32e..e65f485b6 100644 --- a/src/PowderToySDL.cpp +++ b/src/PowderToySDL.cpp @@ -1009,7 +1009,7 @@ int main(int argc, char * argv[]) if(arguments["scale"].length()) { - tempScale = format::ByteStringToNumber(arguments["scale"]); + tempScale = arguments["scale"].ToNumber(); Client::Ref().SetPref("Scale", tempScale); } @@ -1181,9 +1181,7 @@ int main(int argc, char * argv[]) #ifdef DEBUG std::cout << "Got Ptsave: id: " << saveIdPart << std::endl; #endif - int saveId = format::ByteStringToNumber(saveIdPart); - if (!saveId) - throw std::runtime_error("Invalid Save ID"); + int saveId = saveIdPart.ToNumber(); SaveInfo * newSave = Client::Ref().GetSave(saveId, 0); if (!newSave) diff --git a/src/client/Client.cpp b/src/client/Client.cpp index 4741c896a..a43741dc1 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -150,7 +150,7 @@ void Client::Initialise(ByteString proxyString) if (authUser.UserID) { - ByteString idTempString = format::NumberToByteString(authUser.UserID); + ByteString idTempString = ByteString::Build(authUser.UserID); char *id = new char[idTempString.length() + 1]; std::strcpy (id, idTempString.c_str()); char *session = new char[authUser.SessionID.length() + 1]; @@ -378,12 +378,11 @@ bool Client::DoInstallation() "NoDisplay=true\n" "Categories=Game;Simulation\n" "Icon=powdertoy.png\n"; - ByteString::Stream protocolfiledata; - protocolfiledata << protocolfiledata_tmp << "Exec=" << filename << " ptsave %u\nPath=" << pathname << "\n"; + ByteString protocolfiledata = ByteString::Build(protocolfiledata_tmp, "Exec=", filename, " ptsave %u\nPath=", pathname, "\n"); f = fopen("powdertoy-tpt-ptsave.desktop", "wb"); if (!f) return 0; - fwrite(protocolfiledata.str().c_str(), 1, strlen(protocolfiledata.str().c_str()), f); + fwrite(protocolfiledata.c_str(), 1, protocolfiledata.size(), f); fclose(f); success = system("xdg-desktop-menu install powdertoy-tpt-ptsave.desktop"); @@ -396,12 +395,11 @@ bool Client::DoInstallation() "NoDisplay=true\n" "Categories=Game;Simulation\n" "Icon=powdertoy.png\n"; - ByteString::Stream desktopopenfiledata; - desktopopenfiledata << desktopopenfiledata_tmp << "Exec=" << filename << " open %f\nPath=" << pathname << "\n"; + ByteString desktopopenfiledata = ByteString::Build(desktopopenfiledata_tmp, "Exec=", filename, " open %f\nPath=", pathname, "\n"); f = fopen("powdertoy-tpt-open.desktop", "wb"); if (!f) return 0; - fwrite(desktopopenfiledata.str().c_str(), 1, strlen(desktopopenfiledata.str().c_str()), f); + fwrite(desktopopenfiledata.c_str(), 1, desktopopenfiledata.size(), f); fclose(f); success = system("xdg-mime install powdertoy-save.xml") && success; success = system("xdg-desktop-menu install powdertoy-tpt-open.desktop") && success; @@ -415,12 +413,11 @@ bool Client::DoInstallation() "Comment=Physics sandbox game\n" "Categories=Game;Simulation\n" "Icon=powdertoy.png\n"; - ByteString::Stream desktopfiledata; - desktopfiledata << desktopfiledata_tmp << "Exec=" << filename << "\nPath=" << pathname << "\n"; + ByteString desktopfiledata = ByteString::Build(desktopfiledata_tmp, "Exec=", filename, "\nPath=", pathname, "\n"); f = fopen("powdertoy-tpt.desktop", "wb"); if (!f) return 0; - fwrite(desktopfiledata.str().c_str(), 1, strlen(desktopfiledata.str().c_str()), f); + fwrite(desktopfiledata.c_str(), 1, desktopfiledata.size(), f); fclose(f); success = system("xdg-desktop-menu install powdertoy-tpt.desktop") && success; @@ -989,8 +986,7 @@ RequestStatus Client::UploadSave(SaveInfo & save) int dataStatus; char * data; int dataLength = 0; - ByteString::Stream userIDStream; - userIDStream << authUser.UserID; + ByteString userID = ByteString::Build(authUser.UserID); if (authUser.UserID) { if (!save.GetGameSave()) @@ -1020,13 +1016,13 @@ RequestStatus Client::UploadSave(SaveInfo & save) std::strcpy (saveName, save.GetName().ToUtf8().c_str()); char *saveDescription = new char[save.GetDescription().length() + 1]; std::strcpy (saveDescription, save.GetDescription().ToUtf8().c_str()); - char *userid = new char[userIDStream.str().length() + 1]; - std::strcpy (userid, userIDStream.str().c_str()); + char *userid = new char[userID.size() + 1]; + std::strcpy (userid, userID.c_str()); char *session = new char[authUser.SessionID.length() + 1]; std::strcpy (session, authUser.SessionID.c_str()); const char *const postNames[] = { "Name", "Description", "Data:save.bin", "Publish", NULL }; - const char *const postDatas[] = { saveName, saveDescription, gameData, (char *)(save.GetPublished()?"Public":"Private") }; + const char *const postDatas[] = { saveName, saveDescription, gameData, save.GetPublished()?"Public":"Private" }; size_t postLengths[] = { save.GetName().length(), save.GetDescription().length(), gameDataLength, (size_t)(save.GetPublished()?6:7) }; data = http_multipart_post("http://" SERVER "/Save.api", postNames, postDatas, postLengths, userid, NULL, session, &dataStatus, &dataLength); @@ -1044,7 +1040,7 @@ RequestStatus Client::UploadSave(SaveInfo & save) RequestStatus ret = ParseServerReturn(data, dataStatus, false); if (ret == RequestOkay) { - int saveID = format::ByteStringToNumber(data+3); + int saveID = ByteString(data+3).ToNumber(); if (!saveID) { lastError = "Server did not return Save ID"; @@ -1100,12 +1096,8 @@ void Client::DeleteStamp(ByteString stampID) { if((*iterator) == stampID) { - ByteString::Stream stampFilename; - stampFilename << STAMPS_DIR; - stampFilename << PATH_SEP; - stampFilename << stampID; - stampFilename << ".stm"; - remove(stampFilename.str().c_str()); + ByteString stampFilename = ByteString::Build(STAMPS_DIR, PATH_SEP, stampID, ".stm"); + remove(stampFilename.c_str()); stampIDs.erase(iterator); return; } @@ -1124,12 +1116,8 @@ ByteString Client::AddStamp(GameSave * saveData) } else lastStampName++; - ByteString::Stream saveID; - //sprintf(saveID, "%08x%02x", lastStampTime, lastStampName); - saveID - << std::setw(8) << std::setfill('0') << std::hex << lastStampTime - << std::setw(2) << std::setfill('0') << std::hex << lastStampName; - ByteString filename = STAMPS_DIR PATH_SEP + saveID.str() + ".stm"; + ByteString saveID = ByteString::Build(Format::Hex(Format::Width(lastStampTime, 8)), Format::Hex(Format::Width(lastStampName, 2))); + ByteString filename = STAMPS_DIR PATH_SEP + saveID + ".stm"; MakeDirectory(STAMPS_DIR); @@ -1157,11 +1145,11 @@ ByteString Client::AddStamp(GameSave * saveData) delete[] gameData; - stampIDs.push_front(saveID.str()); + stampIDs.push_front(saveID); updateStamps(); - return saveID.str(); + return saveID; } void Client::updateStamps() @@ -1233,8 +1221,8 @@ RequestStatus Client::ExecVote(int saveID, int direction) if (authUser.UserID) { char * directionText = (char*)(direction==1?"Up":"Down"); - ByteString saveIDText = format::NumberToByteString(saveID); - ByteString userIDText = format::NumberToByteString(authUser.UserID); + ByteString saveIDText = ByteString::Build(saveID); + ByteString userIDText = ByteString::Build(authUser.UserID); char *id = new char[saveIDText.length() + 1]; std::strcpy(id, saveIDText.c_str()); @@ -1267,14 +1255,14 @@ unsigned char * Client::GetSaveData(int saveID, int saveDate, int & dataLength) int dataStatus; char *data; dataLength = 0; - ByteString::Stream urlStream; + ByteString urlStr; if (saveDate) - urlStream << "http://" << STATICSERVER << "/" << saveID << "_" << saveDate << ".cps"; + urlStr = ByteString::Build("http://", STATICSERVER, "/", saveID, "_", saveDate, ".cps"); else - urlStream << "http://" << STATICSERVER << "/" << saveID << ".cps"; + urlStr = ByteString::Build("http://", STATICSERVER, "/", saveID, ".cps"); - char *url = new char[urlStream.str().length() + 1]; - std::strcpy(url, urlStream.str().c_str()); + char *url = new char[urlStr.size() + 1]; + std::strcpy(url, urlStr.c_str()); data = http_simple_get(url, &dataStatus, &dataLength); delete[] url; @@ -1300,13 +1288,13 @@ std::vector Client::GetSaveData(int saveID, int saveDate) RequestBroker::Request * Client::GetSaveDataAsync(int saveID, int saveDate) { - ByteString::Stream urlStream; + ByteString url; if(saveDate){ - urlStream << "http://" << STATICSERVER << "/" << saveID << "_" << saveDate << ".cps"; + url = ByteString::Build("http://", STATICSERVER, "/", saveID, "_", saveDate, ".cps"); } else { - urlStream << "http://" << STATICSERVER << "/" << saveID << ".cps"; + url = ByteString::Build("http://", STATICSERVER, "/", saveID, ".cps"); } - return new WebRequest(urlStream.str()); + return new WebRequest(url); } RequestBroker::Request * Client::SaveUserInfoAsync(UserInfo info) @@ -1381,7 +1369,6 @@ RequestBroker::Request * Client::GetUserInfoAsync(ByteString username) LoginStatus Client::Login(ByteString username, ByteString password, User & user) { lastError = ""; - ByteString::Stream hashStream; char passwordHash[33]; char totalHash[33]; @@ -1393,14 +1380,14 @@ LoginStatus Client::Login(ByteString username, ByteString password, User & user) //Doop md5_ascii(passwordHash, (const unsigned char *)password.c_str(), password.length()); passwordHash[32] = 0; - hashStream << username << "-" << passwordHash; - md5_ascii(totalHash, (const unsigned char *)(hashStream.str().c_str()), hashStream.str().length()); + ByteString total = ByteString::Build(username, "-", passwordHash); + md5_ascii(totalHash, (const unsigned char *)(total.c_str()), total.size()); totalHash[32] = 0; char * data; int dataStatus, dataLength; const char *const postNames[] = { "Username", "Hash", NULL }; - const char *const postDatas[] = { (char*)username.c_str(), totalHash }; + const char *const postDatas[] = { username.c_str(), totalHash }; size_t postLengths[] = { username.length(), 32 }; data = http_multipart_post("http://" SERVER "/Login.json", postNames, postDatas, postLengths, NULL, NULL, NULL, &dataStatus, &dataLength); RequestStatus ret = ParseServerReturn(data, dataStatus, true); @@ -1454,15 +1441,13 @@ LoginStatus Client::Login(ByteString username, ByteString password, User & user) RequestStatus Client::DeleteSave(int saveID) { lastError = ""; - ByteString::Stream urlStream; char * data = NULL; int dataStatus, dataLength; - urlStream << "http://" << SERVER << "/Browse/Delete.json?ID=" << saveID << "&Mode=Delete&Key=" << authUser.SessionKey; + ByteString url = ByteString::Build("http://", SERVER, "/Browse/Delete.json?ID=", saveID, "&Mode=Delete&Key=", authUser.SessionKey); if(authUser.UserID) { - ByteString::Stream userIDStream; - userIDStream << authUser.UserID; - data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength); + ByteString userID = ByteString::Build(authUser.UserID); + data = http_auth_get(url.c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength); } else { @@ -1477,19 +1462,18 @@ RequestStatus Client::DeleteSave(int saveID) RequestStatus Client::AddComment(int saveID, String comment) { lastError = ""; - ByteString::Stream urlStream; char * data = NULL; int dataStatus, dataLength; - urlStream << "http://" << SERVER << "/Browse/Comments.json?ID=" << saveID; + ByteString url = ByteString::Build("http://", SERVER, "/Browse/Comments.json?ID=", saveID); if(authUser.UserID) { - ByteString::Stream userIDStream; - userIDStream << authUser.UserID; + ByteString userID = ByteString::Build(authUser.UserID); const char *const postNames[] = { "Comment", NULL }; - const char *const postDatas[] = { (char*)(comment.c_str()) }; - size_t postLengths[] = { comment.length() }; - data = http_multipart_post((char *)urlStream.str().c_str(), postNames, postDatas, postLengths, (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength); + ByteString commentBytes = comment.ToUtf8(); + const char *const postDatas[] = { commentBytes.c_str() }; + size_t postLengths[] = { commentBytes.size() }; + data = http_multipart_post(url.c_str(), postNames, postDatas, postLengths, userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength); } else { @@ -1504,7 +1488,7 @@ RequestStatus Client::AddComment(int saveID, String comment) RequestStatus Client::FavouriteSave(int saveID, bool favourite) { lastError = ""; - ByteString::Stream urlStream; + ByteStringBuilder urlStream; char * data = NULL; int dataStatus, dataLength; urlStream << "http://" << SERVER << "/Browse/Favourite.json?ID=" << saveID << "&Key=" << authUser.SessionKey; @@ -1512,9 +1496,8 @@ RequestStatus Client::FavouriteSave(int saveID, bool favourite) urlStream << "&Mode=Remove"; if(authUser.UserID) { - ByteString::Stream userIDStream; - userIDStream << authUser.UserID; - data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength); + ByteString userID = ByteString::Build(authUser.UserID); + data = http_auth_get(urlStream.Build().c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength); } else { @@ -1529,19 +1512,18 @@ RequestStatus Client::FavouriteSave(int saveID, bool favourite) RequestStatus Client::ReportSave(int saveID, String message) { lastError = ""; - ByteString::Stream urlStream; char * data = NULL; int dataStatus, dataLength; - urlStream << "http://" << SERVER << "/Browse/Report.json?ID=" << saveID << "&Key=" << authUser.SessionKey; + ByteString url = ByteString::Build("http://", SERVER, "/Browse/Report.json?ID=", saveID, "&Key=", authUser.SessionKey); if(authUser.UserID) { - ByteString::Stream userIDStream; - userIDStream << authUser.UserID; + ByteString userID = ByteString::Build(authUser.UserID); const char *const postNames[] = { "Reason", NULL }; - const char *const postDatas[] = { (char*)(message.c_str()) }; - size_t postLengths[] = { message.length() }; - data = http_multipart_post((char *)urlStream.str().c_str(), postNames, postDatas, postLengths, (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength); + ByteString messageBytes = message.ToUtf8(); + const char *const postDatas[] = { messageBytes.c_str() }; + size_t postLengths[] = { messageBytes.size() }; + data = http_multipart_post(url.c_str(), postNames, postDatas, postLengths, userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength); } else { @@ -1556,15 +1538,14 @@ RequestStatus Client::ReportSave(int saveID, String message) RequestStatus Client::UnpublishSave(int saveID) { lastError = ""; - ByteString::Stream urlStream; char * data = NULL; int dataStatus, dataLength; - urlStream << "http://" << SERVER << "/Browse/Delete.json?ID=" << saveID << "&Mode=Unpublish&Key=" << authUser.SessionKey; + ByteString url = ByteString::Build("http://", SERVER, "/Browse/Delete.json?ID=", saveID, "&Mode=Unpublish&Key=", authUser.SessionKey); if(authUser.UserID) { - ByteString::Stream userIDStream; - userIDStream << authUser.UserID; - data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength); + ByteString userID = ByteString::Build(authUser.UserID); + + data = http_auth_get(url.c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength); } else { @@ -1579,18 +1560,17 @@ RequestStatus Client::UnpublishSave(int saveID) RequestStatus Client::PublishSave(int saveID) { lastError = ""; - ByteString::Stream urlStream; char *data; int dataStatus; - urlStream << "http://" << SERVER << "/Browse/View.json?ID=" << saveID << "&Key=" << authUser.SessionKey; + ByteString url = ByteString::Build("http://", SERVER, "/Browse/View.json?ID=", saveID, "&Key=", authUser.SessionKey); if (authUser.UserID) { - ByteString::Stream userIDStream; - userIDStream << authUser.UserID; + ByteString userID = ByteString::Build(authUser.UserID); + const char *const postNames[] = { "ActionPublish", NULL }; const char *const postDatas[] = { "" }; - size_t postLengths[] = { 1 }; - data = http_multipart_post(urlStream.str().c_str(), postNames, postDatas, postLengths, userIDStream.str().c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, NULL); } + size_t postLengths[] = { 0 }; + data = http_multipart_post(url.c_str(), postNames, postDatas, postLengths, userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, NULL); } else { lastError = "Not authenticated"; @@ -1604,7 +1584,7 @@ RequestStatus Client::PublishSave(int saveID) SaveInfo * Client::GetSave(int saveID, int saveDate) { lastError = ""; - ByteString::Stream urlStream; + ByteStringBuilder urlStream; urlStream << "http://" << SERVER << "/Browse/View.json?ID=" << saveID; if(saveDate) { @@ -1614,13 +1594,13 @@ SaveInfo * Client::GetSave(int saveID, int saveDate) int dataStatus, dataLength; if(authUser.UserID) { - ByteString::Stream userIDStream; - userIDStream << authUser.UserID; - data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength); + ByteString userID = ByteString::Build(authUser.UserID); + + data = http_auth_get(urlStream.Build().c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength); } else { - data = http_simple_get((char *)urlStream.str().c_str(), &dataStatus, &dataLength); + data = http_simple_get(urlStream.Build().c_str(), &dataStatus, &dataLength); } if(dataStatus == 200 && data) { @@ -1677,7 +1657,7 @@ SaveInfo * Client::GetSave(int saveID, int saveDate) RequestBroker::Request * Client::GetSaveAsync(int saveID, int saveDate) { - ByteString::Stream urlStream; + ByteStringBuilder urlStream; urlStream << "http://" << SERVER << "/Browse/View.json?ID=" << saveID; if(saveDate) { @@ -1734,7 +1714,7 @@ RequestBroker::Request * Client::GetSaveAsync(int saveID, int saveDate) } virtual ~SaveInfoParser() { } }; - return new APIRequest(urlStream.str(), new SaveInfoParser()); + return new APIRequest(urlStream.Build(), new SaveInfoParser()); } RequestBroker::Request * Client::GetCommentsAsync(int saveID, int start, int count) @@ -1752,7 +1732,7 @@ RequestBroker::Request * Client::GetCommentsAsync(int saveID, int start, int cou for (Json::UInt j = 0; j < commentsArray.size(); j++) { - int userID = format::ByteStringToNumber(commentsArray[j]["UserID"].asString()); + int userID = ByteString(commentsArray[j]["UserID"].asString()).ToNumber(); ByteString username = commentsArray[j]["Username"].asString(); ByteString formattedUsername = commentsArray[j]["FormattedUsername"].asString(); if (formattedUsername == "jacobot") @@ -1775,9 +1755,8 @@ RequestBroker::Request * Client::GetCommentsAsync(int saveID, int start, int cou virtual ~CommentsParser() { } }; - ByteString::Stream urlStream; - urlStream << "http://" << SERVER << "/Browse/Comments.json?ID=" << saveID << "&Start=" << start << "&Count=" << count; - return new APIRequest(urlStream.str(), new CommentsParser()); + ByteString url = ByteString::Build("http://", SERVER, "/Browse/Comments.json?ID=", saveID, "&Start=", start, "&Count=", count); + return new APIRequest(url, new CommentsParser()); } std::vector > * Client::GetTags(int start, int count, String query, int & resultCount) @@ -1785,7 +1764,7 @@ std::vector > * Client::GetTags(int start, int count, lastError = ""; resultCount = 0; std::vector > * tagArray = new std::vector >(); - ByteString::Stream urlStream; + ByteStringBuilder urlStream; char * data; int dataStatus, dataLength; urlStream << "http://" << SERVER << "/Browse/Tags.json?Start=" << start << "&Count=" << count; @@ -1796,7 +1775,7 @@ std::vector > * Client::GetTags(int start, int count, urlStream << format::URLEncode(query.ToUtf8()); } - data = http_simple_get((char *)urlStream.str().c_str(), &dataStatus, &dataLength); + data = http_simple_get(urlStream.Build().c_str(), &dataStatus, &dataLength); if(dataStatus == 200 && data) { try @@ -1832,7 +1811,7 @@ std::vector * Client::SearchSaves(int start, int count, String query, lastError = ""; resultCount = 0; std::vector * saveArray = new std::vector(); - ByteString::Stream urlStream; + ByteStringBuilder urlStream; char * data; int dataStatus, dataLength; urlStream << "http://" << SERVER << "/Browse.json?Start=" << start << "&Count=" << count; @@ -1854,13 +1833,12 @@ std::vector * Client::SearchSaves(int start, int count, String query, } if(authUser.UserID) { - ByteString::Stream userIDStream; - userIDStream << authUser.UserID; - data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength); + ByteString userID = ByteString::Build(authUser.UserID); + data = http_auth_get(urlStream.Build().c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength); } else { - data = http_simple_get((char *)urlStream.str().c_str(), &dataStatus, &dataLength); + data = http_simple_get(urlStream.Build().c_str(), &dataStatus, &dataLength); } ParseServerReturn(data, dataStatus, true); if (dataStatus == 200 && data) @@ -1917,15 +1895,13 @@ std::list * Client::RemoveTag(int saveID, ByteString tag) { lastError = ""; std::list * tags = NULL; - ByteString::Stream urlStream; char * data = NULL; int dataStatus, dataLength; - urlStream << "http://" << SERVER << "/Browse/EditTag.json?Op=delete&ID=" << saveID << "&Tag=" << tag << "&Key=" << authUser.SessionKey; + ByteString url = ByteString::Build("http://", SERVER, "/Browse/EditTag.json?Op=delete&ID=", saveID, "&Tag=", tag, "&Key=", authUser.SessionKey); if(authUser.UserID) { - ByteString::Stream userIDStream; - userIDStream << authUser.UserID; - data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength); + ByteString userID = ByteString::Build(authUser.UserID); + data = http_auth_get(url.c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength); } else { @@ -1959,15 +1935,13 @@ std::list * Client::AddTag(int saveID, ByteString tag) { lastError = ""; std::list * tags = NULL; - ByteString::Stream urlStream; char * data = NULL; int dataStatus, dataLength; - urlStream << "http://" << SERVER << "/Browse/EditTag.json?Op=add&ID=" << saveID << "&Tag=" << tag << "&Key=" << authUser.SessionKey; + ByteString url = ByteString::Build("http://", SERVER, "/Browse/EditTag.json?Op=add&ID=", saveID, "&Tag=", tag, "&Key=", authUser.SessionKey); if(authUser.UserID) { - ByteString::Stream userIDStream; - userIDStream << authUser.UserID; - data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength); + ByteString userID = ByteString::Build(authUser.UserID); + data = http_auth_get(url.c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength); } else { diff --git a/src/client/GameSave.cpp b/src/client/GameSave.cpp index b7fd2af36..eff87d3df 100644 --- a/src/client/GameSave.cpp +++ b/src/client/GameSave.cpp @@ -629,7 +629,7 @@ void GameSave::readOPS(char * data, int dataLength) int bz2ret; if ((bz2ret = BZ2_bzBuffToBuffDecompress((char*)bsonData, &bsonDataLen, (char*)(inputData+12), inputDataLen-12, 0, 0)) != BZ_OK) { - throw ParseException(ParseException::Corrupt, "Unable to decompress (ret " + format::NumberToString(bz2ret) + ")"); + throw ParseException(ParseException::Corrupt, String::Build("Unable to decompress (ret ", bz2ret, ")")); } set_bson_err_handler([](const char* err) { throw ParseException(ParseException::Corrupt, "BSON error when parsing save: " + ByteString(err).FromUtf8()); }); @@ -1406,7 +1406,7 @@ void GameSave::readPSv(char * saveDataChar, int dataLength) int bzStatus = 0; if ((bzStatus = BZ2_bzBuffToBuffDecompress((char *)data, (unsigned *)&size, (char *)(saveData+12), dataLength-12, 0, 0))) - throw ParseException(ParseException::Corrupt, "Cannot decompress: " + format::NumberToString(bzStatus)); + throw ParseException(ParseException::Corrupt, String::Build("Cannot decompress: ", bzStatus)); dataLength = size; #ifdef DEBUG @@ -2510,7 +2510,7 @@ char * GameSave::serialiseOPS(unsigned int & dataLength) unsigned int finalDataLen = bson_size(&b); auto outputData = std::unique_ptr(new unsigned char[finalDataLen*2+12]); if (!outputData) - throw BuildException("Save error, out of memory (finalData): " + format::NumberToString(finalDataLen*2+12)); + throw BuildException(String::Build("Save error, out of memory (finalData): ", finalDataLen*2+12)); outputData[0] = 'O'; outputData[1] = 'P'; @@ -2528,7 +2528,7 @@ char * GameSave::serialiseOPS(unsigned int & dataLength) unsigned int compressedSize = finalDataLen*2, bz2ret; if ((bz2ret = BZ2_bzBuffToBuffCompress((char*)(outputData.get()+12), &compressedSize, (char*)finalData, bson_size(&b), 9, 0, 0)) != BZ_OK) { - throw BuildException("Save error, could not compress (ret " + format::NumberToString(bz2ret) + ")"); + throw BuildException(String::Build("Save error, could not compress (ret ", bz2ret, ")")); } #ifdef DEBUG diff --git a/src/client/HTTP.cpp b/src/client/HTTP.cpp index 26da8f496..899122924 100644 --- a/src/client/HTTP.cpp +++ b/src/client/HTTP.cpp @@ -192,11 +192,7 @@ void http_init(char *proxy) free(host); free(port); } - ByteString::Stream userAgentBuilder; - userAgentBuilder << "PowderToy/" << SAVE_VERSION << "." << MINOR_VERSION << " "; - userAgentBuilder << "(" << IDENT_PLATFORM << "; " << IDENT_BUILD << "; M" << MOD_ID << ") "; - userAgentBuilder << "TPTPP/" << SAVE_VERSION << "." << MINOR_VERSION << "." << BUILD_NUM << IDENT_RELTYPE << "." << SNAPSHOT_ID; - ByteString newUserAgent = userAgentBuilder.str(); + ByteString newUserAgent = ByteString::Build("PowderToy/", SAVE_VERSION, ".", MINOR_VERSION, " (", IDENT_PLATFORM, "; ", IDENT_BUILD, "; M", MOD_ID, ") TPTPP/", SAVE_VERSION, ".", MINOR_VERSION, ".", BUILD_NUM, IDENT_RELTYPE, ".", SNAPSHOT_ID); userAgent = new char[newUserAgent.length()+1]; std::copy(newUserAgent.begin(), newUserAgent.end(), userAgent); userAgent[newUserAgent.length()] = 0; @@ -987,7 +983,7 @@ ByteString FindBoundary(std::map parts, ByteString bound // this function used in Download class, and eventually all http requests ByteString GetMultipartMessage(std::map parts, ByteString boundary) { - ByteString::Stream data; + ByteStringBuilder data; // loop through each part, adding it for (std::map::iterator iter = parts.begin(); iter != parts.end(); iter++) @@ -1014,7 +1010,7 @@ ByteString GetMultipartMessage(std::map parts, ByteStrin data << "\r\n"; } data << "--" << boundary << "--\r\n"; - return data.str(); + return data.Build(); } // add the header needed to make POSTS work diff --git a/src/client/requestbroker/APIRequest.cpp b/src/client/requestbroker/APIRequest.cpp index dcd2e143a..084e580c9 100644 --- a/src/client/requestbroker/APIRequest.cpp +++ b/src/client/requestbroker/APIRequest.cpp @@ -103,7 +103,7 @@ RequestBroker::ProcessResponse APIRequest::Process(RequestBroker & rb) User user = Client::Ref().GetAuthUser(); char userName[12]; char *userSession = new char[user.SessionID.length() + 1]; - std::strcpy(userName, format::NumberToByteString(user.UserID).c_str()); + std::strcpy(userName, ByteString::Build(user.UserID).c_str()); std::strcpy(userSession, user.SessionID.c_str()); HTTPContext = http_multipart_post_async((char*)URL.c_str(), postNames, postData, postLength, userName, NULL, userSession); delete[] userSession; @@ -122,7 +122,7 @@ RequestBroker::ProcessResponse APIRequest::Process(RequestBroker & rb) User user = Client::Ref().GetAuthUser(); char userName[12]; char *userSession = new char[user.SessionID.length() + 1]; - std::strcpy(userName, format::NumberToByteString(user.UserID).c_str()); + std::strcpy(userName, ByteString::Build(user.UserID).c_str()); std::strcpy(userSession, user.SessionID.c_str()); http_auth_headers(HTTPContext, userName, NULL, userSession); delete[] userSession; diff --git a/src/client/requestbroker/RequestBroker.cpp b/src/client/requestbroker/RequestBroker.cpp index b3395e78e..5a446a754 100644 --- a/src/client/requestbroker/RequestBroker.cpp +++ b/src/client/requestbroker/RequestBroker.cpp @@ -97,23 +97,22 @@ void RequestBroker::RenderThumbnail(GameSave * gameSave, bool decorations, bool void RequestBroker::RetrieveThumbnail(int saveID, int saveDate, int width, int height, RequestListener * tListener) { - ByteString::Stream urlStream; - urlStream << "http://" << STATICSERVER << "/" << saveID; + ByteStringBuilder url; + url << "http://" << STATICSERVER << "/" << saveID; if(saveDate) { - urlStream << "_" << saveDate; + url << "_" << saveDate; } - urlStream << "_small.pti"; + url << "_small.pti"; - RetrieveImage(urlStream.str(), width, height, tListener); + RetrieveImage(url.Build(), width, height, tListener); } void RequestBroker::RetrieveAvatar(ByteString username, int width, int height, RequestListener * tListener) { - ByteString::Stream urlStream; - urlStream << "http://" << STATICSERVER << "/avatars/" << username << ".pti"; + ByteString url = ByteString::Build("http://", STATICSERVER, "/avatars/", username, ".pti"); - RetrieveImage(urlStream.str(), width, height, tListener); + RetrieveImage(url, width, height, tListener); } void RequestBroker::Start(Request * request, RequestListener * tListener, int identifier) diff --git a/src/client/requestbroker/WebRequest.cpp b/src/client/requestbroker/WebRequest.cpp index bd8b99ea9..c72b130d0 100644 --- a/src/client/requestbroker/WebRequest.cpp +++ b/src/client/requestbroker/WebRequest.cpp @@ -106,7 +106,7 @@ RequestBroker::ProcessResponse WebRequest::Process(RequestBroker & rb) User user = Client::Ref().GetAuthUser(); char userName[12]; char *userSession = new char[user.SessionID.length() + 1]; - std::strcpy(userName, format::NumberToByteString(user.UserID).c_str()); + std::strcpy(userName, ByteString::Build(user.UserID).c_str()); std::strcpy(userSession, user.SessionID.c_str()); HTTPContext = http_multipart_post_async((char*)URL.c_str(), postNames, postData, postLength, userName, NULL, userSession); delete[] userSession; @@ -125,7 +125,7 @@ RequestBroker::ProcessResponse WebRequest::Process(RequestBroker & rb) User user = Client::Ref().GetAuthUser(); char userName[12]; char *userSession = new char[user.SessionID.length() + 1]; - std::strcpy(userName, format::NumberToByteString(user.UserID).c_str()); + std::strcpy(userName, ByteString::Build(user.UserID).c_str()); std::strcpy(userSession, user.SessionID.c_str()); http_auth_headers(HTTPContext, userName, NULL, userSession); delete[] userSession; diff --git a/src/common/Format.h b/src/common/Format.h index 3e76d2fab..e5afe1eae 100644 --- a/src/common/Format.h +++ b/src/common/Format.h @@ -25,6 +25,18 @@ namespace Format inline FlagsOverride() {} }; + template struct FillOverride + { + T value; + size_t fill; + inline FillOverride(T _value, size_t _fill): value(_value), fill(_fill) {} + }; + template<> struct FillOverride + { + String::value_type fill; + inline FillOverride(size_t _fill): fill(_fill) {} + }; + template struct WidthOverride { T value; @@ -74,8 +86,10 @@ namespace Format inline FlagsOverride Scientific() { return FlagsOverride(); } inline FlagsOverride FloatDefault() { return FlagsOverride(); } + template inline FillOverride Fill(T value, String::value_type fill) { return FillOverride(value, fill); } template inline WidthOverride Width(T value, size_t width) { return WidthOverride(value, width); } template inline PrecisionOverride Precision(T value, size_t precision) { return PrecisionOverride(value, precision); } + inline FillOverride Fill(String::value_type fill) { return FillOverride(fill); } inline WidthOverride Width(size_t width) { return WidthOverride(width); } inline PrecisionOverride Precision(size_t precision) { return PrecisionOverride(precision); } }; @@ -94,16 +108,36 @@ template inline Byte return b; } +template inline ByteStringBuilder &operator<<(ByteStringBuilder &b, Format::FillOverride data) +{ + size_t oldfill = b.fill; + b.fill = data.fill; + b << data.value; + b.fill = oldfill; + return b; +} +inline ByteStringBuilder &operator<<(ByteStringBuilder &b, Format::FillOverride data) +{ + b.fill = data.fill; + return b; +} + template inline ByteStringBuilder &operator<<(ByteStringBuilder &b, Format::WidthOverride data) { + String::value_type oldfill = b.fill; + if(oldfill == ' ') + b.fill = '0'; size_t oldwidth = b.width; b.width = data.width; b << data.value; b.width = oldwidth; + b.fill = oldfill; return b; } inline ByteStringBuilder &operator<<(ByteStringBuilder &b, Format::WidthOverride data) { + if(b.fill == ' ') + b.fill = '0'; b.width = data.width; return b; } @@ -142,16 +176,36 @@ template inline Stri return b; } +template inline StringBuilder &operator<<(StringBuilder &b, Format::FillOverride data) +{ + size_t oldfill = b.fill; + b.fill = data.fill; + b << data.value; + b.fill = oldfill; + return b; +} +inline StringBuilder &operator<<(StringBuilder &b, Format::FillOverride data) +{ + b.fill = data.fill; + return b; +} + template inline StringBuilder &operator<<(StringBuilder &b, Format::WidthOverride data) { + String::value_type oldfill = b.fill; + if(oldfill == ' ') + b.fill = '0'; size_t oldwidth = b.width; b.width = data.width; b << data.value; b.width = oldwidth; + b.fill = oldfill; return b; } inline StringBuilder &operator<<(StringBuilder &b, Format::WidthOverride data) { + if(b.fill == ' ') + b.fill = '0'; b.width = data.width; return b; } diff --git a/src/common/String.h b/src/common/String.h index bb6be1841..4ac454a17 100644 --- a/src/common/String.h +++ b/src/common/String.h @@ -168,8 +168,6 @@ public: String FromUtf8(bool ignoreError = true) const; inline String FromAscii() const; template static ByteString Build(Ts&&... args); - - using Stream = std::basic_stringstream; }; inline ByteString operator+(ByteString const &lhs, ByteString const &rhs) { return static_cast const &>(lhs) + static_cast const &>(rhs); } @@ -405,7 +403,7 @@ public: size_t Size() const { return buffer.size(); } ByteString Build() const; - template ByteStringBuilder &operator<<(T) = delete; + template ByteStringBuilder &operator<<(T) &&= delete; template ByteStringBuilder &Add(T &&arg, Ts&&... args) { diff --git a/src/debug/ElementPopulation.cpp b/src/debug/ElementPopulation.cpp index 3de462a11..c9739bd84 100644 --- a/src/debug/ElementPopulation.cpp +++ b/src/debug/ElementPopulation.cpp @@ -37,8 +37,8 @@ void ElementPopulationDebug::Draw() maxAverage = (maxAverage*(1.0f-0.015f)) + (0.015f*maxVal); scale = 255.0f/maxAverage; - maxValString = format::NumberToString(maxAverage); - halfValString = format::NumberToString(maxAverage/2); + maxValString = String::Build(maxAverage); + halfValString = String::Build(maxAverage/2); g->fillrect(xStart-5, yBottom - 263, bars+10+Graphics::textwidth(maxValString)+10, 255 + 13, 0, 0, 0, 180); diff --git a/src/gui/colourpicker/ColourPickerActivity.cpp b/src/gui/colourpicker/ColourPickerActivity.cpp index a3bef8f23..93c58b378 100644 --- a/src/gui/colourpicker/ColourPickerActivity.cpp +++ b/src/gui/colourpicker/ColourPickerActivity.cpp @@ -28,10 +28,10 @@ ColourPickerActivity::ColourPickerActivity(ui::Colour initialColour, ColourPicke void TextChangedCallback(ui::Textbox * sender) { int r, g, b, alpha; - r = format::StringToNumber(a->rValue->GetText()); - g = format::StringToNumber(a->gValue->GetText()); - b = format::StringToNumber(a->bValue->GetText()); - alpha = format::StringToNumber(a->aValue->GetText()); + r = a->rValue->GetText().ToNumber(true); + g = a->gValue->GetText().ToNumber(true); + b = a->bValue->GetText().ToNumber(true); + alpha = a->aValue->GetText().ToNumber(true); if (r > 255) r = 255; if (g > 255) @@ -82,9 +82,9 @@ ColourPickerActivity::ColourPickerActivity(ui::Colour initialColour, ColourPicke void ActionCallback(ui::Button * sender) { int Red, Green, Blue; - Red = format::StringToNumber(a->rValue->GetText()); - Green = format::StringToNumber(a->gValue->GetText()); - Blue = format::StringToNumber(a->bValue->GetText()); + Red = a->rValue->GetText().ToNumber(true); + Green = a->gValue->GetText().ToNumber(true); + Blue = a->bValue->GetText().ToNumber(true); ui::Colour col(Red, Green, Blue, a->currentAlpha); if(a->callback) a->callback->ColourPicked(col); @@ -104,10 +104,10 @@ ColourPickerActivity::ColourPickerActivity(ui::Colour initialColour, ColourPicke void ColourPickerActivity::UpdateTextboxes(int r, int g, int b, int a) { - rValue->SetText(format::NumberToString(r)); - gValue->SetText(format::NumberToString(g)); - bValue->SetText(format::NumberToString(b)); - aValue->SetText(format::NumberToString(a)); + rValue->SetText(String::Build(r)); + gValue->SetText(String::Build(g)); + bValue->SetText(String::Build(b)); + aValue->SetText(String::Build(a)); hexValue->SetText(String::Build(Format::Hex(), Format::Uppercase(), Format::Width(2), a, r, g, b)); } void ColourPickerActivity::OnTryExit(ExitMethod method) diff --git a/src/gui/dialogues/SaveIDMessage.cpp b/src/gui/dialogues/SaveIDMessage.cpp index 2969708c8..53b922f04 100644 --- a/src/gui/dialogues/SaveIDMessage.cpp +++ b/src/gui/dialogues/SaveIDMessage.cpp @@ -28,8 +28,8 @@ SaveIDMessage::SaveIDMessage(int id): copyTextLabel->Appearance.HorizontalAlign = ui::Appearance::AlignCentre; AddComponent(copyTextLabel); - textWidth = Graphics::textwidth(format::NumberToString(id).c_str()); - ui::CopyTextButton * copyTextButton = new ui::CopyTextButton(ui::Point((Size.X-textWidth-10)/2, 50), ui::Point(textWidth+10, 18), format::NumberToString(id), copyTextLabel); + textWidth = Graphics::textwidth(String::Build(id)); + ui::CopyTextButton * copyTextButton = new ui::CopyTextButton(ui::Point((Size.X-textWidth-10)/2, 50), ui::Point(textWidth+10, 18), String::Build(id), copyTextLabel); AddComponent(copyTextButton); class DismissAction: public ui::ButtonAction diff --git a/src/gui/font/FontEditor.cpp b/src/gui/font/FontEditor.cpp index 82a761f60..79d84517f 100644 --- a/src/gui/font/FontEditor.cpp +++ b/src/gui/font/FontEditor.cpp @@ -293,9 +293,7 @@ FontEditor::FontEditor(ByteString _header): CharNumberAction(FontEditor *_v): v(_v) {} void TextChangedCallback(ui::Textbox *) { - unsigned int number; - ByteString::Stream ss(v->currentCharTextbox->GetText().ToUtf8()); - ss >> std::hex >> number; + unsigned int number = v->currentCharTextbox->GetText().ToNumber(true); if(number <= 0x10FFFF) v->currentChar = number; } @@ -426,14 +424,13 @@ FontEditor::FontEditor(ByteString _header): ColorComponentAction(int &_color): color(_color) {} void TextChangedCallback(ui::Textbox *box) { - ByteString::Stream ss(box->GetText().ToUtf8()); - ss >> color; + color = box->GetText().ToNumber(true); } }; int *refs[6] = {&fgR, &fgG, &fgB, &bgR, &bgG, &bgB}; for(int i = 0; i < 6; i++) { - ui::Textbox *colorComponent = new ui::Textbox(ui::Point(currentX, baseline), ui::Point(27, 17), format::NumberToString(*refs[i])); + ui::Textbox *colorComponent = new ui::Textbox(ui::Point(currentX, baseline), ui::Point(27, 17), String::Build(*refs[i])); currentX += 28; colorComponent->SetActionCallback(new ColorComponentAction(*refs[i])); AddComponent(colorComponent); @@ -489,28 +486,26 @@ FontEditor::FontEditor(ByteString _header): PreviewAction(FontEditor *_v): v(_v) {} void TextChangedCallback(ui::Textbox *box) { - ByteString::Stream ss(box->GetText().ToUtf8()); // ByteString::Stream for now - String text; - while(!ss.eof()) + String str = box->GetText(); + size_t at = 0; + StringBuilder text; + while(at < str.size()) { - if(ss.peek() == '\n') - { - text.push_back('\n'); - ss.get(); - } unsigned int ch; - ss >> std::hex >> ch; - if(ss.fail()) - { - ss.clear(); - String::value_type ch = ss.get(); - if(!ss.eof()) - text.push_back(ch); - continue; - } - text.push_back(ch); + if(str[at] != ' ') + if(String::Split split = str.SplitNumber(ch, Format::Hex(), at)) + { + text << String::value_type(ch); + at = split.PositionAfter(); + } + else + { + text << str[at++]; + } + else + at++; } - v->outputPreview->SetText(text); + v->outputPreview->SetText(text.Build()); } }; ui::Textbox *inputPreview = new ui::Textbox(ui::Point(0, baseline), ui::Point(Size.X, (Size.Y - baseline) * 3 / 5)); @@ -611,9 +606,7 @@ void FontEditor::OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bo void FontEditor::UpdateCharNumber() { - ByteString::Stream ss; - ss << std::hex << currentChar; - currentCharTextbox->SetText(ByteString(ss.str()).FromUtf8()); + currentCharTextbox->SetText(String::Build(Format::Hex((unsigned int)currentChar))); } void FontEditor::PrevChar() diff --git a/src/gui/game/GameController.cpp b/src/gui/game/GameController.cpp index f82dc4a5d..cdc60911d 100644 --- a/src/gui/game/GameController.cpp +++ b/src/gui/game/GameController.cpp @@ -679,7 +679,7 @@ bool GameController::MouseUp(int x, int y, unsigned button, char type) { case 'c': { - int saveID = format::StringToNumber(link); + int saveID = link.ToNumber(true); if (saveID) OpenSavePreview(saveID, 0, false); break; @@ -687,9 +687,7 @@ bool GameController::MouseUp(int x, int y, unsigned button, char type) case 't': { // buff is already confirmed to be a number by sign::splitsign - ByteString::Stream uri; - uri << "http://powdertoy.co.uk/Discussions/Thread/View.html?Thread=" << link.ToUtf8(); - Platform::OpenURI(uri.str()); + Platform::OpenURI(ByteString::Build("http://powdertoy.co.uk/Discussions/Thread/View.html?Thread=", link.ToUtf8())); break; } case 's': diff --git a/src/gui/game/GameView.cpp b/src/gui/game/GameView.cpp index 37b95e3c9..e0a7bc58e 100644 --- a/src/gui/game/GameView.cpp +++ b/src/gui/game/GameView.cpp @@ -1060,10 +1060,8 @@ int GameView::Record(bool record) { time_t startTime = time(NULL); recordingFolder = startTime; - ByteString::Stream recordingDir; - recordingDir << "recordings" << PATH_SEP << recordingFolder; Client::Ref().MakeDirectory("recordings"); - Client::Ref().MakeDirectory(recordingDir.str().c_str()); + Client::Ref().MakeDirectory(ByteString::Build("recordings", PATH_SEP, recordingFolder).c_str()); recording = true; recordingIndex = 0; } @@ -2211,12 +2209,9 @@ void GameView::OnDraw() VideoBuffer screenshot(ren->DumpFrame()); std::vector data = format::VideoBufferToPNG(screenshot); - ByteString::Stream filename; - filename << "screenshot_"; - filename << std::setfill('0') << std::setw(6) << (screenshotIndex++); - filename << ".png"; + ByteString filename = ByteString::Build("screenshot_", Format::Width(screenshotIndex++, 6), ".png"); - Client::Ref().WriteFile(data, filename.str()); + Client::Ref().WriteFile(data, filename); doScreenshot = false; } @@ -2225,13 +2220,9 @@ void GameView::OnDraw() VideoBuffer screenshot(ren->DumpFrame()); std::vector data = format::VideoBufferToPPM(screenshot); - ByteString::Stream filename; - filename << "recordings" << PATH_SEP << recordingFolder << PATH_SEP; - filename << "frame_"; - filename << std::setfill('0') << std::setw(6) << (recordingIndex++); - filename << ".ppm"; + ByteString filename = ByteString::Build("recordings", PATH_SEP, recordingFolder, PATH_SEP, "frame_", Format::Width(screenshotIndex++, 6), ".ppm"); - Client::Ref().WriteFile(data, filename.str()); + Client::Ref().WriteFile(data, filename); } if (logEntries.size()) diff --git a/src/gui/interface/SaveButton.cpp b/src/gui/interface/SaveButton.cpp index 8fd9aef2c..1dc93a46a 100644 --- a/src/gui/interface/SaveButton.cpp +++ b/src/gui/interface/SaveButton.cpp @@ -40,7 +40,7 @@ SaveButton::SaveButton(Point position, Point size, SaveInfo * save): String votes, icon; - votes = format::NumberToString(save->GetVotesUp()-save->GetVotesDown()); + votes = String::Build(save->GetVotesUp()-save->GetVotesDown()); icon += 0xE03B; for (size_t j = 1; j < votes.length(); j++) icon += 0xE03C; diff --git a/src/gui/localbrowser/LocalBrowserView.cpp b/src/gui/localbrowser/LocalBrowserView.cpp index 1a87a42e1..850264d07 100644 --- a/src/gui/localbrowser/LocalBrowserView.cpp +++ b/src/gui/localbrowser/LocalBrowserView.cpp @@ -108,11 +108,11 @@ LocalBrowserView::LocalBrowserView(): void LocalBrowserView::textChanged() { - int num = format::StringToNumber(pageTextbox->GetText()); + int num = pageTextbox->GetText().ToNumber(true); if (num < 0) //0 is allowed so that you can backspace the 1 pageTextbox->SetText("1"); else if (num > pageCount) - pageTextbox->SetText(format::NumberToString(pageCount)); + pageTextbox->SetText(String::Build(pageCount)); changed = true; #ifdef USE_SDL lastChanged = GetTicks()+600; @@ -126,7 +126,7 @@ void LocalBrowserView::OnTick(float dt) if (changed && lastChanged < GetTicks()) { changed = false; - c->SetPage(std::max(format::StringToNumber(pageTextbox->GetText()), 0)); + c->SetPage(std::max(pageTextbox->GetText().ToNumber(true), 0)); } #endif } diff --git a/src/gui/options/OptionsView.cpp b/src/gui/options/OptionsView.cpp index a40794023..c2881d2cd 100644 --- a/src/gui/options/OptionsView.cpp +++ b/src/gui/options/OptionsView.cpp @@ -158,7 +158,7 @@ OptionsView::OptionsView(): { if (current_scale == ix_scale) current_scale_valid = true; - scale->AddOption(std::pair(format::NumberToString(ix_scale), ix_scale)); + scale->AddOption(std::pair(String::Build(ix_scale), ix_scale)); ix_scale += 1; } while (ui::Engine::Ref().GetMaxWidth() >= ui::Engine::Ref().GetWidth() * ix_scale && ui::Engine::Ref().GetMaxHeight() >= ui::Engine::Ref().GetHeight() * ix_scale); @@ -233,9 +233,9 @@ OptionsView::OptionsView(): OptionsView * v; public: DepthAction(OptionsView * v_) { v = v_; } - virtual void TextChangedCallback(ui::Textbox * sender) { v->c->Set3dDepth(format::StringToNumber(sender->GetText())); } + virtual void TextChangedCallback(ui::Textbox * sender) { v->c->Set3dDepth(sender->GetText().ToNumber(true)); } }; - depthTextbox = new ui::Textbox(ui::Point(8, Size.Y-58), ui::Point(25, 16), format::NumberToString(ui::Engine::Ref().Get3dDepth())); + depthTextbox = new ui::Textbox(ui::Point(8, Size.Y-58), ui::Point(25, 16), String::Build(ui::Engine::Ref().Get3dDepth())); depthTextbox->SetInputType(ui::Textbox::Numeric); depthTextbox->SetActionCallback(new DepthAction(this)); AddComponent(depthTextbox); diff --git a/src/gui/preview/PreviewController.cpp b/src/gui/preview/PreviewController.cpp index 44870f9d2..ea19620c7 100644 --- a/src/gui/preview/PreviewController.cpp +++ b/src/gui/preview/PreviewController.cpp @@ -153,9 +153,8 @@ void PreviewController::FavouriteSave() void PreviewController::OpenInBrowser() { - ByteString::Stream uriStream; - uriStream << "http://" << SERVER << "/Browse/View.html?ID=" << saveId; - Platform::OpenURI(uriStream.str()); + ByteString uri = ByteString::Build("http://", SERVER, "/Browse/View.html?ID=", saveId); + Platform::OpenURI(uri); } bool PreviewController::NextCommentPage() diff --git a/src/gui/preview/PreviewModel.cpp b/src/gui/preview/PreviewModel.cpp index 5cc503e15..cb3987c12 100644 --- a/src/gui/preview/PreviewModel.cpp +++ b/src/gui/preview/PreviewModel.cpp @@ -70,30 +70,28 @@ void PreviewModel::UpdateSave(int saveID, int saveDate) notifySaveChanged(); notifySaveCommentsChanged(); - ByteString::Stream urlStream; + ByteString url; if (saveDate) - urlStream << "http://" << STATICSERVER << "/" << saveID << "_" << saveDate << ".cps"; + url = ByteString::Build("http://", STATICSERVER, "/", saveID, "_", saveDate, ".cps"); else - urlStream << "http://" << STATICSERVER << "/" << saveID << ".cps"; - saveDataDownload = new Download(urlStream.str()); + url = ByteString::Build("http://", STATICSERVER, "/", saveID, ".cps"); + saveDataDownload = new Download(url); saveDataDownload->Start(); - urlStream.str(""); - urlStream << "http://" << SERVER << "/Browse/View.json?ID=" << saveID; + url = ByteString::Build("http://", SERVER , "/Browse/View.json?ID=", saveID); if (saveDate) - urlStream << "&Date=" << saveDate; - saveInfoDownload = new Download(urlStream.str()); - saveInfoDownload->AuthHeaders(format::NumberToByteString(Client::Ref().GetAuthUser().UserID), Client::Ref().GetAuthUser().SessionID); + url += ByteString::Build("&Date=", saveDate); + saveInfoDownload = new Download(url); + saveInfoDownload->AuthHeaders(ByteString::Build(Client::Ref().GetAuthUser().UserID), Client::Ref().GetAuthUser().SessionID); saveInfoDownload->Start(); if (!GetDoOpen()) { commentsLoaded = false; - urlStream.str(""); - urlStream << "http://" << SERVER << "/Browse/Comments.json?ID=" << saveID << "&Start=" << (commentsPageNumber-1)*20 << "&Count=20"; - commentsDownload = new Download(urlStream.str()); - commentsDownload->AuthHeaders(format::NumberToByteString(Client::Ref().GetAuthUser().UserID), Client::Ref().GetAuthUser().SessionID); + url = ByteString::Build("http://", SERVER, "/Browse/Comments.json?ID=", saveID, "&Start=", (commentsPageNumber-1)*20, "&Count=20"); + commentsDownload = new Download(url); + commentsDownload->AuthHeaders(ByteString::Build(Client::Ref().GetAuthUser().UserID), Client::Ref().GetAuthUser().SessionID); commentsDownload->Start(); } } @@ -143,10 +141,9 @@ void PreviewModel::UpdateComments(int pageNumber) commentsPageNumber = pageNumber; if (!GetDoOpen()) { - ByteString::Stream urlStream; - urlStream << "http://" << SERVER << "/Browse/Comments.json?ID=" << saveID << "&Start=" << (commentsPageNumber-1)*20 << "&Count=20"; - commentsDownload = new Download(urlStream.str()); - commentsDownload->AuthHeaders(format::NumberToByteString(Client::Ref().GetAuthUser().UserID), Client::Ref().GetAuthUser().SessionID); + ByteString url = ByteString::Build("http://", SERVER, "/Browse/Comments.json?ID=", saveID, "&Start=", (commentsPageNumber-1)*20, "&Count=20"); + commentsDownload = new Download(url); + commentsDownload->AuthHeaders(ByteString::Build(Client::Ref().GetAuthUser().UserID), Client::Ref().GetAuthUser().SessionID); commentsDownload->Start(); } @@ -242,9 +239,7 @@ bool PreviewModel::ParseSaveInfo(char * saveInfoResponse) saveDataDownload->Cancel(); delete saveData; saveData = NULL; - ByteString::Stream urlStream; - urlStream << "http://" << STATICSERVER << "/2157797.cps"; - saveDataDownload = new Download(urlStream.str()); + saveDataDownload = new Download(ByteString::Build("http://", STATICSERVER, "/2157797.cps")); saveDataDownload->Start(); } return true; @@ -268,7 +263,7 @@ bool PreviewModel::ParseComments(char *commentsResponse) for (Json::UInt j = 0; j < commentsArray.size(); j++) { - int userID = format::ByteStringToNumber(commentsArray[j]["UserID"].asString()); + int userID = ByteString(commentsArray[j]["UserID"].asString()).ToNumber(); ByteString username = commentsArray[j]["Username"].asString(); ByteString formattedUsername = commentsArray[j]["FormattedUsername"].asString(); if (formattedUsername == "jacobot") diff --git a/src/gui/preview/PreviewView.cpp b/src/gui/preview/PreviewView.cpp index d1565471b..05140c921 100644 --- a/src/gui/preview/PreviewView.cpp +++ b/src/gui/preview/PreviewView.cpp @@ -227,11 +227,11 @@ void PreviewView::AttachController(PreviewController * controller) saveIDLabel->Appearance.HorizontalAlign = ui::Appearance::AlignCentre; AddComponent(saveIDLabel); - textWidth = Graphics::textwidth(format::NumberToString(c->SaveID()).c_str()); + textWidth = Graphics::textwidth(String::Build(c->SaveID())); saveIDLabel2 = new ui::Label(ui::Point((Size.X-textWidth-20)/2-37, Size.Y+22), ui::Point(40, 16), "Save ID:"); AddComponent(saveIDLabel2); - saveIDButton = new ui::CopyTextButton(ui::Point((Size.X-textWidth-10)/2, Size.Y+20), ui::Point(textWidth+10, 18), format::NumberToString(c->SaveID()), saveIDLabel); + saveIDButton = new ui::CopyTextButton(ui::Point((Size.X-textWidth-10)/2, Size.Y+20), ui::Point(textWidth+10, 18), String::Build(c->SaveID()), saveIDLabel); AddComponent(saveIDButton); } @@ -514,7 +514,7 @@ void PreviewView::NotifySaveChanged(PreviewModel * sender) userIsAuthor = true; else userIsAuthor = false; - viewsLabel->SetText("\bgViews:\bw " + format::NumberToString(save->Views)); + viewsLabel->SetText(String::Build("\bgViews:\bw ", save->Views)); saveDescriptionLabel->SetText(save->Description); if(save->Favourite) { diff --git a/src/gui/profile/ProfileActivity.cpp b/src/gui/profile/ProfileActivity.cpp index e012e833a..7e9ee0644 100644 --- a/src/gui/profile/ProfileActivity.cpp +++ b/src/gui/profile/ProfileActivity.cpp @@ -122,7 +122,7 @@ void ProfileActivity::setUserInfo(UserInfo newInfo) scrollPanel->AddChild(ageTitle); // can't figure out how to tell a null from a 0 in the json library we use - ui::Label *age = new ui::Label(ui::Point(8+ageTitle->Size.X, currentY), ui::Point(40, 15), info.age ? format::NumberToString(info.age) : "\bgNot Provided"); + ui::Label *age = new ui::Label(ui::Point(8+ageTitle->Size.X, currentY), ui::Point(40, 15), info.age ? String::Build(info.age) : "\bgNot Provided"); age->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; scrollPanel->AddChild(age); currentY += 2+age->Size.Y; @@ -165,7 +165,7 @@ void ProfileActivity::setUserInfo(UserInfo newInfo) saveCountTitle->SetTextColour(ui::Colour(180, 180, 180)); scrollPanel->AddChild(saveCountTitle); - ui::Label *savesCount = new ui::Label(ui::Point(12+saveCountTitle->Size.X, currentY), ui::Point(Size.X-saveCountTitle->Size.X-16, 15), format::NumberToString(info.saveCount)); + ui::Label *savesCount = new ui::Label(ui::Point(12+saveCountTitle->Size.X, currentY), ui::Point(Size.X-saveCountTitle->Size.X-16, 15), String::Build(info.saveCount)); savesCount->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; scrollPanel->AddChild(savesCount); currentY += savesCount->Size.Y; @@ -176,7 +176,7 @@ void ProfileActivity::setUserInfo(UserInfo newInfo) averageScoreTitle->SetTextColour(ui::Colour(180, 180, 180)); scrollPanel->AddChild(averageScoreTitle); - ui::Label *averageScore = new ui::Label(ui::Point(12+averageScoreTitle->Size.X, currentY), ui::Point(Size.X-averageScoreTitle->Size.X-16, 15), format::NumberToString(info.averageScore)); + ui::Label *averageScore = new ui::Label(ui::Point(12+averageScoreTitle->Size.X, currentY), ui::Point(Size.X-averageScoreTitle->Size.X-16, 15), String::Build(info.averageScore)); averageScore->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; scrollPanel->AddChild(averageScore); currentY += averageScore->Size.Y; @@ -187,7 +187,7 @@ void ProfileActivity::setUserInfo(UserInfo newInfo) highestScoreTitle->SetTextColour(ui::Colour(180, 180, 180)); scrollPanel->AddChild(highestScoreTitle); - ui::Label *highestScore = new ui::Label(ui::Point(12+highestScoreTitle->Size.X, currentY), ui::Point(Size.X-highestScoreTitle->Size.X-16, 15), format::NumberToString(info.highestScore)); + ui::Label *highestScore = new ui::Label(ui::Point(12+highestScoreTitle->Size.X, currentY), ui::Point(Size.X-highestScoreTitle->Size.X-16, 15), String::Build(info.highestScore)); highestScore->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; scrollPanel->AddChild(highestScore); currentY += 2+highestScore->Size.Y; diff --git a/src/gui/search/SearchView.cpp b/src/gui/search/SearchView.cpp index 14fe3798f..e37658e2f 100644 --- a/src/gui/search/SearchView.cpp +++ b/src/gui/search/SearchView.cpp @@ -270,11 +270,11 @@ void SearchView::clearSearch() void SearchView::textChanged() { - int num = format::StringToNumber(pageTextbox->GetText()); + int num = pageTextbox->GetText().ToNumber(true); if (num < 0) //0 is allowed so that you can backspace the 1 pageTextbox->SetText("1"); else if (num > pageCount) - pageTextbox->SetText(format::NumberToString(pageCount)); + pageTextbox->SetText(String::Build(pageCount)); changed = true; #ifdef USE_SDL lastChanged = GetTicks()+600; @@ -763,7 +763,7 @@ void SearchView::OnTick(float dt) if (changed && lastChanged < GetTicks()) { changed = false; - c->SetPage(std::max(format::StringToNumber(pageTextbox->GetText()), 0)); + c->SetPage(std::max(pageTextbox->GetText().ToNumber(true), 0)); } #endif } diff --git a/src/gui/update/UpdateActivity.cpp b/src/gui/update/UpdateActivity.cpp index 3f9ddcb8b..03877c07d 100644 --- a/src/gui/update/UpdateActivity.cpp +++ b/src/gui/update/UpdateActivity.cpp @@ -116,13 +116,13 @@ private: }; UpdateActivity::UpdateActivity() { - ByteString::Stream file; + ByteString file; #ifdef UPDATESERVER - file << "http://" << UPDATESERVER << Client::Ref().GetUpdateInfo().File; + file = ByteString::Build("http://", UPDATESERVER, Client::Ref().GetUpdateInfo().File); #else - file << "http://" << SERVER << Client::Ref().GetUpdateInfo().File; + file = ByteString::Build("http://", SERVER, Client::Ref().GetUpdateInfo().File); #endif - updateDownloadTask = new UpdateDownloadTask(file.str(), this); + updateDownloadTask = new UpdateDownloadTask(file, this); updateWindow = new TaskWindow("Downloading update...", updateDownloadTask, true); } diff --git a/src/lua/LegacyLuaAPI.cpp b/src/lua/LegacyLuaAPI.cpp index b72c5a6d5..e24e33dcd 100644 --- a/src/lua/LegacyLuaAPI.cpp +++ b/src/lua/LegacyLuaAPI.cpp @@ -1914,13 +1914,12 @@ int luatpt_getscript(lua_State* l) int runScript = luaL_optint(l, 3, 0); int confirmPrompt = luaL_optint(l, 4, 1); - ByteString::Stream url; - url << "http://starcatcher.us/scripts/main.lua?get=" << scriptID; - if (confirmPrompt && !ConfirmPrompt::Blocking("Do you want to install script?", ByteString(url.str()).FromUtf8(), "Install")) + ByteString url = ByteString::Build("http://starcatcher.us/scripts/main.lua?get=", scriptID); + if (confirmPrompt && !ConfirmPrompt::Blocking("Do you want to install script?", url.FromUtf8(), "Install")) return 0; int ret, len; - char *scriptData = http_simple_get(url.str().c_str(), &ret, &len); + char *scriptData = http_simple_get(url.c_str(), &ret, &len); if (len <= 0 || !filename) { free(scriptData); @@ -1968,9 +1967,7 @@ int luatpt_getscript(lua_State* l) outputfile = NULL; if (runScript) { - ByteString::Stream luaCommand; - luaCommand << "dofile('" << filename << "')"; - luaL_dostring(l, luaCommand.str().c_str()); + luaL_dostring(l, ByteString::Build("dofile('", filename, "')").c_str()); } return 0; @@ -2018,18 +2015,16 @@ int luatpt_screenshot(lua_State* l) data = format::VideoBufferToPNG(screenshot); } } - ByteString::Stream filename; - filename << "screenshot_"; - filename << std::setfill('0') << std::setw(6) << (screenshotIndex++); + ByteString filename = ByteString::Build("screenshot_", Format::Width(screenshotIndex++, 6)); if(fileType == 1) { - filename << ".bmp"; + filename += ".bmp"; } else if(fileType == 2) { - filename << ".ppm"; + filename += ".ppm"; } else { - filename << ".png"; + filename += ".png"; } - Client::Ref().WriteFile(data, filename.str()); - lua_pushstring(l, filename.str().c_str()); + Client::Ref().WriteFile(data, filename); + lua_pushstring(l, filename.c_str()); return 1; }