Class: Fasttrack::File

Inherits:
Object
  • Object
show all
Defined in:
lib/fasttrack/file.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, mode = "r") ⇒ File

Instantiates a new Fasttrack::File object, which is a representation of a file on disk and its associated XMP metadata. To create a new file on disk you should use Fasttrack::XMP#to_s instead.

Parameters:

  • path (String)

    path to the file on disk; must exist

  • mode (String) (defaults to: "r")

    file mode; accepted values are “r” (read-only; default), “w” and “rw” (read-write)

Raises:



51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/fasttrack/file.rb', line 51

def initialize path, mode="r"
  @open = false
  @path = Pathname.new(path).expand_path
  if not @path.exist?
    raise Errno::ENOENT, "#{@path} does not exist"
  end

  @file_ptr = Exempi.xmp_files_new
  @read_mode = mode
  open @read_mode

  ObjectSpace.define_finalizer(self, self.class.finalize(@file_ptr))
end

Instance Attribute Details

#file_ptrFFI::Pointer (readonly)

The Exempi C pointer for this object. You normally shouldn’t need to access this, but it is exposed so that unwrapped Exempi functions can be called on Fasttrack-tracked objects.

Returns:

  • (FFI::Pointer)


15
16
17
# File 'lib/fasttrack/file.rb', line 15

def file_ptr
  @file_ptr
end

#pathPathname (readonly)

Returns:

  • (Pathname)


36
37
38
# File 'lib/fasttrack/file.rb', line 36

def path
  @path
end

#xmpFasttrack::XMP

The Fasttrack::XMP object associated with this file. You can replace it with another Fasttrack::XMP object.

Examples:

Replace an object’s XMP with the XMP from another file

file1.xmp = file2.xmp
file1.save!

Create a new XMP document and save it into a file

newxmp = Fasttrack::XMP.new
newxmp['tiff:Make'] = 'Sony'
file.xmp = newxmp
file.save!

Create a new XMP document manually, then add it to a File object

ptr = Exempi.xmp_new_empty
Exempi.xmp_set_property Fasttrack::NAMESPACES[:tiff],
  'tiff:Make', 'Sony', nil
file.xmp = ptr

Returns:



33
34
35
# File 'lib/fasttrack/file.rb', line 33

def xmp
  @xmp
end

Class Method Details

.finalize(pointer) ⇒ Object



38
39
40
# File 'lib/fasttrack/file.rb', line 38

def self.finalize pointer
  proc { Exempi.xmp_files_free pointer }
end

Instance Method Details

#can_put_xmp?(xmp = @xmp) ⇒ true, false

Checks to see whether XMP can be written to the current file. If no XMP is specified, the file’s associated XMP is used.

Parameters:

  • xmp (FFI::Pointer, Fasttrack::XMP) (defaults to: @xmp)

    XMP to check; can be a Fasttrack::XMP object or a pointer to a C XMP object

Returns:

  • (true, false)

Raises:

  • (TypeError)

    if an object without an XMP pointer is passed



72
73
74
75
76
77
78
79
80
# File 'lib/fasttrack/file.rb', line 72

def can_put_xmp? xmp=@xmp
  if xmp.is_a? Fasttrack::XMP
    xmp = xmp.xmp_ptr
  end

  raise TypeError, "#{xmp} is not a pointer" unless xmp.is_a? FFI::Pointer

  Exempi.xmp_files_can_put_xmp @file_ptr, xmp
end

#close!Boolean

Closes the current file and frees its memory. While this will not save changes made to the current XMP object, it still has the potential to make changes to the file being closed.

Returns:

  • (Boolean)

    true if successful

Raises:



127
128
129
130
131
132
133
134
135
136
# File 'lib/fasttrack/file.rb', line 127

def close!
  raise Fasttrack::WriteError, "file is already closed" unless @open

  @open = !Exempi.xmp_files_close(@file_ptr, :XMP_CLOSE_SAFEUPDATE)
  if @open # did not successfully close
    Fasttrack.handle_exempi_failure
  else
    true
  end
end

#open(mode = @read_mode) ⇒ Object

Reopens a closed Fasttrack::File object.

Parameters:

  • mode (String) (defaults to: @read_mode)

    file mode

Raises:

  • (Exempi::ExempiError)

    if Exempi reports an error while attempting to open the file

  • (Fasttrack::OpenError)

    if an opened file is reopened



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/fasttrack/file.rb', line 144

def open mode=@read_mode
  raise Fasttrack::OpenError, "file is already open" if @open

  case mode
  when 'r'
    open_option = :XMP_OPEN_READ
  when 'w', 'rw'
    open_option = :XMP_OPEN_FORUPDATE
  else
    open_option = :XMP_OPEN_NOOPTION
  end

  @open = Exempi.xmp_files_open @file_ptr, @path.to_s, open_option

  if not @open
    Exempi.xmp_files_free(@file_ptr)
    Fasttrack.handle_exempi_failure
  else
    @xmp = Fasttrack::XMP.from_file_pointer @file_ptr
  end

  @open
end

#save!Boolean

Save changes to a file. Exempi only saves changes when a file is closed; this method closes and then reopens the file so it can continue to be used. This always uses Exempi’s “safe close”, which writes into a temporary file and swap in case of unexpected termination.

Returns:

  • (Boolean)

    true if successful

Raises:



109
110
111
112
113
114
115
116
117
118
119
# File 'lib/fasttrack/file.rb', line 109

def save!
  if @read_mode == "r"
    raise Fasttrack::WriteError, "file opened read-only"
  end

  raise Fasttrack::WriteError, "file is closed" unless @open
  # Make sure we let Exempi know there's new XMP to write
  Exempi.xmp_files_put_xmp @file_ptr, @xmp.xmp_ptr
  close!
  open @read_mode
end