-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompression.rb
129 lines (112 loc) · 3.29 KB
/
compression.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# Copyright (c) 2025 Tom Lahti
# MIT License
module AESCompression
@algorithms = {}
@default_algorithm = nil
# Compression algorithm identifiers for serialization
ALGORITHM_IDS = {
nil => 0, # No compression
:zstd => 1,
:snappy => 2,
:lz4 => 3
}.freeze
ID_TO_ALGORITHM = ALGORITHM_IDS.invert.freeze
# Try to load zstd with platform-specific support
begin
if defined?(JRUBY_VERSION)
require 'zstandard-ruby'
@algorithms[:zstd] = {
compress: ->(data) { Zstandard.compress(data) },
decompress: ->(data) { Zstandard.decompress(data) }
}
@default_algorithm = :zstd
else
require 'zstd-ruby'
@algorithms[:zstd] = {
compress: ->(data) { Zstd.compress(data) },
decompress: ->(data) { Zstd.decompress(data) }
}
@default_algorithm = :zstd
end
rescue LoadError
# zstd not available
end
# Try to load snappy with platform-specific support
begin
if defined?(JRUBY_VERSION)
require 'jruby-snappy'
@algorithms[:snappy] = {
compress: ->(data) { Snappy.deflate(data) },
decompress: ->(data) { Snappy.inflate(data) }
}
else
require 'snappy'
@algorithms[:snappy] = {
compress: ->(data) { Snappy.deflate(data) },
decompress: ->(data) { Snappy.inflate(data) }
}
end
@default_algorithm ||= :snappy
rescue LoadError
# snappy not available
end
# Try to load lz4 with platform-specific support
begin
if defined?(JRUBY_VERSION)
require 'jruby-lz4'
@algorithms[:lz4] = {
compress: ->(data) { LZ4::compress(data) },
decompress: ->(data) { LZ4::uncompress(data, data.bytesize * 3) } # Estimate output size
}
else
require 'lz4-ruby'
@algorithms[:lz4] = {
compress: ->(data) { LZ4.compress(data) },
decompress: ->(data) { LZ4.decompress(data) }
}
end
@default_algorithm ||= :lz4
rescue LoadError
# lz4 not available
end
def self.available_algorithms
@algorithms.keys
end
def self.algorithm_available?(algorithm)
@algorithms.key?(algorithm)
end
def self.default_algorithm
@default_algorithm
end
def self.compress(data, algorithm = nil)
return [data, nil] unless data && !data.empty?
algorithm ||= @default_algorithm
return [data, nil] unless algorithm && @algorithms[algorithm]
begin
compressed = @algorithms[algorithm][:compress].call(data)
[compressed, algorithm]
rescue => e
# Fallback to uncompressed data on error
[data, nil]
end
end
def self.decompress(data, algorithm)
return data unless data && !data.empty? && algorithm
# Check if algorithm is a valid symbol we recognize
unless ID_TO_ALGORITHM.values.include?(algorithm)
raise "Unknown compression algorithm identifier: #{algorithm}"
end
# Check if the algorithm is available
unless @algorithms[algorithm]
raise "Compression algorithm #{algorithm} required but not available. Please install the required gem."
end
begin
@algorithms[algorithm][:decompress].call(data)
rescue => e
raise "Error decompressing data: #{e.message}. The #{algorithm} library may not be installed correctly."
end
end
def self.enabled?
end
end