aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2018-06-21 20:03:45 +0200
committerJay Berkenbilt <ejb@ql.org>2018-06-21 21:57:13 +0200
commit952a665a4ed51400b5925e7cd69f08f0aeb374fe (patch)
tree080fef42cc7978c01e88a854ce9b96fb1b1916c0 /libqpdf
parente44c395c51518bafbf8f8466ea5a0f4b1f2b2efe (diff)
downloadqpdf-952a665a4ed51400b5925e7cd69f08f0aeb374fe.tar.zst
Better support for creating Unicode strings
Diffstat (limited to 'libqpdf')
-rw-r--r--libqpdf/QPDFObjectHandle.cc20
-rw-r--r--libqpdf/QPDF_String.cc52
-rw-r--r--libqpdf/qpdf/QPDF_String.hh1
3 files changed, 73 insertions, 0 deletions
diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc
index 5c111cc8..da609cc2 100644
--- a/libqpdf/QPDFObjectHandle.cc
+++ b/libqpdf/QPDFObjectHandle.cc
@@ -1221,6 +1221,20 @@ QPDFObjectHandle::unparseResolved()
return this->m->obj->unparse();
}
+std::string
+QPDFObjectHandle::unparseBinary()
+{
+ if (this->isString())
+ {
+ return dynamic_cast<QPDF_String*>(
+ this->m->obj.getPointer())->unparse(true);
+ }
+ else
+ {
+ return unparse();
+ }
+}
+
QPDFObjectHandle
QPDFObjectHandle::parse(std::string const& object_str,
std::string const& object_description)
@@ -1846,6 +1860,12 @@ QPDFObjectHandle::newString(std::string const& str)
}
QPDFObjectHandle
+QPDFObjectHandle::newUnicodeString(std::string const& utf8_str)
+{
+ return QPDFObjectHandle(QPDF_String::new_utf16(utf8_str));
+}
+
+QPDFObjectHandle
QPDFObjectHandle::newOperator(std::string const& value)
{
return QPDFObjectHandle(new QPDF_Operator(value));
diff --git a/libqpdf/QPDF_String.cc b/libqpdf/QPDF_String.cc
index 60a3e0df..eb31a808 100644
--- a/libqpdf/QPDF_String.cc
+++ b/libqpdf/QPDF_String.cc
@@ -64,6 +64,58 @@ QPDF_String::~QPDF_String()
{
}
+QPDF_String*
+QPDF_String::new_utf16(std::string const& utf8_val)
+{
+ std::string result = "\xfe\xff";
+ size_t len = utf8_val.length();
+ for (size_t i = 0; i < len; ++i)
+ {
+ unsigned char ch = static_cast<unsigned char>(utf8_val.at(i));
+ if (ch < 128)
+ {
+ result += QUtil::toUTF16(ch);
+ }
+ else
+ {
+ size_t bytes_needed = 0;
+ unsigned bit_check = 0x40;
+ unsigned char to_clear = 0x80;
+ while (ch & bit_check)
+ {
+ ++bytes_needed;
+ to_clear |= bit_check;
+ bit_check >>= 1;
+ }
+
+ if (((bytes_needed > 5) || (bytes_needed < 1)) ||
+ ((i + bytes_needed) >= len))
+ {
+ result += "\xff\xfd";
+ }
+ else
+ {
+ unsigned long codepoint = (ch & ~to_clear);
+ while (bytes_needed > 0)
+ {
+ --bytes_needed;
+ ch = utf8_val.at(++i);
+ if ((ch & 0xc0) != 0x80)
+ {
+ --i;
+ codepoint = 0xfffd;
+ break;
+ }
+ codepoint <<= 6;
+ codepoint += (ch & 0x3f);
+ }
+ result += QUtil::toUTF16(codepoint);
+ }
+ }
+ }
+ return new QPDF_String(result);
+}
+
std::string
QPDF_String::unparse()
{
diff --git a/libqpdf/qpdf/QPDF_String.hh b/libqpdf/qpdf/QPDF_String.hh
index abf8291a..b4858c49 100644
--- a/libqpdf/qpdf/QPDF_String.hh
+++ b/libqpdf/qpdf/QPDF_String.hh
@@ -9,6 +9,7 @@ class QPDF_String: public QPDFObject
{
public:
QPDF_String(std::string const& val);
+ static QPDF_String* new_utf16(std::string const& utf8_val);
virtual ~QPDF_String();
virtual std::string unparse();
virtual QPDFObject::object_type_e getTypeCode() const;