Class: Pdfrb::Serializer

Inherits:
Object
  • Object
show all
Defined in:
lib/pdfrb/serializer.rb

Overview

Model -> PDF bytes (COS values). Stateless; safe to share across documents. Indirect-object aware: a Model::Reference value is emitted as oid gen R, not inlined.

Streams are emitted only as part of an indirect object via the Writer (which handles obj/endobj framing); the Serializer's job is to produce the COS-fragment bytes for the dict body, the stream payload, etc.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(encrypter: nil, compress_streams: false, compress_min_size: 256) ⇒ Serializer

Returns a new instance of Serializer.



15
16
17
18
19
# File 'lib/pdfrb/serializer.rb', line 15

def initialize(encrypter: nil, compress_streams: false, compress_min_size: 256)
  @encrypter = encrypter
  @compress_streams = compress_streams
  @compress_min_size = compress_min_size.to_i
end

Instance Attribute Details

#compress_min_sizeObject (readonly)

Returns the value of attribute compress_min_size.



13
14
15
# File 'lib/pdfrb/serializer.rb', line 13

def compress_min_size
  @compress_min_size
end

#compress_streamsObject (readonly)

Returns the value of attribute compress_streams.



13
14
15
# File 'lib/pdfrb/serializer.rb', line 13

def compress_streams
  @compress_streams
end

#encrypterObject (readonly)

Returns the value of attribute encrypter.



13
14
15
# File 'lib/pdfrb/serializer.rb', line 13

def encrypter
  @encrypter
end

Class Method Details

.serialize(value, encrypter: nil) ⇒ Object



22
23
24
# File 'lib/pdfrb/serializer.rb', line 22

def serialize(value, encrypter: nil, **)
  new(encrypter: encrypter, **).serialize(value)
end

Instance Method Details

#serialize(value) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/pdfrb/serializer.rb', line 27

def serialize(value)
  case value
  when ::Integer then serialize_integer(value)
  when ::Float then serialize_real(value)
  when ::Symbol then serialize_name(value)
  when ::String then serialize_string(value)
  when true then "true"
  when false then "false"
  when nil then "null"
  when Pdfrb::Model::Reference then serialize_reference(value)
  when ::Array then serialize_array(value)
  when Pdfrb::Model::PdfArray then serialize_array(value.value)
  when ::Hash then serialize_dict(value)
  when Pdfrb::Model::Cos::Dictionary then serialize_dict(value.value)
  when Pdfrb::Model::Cos::Stream then serialize_dict(value.value)
  when Pdfrb::Model::Object then serialize(value.value)
  when Pdfrb::Model::Date then serialize_date_string(value)
  when Pdfrb::Model::Rectangle then serialize_array(value.to_a)
  when Pdfrb::Model::Matrix then serialize_array(value.to_a)
  else
    raise Pdfrb::SerializeError,
          "cannot serialise #{value.class}: #{value.inspect}"
  end
end

#serialize_indirect(obj, skip_string_encryption: false) ⇒ Object

Serialise an indirect object's body, including oid gen obj header and (for streams) the stream payload. When an encrypter is set, all strings in the object's dictionaries and the stream payload are encrypted with the per-object key (s7.6.1) — pass skip_string_encryption: for the /Encrypt dictionary itself, whose entries must stay readable.

Raises:

  • (ArgumentError)


58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/pdfrb/serializer.rb', line 58

def serialize_indirect(obj, skip_string_encryption: false)
  raise ArgumentError, "not indirect: #{obj.inspect}" unless obj.indirect?

  encrypt_strings = !skip_string_encryption && encrypter
  buffer = +""
  buffer << "#{obj.oid} #{obj.gen} obj\n"
  case obj
  when Pdfrb::Model::Cos::Stream
    dict_value = encrypt_strings ? encrypt_value_strings(obj.value, obj.oid, obj.gen) : obj.value
    dict, payload = emit_stream(obj, dict_value)
    buffer << dict
    buffer << "\nstream\n"
    buffer << (encrypter ? encrypter.encrypt(payload, obj.oid, obj.gen) : payload)
    buffer << "\nendstream\n"
  else
    value = encrypt_strings ? encrypt_value_strings(obj.value, obj.oid, obj.gen) : obj.value
    buffer << serialize(value)
    buffer << "\n"
  end
  buffer << "endobj\n"
  buffer.force_encoding(Encoding::BINARY)
end