Module: Pdfrb::Model::Cos::NameEncoding

Defined in:
lib/pdfrb/model/cos/name_encoding.rb

Overview

Helpers for PDF Name (s7.3.5): a Symbol on the Ruby side, a /... token on the wire. Non-printable or delimiter bytes are #xx-escaped; we always emit # escapes for the delimiter set even when printable, to match HexaPDF behaviour.

Constant Summary collapse

DELIMITERS =
"()<>[]{}/%".b
WHITESPACE =
" \t\n\f\r\0".b
ESCAPE_CHARS =
(DELIMITERS + WHITESPACE + "#").b.chars.uniq.freeze

Class Method Summary collapse

Class Method Details

.decode(str) ⇒ Object

"/..." or "..." String -> Symbol. #xx sequences decoded.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/pdfrb/model/cos/name_encoding.rb', line 31

def decode(str)
  s = str.to_s
  s = s.delete_prefix("/")
  out = +""
  i = 0
  bytes = s.bytes
  while i < bytes.length
    b = bytes[i]
    if b == 35 # #
      hex = bytes[i + 1, 2]
      if hex && hex.length == 2 && hex.all? { |h| hex_byte?(h) }
        hex_str = hex.map(&:chr).join
        out << hex_str.to_i(16).chr
        i += 3
      else
        out << "#"
        i += 1
      end
    else
      out << b.chr
      i += 1
    end
  end
  out.to_sym
end

.encode(sym) ⇒ Object

Symbol -> "/..." String ready for the byte stream.

Raises:

  • (ArgumentError)


18
19
20
21
22
23
24
25
26
27
28
# File 'lib/pdfrb/model/cos/name_encoding.rb', line 18

def encode(sym)
  raise ArgumentError, "Name must be a Symbol" unless sym.is_a?(Symbol)

  +"/" << sym.to_s.each_char.with_object(+"") do |ch, buf|
    buf << if ESCAPE_CHARS.include?(ch) || ch.bytes.any? { |b| b < 33 || b > 126 }
             "#%02X" % ch.bytes.first
           else
             ch
           end
  end
end

.hex_byte?(b) ⇒ Object



57
58
59
# File 'lib/pdfrb/model/cos/name_encoding.rb', line 57

def hex_byte?(b)
  (48..57).cover?(b) || (65..70).cover?(b) || (97..102).cover?(b)
end