From 9a0b88bf7777c153dc46ace22db74ef24d51583a Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Tue, 29 Apr 2008 12:55:25 +0000 Subject: update release date to actual date git-svn-id: svn+q:///qpdf/trunk@599 71b93d88-0707-0410-a8cf-f5a4172ac649 --- libqpdf/QUtil.cc | 198 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 libqpdf/QUtil.cc (limited to 'libqpdf/QUtil.cc') diff --git a/libqpdf/QUtil.cc b/libqpdf/QUtil.cc new file mode 100644 index 00000000..c0de95f7 --- /dev/null +++ b/libqpdf/QUtil.cc @@ -0,0 +1,198 @@ + +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +#include +#else +#include +#endif + +std::string +QUtil::int_to_string(int num, int fullpad) +{ + // This routine will need to be recompiled if an int can be longer than + // 49 digits. + char t[50]; + + // -2 or -1 to leave space for the possible negative sign and for NUL... + if (abs(fullpad) > (int)sizeof(t) - ((num < 0)?2:1)) + { + throw QEXC::Internal("Util::int_to_string has been called with " + "a padding value greater than its internal " + "limit"); + } + + if (fullpad) + { + sprintf(t, "%0*d", fullpad, num); + } + else + { + sprintf(t, "%d", num); + } + + return std::string(t); +} + +std::string +QUtil::double_to_string(double num, int decimal_places) +{ + // This routine will need to be recompiled if a double can be longer than + // 99 digits. + char t[100]; + + std::string lhs = int_to_string((int)num); + + // lhs.length() gives us the length of the part on the right hand + // side of the dot + 1 for the dot + decimal_places: total size of + // the required string. -1 on the sizeof side to allow for NUL at + // the end. + // + // If decimal_places <= 0, it is as if no precision was provided + // so trust the buffer is big enough. The following test will + // always pass in those cases. + if (decimal_places + 1 + (int)lhs.length() > (int)sizeof(t) - 1) + { + throw QEXC::Internal("Util::double_to_string has been called with " + "a number and a decimal places specification " + "that would break an internal limit"); + } + + if (decimal_places) + { + sprintf(t, "%.*f", decimal_places, num); + } + else + { + sprintf(t, "%f", num); + } + return std::string(t); +} + +int +QUtil::os_wrapper(std::string const& description, int status) throw (QEXC::System) +{ + if (status == -1) + { + throw QEXC::System(description, errno); + } + return status; +} + +FILE* +QUtil::fopen_wrapper(std::string const& description, FILE* f) throw (QEXC::System) +{ + if (f == 0) + { + throw QEXC::System(description, errno); + } + return f; +} + +char* +QUtil::copy_string(std::string const& str) +{ + char* result = new char[str.length() + 1]; + // Use memcpy in case string contains nulls + result[str.length()] = '\0'; + memcpy(result, str.c_str(), str.length()); + return result; +} + +bool +QUtil::get_env(std::string const& var, std::string* value) +{ + // This was basically ripped out of wxWindows. +#ifdef _WIN32 + // first get the size of the buffer + DWORD len = ::GetEnvironmentVariable(var.c_str(), NULL, 0); + if (len == 0) + { + // this means that there is no such variable + return false; + } + + if (value) + { + char* t = new char[len + 1]; + ::GetEnvironmentVariable(var.c_str(), t, len); + *value = t; + delete [] t; + } + + return true; +#else + char* p = getenv(var.c_str()); + if (p == 0) + { + return false; + } + if (value) + { + *value = p; + } + + return true; +#endif +} + +std::string +QUtil::toUTF8(unsigned long uval) +{ + std::string result; + + // A UTF-8 encoding of a Unicode value is a single byte for + // Unicode values <= 127. For larger values, the first byte of + // the UTF-8 encoding has '1' as each of its n highest bits and + // '0' for its (n+1)th highest bit where n is the total number of + // bytes required. Subsequent bytes start with '10' and have the + // remaining 6 bits free for encoding. For example, an 11-bit + // unicode value can be stored in two bytes where the first is + // 110zzzzz, the second is 10zzzzzz, and the z's represent the + // remaining bits. + + if (uval > 0x7fffffff) + { + throw QEXC::General("bounds error in QUtil::toUTF8"); + } + else if (uval < 128) + { + result += (char)(uval); + } + else + { + unsigned char bytes[7]; + bytes[6] = '\0'; + unsigned char* cur_byte = &bytes[5]; + + // maximum value that will fit in the current number of bytes + unsigned char maxval = 0x3f; // six bits + + while (uval > maxval) + { + // Assign low six bits plus 10000000 to lowest unused + // byte position, then shift + *cur_byte = (unsigned char) (0x80 + (uval & 0x3f)); + uval >>= 6; + // Maximum that will fit in high byte now shrinks by one bit + maxval >>= 1; + // Slide to the left one byte + --cur_byte; + if (cur_byte < bytes) + { + throw QEXC::Internal("QUtil::toUTF8: overflow error"); + } + } + // If maxval is k bits long, the high (7 - k) bits of the + // resulting byte must be high. + *cur_byte = (unsigned char)((0xff - (1 + (maxval << 1))) + uval); + + result += (char*)cur_byte; + } + + return result; +} -- cgit v1.2.3-54-g00ecf