Class: Omnizip::Buffer::MemoryExtractor

Inherits:
Object
  • Object
show all
Defined in:
lib/omnizip/buffer/memory_extractor.rb

Overview

Extract archive contents to memory

Provides efficient extraction of archive entries to Hash without loading all files at once. Uses lazy evaluation where possible.

Examples:

Extract all files

extractor = MemoryExtractor.new(zip_data)
files = extractor.extract_all
# => {"file1.txt" => "content1", "file2.txt" => "content2"}

Extract single file

extractor = MemoryExtractor.new(zip_data)
content = extractor.extract_entry('file1.txt')
# => "content1"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data, format: nil) ⇒ MemoryExtractor

Initialize extractor

Examples:

Create extractor

extractor = MemoryExtractor.new(zip_data)
extractor = MemoryExtractor.new(zip_buffer, format: :zip)

Parameters:

  • data (String, StringIO)

    Archive data

  • format (Symbol, nil) (defaults to: nil)

    Archive format (auto-detected if nil)



32
33
34
35
36
# File 'lib/omnizip/buffer/memory_extractor.rb', line 32

def initialize(data, format: nil)
  @buffer = data.is_a?(StringIO) ? data : StringIO.new(data.b)
  @format = format || detect_format
  @extracted_cache = {}
end

Instance Attribute Details

#formatObject (readonly)

Returns the value of attribute format.



22
23
24
# File 'lib/omnizip/buffer/memory_extractor.rb', line 22

def format
  @format
end

Instance Method Details

#entry_countInteger

Get total number of entries

Returns:

  • (Integer)

    Number of entries



125
126
127
# File 'lib/omnizip/buffer/memory_extractor.rb', line 125

def entry_count
  list_entries.size
end

#entry_exists?(name) ⇒ Boolean

Check if entry exists in archive

Examples:

Check existence

extractor.entry_exists?('file.txt')  # => true

Parameters:

  • name (String)

    Entry name

Returns:

  • (Boolean)

    True if entry exists



118
119
120
# File 'lib/omnizip/buffer/memory_extractor.rb', line 118

def entry_exists?(name)
  list_entries.include?(name)
end

#extract_allHash<String, String>

Extract all entries to Hash

Examples:

Extract everything

files = extractor.extract_all
files.keys  # => ["file1.txt", "file2.txt", "dir/file3.txt"]

Returns:

  • (Hash<String, String>)

    Filename => content mapping



45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/omnizip/buffer/memory_extractor.rb', line 45

def extract_all
  result = {}

  case @format
  when :zip
    extract_all_zip(result)
  when :seven_zip, :"7z"
    raise NotImplementedError, "7z format support coming in Phase 2"
  else
    raise ArgumentError, "Unsupported format: #{@format}"
  end

  result
end

#extract_entry(name) ⇒ String?

Extract single entry by name

Examples:

Extract specific file

content = extractor.extract_entry('readme.txt')
# => "Hello World"

Parameters:

  • name (String)

    Entry name to extract

Returns:

  • (String, nil)

    Entry content or nil if not found



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/omnizip/buffer/memory_extractor.rb', line 68

def extract_entry(name)
  # Check cache first
  return @extracted_cache[name] if @extracted_cache.key?(name)

  # Extract from archive
  content = nil

  case @format
  when :zip
    content = extract_entry_zip(name)
  when :seven_zip, :"7z"
    raise NotImplementedError, "7z format support coming in Phase 2"
  else
    raise ArgumentError, "Unsupported format: #{@format}"
  end

  # Cache the result
  @extracted_cache[name] = content if content
  content
end

#extract_matching(pattern) ⇒ Hash<String, String>

Extract entries matching pattern

Examples:

Extract by pattern

extractor.extract_matching(/\.txt$/)
# => {"file1.txt" => "content1", "file2.txt" => "content2"}

Parameters:

  • pattern (Regexp, String)

    Pattern to match

Returns:

  • (Hash<String, String>)

    Matching entries



137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/omnizip/buffer/memory_extractor.rb', line 137

def extract_matching(pattern)
  pattern = Regexp.new(pattern) if pattern.is_a?(String)
  result = {}

  list_entries.each do |name|
    next unless name&.match?(pattern)
    next if name.end_with?("/") # Skip directories

    content = extract_entry(name)
    result[name] = content if content
  end

  result
end

#list_entriesArray<String>

List all entry names without extracting

Examples:

List files

extractor.list_entries
# => ["file1.txt", "dir/", "dir/file2.txt"]

Returns:

  • (Array<String>)

    Entry names



96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/omnizip/buffer/memory_extractor.rb', line 96

def list_entries
  names = []

  case @format
  when :zip
    list_entries_zip(names)
  when :seven_zip, :"7z"
    raise NotImplementedError, "7z format support coming in Phase 2"
  else
    raise ArgumentError, "Unsupported format: #{@format}"
  end

  names
end