Remove ByteString::Stream

This commit is contained in:
mniip 2018-05-04 23:10:39 +03:00
parent e29d2c58c2
commit f8586ea3a2
26 changed files with 248 additions and 282 deletions

View File

@ -9,30 +9,6 @@ namespace format
{ {
const static char hex[] = "0123456789ABCDEF"; const static char hex[] = "0123456789ABCDEF";
template <typename T> ByteString NumberToByteString(T number)
{
ByteString::Stream ss;
ss << number;
return ss.str();
}
template <typename T> String NumberToString(T number)
{
return String::Build(number);
}
template <typename T> T ByteStringToNumber(const ByteString & text)
{
ByteString::Stream ss(text);
T number;
return (ss >> number)?number:0;
}
template <typename T> T StringToNumber(const String & text)
{
return text.ToNumber<T>(true);
}
ByteString URLEncode(ByteString value); ByteString URLEncode(ByteString value);
ByteString UnixtimeToDate(time_t unixtime, ByteString dateFomat = "%d %b %Y"); ByteString UnixtimeToDate(time_t unixtime, ByteString dateFomat = "%d %b %Y");
ByteString UnixtimeToDateMini(time_t unixtime); ByteString UnixtimeToDateMini(time_t unixtime);

View File

@ -1009,7 +1009,7 @@ int main(int argc, char * argv[])
if(arguments["scale"].length()) if(arguments["scale"].length())
{ {
tempScale = format::ByteStringToNumber<int>(arguments["scale"]); tempScale = arguments["scale"].ToNumber<int>();
Client::Ref().SetPref("Scale", tempScale); Client::Ref().SetPref("Scale", tempScale);
} }
@ -1181,9 +1181,7 @@ int main(int argc, char * argv[])
#ifdef DEBUG #ifdef DEBUG
std::cout << "Got Ptsave: id: " << saveIdPart << std::endl; std::cout << "Got Ptsave: id: " << saveIdPart << std::endl;
#endif #endif
int saveId = format::ByteStringToNumber<int>(saveIdPart); int saveId = saveIdPart.ToNumber<int>();
if (!saveId)
throw std::runtime_error("Invalid Save ID");
SaveInfo * newSave = Client::Ref().GetSave(saveId, 0); SaveInfo * newSave = Client::Ref().GetSave(saveId, 0);
if (!newSave) if (!newSave)

View File

@ -150,7 +150,7 @@ void Client::Initialise(ByteString proxyString)
if (authUser.UserID) if (authUser.UserID)
{ {
ByteString idTempString = format::NumberToByteString<int>(authUser.UserID); ByteString idTempString = ByteString::Build(authUser.UserID);
char *id = new char[idTempString.length() + 1]; char *id = new char[idTempString.length() + 1];
std::strcpy (id, idTempString.c_str()); std::strcpy (id, idTempString.c_str());
char *session = new char[authUser.SessionID.length() + 1]; char *session = new char[authUser.SessionID.length() + 1];
@ -378,12 +378,11 @@ bool Client::DoInstallation()
"NoDisplay=true\n" "NoDisplay=true\n"
"Categories=Game;Simulation\n" "Categories=Game;Simulation\n"
"Icon=powdertoy.png\n"; "Icon=powdertoy.png\n";
ByteString::Stream protocolfiledata; ByteString protocolfiledata = ByteString::Build(protocolfiledata_tmp, "Exec=", filename, " ptsave %u\nPath=", pathname, "\n");
protocolfiledata << protocolfiledata_tmp << "Exec=" << filename << " ptsave %u\nPath=" << pathname << "\n";
f = fopen("powdertoy-tpt-ptsave.desktop", "wb"); f = fopen("powdertoy-tpt-ptsave.desktop", "wb");
if (!f) if (!f)
return 0; return 0;
fwrite(protocolfiledata.str().c_str(), 1, strlen(protocolfiledata.str().c_str()), f); fwrite(protocolfiledata.c_str(), 1, protocolfiledata.size(), f);
fclose(f); fclose(f);
success = system("xdg-desktop-menu install powdertoy-tpt-ptsave.desktop"); success = system("xdg-desktop-menu install powdertoy-tpt-ptsave.desktop");
@ -396,12 +395,11 @@ bool Client::DoInstallation()
"NoDisplay=true\n" "NoDisplay=true\n"
"Categories=Game;Simulation\n" "Categories=Game;Simulation\n"
"Icon=powdertoy.png\n"; "Icon=powdertoy.png\n";
ByteString::Stream desktopopenfiledata; ByteString desktopopenfiledata = ByteString::Build(desktopopenfiledata_tmp, "Exec=", filename, " open %f\nPath=", pathname, "\n");
desktopopenfiledata << desktopopenfiledata_tmp << "Exec=" << filename << " open %f\nPath=" << pathname << "\n";
f = fopen("powdertoy-tpt-open.desktop", "wb"); f = fopen("powdertoy-tpt-open.desktop", "wb");
if (!f) if (!f)
return 0; return 0;
fwrite(desktopopenfiledata.str().c_str(), 1, strlen(desktopopenfiledata.str().c_str()), f); fwrite(desktopopenfiledata.c_str(), 1, desktopopenfiledata.size(), f);
fclose(f); fclose(f);
success = system("xdg-mime install powdertoy-save.xml") && success; success = system("xdg-mime install powdertoy-save.xml") && success;
success = system("xdg-desktop-menu install powdertoy-tpt-open.desktop") && success; success = system("xdg-desktop-menu install powdertoy-tpt-open.desktop") && success;
@ -415,12 +413,11 @@ bool Client::DoInstallation()
"Comment=Physics sandbox game\n" "Comment=Physics sandbox game\n"
"Categories=Game;Simulation\n" "Categories=Game;Simulation\n"
"Icon=powdertoy.png\n"; "Icon=powdertoy.png\n";
ByteString::Stream desktopfiledata; ByteString desktopfiledata = ByteString::Build(desktopfiledata_tmp, "Exec=", filename, "\nPath=", pathname, "\n");
desktopfiledata << desktopfiledata_tmp << "Exec=" << filename << "\nPath=" << pathname << "\n";
f = fopen("powdertoy-tpt.desktop", "wb"); f = fopen("powdertoy-tpt.desktop", "wb");
if (!f) if (!f)
return 0; return 0;
fwrite(desktopfiledata.str().c_str(), 1, strlen(desktopfiledata.str().c_str()), f); fwrite(desktopfiledata.c_str(), 1, desktopfiledata.size(), f);
fclose(f); fclose(f);
success = system("xdg-desktop-menu install powdertoy-tpt.desktop") && success; success = system("xdg-desktop-menu install powdertoy-tpt.desktop") && success;
@ -989,8 +986,7 @@ RequestStatus Client::UploadSave(SaveInfo & save)
int dataStatus; int dataStatus;
char * data; char * data;
int dataLength = 0; int dataLength = 0;
ByteString::Stream userIDStream; ByteString userID = ByteString::Build(authUser.UserID);
userIDStream << authUser.UserID;
if (authUser.UserID) if (authUser.UserID)
{ {
if (!save.GetGameSave()) if (!save.GetGameSave())
@ -1020,13 +1016,13 @@ RequestStatus Client::UploadSave(SaveInfo & save)
std::strcpy (saveName, save.GetName().ToUtf8().c_str()); std::strcpy (saveName, save.GetName().ToUtf8().c_str());
char *saveDescription = new char[save.GetDescription().length() + 1]; char *saveDescription = new char[save.GetDescription().length() + 1];
std::strcpy (saveDescription, save.GetDescription().ToUtf8().c_str()); std::strcpy (saveDescription, save.GetDescription().ToUtf8().c_str());
char *userid = new char[userIDStream.str().length() + 1]; char *userid = new char[userID.size() + 1];
std::strcpy (userid, userIDStream.str().c_str()); std::strcpy (userid, userID.c_str());
char *session = new char[authUser.SessionID.length() + 1]; char *session = new char[authUser.SessionID.length() + 1];
std::strcpy (session, authUser.SessionID.c_str()); std::strcpy (session, authUser.SessionID.c_str());
const char *const postNames[] = { "Name", "Description", "Data:save.bin", "Publish", NULL }; 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) }; 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); 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); RequestStatus ret = ParseServerReturn(data, dataStatus, false);
if (ret == RequestOkay) if (ret == RequestOkay)
{ {
int saveID = format::ByteStringToNumber<int>(data+3); int saveID = ByteString(data+3).ToNumber<int>();
if (!saveID) if (!saveID)
{ {
lastError = "Server did not return Save ID"; lastError = "Server did not return Save ID";
@ -1100,12 +1096,8 @@ void Client::DeleteStamp(ByteString stampID)
{ {
if((*iterator) == stampID) if((*iterator) == stampID)
{ {
ByteString::Stream stampFilename; ByteString stampFilename = ByteString::Build(STAMPS_DIR, PATH_SEP, stampID, ".stm");
stampFilename << STAMPS_DIR; remove(stampFilename.c_str());
stampFilename << PATH_SEP;
stampFilename << stampID;
stampFilename << ".stm";
remove(stampFilename.str().c_str());
stampIDs.erase(iterator); stampIDs.erase(iterator);
return; return;
} }
@ -1124,12 +1116,8 @@ ByteString Client::AddStamp(GameSave * saveData)
} }
else else
lastStampName++; lastStampName++;
ByteString::Stream saveID; ByteString saveID = ByteString::Build(Format::Hex(Format::Width(lastStampTime, 8)), Format::Hex(Format::Width(lastStampName, 2)));
//sprintf(saveID, "%08x%02x", lastStampTime, lastStampName); ByteString filename = STAMPS_DIR PATH_SEP + saveID + ".stm";
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";
MakeDirectory(STAMPS_DIR); MakeDirectory(STAMPS_DIR);
@ -1157,11 +1145,11 @@ ByteString Client::AddStamp(GameSave * saveData)
delete[] gameData; delete[] gameData;
stampIDs.push_front(saveID.str()); stampIDs.push_front(saveID);
updateStamps(); updateStamps();
return saveID.str(); return saveID;
} }
void Client::updateStamps() void Client::updateStamps()
@ -1233,8 +1221,8 @@ RequestStatus Client::ExecVote(int saveID, int direction)
if (authUser.UserID) if (authUser.UserID)
{ {
char * directionText = (char*)(direction==1?"Up":"Down"); char * directionText = (char*)(direction==1?"Up":"Down");
ByteString saveIDText = format::NumberToByteString<int>(saveID); ByteString saveIDText = ByteString::Build(saveID);
ByteString userIDText = format::NumberToByteString<int>(authUser.UserID); ByteString userIDText = ByteString::Build(authUser.UserID);
char *id = new char[saveIDText.length() + 1]; char *id = new char[saveIDText.length() + 1];
std::strcpy(id, saveIDText.c_str()); std::strcpy(id, saveIDText.c_str());
@ -1267,14 +1255,14 @@ unsigned char * Client::GetSaveData(int saveID, int saveDate, int & dataLength)
int dataStatus; int dataStatus;
char *data; char *data;
dataLength = 0; dataLength = 0;
ByteString::Stream urlStream; ByteString urlStr;
if (saveDate) if (saveDate)
urlStream << "http://" << STATICSERVER << "/" << saveID << "_" << saveDate << ".cps"; urlStr = ByteString::Build("http://", STATICSERVER, "/", saveID, "_", saveDate, ".cps");
else else
urlStream << "http://" << STATICSERVER << "/" << saveID << ".cps"; urlStr = ByteString::Build("http://", STATICSERVER, "/", saveID, ".cps");
char *url = new char[urlStream.str().length() + 1]; char *url = new char[urlStr.size() + 1];
std::strcpy(url, urlStream.str().c_str()); std::strcpy(url, urlStr.c_str());
data = http_simple_get(url, &dataStatus, &dataLength); data = http_simple_get(url, &dataStatus, &dataLength);
delete[] url; delete[] url;
@ -1300,13 +1288,13 @@ std::vector<unsigned char> Client::GetSaveData(int saveID, int saveDate)
RequestBroker::Request * Client::GetSaveDataAsync(int saveID, int saveDate) RequestBroker::Request * Client::GetSaveDataAsync(int saveID, int saveDate)
{ {
ByteString::Stream urlStream; ByteString url;
if(saveDate){ if(saveDate){
urlStream << "http://" << STATICSERVER << "/" << saveID << "_" << saveDate << ".cps"; url = ByteString::Build("http://", STATICSERVER, "/", saveID, "_", saveDate, ".cps");
} else { } 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) 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) LoginStatus Client::Login(ByteString username, ByteString password, User & user)
{ {
lastError = ""; lastError = "";
ByteString::Stream hashStream;
char passwordHash[33]; char passwordHash[33];
char totalHash[33]; char totalHash[33];
@ -1393,14 +1380,14 @@ LoginStatus Client::Login(ByteString username, ByteString password, User & user)
//Doop //Doop
md5_ascii(passwordHash, (const unsigned char *)password.c_str(), password.length()); md5_ascii(passwordHash, (const unsigned char *)password.c_str(), password.length());
passwordHash[32] = 0; passwordHash[32] = 0;
hashStream << username << "-" << passwordHash; ByteString total = ByteString::Build(username, "-", passwordHash);
md5_ascii(totalHash, (const unsigned char *)(hashStream.str().c_str()), hashStream.str().length()); md5_ascii(totalHash, (const unsigned char *)(total.c_str()), total.size());
totalHash[32] = 0; totalHash[32] = 0;
char * data; char * data;
int dataStatus, dataLength; int dataStatus, dataLength;
const char *const postNames[] = { "Username", "Hash", NULL }; 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 }; size_t postLengths[] = { username.length(), 32 };
data = http_multipart_post("http://" SERVER "/Login.json", postNames, postDatas, postLengths, NULL, NULL, NULL, &dataStatus, &dataLength); data = http_multipart_post("http://" SERVER "/Login.json", postNames, postDatas, postLengths, NULL, NULL, NULL, &dataStatus, &dataLength);
RequestStatus ret = ParseServerReturn(data, dataStatus, true); RequestStatus ret = ParseServerReturn(data, dataStatus, true);
@ -1454,15 +1441,13 @@ LoginStatus Client::Login(ByteString username, ByteString password, User & user)
RequestStatus Client::DeleteSave(int saveID) RequestStatus Client::DeleteSave(int saveID)
{ {
lastError = ""; lastError = "";
ByteString::Stream urlStream;
char * data = NULL; char * data = NULL;
int dataStatus, dataLength; 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) if(authUser.UserID)
{ {
ByteString::Stream userIDStream; ByteString userID = ByteString::Build(authUser.UserID);
userIDStream << authUser.UserID; data = http_auth_get(url.c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength);
data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength);
} }
else else
{ {
@ -1477,19 +1462,18 @@ RequestStatus Client::DeleteSave(int saveID)
RequestStatus Client::AddComment(int saveID, String comment) RequestStatus Client::AddComment(int saveID, String comment)
{ {
lastError = ""; lastError = "";
ByteString::Stream urlStream;
char * data = NULL; char * data = NULL;
int dataStatus, dataLength; 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) if(authUser.UserID)
{ {
ByteString::Stream userIDStream; ByteString userID = ByteString::Build(authUser.UserID);
userIDStream << authUser.UserID;
const char *const postNames[] = { "Comment", NULL }; const char *const postNames[] = { "Comment", NULL };
const char *const postDatas[] = { (char*)(comment.c_str()) }; ByteString commentBytes = comment.ToUtf8();
size_t postLengths[] = { comment.length() }; const char *const postDatas[] = { commentBytes.c_str() };
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); 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 else
{ {
@ -1504,7 +1488,7 @@ RequestStatus Client::AddComment(int saveID, String comment)
RequestStatus Client::FavouriteSave(int saveID, bool favourite) RequestStatus Client::FavouriteSave(int saveID, bool favourite)
{ {
lastError = ""; lastError = "";
ByteString::Stream urlStream; ByteStringBuilder urlStream;
char * data = NULL; char * data = NULL;
int dataStatus, dataLength; int dataStatus, dataLength;
urlStream << "http://" << SERVER << "/Browse/Favourite.json?ID=" << saveID << "&Key=" << authUser.SessionKey; 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"; urlStream << "&Mode=Remove";
if(authUser.UserID) if(authUser.UserID)
{ {
ByteString::Stream userIDStream; ByteString userID = ByteString::Build(authUser.UserID);
userIDStream << authUser.UserID; data = http_auth_get(urlStream.Build().c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength);
data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength);
} }
else else
{ {
@ -1529,19 +1512,18 @@ RequestStatus Client::FavouriteSave(int saveID, bool favourite)
RequestStatus Client::ReportSave(int saveID, String message) RequestStatus Client::ReportSave(int saveID, String message)
{ {
lastError = ""; lastError = "";
ByteString::Stream urlStream;
char * data = NULL; char * data = NULL;
int dataStatus, dataLength; 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) if(authUser.UserID)
{ {
ByteString::Stream userIDStream; ByteString userID = ByteString::Build(authUser.UserID);
userIDStream << authUser.UserID;
const char *const postNames[] = { "Reason", NULL }; const char *const postNames[] = { "Reason", NULL };
const char *const postDatas[] = { (char*)(message.c_str()) }; ByteString messageBytes = message.ToUtf8();
size_t postLengths[] = { message.length() }; const char *const postDatas[] = { messageBytes.c_str() };
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); 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 else
{ {
@ -1556,15 +1538,14 @@ RequestStatus Client::ReportSave(int saveID, String message)
RequestStatus Client::UnpublishSave(int saveID) RequestStatus Client::UnpublishSave(int saveID)
{ {
lastError = ""; lastError = "";
ByteString::Stream urlStream;
char * data = NULL; char * data = NULL;
int dataStatus, dataLength; 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) if(authUser.UserID)
{ {
ByteString::Stream userIDStream; ByteString userID = ByteString::Build(authUser.UserID);
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); data = http_auth_get(url.c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength);
} }
else else
{ {
@ -1579,18 +1560,17 @@ RequestStatus Client::UnpublishSave(int saveID)
RequestStatus Client::PublishSave(int saveID) RequestStatus Client::PublishSave(int saveID)
{ {
lastError = ""; lastError = "";
ByteString::Stream urlStream;
char *data; char *data;
int dataStatus; 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) if (authUser.UserID)
{ {
ByteString::Stream userIDStream; ByteString userID = ByteString::Build(authUser.UserID);
userIDStream << authUser.UserID;
const char *const postNames[] = { "ActionPublish", NULL }; const char *const postNames[] = { "ActionPublish", NULL };
const char *const postDatas[] = { "" }; const char *const postDatas[] = { "" };
size_t postLengths[] = { 1 }; size_t postLengths[] = { 0 };
data = http_multipart_post(urlStream.str().c_str(), postNames, postDatas, postLengths, userIDStream.str().c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, NULL); } data = http_multipart_post(url.c_str(), postNames, postDatas, postLengths, userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, NULL); }
else else
{ {
lastError = "Not authenticated"; lastError = "Not authenticated";
@ -1604,7 +1584,7 @@ RequestStatus Client::PublishSave(int saveID)
SaveInfo * Client::GetSave(int saveID, int saveDate) SaveInfo * Client::GetSave(int saveID, int saveDate)
{ {
lastError = ""; lastError = "";
ByteString::Stream urlStream; ByteStringBuilder urlStream;
urlStream << "http://" << SERVER << "/Browse/View.json?ID=" << saveID; urlStream << "http://" << SERVER << "/Browse/View.json?ID=" << saveID;
if(saveDate) if(saveDate)
{ {
@ -1614,13 +1594,13 @@ SaveInfo * Client::GetSave(int saveID, int saveDate)
int dataStatus, dataLength; int dataStatus, dataLength;
if(authUser.UserID) if(authUser.UserID)
{ {
ByteString::Stream userIDStream; ByteString userID = ByteString::Build(authUser.UserID);
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); data = http_auth_get(urlStream.Build().c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength);
} }
else 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) if(dataStatus == 200 && data)
{ {
@ -1677,7 +1657,7 @@ SaveInfo * Client::GetSave(int saveID, int saveDate)
RequestBroker::Request * Client::GetSaveAsync(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; urlStream << "http://" << SERVER << "/Browse/View.json?ID=" << saveID;
if(saveDate) if(saveDate)
{ {
@ -1734,7 +1714,7 @@ RequestBroker::Request * Client::GetSaveAsync(int saveID, int saveDate)
} }
virtual ~SaveInfoParser() { } 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) 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++) for (Json::UInt j = 0; j < commentsArray.size(); j++)
{ {
int userID = format::ByteStringToNumber<int>(commentsArray[j]["UserID"].asString()); int userID = ByteString(commentsArray[j]["UserID"].asString()).ToNumber<int>();
ByteString username = commentsArray[j]["Username"].asString(); ByteString username = commentsArray[j]["Username"].asString();
ByteString formattedUsername = commentsArray[j]["FormattedUsername"].asString(); ByteString formattedUsername = commentsArray[j]["FormattedUsername"].asString();
if (formattedUsername == "jacobot") if (formattedUsername == "jacobot")
@ -1775,9 +1755,8 @@ RequestBroker::Request * Client::GetCommentsAsync(int saveID, int start, int cou
virtual ~CommentsParser() { } virtual ~CommentsParser() { }
}; };
ByteString::Stream urlStream; ByteString url = ByteString::Build("http://", SERVER, "/Browse/Comments.json?ID=", saveID, "&Start=", start, "&Count=", count);
urlStream << "http://" << SERVER << "/Browse/Comments.json?ID=" << saveID << "&Start=" << start << "&Count=" << count; return new APIRequest(url, new CommentsParser());
return new APIRequest(urlStream.str(), new CommentsParser());
} }
std::vector<std::pair<ByteString, int> > * Client::GetTags(int start, int count, String query, int & resultCount) std::vector<std::pair<ByteString, int> > * Client::GetTags(int start, int count, String query, int & resultCount)
@ -1785,7 +1764,7 @@ std::vector<std::pair<ByteString, int> > * Client::GetTags(int start, int count,
lastError = ""; lastError = "";
resultCount = 0; resultCount = 0;
std::vector<std::pair<ByteString, int> > * tagArray = new std::vector<std::pair<ByteString, int> >(); std::vector<std::pair<ByteString, int> > * tagArray = new std::vector<std::pair<ByteString, int> >();
ByteString::Stream urlStream; ByteStringBuilder urlStream;
char * data; char * data;
int dataStatus, dataLength; int dataStatus, dataLength;
urlStream << "http://" << SERVER << "/Browse/Tags.json?Start=" << start << "&Count=" << count; urlStream << "http://" << SERVER << "/Browse/Tags.json?Start=" << start << "&Count=" << count;
@ -1796,7 +1775,7 @@ std::vector<std::pair<ByteString, int> > * Client::GetTags(int start, int count,
urlStream << format::URLEncode(query.ToUtf8()); 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) if(dataStatus == 200 && data)
{ {
try try
@ -1832,7 +1811,7 @@ std::vector<SaveInfo*> * Client::SearchSaves(int start, int count, String query,
lastError = ""; lastError = "";
resultCount = 0; resultCount = 0;
std::vector<SaveInfo*> * saveArray = new std::vector<SaveInfo*>(); std::vector<SaveInfo*> * saveArray = new std::vector<SaveInfo*>();
ByteString::Stream urlStream; ByteStringBuilder urlStream;
char * data; char * data;
int dataStatus, dataLength; int dataStatus, dataLength;
urlStream << "http://" << SERVER << "/Browse.json?Start=" << start << "&Count=" << count; urlStream << "http://" << SERVER << "/Browse.json?Start=" << start << "&Count=" << count;
@ -1854,13 +1833,12 @@ std::vector<SaveInfo*> * Client::SearchSaves(int start, int count, String query,
} }
if(authUser.UserID) if(authUser.UserID)
{ {
ByteString::Stream userIDStream; ByteString userID = ByteString::Build(authUser.UserID);
userIDStream << authUser.UserID; data = http_auth_get(urlStream.Build().c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength);
data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength);
} }
else 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); ParseServerReturn(data, dataStatus, true);
if (dataStatus == 200 && data) if (dataStatus == 200 && data)
@ -1917,15 +1895,13 @@ std::list<ByteString> * Client::RemoveTag(int saveID, ByteString tag)
{ {
lastError = ""; lastError = "";
std::list<ByteString> * tags = NULL; std::list<ByteString> * tags = NULL;
ByteString::Stream urlStream;
char * data = NULL; char * data = NULL;
int dataStatus, dataLength; 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) if(authUser.UserID)
{ {
ByteString::Stream userIDStream; ByteString userID = ByteString::Build(authUser.UserID);
userIDStream << authUser.UserID; data = http_auth_get(url.c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength);
data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength);
} }
else else
{ {
@ -1959,15 +1935,13 @@ std::list<ByteString> * Client::AddTag(int saveID, ByteString tag)
{ {
lastError = ""; lastError = "";
std::list<ByteString> * tags = NULL; std::list<ByteString> * tags = NULL;
ByteString::Stream urlStream;
char * data = NULL; char * data = NULL;
int dataStatus, dataLength; 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) if(authUser.UserID)
{ {
ByteString::Stream userIDStream; ByteString userID = ByteString::Build(authUser.UserID);
userIDStream << authUser.UserID; data = http_auth_get(url.c_str(), userID.c_str(), NULL, authUser.SessionID.c_str(), &dataStatus, &dataLength);
data = http_auth_get((char *)urlStream.str().c_str(), (char *)(userIDStream.str().c_str()), NULL, (char *)(authUser.SessionID.c_str()), &dataStatus, &dataLength);
} }
else else
{ {

View File

@ -629,7 +629,7 @@ void GameSave::readOPS(char * data, int dataLength)
int bz2ret; int bz2ret;
if ((bz2ret = BZ2_bzBuffToBuffDecompress((char*)bsonData, &bsonDataLen, (char*)(inputData+12), inputDataLen-12, 0, 0)) != BZ_OK) 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<int>(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()); }); 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; int bzStatus = 0;
if ((bzStatus = BZ2_bzBuffToBuffDecompress((char *)data, (unsigned *)&size, (char *)(saveData+12), dataLength-12, 0, 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; dataLength = size;
#ifdef DEBUG #ifdef DEBUG
@ -2510,7 +2510,7 @@ char * GameSave::serialiseOPS(unsigned int & dataLength)
unsigned int finalDataLen = bson_size(&b); unsigned int finalDataLen = bson_size(&b);
auto outputData = std::unique_ptr<unsigned char[]>(new unsigned char[finalDataLen*2+12]); auto outputData = std::unique_ptr<unsigned char[]>(new unsigned char[finalDataLen*2+12]);
if (!outputData) if (!outputData)
throw BuildException("Save error, out of memory (finalData): " + format::NumberToString<unsigned int>(finalDataLen*2+12)); throw BuildException(String::Build("Save error, out of memory (finalData): ", finalDataLen*2+12));
outputData[0] = 'O'; outputData[0] = 'O';
outputData[1] = 'P'; outputData[1] = 'P';
@ -2528,7 +2528,7 @@ char * GameSave::serialiseOPS(unsigned int & dataLength)
unsigned int compressedSize = finalDataLen*2, bz2ret; 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) 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<int>(bz2ret) + ")"); throw BuildException(String::Build("Save error, could not compress (ret ", bz2ret, ")"));
} }
#ifdef DEBUG #ifdef DEBUG

View File

@ -192,11 +192,7 @@ void http_init(char *proxy)
free(host); free(host);
free(port); free(port);
} }
ByteString::Stream userAgentBuilder; 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);
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();
userAgent = new char[newUserAgent.length()+1]; userAgent = new char[newUserAgent.length()+1];
std::copy(newUserAgent.begin(), newUserAgent.end(), userAgent); std::copy(newUserAgent.begin(), newUserAgent.end(), userAgent);
userAgent[newUserAgent.length()] = 0; userAgent[newUserAgent.length()] = 0;
@ -987,7 +983,7 @@ ByteString FindBoundary(std::map<ByteString, ByteString> parts, ByteString bound
// this function used in Download class, and eventually all http requests // this function used in Download class, and eventually all http requests
ByteString GetMultipartMessage(std::map<ByteString, ByteString> parts, ByteString boundary) ByteString GetMultipartMessage(std::map<ByteString, ByteString> parts, ByteString boundary)
{ {
ByteString::Stream data; ByteStringBuilder data;
// loop through each part, adding it // loop through each part, adding it
for (std::map<ByteString, ByteString>::iterator iter = parts.begin(); iter != parts.end(); iter++) for (std::map<ByteString, ByteString>::iterator iter = parts.begin(); iter != parts.end(); iter++)
@ -1014,7 +1010,7 @@ ByteString GetMultipartMessage(std::map<ByteString, ByteString> parts, ByteStrin
data << "\r\n"; data << "\r\n";
} }
data << "--" << boundary << "--\r\n"; data << "--" << boundary << "--\r\n";
return data.str(); return data.Build();
} }
// add the header needed to make POSTS work // add the header needed to make POSTS work

View File

@ -103,7 +103,7 @@ RequestBroker::ProcessResponse APIRequest::Process(RequestBroker & rb)
User user = Client::Ref().GetAuthUser(); User user = Client::Ref().GetAuthUser();
char userName[12]; char userName[12];
char *userSession = new char[user.SessionID.length() + 1]; char *userSession = new char[user.SessionID.length() + 1];
std::strcpy(userName, format::NumberToByteString<int>(user.UserID).c_str()); std::strcpy(userName, ByteString::Build(user.UserID).c_str());
std::strcpy(userSession, user.SessionID.c_str()); std::strcpy(userSession, user.SessionID.c_str());
HTTPContext = http_multipart_post_async((char*)URL.c_str(), postNames, postData, postLength, userName, NULL, userSession); HTTPContext = http_multipart_post_async((char*)URL.c_str(), postNames, postData, postLength, userName, NULL, userSession);
delete[] userSession; delete[] userSession;
@ -122,7 +122,7 @@ RequestBroker::ProcessResponse APIRequest::Process(RequestBroker & rb)
User user = Client::Ref().GetAuthUser(); User user = Client::Ref().GetAuthUser();
char userName[12]; char userName[12];
char *userSession = new char[user.SessionID.length() + 1]; char *userSession = new char[user.SessionID.length() + 1];
std::strcpy(userName, format::NumberToByteString<int>(user.UserID).c_str()); std::strcpy(userName, ByteString::Build(user.UserID).c_str());
std::strcpy(userSession, user.SessionID.c_str()); std::strcpy(userSession, user.SessionID.c_str());
http_auth_headers(HTTPContext, userName, NULL, userSession); http_auth_headers(HTTPContext, userName, NULL, userSession);
delete[] userSession; delete[] userSession;

View File

@ -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) void RequestBroker::RetrieveThumbnail(int saveID, int saveDate, int width, int height, RequestListener * tListener)
{ {
ByteString::Stream urlStream; ByteStringBuilder url;
urlStream << "http://" << STATICSERVER << "/" << saveID; url << "http://" << STATICSERVER << "/" << saveID;
if(saveDate) 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) void RequestBroker::RetrieveAvatar(ByteString username, int width, int height, RequestListener * tListener)
{ {
ByteString::Stream urlStream; ByteString url = ByteString::Build("http://", STATICSERVER, "/avatars/", username, ".pti");
urlStream << "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) void RequestBroker::Start(Request * request, RequestListener * tListener, int identifier)

View File

@ -106,7 +106,7 @@ RequestBroker::ProcessResponse WebRequest::Process(RequestBroker & rb)
User user = Client::Ref().GetAuthUser(); User user = Client::Ref().GetAuthUser();
char userName[12]; char userName[12];
char *userSession = new char[user.SessionID.length() + 1]; char *userSession = new char[user.SessionID.length() + 1];
std::strcpy(userName, format::NumberToByteString<int>(user.UserID).c_str()); std::strcpy(userName, ByteString::Build(user.UserID).c_str());
std::strcpy(userSession, user.SessionID.c_str()); std::strcpy(userSession, user.SessionID.c_str());
HTTPContext = http_multipart_post_async((char*)URL.c_str(), postNames, postData, postLength, userName, NULL, userSession); HTTPContext = http_multipart_post_async((char*)URL.c_str(), postNames, postData, postLength, userName, NULL, userSession);
delete[] userSession; delete[] userSession;
@ -125,7 +125,7 @@ RequestBroker::ProcessResponse WebRequest::Process(RequestBroker & rb)
User user = Client::Ref().GetAuthUser(); User user = Client::Ref().GetAuthUser();
char userName[12]; char userName[12];
char *userSession = new char[user.SessionID.length() + 1]; char *userSession = new char[user.SessionID.length() + 1];
std::strcpy(userName, format::NumberToByteString<int>(user.UserID).c_str()); std::strcpy(userName, ByteString::Build(user.UserID).c_str());
std::strcpy(userSession, user.SessionID.c_str()); std::strcpy(userSession, user.SessionID.c_str());
http_auth_headers(HTTPContext, userName, NULL, userSession); http_auth_headers(HTTPContext, userName, NULL, userSession);
delete[] userSession; delete[] userSession;

View File

@ -25,6 +25,18 @@ namespace Format
inline FlagsOverride() {} inline FlagsOverride() {}
}; };
template<typename T> struct FillOverride
{
T value;
size_t fill;
inline FillOverride(T _value, size_t _fill): value(_value), fill(_fill) {}
};
template<> struct FillOverride<void>
{
String::value_type fill;
inline FillOverride(size_t _fill): fill(_fill) {}
};
template<typename T> struct WidthOverride template<typename T> struct WidthOverride
{ {
T value; T value;
@ -74,8 +86,10 @@ namespace Format
inline FlagsOverride<void, std::ios_base::scientific, std::ios_base::floatfield> Scientific() { return FlagsOverride<void, std::ios_base::scientific, std::ios_base::floatfield>(); } inline FlagsOverride<void, std::ios_base::scientific, std::ios_base::floatfield> Scientific() { return FlagsOverride<void, std::ios_base::scientific, std::ios_base::floatfield>(); }
inline FlagsOverride<void, std::ios_base::fmtflags{}, std::ios_base::floatfield> FloatDefault() { return FlagsOverride<void, std::ios_base::fmtflags{}, std::ios_base::floatfield>(); } inline FlagsOverride<void, std::ios_base::fmtflags{}, std::ios_base::floatfield> FloatDefault() { return FlagsOverride<void, std::ios_base::fmtflags{}, std::ios_base::floatfield>(); }
template<typename T> inline FillOverride<T> Fill(T value, String::value_type fill) { return FillOverride<T>(value, fill); }
template<typename T> inline WidthOverride<T> Width(T value, size_t width) { return WidthOverride<T>(value, width); } template<typename T> inline WidthOverride<T> Width(T value, size_t width) { return WidthOverride<T>(value, width); }
template<typename T> inline PrecisionOverride<T> Precision(T value, size_t precision) { return PrecisionOverride<T>(value, precision); } template<typename T> inline PrecisionOverride<T> Precision(T value, size_t precision) { return PrecisionOverride<T>(value, precision); }
inline FillOverride<void> Fill(String::value_type fill) { return FillOverride<void>(fill); }
inline WidthOverride<void> Width(size_t width) { return WidthOverride<void>(width); } inline WidthOverride<void> Width(size_t width) { return WidthOverride<void>(width); }
inline PrecisionOverride<void> Precision(size_t precision) { return PrecisionOverride<void>(precision); } inline PrecisionOverride<void> Precision(size_t precision) { return PrecisionOverride<void>(precision); }
}; };
@ -94,16 +108,36 @@ template<std::ios_base::fmtflags set, std::ios_base::fmtflags reset> inline Byte
return b; return b;
} }
template<typename T> inline ByteStringBuilder &operator<<(ByteStringBuilder &b, Format::FillOverride<T> 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<void> data)
{
b.fill = data.fill;
return b;
}
template<typename T> inline ByteStringBuilder &operator<<(ByteStringBuilder &b, Format::WidthOverride<T> data) template<typename T> inline ByteStringBuilder &operator<<(ByteStringBuilder &b, Format::WidthOverride<T> data)
{ {
String::value_type oldfill = b.fill;
if(oldfill == ' ')
b.fill = '0';
size_t oldwidth = b.width; size_t oldwidth = b.width;
b.width = data.width; b.width = data.width;
b << data.value; b << data.value;
b.width = oldwidth; b.width = oldwidth;
b.fill = oldfill;
return b; return b;
} }
inline ByteStringBuilder &operator<<(ByteStringBuilder &b, Format::WidthOverride<void> data) inline ByteStringBuilder &operator<<(ByteStringBuilder &b, Format::WidthOverride<void> data)
{ {
if(b.fill == ' ')
b.fill = '0';
b.width = data.width; b.width = data.width;
return b; return b;
} }
@ -142,16 +176,36 @@ template<std::ios_base::fmtflags set, std::ios_base::fmtflags reset> inline Stri
return b; return b;
} }
template<typename T> inline StringBuilder &operator<<(StringBuilder &b, Format::FillOverride<T> 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<void> data)
{
b.fill = data.fill;
return b;
}
template<typename T> inline StringBuilder &operator<<(StringBuilder &b, Format::WidthOverride<T> data) template<typename T> inline StringBuilder &operator<<(StringBuilder &b, Format::WidthOverride<T> data)
{ {
String::value_type oldfill = b.fill;
if(oldfill == ' ')
b.fill = '0';
size_t oldwidth = b.width; size_t oldwidth = b.width;
b.width = data.width; b.width = data.width;
b << data.value; b << data.value;
b.width = oldwidth; b.width = oldwidth;
b.fill = oldfill;
return b; return b;
} }
inline StringBuilder &operator<<(StringBuilder &b, Format::WidthOverride<void> data) inline StringBuilder &operator<<(StringBuilder &b, Format::WidthOverride<void> data)
{ {
if(b.fill == ' ')
b.fill = '0';
b.width = data.width; b.width = data.width;
return b; return b;
} }

View File

@ -168,8 +168,6 @@ public:
String FromUtf8(bool ignoreError = true) const; String FromUtf8(bool ignoreError = true) const;
inline String FromAscii() const; inline String FromAscii() const;
template<typename... Ts> static ByteString Build(Ts&&... args); template<typename... Ts> static ByteString Build(Ts&&... args);
using Stream = std::basic_stringstream<value_type>;
}; };
inline ByteString operator+(ByteString const &lhs, ByteString const &rhs) { return static_cast<std::basic_string<char> const &>(lhs) + static_cast<std::basic_string<char> const &>(rhs); } inline ByteString operator+(ByteString const &lhs, ByteString const &rhs) { return static_cast<std::basic_string<char> const &>(lhs) + static_cast<std::basic_string<char> const &>(rhs); }
@ -405,7 +403,7 @@ public:
size_t Size() const { return buffer.size(); } size_t Size() const { return buffer.size(); }
ByteString Build() const; ByteString Build() const;
template<typename T> ByteStringBuilder &operator<<(T) = delete; template<typename T> ByteStringBuilder &operator<<(T) &&= delete;
template<typename T, typename... Ts> ByteStringBuilder &Add(T &&arg, Ts&&... args) template<typename T, typename... Ts> ByteStringBuilder &Add(T &&arg, Ts&&... args)
{ {

View File

@ -37,8 +37,8 @@ void ElementPopulationDebug::Draw()
maxAverage = (maxAverage*(1.0f-0.015f)) + (0.015f*maxVal); maxAverage = (maxAverage*(1.0f-0.015f)) + (0.015f*maxVal);
scale = 255.0f/maxAverage; scale = 255.0f/maxAverage;
maxValString = format::NumberToString<int>(maxAverage); maxValString = String::Build(maxAverage);
halfValString = format::NumberToString<int>(maxAverage/2); halfValString = String::Build(maxAverage/2);
g->fillrect(xStart-5, yBottom - 263, bars+10+Graphics::textwidth(maxValString)+10, 255 + 13, 0, 0, 0, 180); g->fillrect(xStart-5, yBottom - 263, bars+10+Graphics::textwidth(maxValString)+10, 255 + 13, 0, 0, 0, 180);

View File

@ -28,10 +28,10 @@ ColourPickerActivity::ColourPickerActivity(ui::Colour initialColour, ColourPicke
void TextChangedCallback(ui::Textbox * sender) void TextChangedCallback(ui::Textbox * sender)
{ {
int r, g, b, alpha; int r, g, b, alpha;
r = format::StringToNumber<int>(a->rValue->GetText()); r = a->rValue->GetText().ToNumber<int>(true);
g = format::StringToNumber<int>(a->gValue->GetText()); g = a->gValue->GetText().ToNumber<int>(true);
b = format::StringToNumber<int>(a->bValue->GetText()); b = a->bValue->GetText().ToNumber<int>(true);
alpha = format::StringToNumber<int>(a->aValue->GetText()); alpha = a->aValue->GetText().ToNumber<int>(true);
if (r > 255) if (r > 255)
r = 255; r = 255;
if (g > 255) if (g > 255)
@ -82,9 +82,9 @@ ColourPickerActivity::ColourPickerActivity(ui::Colour initialColour, ColourPicke
void ActionCallback(ui::Button * sender) void ActionCallback(ui::Button * sender)
{ {
int Red, Green, Blue; int Red, Green, Blue;
Red = format::StringToNumber<int>(a->rValue->GetText()); Red = a->rValue->GetText().ToNumber<int>(true);
Green = format::StringToNumber<int>(a->gValue->GetText()); Green = a->gValue->GetText().ToNumber<int>(true);
Blue = format::StringToNumber<int>(a->bValue->GetText()); Blue = a->bValue->GetText().ToNumber<int>(true);
ui::Colour col(Red, Green, Blue, a->currentAlpha); ui::Colour col(Red, Green, Blue, a->currentAlpha);
if(a->callback) if(a->callback)
a->callback->ColourPicked(col); 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) void ColourPickerActivity::UpdateTextboxes(int r, int g, int b, int a)
{ {
rValue->SetText(format::NumberToString<int>(r)); rValue->SetText(String::Build(r));
gValue->SetText(format::NumberToString<int>(g)); gValue->SetText(String::Build(g));
bValue->SetText(format::NumberToString<int>(b)); bValue->SetText(String::Build(b));
aValue->SetText(format::NumberToString<int>(a)); aValue->SetText(String::Build(a));
hexValue->SetText(String::Build(Format::Hex(), Format::Uppercase(), Format::Width(2), a, r, g, b)); hexValue->SetText(String::Build(Format::Hex(), Format::Uppercase(), Format::Width(2), a, r, g, b));
} }
void ColourPickerActivity::OnTryExit(ExitMethod method) void ColourPickerActivity::OnTryExit(ExitMethod method)

View File

@ -28,8 +28,8 @@ SaveIDMessage::SaveIDMessage(int id):
copyTextLabel->Appearance.HorizontalAlign = ui::Appearance::AlignCentre; copyTextLabel->Appearance.HorizontalAlign = ui::Appearance::AlignCentre;
AddComponent(copyTextLabel); AddComponent(copyTextLabel);
textWidth = Graphics::textwidth(format::NumberToString<int>(id).c_str()); 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), format::NumberToString<int>(id), copyTextLabel); 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); AddComponent(copyTextButton);
class DismissAction: public ui::ButtonAction class DismissAction: public ui::ButtonAction

View File

@ -293,9 +293,7 @@ FontEditor::FontEditor(ByteString _header):
CharNumberAction(FontEditor *_v): v(_v) {} CharNumberAction(FontEditor *_v): v(_v) {}
void TextChangedCallback(ui::Textbox *) void TextChangedCallback(ui::Textbox *)
{ {
unsigned int number; unsigned int number = v->currentCharTextbox->GetText().ToNumber<unsigned int>(true);
ByteString::Stream ss(v->currentCharTextbox->GetText().ToUtf8());
ss >> std::hex >> number;
if(number <= 0x10FFFF) if(number <= 0x10FFFF)
v->currentChar = number; v->currentChar = number;
} }
@ -426,14 +424,13 @@ FontEditor::FontEditor(ByteString _header):
ColorComponentAction(int &_color): color(_color) {} ColorComponentAction(int &_color): color(_color) {}
void TextChangedCallback(ui::Textbox *box) void TextChangedCallback(ui::Textbox *box)
{ {
ByteString::Stream ss(box->GetText().ToUtf8()); color = box->GetText().ToNumber<int>(true);
ss >> color;
} }
}; };
int *refs[6] = {&fgR, &fgG, &fgB, &bgR, &bgG, &bgB}; int *refs[6] = {&fgR, &fgG, &fgB, &bgR, &bgG, &bgB};
for(int i = 0; i < 6; i++) 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; currentX += 28;
colorComponent->SetActionCallback(new ColorComponentAction(*refs[i])); colorComponent->SetActionCallback(new ColorComponentAction(*refs[i]));
AddComponent(colorComponent); AddComponent(colorComponent);
@ -489,28 +486,26 @@ FontEditor::FontEditor(ByteString _header):
PreviewAction(FontEditor *_v): v(_v) {} PreviewAction(FontEditor *_v): v(_v) {}
void TextChangedCallback(ui::Textbox *box) void TextChangedCallback(ui::Textbox *box)
{ {
ByteString::Stream ss(box->GetText().ToUtf8()); // ByteString::Stream for now String str = box->GetText();
String text; size_t at = 0;
while(!ss.eof()) StringBuilder text;
while(at < str.size())
{ {
if(ss.peek() == '\n')
{
text.push_back('\n');
ss.get();
}
unsigned int ch; unsigned int ch;
ss >> std::hex >> ch; if(str[at] != ' ')
if(ss.fail()) if(String::Split split = str.SplitNumber(ch, Format::Hex(), at))
{ {
ss.clear(); text << String::value_type(ch);
String::value_type ch = ss.get(); at = split.PositionAfter();
if(!ss.eof()) }
text.push_back(ch); else
continue; {
} text << str[at++];
text.push_back(ch); }
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)); 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() void FontEditor::UpdateCharNumber()
{ {
ByteString::Stream ss; currentCharTextbox->SetText(String::Build(Format::Hex((unsigned int)currentChar)));
ss << std::hex << currentChar;
currentCharTextbox->SetText(ByteString(ss.str()).FromUtf8());
} }
void FontEditor::PrevChar() void FontEditor::PrevChar()

View File

@ -679,7 +679,7 @@ bool GameController::MouseUp(int x, int y, unsigned button, char type)
{ {
case 'c': case 'c':
{ {
int saveID = format::StringToNumber<int>(link); int saveID = link.ToNumber<int>(true);
if (saveID) if (saveID)
OpenSavePreview(saveID, 0, false); OpenSavePreview(saveID, 0, false);
break; break;
@ -687,9 +687,7 @@ bool GameController::MouseUp(int x, int y, unsigned button, char type)
case 't': case 't':
{ {
// buff is already confirmed to be a number by sign::splitsign // buff is already confirmed to be a number by sign::splitsign
ByteString::Stream uri; Platform::OpenURI(ByteString::Build("http://powdertoy.co.uk/Discussions/Thread/View.html?Thread=", link.ToUtf8()));
uri << "http://powdertoy.co.uk/Discussions/Thread/View.html?Thread=" << link.ToUtf8();
Platform::OpenURI(uri.str());
break; break;
} }
case 's': case 's':

View File

@ -1060,10 +1060,8 @@ int GameView::Record(bool record)
{ {
time_t startTime = time(NULL); time_t startTime = time(NULL);
recordingFolder = startTime; recordingFolder = startTime;
ByteString::Stream recordingDir;
recordingDir << "recordings" << PATH_SEP << recordingFolder;
Client::Ref().MakeDirectory("recordings"); Client::Ref().MakeDirectory("recordings");
Client::Ref().MakeDirectory(recordingDir.str().c_str()); Client::Ref().MakeDirectory(ByteString::Build("recordings", PATH_SEP, recordingFolder).c_str());
recording = true; recording = true;
recordingIndex = 0; recordingIndex = 0;
} }
@ -2211,12 +2209,9 @@ void GameView::OnDraw()
VideoBuffer screenshot(ren->DumpFrame()); VideoBuffer screenshot(ren->DumpFrame());
std::vector<char> data = format::VideoBufferToPNG(screenshot); std::vector<char> data = format::VideoBufferToPNG(screenshot);
ByteString::Stream filename; ByteString filename = ByteString::Build("screenshot_", Format::Width(screenshotIndex++, 6), ".png");
filename << "screenshot_";
filename << std::setfill('0') << std::setw(6) << (screenshotIndex++);
filename << ".png";
Client::Ref().WriteFile(data, filename.str()); Client::Ref().WriteFile(data, filename);
doScreenshot = false; doScreenshot = false;
} }
@ -2225,13 +2220,9 @@ void GameView::OnDraw()
VideoBuffer screenshot(ren->DumpFrame()); VideoBuffer screenshot(ren->DumpFrame());
std::vector<char> data = format::VideoBufferToPPM(screenshot); std::vector<char> data = format::VideoBufferToPPM(screenshot);
ByteString::Stream filename; ByteString filename = ByteString::Build("recordings", PATH_SEP, recordingFolder, PATH_SEP, "frame_", Format::Width(screenshotIndex++, 6), ".ppm");
filename << "recordings" << PATH_SEP << recordingFolder << PATH_SEP;
filename << "frame_";
filename << std::setfill('0') << std::setw(6) << (recordingIndex++);
filename << ".ppm";
Client::Ref().WriteFile(data, filename.str()); Client::Ref().WriteFile(data, filename);
} }
if (logEntries.size()) if (logEntries.size())

View File

@ -40,7 +40,7 @@ SaveButton::SaveButton(Point position, Point size, SaveInfo * save):
String votes, icon; String votes, icon;
votes = format::NumberToString<int>(save->GetVotesUp()-save->GetVotesDown()); votes = String::Build(save->GetVotesUp()-save->GetVotesDown());
icon += 0xE03B; icon += 0xE03B;
for (size_t j = 1; j < votes.length(); j++) for (size_t j = 1; j < votes.length(); j++)
icon += 0xE03C; icon += 0xE03C;

View File

@ -108,11 +108,11 @@ LocalBrowserView::LocalBrowserView():
void LocalBrowserView::textChanged() void LocalBrowserView::textChanged()
{ {
int num = format::StringToNumber<int>(pageTextbox->GetText()); int num = pageTextbox->GetText().ToNumber<int>(true);
if (num < 0) //0 is allowed so that you can backspace the 1 if (num < 0) //0 is allowed so that you can backspace the 1
pageTextbox->SetText("1"); pageTextbox->SetText("1");
else if (num > pageCount) else if (num > pageCount)
pageTextbox->SetText(format::NumberToString(pageCount)); pageTextbox->SetText(String::Build(pageCount));
changed = true; changed = true;
#ifdef USE_SDL #ifdef USE_SDL
lastChanged = GetTicks()+600; lastChanged = GetTicks()+600;
@ -126,7 +126,7 @@ void LocalBrowserView::OnTick(float dt)
if (changed && lastChanged < GetTicks()) if (changed && lastChanged < GetTicks())
{ {
changed = false; changed = false;
c->SetPage(std::max(format::StringToNumber<int>(pageTextbox->GetText()), 0)); c->SetPage(std::max(pageTextbox->GetText().ToNumber<int>(true), 0));
} }
#endif #endif
} }

View File

@ -158,7 +158,7 @@ OptionsView::OptionsView():
{ {
if (current_scale == ix_scale) if (current_scale == ix_scale)
current_scale_valid = true; current_scale_valid = true;
scale->AddOption(std::pair<String, int>(format::NumberToString<int>(ix_scale), ix_scale)); scale->AddOption(std::pair<String, int>(String::Build(ix_scale), ix_scale));
ix_scale += 1; ix_scale += 1;
} }
while (ui::Engine::Ref().GetMaxWidth() >= ui::Engine::Ref().GetWidth() * ix_scale && ui::Engine::Ref().GetMaxHeight() >= ui::Engine::Ref().GetHeight() * ix_scale); 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; OptionsView * v;
public: public:
DepthAction(OptionsView * v_) { v = v_; } DepthAction(OptionsView * v_) { v = v_; }
virtual void TextChangedCallback(ui::Textbox * sender) { v->c->Set3dDepth(format::StringToNumber<int>(sender->GetText())); } virtual void TextChangedCallback(ui::Textbox * sender) { v->c->Set3dDepth(sender->GetText().ToNumber<int>(true)); }
}; };
depthTextbox = new ui::Textbox(ui::Point(8, Size.Y-58), ui::Point(25, 16), format::NumberToString<int>(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->SetInputType(ui::Textbox::Numeric);
depthTextbox->SetActionCallback(new DepthAction(this)); depthTextbox->SetActionCallback(new DepthAction(this));
AddComponent(depthTextbox); AddComponent(depthTextbox);

View File

@ -153,9 +153,8 @@ void PreviewController::FavouriteSave()
void PreviewController::OpenInBrowser() void PreviewController::OpenInBrowser()
{ {
ByteString::Stream uriStream; ByteString uri = ByteString::Build("http://", SERVER, "/Browse/View.html?ID=", saveId);
uriStream << "http://" << SERVER << "/Browse/View.html?ID=" << saveId; Platform::OpenURI(uri);
Platform::OpenURI(uriStream.str());
} }
bool PreviewController::NextCommentPage() bool PreviewController::NextCommentPage()

View File

@ -70,30 +70,28 @@ void PreviewModel::UpdateSave(int saveID, int saveDate)
notifySaveChanged(); notifySaveChanged();
notifySaveCommentsChanged(); notifySaveCommentsChanged();
ByteString::Stream urlStream; ByteString url;
if (saveDate) if (saveDate)
urlStream << "http://" << STATICSERVER << "/" << saveID << "_" << saveDate << ".cps"; url = ByteString::Build("http://", STATICSERVER, "/", saveID, "_", saveDate, ".cps");
else else
urlStream << "http://" << STATICSERVER << "/" << saveID << ".cps"; url = ByteString::Build("http://", STATICSERVER, "/", saveID, ".cps");
saveDataDownload = new Download(urlStream.str()); saveDataDownload = new Download(url);
saveDataDownload->Start(); saveDataDownload->Start();
urlStream.str(""); url = ByteString::Build("http://", SERVER , "/Browse/View.json?ID=", saveID);
urlStream << "http://" << SERVER << "/Browse/View.json?ID=" << saveID;
if (saveDate) if (saveDate)
urlStream << "&Date=" << saveDate; url += ByteString::Build("&Date=", saveDate);
saveInfoDownload = new Download(urlStream.str()); saveInfoDownload = new Download(url);
saveInfoDownload->AuthHeaders(format::NumberToByteString(Client::Ref().GetAuthUser().UserID), Client::Ref().GetAuthUser().SessionID); saveInfoDownload->AuthHeaders(ByteString::Build(Client::Ref().GetAuthUser().UserID), Client::Ref().GetAuthUser().SessionID);
saveInfoDownload->Start(); saveInfoDownload->Start();
if (!GetDoOpen()) if (!GetDoOpen())
{ {
commentsLoaded = false; commentsLoaded = false;
urlStream.str(""); url = ByteString::Build("http://", SERVER, "/Browse/Comments.json?ID=", saveID, "&Start=", (commentsPageNumber-1)*20, "&Count=20");
urlStream << "http://" << SERVER << "/Browse/Comments.json?ID=" << saveID << "&Start=" << (commentsPageNumber-1)*20 << "&Count=20"; commentsDownload = new Download(url);
commentsDownload = new Download(urlStream.str()); commentsDownload->AuthHeaders(ByteString::Build(Client::Ref().GetAuthUser().UserID), Client::Ref().GetAuthUser().SessionID);
commentsDownload->AuthHeaders(format::NumberToByteString(Client::Ref().GetAuthUser().UserID), Client::Ref().GetAuthUser().SessionID);
commentsDownload->Start(); commentsDownload->Start();
} }
} }
@ -143,10 +141,9 @@ void PreviewModel::UpdateComments(int pageNumber)
commentsPageNumber = pageNumber; commentsPageNumber = pageNumber;
if (!GetDoOpen()) if (!GetDoOpen())
{ {
ByteString::Stream urlStream; ByteString url = ByteString::Build("http://", SERVER, "/Browse/Comments.json?ID=", saveID, "&Start=", (commentsPageNumber-1)*20, "&Count=20");
urlStream << "http://" << SERVER << "/Browse/Comments.json?ID=" << saveID << "&Start=" << (commentsPageNumber-1)*20 << "&Count=20"; commentsDownload = new Download(url);
commentsDownload = new Download(urlStream.str()); commentsDownload->AuthHeaders(ByteString::Build(Client::Ref().GetAuthUser().UserID), Client::Ref().GetAuthUser().SessionID);
commentsDownload->AuthHeaders(format::NumberToByteString(Client::Ref().GetAuthUser().UserID), Client::Ref().GetAuthUser().SessionID);
commentsDownload->Start(); commentsDownload->Start();
} }
@ -242,9 +239,7 @@ bool PreviewModel::ParseSaveInfo(char * saveInfoResponse)
saveDataDownload->Cancel(); saveDataDownload->Cancel();
delete saveData; delete saveData;
saveData = NULL; saveData = NULL;
ByteString::Stream urlStream; saveDataDownload = new Download(ByteString::Build("http://", STATICSERVER, "/2157797.cps"));
urlStream << "http://" << STATICSERVER << "/2157797.cps";
saveDataDownload = new Download(urlStream.str());
saveDataDownload->Start(); saveDataDownload->Start();
} }
return true; return true;
@ -268,7 +263,7 @@ bool PreviewModel::ParseComments(char *commentsResponse)
for (Json::UInt j = 0; j < commentsArray.size(); j++) for (Json::UInt j = 0; j < commentsArray.size(); j++)
{ {
int userID = format::ByteStringToNumber<int>(commentsArray[j]["UserID"].asString()); int userID = ByteString(commentsArray[j]["UserID"].asString()).ToNumber<int>();
ByteString username = commentsArray[j]["Username"].asString(); ByteString username = commentsArray[j]["Username"].asString();
ByteString formattedUsername = commentsArray[j]["FormattedUsername"].asString(); ByteString formattedUsername = commentsArray[j]["FormattedUsername"].asString();
if (formattedUsername == "jacobot") if (formattedUsername == "jacobot")

View File

@ -227,11 +227,11 @@ void PreviewView::AttachController(PreviewController * controller)
saveIDLabel->Appearance.HorizontalAlign = ui::Appearance::AlignCentre; saveIDLabel->Appearance.HorizontalAlign = ui::Appearance::AlignCentre;
AddComponent(saveIDLabel); AddComponent(saveIDLabel);
textWidth = Graphics::textwidth(format::NumberToString<int>(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:"); saveIDLabel2 = new ui::Label(ui::Point((Size.X-textWidth-20)/2-37, Size.Y+22), ui::Point(40, 16), "Save ID:");
AddComponent(saveIDLabel2); AddComponent(saveIDLabel2);
saveIDButton = new ui::CopyTextButton(ui::Point((Size.X-textWidth-10)/2, Size.Y+20), ui::Point(textWidth+10, 18), format::NumberToString<int>(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); AddComponent(saveIDButton);
} }
@ -514,7 +514,7 @@ void PreviewView::NotifySaveChanged(PreviewModel * sender)
userIsAuthor = true; userIsAuthor = true;
else else
userIsAuthor = false; userIsAuthor = false;
viewsLabel->SetText("\bgViews:\bw " + format::NumberToString<int>(save->Views)); viewsLabel->SetText(String::Build("\bgViews:\bw ", save->Views));
saveDescriptionLabel->SetText(save->Description); saveDescriptionLabel->SetText(save->Description);
if(save->Favourite) if(save->Favourite)
{ {

View File

@ -122,7 +122,7 @@ void ProfileActivity::setUserInfo(UserInfo newInfo)
scrollPanel->AddChild(ageTitle); scrollPanel->AddChild(ageTitle);
// can't figure out how to tell a null from a 0 in the json library we use // 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<int>(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; age->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
scrollPanel->AddChild(age); scrollPanel->AddChild(age);
currentY += 2+age->Size.Y; currentY += 2+age->Size.Y;
@ -165,7 +165,7 @@ void ProfileActivity::setUserInfo(UserInfo newInfo)
saveCountTitle->SetTextColour(ui::Colour(180, 180, 180)); saveCountTitle->SetTextColour(ui::Colour(180, 180, 180));
scrollPanel->AddChild(saveCountTitle); 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<int>(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; savesCount->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
scrollPanel->AddChild(savesCount); scrollPanel->AddChild(savesCount);
currentY += savesCount->Size.Y; currentY += savesCount->Size.Y;
@ -176,7 +176,7 @@ void ProfileActivity::setUserInfo(UserInfo newInfo)
averageScoreTitle->SetTextColour(ui::Colour(180, 180, 180)); averageScoreTitle->SetTextColour(ui::Colour(180, 180, 180));
scrollPanel->AddChild(averageScoreTitle); 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<float>(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; averageScore->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
scrollPanel->AddChild(averageScore); scrollPanel->AddChild(averageScore);
currentY += averageScore->Size.Y; currentY += averageScore->Size.Y;
@ -187,7 +187,7 @@ void ProfileActivity::setUserInfo(UserInfo newInfo)
highestScoreTitle->SetTextColour(ui::Colour(180, 180, 180)); highestScoreTitle->SetTextColour(ui::Colour(180, 180, 180));
scrollPanel->AddChild(highestScoreTitle); 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<int>(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; highestScore->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
scrollPanel->AddChild(highestScore); scrollPanel->AddChild(highestScore);
currentY += 2+highestScore->Size.Y; currentY += 2+highestScore->Size.Y;

View File

@ -270,11 +270,11 @@ void SearchView::clearSearch()
void SearchView::textChanged() void SearchView::textChanged()
{ {
int num = format::StringToNumber<int>(pageTextbox->GetText()); int num = pageTextbox->GetText().ToNumber<int>(true);
if (num < 0) //0 is allowed so that you can backspace the 1 if (num < 0) //0 is allowed so that you can backspace the 1
pageTextbox->SetText("1"); pageTextbox->SetText("1");
else if (num > pageCount) else if (num > pageCount)
pageTextbox->SetText(format::NumberToString(pageCount)); pageTextbox->SetText(String::Build(pageCount));
changed = true; changed = true;
#ifdef USE_SDL #ifdef USE_SDL
lastChanged = GetTicks()+600; lastChanged = GetTicks()+600;
@ -763,7 +763,7 @@ void SearchView::OnTick(float dt)
if (changed && lastChanged < GetTicks()) if (changed && lastChanged < GetTicks())
{ {
changed = false; changed = false;
c->SetPage(std::max(format::StringToNumber<int>(pageTextbox->GetText()), 0)); c->SetPage(std::max(pageTextbox->GetText().ToNumber<int>(true), 0));
} }
#endif #endif
} }

View File

@ -116,13 +116,13 @@ private:
}; };
UpdateActivity::UpdateActivity() { UpdateActivity::UpdateActivity() {
ByteString::Stream file; ByteString file;
#ifdef UPDATESERVER #ifdef UPDATESERVER
file << "http://" << UPDATESERVER << Client::Ref().GetUpdateInfo().File; file = ByteString::Build("http://", UPDATESERVER, Client::Ref().GetUpdateInfo().File);
#else #else
file << "http://" << SERVER << Client::Ref().GetUpdateInfo().File; file = ByteString::Build("http://", SERVER, Client::Ref().GetUpdateInfo().File);
#endif #endif
updateDownloadTask = new UpdateDownloadTask(file.str(), this); updateDownloadTask = new UpdateDownloadTask(file, this);
updateWindow = new TaskWindow("Downloading update...", updateDownloadTask, true); updateWindow = new TaskWindow("Downloading update...", updateDownloadTask, true);
} }

View File

@ -1914,13 +1914,12 @@ int luatpt_getscript(lua_State* l)
int runScript = luaL_optint(l, 3, 0); int runScript = luaL_optint(l, 3, 0);
int confirmPrompt = luaL_optint(l, 4, 1); int confirmPrompt = luaL_optint(l, 4, 1);
ByteString::Stream url; ByteString url = ByteString::Build("http://starcatcher.us/scripts/main.lua?get=", scriptID);
url << "http://starcatcher.us/scripts/main.lua?get=" << scriptID; if (confirmPrompt && !ConfirmPrompt::Blocking("Do you want to install script?", url.FromUtf8(), "Install"))
if (confirmPrompt && !ConfirmPrompt::Blocking("Do you want to install script?", ByteString(url.str()).FromUtf8(), "Install"))
return 0; return 0;
int ret, len; 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) if (len <= 0 || !filename)
{ {
free(scriptData); free(scriptData);
@ -1968,9 +1967,7 @@ int luatpt_getscript(lua_State* l)
outputfile = NULL; outputfile = NULL;
if (runScript) if (runScript)
{ {
ByteString::Stream luaCommand; luaL_dostring(l, ByteString::Build("dofile('", filename, "')").c_str());
luaCommand << "dofile('" << filename << "')";
luaL_dostring(l, luaCommand.str().c_str());
} }
return 0; return 0;
@ -2018,18 +2015,16 @@ int luatpt_screenshot(lua_State* l)
data = format::VideoBufferToPNG(screenshot); data = format::VideoBufferToPNG(screenshot);
} }
} }
ByteString::Stream filename; ByteString filename = ByteString::Build("screenshot_", Format::Width(screenshotIndex++, 6));
filename << "screenshot_";
filename << std::setfill('0') << std::setw(6) << (screenshotIndex++);
if(fileType == 1) { if(fileType == 1) {
filename << ".bmp"; filename += ".bmp";
} else if(fileType == 2) { } else if(fileType == 2) {
filename << ".ppm"; filename += ".ppm";
} else { } else {
filename << ".png"; filename += ".png";
} }
Client::Ref().WriteFile(data, filename.str()); Client::Ref().WriteFile(data, filename);
lua_pushstring(l, filename.str().c_str()); lua_pushstring(l, filename.c_str());
return 1; return 1;
} }