Cleanup package_string() and its users
package_string() isn't readable in its current form and a loop is unnecessary, so let's replace that with the direct calculations. The new and old functions are identical in results except an edge case where the old function incorrectly believes it needs to round up to '10' for the size prefix, when '9' would be ok, specifically: 10\naaaaa\n\f vs 9\naaaaa\n\f. This is true for all powers of 10. Clean up the calling side in logcat as well. Test: printing log statistics and prune list works Change-Id: Ib62ab2badab59040215b130ec9e3efbc7c95af3f
This commit is contained in:
parent
ed860ff4bf
commit
e17b4f62df
2 changed files with 49 additions and 43 deletions
|
@ -1082,50 +1082,45 @@ int Logcat::Run(int argc, char** argv) {
|
|||
}
|
||||
|
||||
if (printStatistics || getPruneList) {
|
||||
size_t len = 8192;
|
||||
char* buf;
|
||||
std::string buf(8192, '\0');
|
||||
size_t ret_length = 0;
|
||||
int retry = 32;
|
||||
|
||||
for (int retry = 32; (retry >= 0) && ((buf = new char[len]));
|
||||
delete[] buf, buf = nullptr, --retry) {
|
||||
for (; retry >= 0; --retry) {
|
||||
if (getPruneList) {
|
||||
android_logger_get_prune_list(logger_list.get(), buf, len);
|
||||
android_logger_get_prune_list(logger_list.get(), buf.data(), buf.size());
|
||||
} else {
|
||||
android_logger_get_statistics(logger_list.get(), buf, len);
|
||||
android_logger_get_statistics(logger_list.get(), buf.data(), buf.size());
|
||||
}
|
||||
buf[len - 1] = '\0';
|
||||
if (atol(buf) < 3) {
|
||||
delete[] buf;
|
||||
buf = nullptr;
|
||||
|
||||
ret_length = atol(buf.c_str());
|
||||
if (ret_length < 3) {
|
||||
error(EXIT_FAILURE, 0, "Failed to read data.");
|
||||
}
|
||||
|
||||
if (ret_length < buf.size()) {
|
||||
break;
|
||||
}
|
||||
size_t ret = atol(buf) + 1;
|
||||
if (ret <= len) {
|
||||
len = ret;
|
||||
break;
|
||||
}
|
||||
len = ret;
|
||||
|
||||
buf.resize(ret_length + 1);
|
||||
}
|
||||
|
||||
if (!buf) {
|
||||
if (retry < 0) {
|
||||
error(EXIT_FAILURE, 0, "Failed to read data.");
|
||||
}
|
||||
|
||||
// remove trailing FF
|
||||
char* cp = buf + len - 1;
|
||||
*cp = '\0';
|
||||
bool truncated = *--cp != '\f';
|
||||
if (!truncated) *cp = '\0';
|
||||
|
||||
// squash out the byte count
|
||||
cp = buf;
|
||||
if (!truncated) {
|
||||
while (isdigit(*cp)) ++cp;
|
||||
if (*cp == '\n') ++cp;
|
||||
buf.resize(ret_length);
|
||||
if (buf.back() == '\f') {
|
||||
buf.pop_back();
|
||||
}
|
||||
|
||||
len = strlen(cp);
|
||||
// Remove the byte count prefix
|
||||
const char* cp = buf.c_str();
|
||||
while (isdigit(*cp)) ++cp;
|
||||
if (*cp == '\n') ++cp;
|
||||
|
||||
size_t len = strlen(cp);
|
||||
TEMP_FAILURE_RETRY(write(output_fd_.get(), cp, len));
|
||||
delete[] buf;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <math.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -186,14 +187,26 @@ CommandListener::GetStatisticsCmd::GetStatisticsCmd(LogBuffer* buf)
|
|||
: LogCommand("getStatistics"), mBuf(*buf) {
|
||||
}
|
||||
|
||||
static std::string package_string(const std::string& str) {
|
||||
// Calculate total buffer size prefix, count is the string length w/o nul
|
||||
char fmt[32];
|
||||
for (size_t l = str.length(), y = 0, x = 6; y != x;
|
||||
y = x, x = strlen(fmt) - 2) {
|
||||
snprintf(fmt, sizeof(fmt), "%zu\n%%s\n\f", l + x);
|
||||
// This returns a string with a length prefix with the format <length>\n<data>\n\f. The length
|
||||
// prefix includes the length of the prefix itself.
|
||||
static std::string PackageString(const std::string& str) {
|
||||
size_t overhead_length = 3; // \n \n \f.
|
||||
|
||||
// Number of digits needed to represent length(str + overhead_length).
|
||||
size_t str_size_digits = 1 + static_cast<size_t>(log10(str.size() + overhead_length));
|
||||
// Number of digits needed to represent the total size.
|
||||
size_t total_size_digits =
|
||||
1 + static_cast<size_t>(log10(str.size() + overhead_length + str_size_digits));
|
||||
|
||||
// If adding the size prefix causes a new digit to be required to represent the new total
|
||||
// size, add it to the 'overhead_length'. This can only happen once, since each new digit
|
||||
// allows for 10x the previous size to be recorded.
|
||||
if (total_size_digits != str_size_digits) {
|
||||
overhead_length++;
|
||||
}
|
||||
return android::base::StringPrintf(fmt, str.c_str());
|
||||
|
||||
size_t total_size = str.size() + overhead_length + str_size_digits;
|
||||
return android::base::StringPrintf("%zu\n%s\n\f", total_size, str.c_str());
|
||||
}
|
||||
|
||||
int CommandListener::GetStatisticsCmd::runCommand(SocketClient* cli, int argc,
|
||||
|
@ -228,8 +241,7 @@ int CommandListener::GetStatisticsCmd::runCommand(SocketClient* cli, int argc,
|
|||
}
|
||||
}
|
||||
|
||||
cli->sendMsg(
|
||||
package_string(mBuf.formatStatistics(uid, pid, logMask)).c_str());
|
||||
cli->sendMsg(PackageString(mBuf.formatStatistics(uid, pid, logMask)).c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -240,7 +252,7 @@ CommandListener::GetPruneListCmd::GetPruneListCmd(LogBuffer* buf)
|
|||
int CommandListener::GetPruneListCmd::runCommand(SocketClient* cli,
|
||||
int /*argc*/, char** /*argv*/) {
|
||||
setname();
|
||||
cli->sendMsg(package_string(mBuf.formatPrune()).c_str());
|
||||
cli->sendMsg(PackageString(mBuf.formatPrune()).c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -316,12 +328,11 @@ int CommandListener::GetEventTagCmd::runCommand(SocketClient* cli, int argc,
|
|||
cli->sendMsg("can not mix id= with either format= or name=");
|
||||
return 0;
|
||||
}
|
||||
cli->sendMsg(package_string(mBuf.formatEntry(atoi(id), uid)).c_str());
|
||||
cli->sendMsg(PackageString(mBuf.formatEntry(atoi(id), uid)).c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
cli->sendMsg(
|
||||
package_string(mBuf.formatGetEventTag(uid, name, format)).c_str());
|
||||
cli->sendMsg(PackageString(mBuf.formatGetEventTag(uid, name, format)).c_str());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue