Class: LibMsPack::MsCab::MsCabDecompressor

Inherits:
FFI::Struct
  • Object
show all
Defined in:
lib/libmspack/mscab.rb

Overview

CAB decompressor

Instance Method Summary collapse

Instance Method Details

#append(decompressor, cab, nextcab) ⇒ Fixnum

Appends one MsCabdCabinet to another, forming or extending a cabinet set.

This will attempt to append one cabinet to another such that (cab.nextcab == nextcab) && (nextcab.prevcab == cab) and any folders split between the two cabinets are merged.

The cabinets MUST be part of a cabinet set -- a cabinet set is a cabinet that spans more than one physical cabinet file on disk -- and must be appropriately matched.

It can be determined if a cabinet has further parts to load by examining the MsCabdCabinet.flags field:

  • if (flags & MSCAB_HDR_PREVCAB) is non-zero, there is a predecessor cabinet to #open and #prepend. Its MS-DOS case-insensitive filename is MsCabdCabinet.prevname
  • if (flags & MSCAB_HDR_NEXTCAB) is non-zero, there is a successor cabinet to #open and #append. Its MS-DOS case-insensitive filename is MsCabdCabinet.nextname

If the cabinets do not match, an error code will be returned. Neither cabinet has been altered, and both should be closed seperately.

Files and folders in a cabinet set are a single entity. All cabinets in a set use the same file list, which is updated as cabinets in the set are added.

Parameters:

  • decompressor (MsCabDecompressor)

    MsCabDecompressor instance being called

  • cab (MsCabdCabinet)

    the cabinet which will be appended to, predecessor of nextcab

  • nextcab (MsCabdCabinet)

    the cabinet which will be appended, successor of cab

Returns:

  • (Fixnum)

    an error code, or MSPACK_ERR_OK if successful

See Also:



462
463
464
# File 'lib/libmspack/mscab.rb', line 462

def append(decompressor, cab, nextcab)
    self[:append].call(decompressor, cab, nextcab)
end

#close(decompressor, cabinet) ⇒ Object

Closes a previously opened cabinet or cabinet set.

This closes a cabinet, all cabinets associated with it via the MsCabdCabinet#next, MsCabdCabinet#prevcab and MsCabdCabinet#nextcab, and all folders and files. All memory used by these entities is freed.

The cabinet is now invalid and cannot be used again. All MsCabdFolder and MsCabdFile from that cabinet or cabinet set are also now invalid, and cannot be used again.

If the cabinet given was created using #search, it MUST be the cabinet returned by #search and not one of the later cabinet pointers further along the MsCabdCabinet::next chain.

If extra cabinets have been added using #append or #prepend, these will all be freed, even if the cabinet given is not the first cabinet in the set. Do NOT #close more than one cabinet in the set.

Parameters:

See Also:



412
413
414
# File 'lib/libmspack/mscab.rb', line 412

def close(decompressor, cabinet)
    self[:close].call(decompressor, cabinet)
end

#extract(decompressor, cabfile, filename) ⇒ Fixnum

Extracts a file from a cabinet or cabinet set.

This extracts a compressed file in a cabinet and writes it to the given filename.

The MS-DOS filename of the file, MsCabdCabinet.filename, is NOT USED by #extract. The caller must examine this MS-DOS filename, copy and change it as necessary, create directories as necessary, and provide the correct filename as a parameter, which will be passed unchanged to the decompressor's MsPackSystem#open

If the file belongs to a split folder in a multi-part cabinet set, and not enough parts of the cabinet set have been loaded and appended or prepended, an error will be returned immediately.

Parameters:

  • decompressor (MsCabDecompressor)

    MsCabDecompressor instance being called

  • cabfile (MsCabdFile)

    the file to be decompressed

  • filename (String)

    the filename of the file being written to

Returns:

  • (Fixnum)

    an error code, or MSPACK_ERR_OK if successful



494
495
496
# File 'lib/libmspack/mscab.rb', line 494

