| 97 | } |
| 98 | |
| 99 | void WriteTextString(const std::shared_ptr<WriteStream>& stream, const char* data, size_t length) { |
| 100 | bool inputIsValidUTF8 = true; |
| 101 | bool inputIsPDFDocEncoding = true; |
| 102 | size_t literalExtras = 0; |
| 103 | { |
| 104 | const char* textStart = data; |
| 105 | const char* textEnd = data + length; |
| 106 | while (textStart < textEnd) { |
| 107 | Unichar unichar = UTF::NextUTF8(&textStart, textEnd); |
| 108 | if (unichar < 0) { |
| 109 | inputIsValidUTF8 = false; |
| 110 | break; |
| 111 | } |
| 112 | // See Table D.2 (PDFDocEncoding Character Set) in the PDF3200_2008 spec. |
| 113 | // Could convert from UTF-8 to PDFDocEncoding and, if successful, use that. |
| 114 | if ((0x15 < unichar && unichar < 0x20) || 0x7E < unichar) { |
| 115 | inputIsPDFDocEncoding = false; |
| 116 | break; |
| 117 | } |
| 118 | if (unichar < ' ' || '~' < unichar) { |
| 119 | literalExtras += 3; |
| 120 | } else if (unichar == '\\' || unichar == '(' || unichar == ')') { |
| 121 | ++literalExtras; |
| 122 | } |
| 123 | } |
| 124 | } |
| 125 | |
| 126 | if (!inputIsValidUTF8) { |
| 127 | LOGE("Invalid UTF8: %.*s\n", (int)length, data); |
| 128 | stream->writeText("<>"); |
| 129 | return; |
| 130 | } |
| 131 | |
| 132 | if (inputIsPDFDocEncoding) { |
| 133 | WriteOptimizedByteString(stream, data, length, literalExtras); |
| 134 | return; |
| 135 | } |
| 136 | |
| 137 | stream->writeText("<FEFF"); |
| 138 | const char* textPtr = data; |
| 139 | const char* textEnd = data + length; |
| 140 | while (textPtr < textEnd) { |
| 141 | Unichar unichar = UTF::NextUTF8(&textPtr, textEnd); |
| 142 | PDFUtils::WriteUTF16beHex(stream, unichar); |
| 143 | } |
| 144 | stream->writeText(">"); |
| 145 | } |
| 146 | } // namespace |
| 147 | |
| 148 | PDFUnion::PDFUnion(Type type, int32_t value) : intValue(value), type(type) { |
no test coverage detected