Example #1
0
        /// <summary>
        /// Converts the specified byte array into a byte array representing a string literal.
        /// </summary>
        /// <param name="bytes">The bytes of the string.</param>
        /// <param name="unicode">Indicates whether one or two bytes are one character.</param>
        /// <param name="prefix">Indicates whether to use Unicode prefix.</param>
        /// <param name="hex">Indicates whether to create a hexadecimal string literal.</param>
        /// <param name="securityHandler">Encrypts the bytes if specified.</param>
        /// <returns>The PDF bytes.</returns>
        public static byte[] FormatStringLiteral(byte[] bytes, bool unicode, bool prefix, bool hex, PdfStandardSecurityHandler securityHandler)
        {
            if (bytes == null || bytes.Length == 0)
            {
                return hex ? new byte[] { (byte)'<', (byte)'>' }
            }
            : new byte[] { (byte)'(', (byte)')' };

            Debug.Assert(!unicode || bytes.Length % 2 == 0, "Odd number of bytes in Unicode string.");

            byte[] originalBytes = null;

            bool encrypted = false;

            if (securityHandler != null && !hex)
            {
                originalBytes = bytes;

                bytes     = (byte[])bytes.Clone();
                bytes     = securityHandler.EncryptBytes(bytes);
                encrypted = true;
            }

            int           count = bytes.Length;
            StringBuilder pdf   = new StringBuilder();

            if (!unicode)
            {
                if (!hex)
                {
                    pdf.Append("(");
                    for (int idx = 0; idx < count; idx++)
                    {
                        char ch = (char)bytes[idx];
                        if (ch < 32)
                        {
                            switch (ch)
                            {
                            case '\n':
                                pdf.Append("\\n");
                                break;

                            case '\r':
                                pdf.Append("\\r");
                                break;

                            case '\t':
                                pdf.Append("\\t");
                                break;

                            case '\b':
                                pdf.Append("\\b");
                                break;

                            // Corrupts encrypted text.
                            //case '\f':
                            //  pdf.Append("\\f");
                            //  break;

                            default:
                                // Don't escape characters less than 32 if the string is encrypted, because it is
                                // unreadable anyway.
                                encrypted = true;
                                if (!encrypted)
                                {
                                    pdf.Append("\\0");
                                    pdf.Append((char)(ch % 8 + '0'));
                                    pdf.Append((char)(ch / 8 + '0'));
                                }
                                else
                                {
                                    pdf.Append(ch);
                                }
                                break;
                            }
                        }
                        else
                        {
                            switch (ch)
                            {
                            case '(':
                                pdf.Append("\\(");
                                break;

                            case ')':
                                pdf.Append("\\)");
                                break;

                            case '\\':
                                pdf.Append("\\\\");
                                break;

                            default:
                                pdf.Append(ch);
                                break;
                            }
                        }
                    }
                    pdf.Append(')');
                }
                else
                {
                    pdf.Append('<');
                    for (int idx = 0; idx < count; idx++)
                    {
                        pdf.AppendFormat("{0:X2}", bytes[idx]);
                    }
                    pdf.Append('>');
                }
            }
            else
            {
                //Hex:
                if (hex)
                {
                    if (securityHandler != null && prefix)
                    {
                        // TODO Reduce redundancy.
                        // Encrypt data after padding BOM.
                        var bytes2 = new byte[bytes.Length + 2];
                        // Add BOM.
                        bytes2[0] = 0xfe;
                        bytes2[1] = 0xff;
                        // Copy bytes.
                        Array.Copy(bytes, 0, bytes2, 2, bytes.Length);
                        // Encyption.
                        bytes2    = securityHandler.EncryptBytes(bytes2);
                        encrypted = true;
                        pdf.Append("<");
                        var count2 = bytes2.Length;
                        for (int idx = 0; idx < count2; idx += 2)
                        {
                            pdf.AppendFormat("{0:X2}{1:X2}", bytes2[idx], bytes2[idx + 1]);
                            if (idx != 0 && (idx % 48) == 0)
                            {
                                pdf.Append("\n");
                            }
                        }
                        pdf.Append(">");
                    }
                    else
                    {
                        // No prefix or no encryption.
                        pdf.Append(prefix ? "<FEFF" : "<");
                        for (int idx = 0; idx < count; idx += 2)
                        {
                            pdf.AppendFormat("{0:X2}{1:X2}", bytes[idx], bytes[idx + 1]);
                            if (idx != 0 && (idx % 48) == 0)
                            {
                                pdf.Append("\n");
                            }
                        }
                        pdf.Append(">");
                    }
                }
                else
                {
                    // TODO non hex literals... not sure how to treat linefeeds, '(', '\' etc.
                    if (encrypted)
                    {
                        // Hack: Call self with hex := true.
                        return(FormatStringLiteral(originalBytes, unicode, prefix, true, securityHandler));
                    }
                    else
                    {
                        // Hack: Call self with hex := true.
                        return(FormatStringLiteral(bytes, true, prefix, true, null));
                    }
                }
            }
            return(RawEncoding.GetBytes(pdf.ToString()));
        }
        /// <summary>
        /// Converts the specified byte array into a byte array representing a string literal.
        /// </summary>
        /// <param name="bytes">The bytes of the string.</param>
        /// <param name="unicode">Indicates whether one or two bytes are one character.</param>
        /// <param name="prefix">Indicates whether to use Unicode prefix.</param>
        /// <param name="hex">Indicates whether to create a hexadecimal string literal.</param>
        /// <param name="securityHandler">Encrypts the bytes if specified.</param>
        /// <returns>The PDF bytes.</returns>
        public static byte[] FormatStringLiteral(byte[] bytes, bool unicode, bool prefix, bool hex, PdfStandardSecurityHandler securityHandler)
        {
            if (bytes == null || bytes.Length == 0)
            {
                return hex ? new byte[] { (byte)'<', (byte)'>' }
            }
            : new byte[] { (byte)'(', (byte)')' };

            Debug.Assert(!unicode || bytes.Length % 2 == 0, "Odd number of bytes in Unicode string.");

            bool encrypted = false;

            if (securityHandler != null)
            {
                bytes = (byte[])bytes.Clone();

                bytes     = securityHandler.EncryptBytes(bytes);
                encrypted = true;
            }

            int           count = bytes.Length;
            StringBuilder pdf   = new StringBuilder();

            if (!unicode)
            {
                if (!hex)
                {
                    pdf.Append("(");
                    for (int idx = 0; idx < count; idx++)
                    {
                        char ch = (char)bytes[idx];
                        if (ch < 32)
                        {
                            switch (ch)
                            {
                            case '\n':
                                pdf.Append("\\n");
                                break;

                            case '\r':
                                pdf.Append("\\r");
                                break;

                            case '\t':
                                pdf.Append("\\t");
                                break;

                            case '\b':
                                pdf.Append("\\b");
                                break;

                            // Corrupts encrypted text.
                            //case '\f':
                            //  pdf.Append("\\f");
                            //  break;

                            default:
                                // Don't escape characters less than 32 if the string is encrypted, because it is
                                // unreadable anyway.
                                encrypted = true;
                                if (!encrypted)
                                {
                                    pdf.Append("\\0");
                                    pdf.Append((char)(ch % 8 + '0'));
                                    pdf.Append((char)(ch / 8 + '0'));
                                }
                                else
                                {
                                    pdf.Append(ch);
                                }
                                break;
                            }
                        }
                        else
                        {
                            switch (ch)
                            {
                            case '(':
                                pdf.Append("\\(");
                                break;

                            case ')':
                                pdf.Append("\\)");
                                break;

                            case '\\':
                                pdf.Append("\\\\");
                                break;

                            default:
                                pdf.Append(ch);
                                break;
                            }
                        }
                    }
                    pdf.Append(')');
                }
                else
                {
                    pdf.Append('<');
                    for (int idx = 0; idx < count; idx++)
                    {
                        pdf.AppendFormat("{0:X2}", bytes[idx]);
                    }
                    pdf.Append('>');
                }
            }
            else
            {
                Hex:
                if (hex)
                {
                    pdf.Append(prefix ? "<FEFF" : "<");
                    for (int idx = 0; idx < count; idx += 2)
                    {
                        pdf.AppendFormat("{0:X2}{1:X2}", bytes[idx], bytes[idx + 1]);
                        if (idx != 0 && (idx % 48) == 0)
                        {
                            pdf.Append("\n");
                        }
                    }
                    pdf.Append(">");
                }
                else
                {
                    // TODO non hex literals... not sure how to treat linefeeds, '(', '\' etc.
                    hex = true;
                    goto Hex;
                }
            }
            return(RawEncoding.GetBytes(pdf.ToString()));
        }