def extract(decompressor, cabfile, filename)
    self[:extract].call(decompressor, cabfile, filename)
end

#last_error(decompressor) ⇒ Fixnum

Returns the error code set by the most recently called method

Parameters:

Returns:

  • (Fixnum)

    the most recent error code

See Also:



520
521
522
# File 'lib/libmspack/mscab.rb', line 520

def last_error(decompressor)
    self[:last_error].call(decompressor)
end

#open(decompressor, filename) ⇒ MsCabdCabinet?

Opens a cabinet file and reads its contents.

If the file opened is a valid cabinet file, all headers will be read and a MsCabdCabinet structure will be returned, with a full list of folders and files.

In the case of an error occuring, nil is returned and the error code is available from #last_error

Parameters:

  • decompressor (MsCabDecompressor)

    MsCabDecompressor instance being called

  • filename (String)

    name of the cabinet file

Returns:

See Also:



392
393
394
# File 'lib/libmspack/mscab.rb', line 392

def open(decompressor, filename)
    self[:open].call(decompressor, filename)
end

#prepend(decompressor, cab, prevcab) ⇒ Object

Prepends one MsCabdCabinet to another, forming or extending a cabinet set.

This will attempt to prepend one cabinet to another, such that (cab.prevcab == prevcab) && (prevcab.nextcab == cab). In all other respects, it is identical to #append.

Parameters:

  • decompressor (MsCabDecompressor)

    MsCabDecompressor instance being called

  • cab (MsCabdCabinet)

    the cabinet which will be prepended to, successor of prevcab

  • prevcab (MsCabdCabinet)

    the cabinet which will be prepended, predecessor of cab

See Also:



478
479
480
# File 'lib/libmspack/mscab.rb', line 478

def prepend(decompressor, cab, prevcab)
    self[:prepend].call(decompressor, cab, prevcab)
end

#search(decompressor, filename) ⇒ MsCabdCabinet?

Searches a regular file for embedded cabinets.

This opens a normal file with the given filename and will search the entire file for embedded cabinet files

If any cabinets are found, the equivalent of #open is called on each potential cabinet file at the offset it was found. All successfully #open'ed cabinets are kept in a list.

The first cabinet found will be returned directly as the result of this method. Any further cabinets found will be chained in a list using the MsCabdCabinet#next field.

In the case of an error occuring anywhere other than the simulated #open, nil is returned and the error code is available from #last_error

If no error occurs, but no cabinets can be found in the file, nil is returned and #last_error returns MSPACK_ERR_OK

#close should only be called on the result of #search, not on any subsequent cabinets in the MsCabdCabinet#next chain.

Parameters:

  • decompressor (MsCabDecompressor)

    MsCabDecompressor instance being called

  • filename (String)

    the filename of the file to search for cabinets

Returns:

See Also:



436
437
438
# File 'lib/libmspack/mscab.rb', line 436

def search(decompressor, filename)
    self[:search].call(decompressor, filename)
end

#set_param(decompressor, param, value) ⇒ Object

Sets a CAB decompression engine parameter.

The following parameters are defined:

  • MSCABD_PARAM_SEARCHBUF: How many bytes should be allocated as a buffer when using #search ? The minimum value is 4. The default value is 32768.
  • MSCABD_PARAM_FIXMSZIP: If non-zero, #extract will ignore bad checksums and recover from decompression errors in MS-ZIP compressed folders. The default value is 0 (don't recover).
  • MSCABD_PARAM_DECOMPBUF: How many bytes should be used as an input bit buffer by decompressors? The minimum value is 4. The default value is 4096.

Parameters:

  • decompressor (MsCabDecompressor)

    MsCabDecompressor instance being called

  • param (Fixnum)

    the parameter to set

  • value (Fixnum)

    the value to set the parameter to

See Also:



511
512
513
# File 'lib/libmspack/mscab.rb', line 511

def set_param(decompressor, param, value)
    self[:set_param].call(decompressor, param, value)
end