Skip to content

Instantly share code, notes, and snippets.

@Svenskunganka
Created February 5, 2018 18:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Svenskunganka/4e18d9d8183d2b68ba3b140ceaa5e93f to your computer and use it in GitHub Desktop.
Save Svenskunganka/4e18d9d8183d2b68ba3b140ceaa5e93f to your computer and use it in GitHub Desktop.
Crystal class reopening issue
require "./audio"
class Filetype
def self.match(slice : Bytes) : (self.class | Nil)
classes = self.subclasses
classes.each do |obj|
result = obj.match(slice)
print "#{obj} returned #{result.nil? ? "nil" : result}\n"
return result if result != nil
end
nil
end
def self.subclasses
{% if @type.subclasses.empty? %}
arr = [] of NoReturn
{% else %}
arr = {{@type.subclasses}}
{% end %}
end
end
slice = Bytes[0x4D, 0x54, 0x68, 0x64]
filetype = Filetype.match(slice)
case filetype
when Filetype::Audio.class
puts "is an audio"
else
puts "other"
end
require "./audio"
require "./archive"
class Filetype
def self.match(slice : Bytes) : (self.class | Nil)
classes = self.subclasses
classes.each do |obj|
result = obj.match(slice)
print "#{obj} returned #{result.nil? ? "nil" : result}\n"
return result if result != nil
end
nil
end
def self.subclasses
{% if @type.subclasses.empty? %}
arr = [] of NoReturn
{% else %}
arr = {{@type.subclasses}}
{% end %}
end
end
slice = Bytes[0x4D, 0x54, 0x68, 0x64]
filetype = Filetype.match(slice)
case filetype
when Filetype::Audio.class
puts "is an audio"
else
puts "other"
end
class Filetype
class Archive < Filetype
class Epub < Archive
def self.match(slice)
return self if slice.size > 57 &&
slice[0] == 0x50 && slice[1] == 0x4B && slice[2] == 0x3 && slice[3] == 0x4 &&
slice[30] == 0x6D && slice[31] == 0x69 && slice[32] == 0x6D && slice[33] == 0x65 &&
slice[34] == 0x74 && slice[35] == 0x79 && slice[36] == 0x70 && slice[37] == 0x65 &&
slice[38] == 0x61 && slice[39] == 0x70 && slice[40] == 0x70 && slice[41] == 0x6C &&
slice[42] == 0x69 && slice[43] == 0x63 && slice[44] == 0x61 && slice[45] == 0x74 &&
slice[46] == 0x69 && slice[47] == 0x6F && slice[48] == 0x6E && slice[49] == 0x2F &&
slice[50] == 0x65 && slice[51] == 0x70 && slice[52] == 0x75 && slice[53] == 0x62 &&
slice[54] == 0x2B && slice[55] == 0x7A && slice[56] == 0x69 && slice[57] == 0x70
nil
end
end
class Zip < Archive
def self.match(slice)
return self if slice.size > 3 &&
slice[0] == 0x50 && slice[1] == 0x4B &&
(slice[2] == 0x3 || slice[2] == 0x5 || slice[2] == 0x7) &&
(slice[3] == 0x4 || slice[3] == 0x6 || slice[3] == 0x8)
nil
end
end
class Tar < Archive
def self.match(slice)
return self if slice.size > 261 &&
slice[257] == 0x75 && slice[258] == 0x73 &&
slice[259] == 0x74 && slice[260] == 0x61 &&
slice[261] == 0x72
nil
end
end
class Rar < Archive
def self.match(slice)
return self if slice.size > 6 &&
slice[0] == 0x52 && slice[1] == 0x61 && slice[2] == 0x72 &&
slice[3] == 0x21 && slice[4] == 0x1A && slice[5] == 0x7 &&
(slice[6] == 0x0 || slice[6] == 0x1)
nil
end
end
class Gz < Archive
def self.match(slice)
return self if slice.size > 2 &&
slice[0] == 0x1F && slice[1] == 0x8B && slice[2] == 0x8
nil
end
end
class Bz2 < Archive
def self.match(slice)
return self if slice.size > 2 &&
slice[0] == 0x42 && slice[1] == 0x5A && slice[2] == 0x68
nil
end
end
class Sevenz < Archive
def self.match(slice)
return self if slice.size > 5 &&
slice[0] == 0x37 && slice[1] == 0x7A && slice[2] == 0xBC &&
slice[3] == 0xAF && slice[4] == 0x27 && slice[5] == 0x1C
nil
end
end
class Pdf < Archive
def self.match(slice)
return self if slice.size > 3 &&
slice[0] == 0x25 && slice[1] == 0x50 &&
slice[2] == 0x44 && slice[3] == 0x46
nil
end
end
class Exe < Archive
def self.match(slice)
return self if slice.size > 1 &&
slice[0] == 0x4D && slice[1] == 0x5A
nil
end
end
class Swf < Archive
def self.match(slice)
return self if slice.size > 2 &&
(slice[0] == 0x43 || slice[0] == 0x46) &&
slice[1] == 0x57 && slice[2] == 0x53
nil
end
end
class Rtf < Archive
def self.match(slice)
return self if slice.size > 4 &&
slice[0] == 0x7B && slice[1] == 0x5C &&
slice[2] == 0x72 && slice[3] == 0x74 &&
slice[4] == 0x66
nil
end
end
class Nes < Archive
def self.match(slice)
return self if slice.size > 3 &&
slice[0] == 0x4E && slice[1] == 0x45 &&
slice[2] == 0x53 && slice[3] == 0x1A
nil
end
end
class Crx < Archive
def self.match(slice)
return self if slice.size > 3 &&
slice[0] == 0x43 && slice[1] == 0x72 &&
slice[2] == 0x32 && slice[3] == 0x34
nil
end
end
class Cab < Archive
def self.match(slice)
return self if slice.size > 3 &&
((slice[0] == 0x4D && slice[1] == 0x53 && slice[2] == 0x43 && slice[3] == 0x46) ||
(slice[0] == 0x49 && slice[1] == 0x53 && slice[2] == 0x63 && slice[3] == 0x28))
nil
end
end
class Eot < Archive
def self.match(slice)
return self if slice.size > 35 &&
slice[34] == 0x4C && slice[35] == 0x50 &&
((slice[8] == 0x02 && slice[9] == 0x00 &&
slice[10] == 0x01) || (slice[8] == 0x01 &&
slice[9] == 0x00 && slice[10] == 0x00) ||
(slice[8] == 0x02 && slice[9] == 0x00 &&
slice[10] == 0x02))
nil
end
end
class Ps < Archive
def self.match(slice)
return self if slice.size > 1 &&
slice[0] == 0x25 && slice[1] == 0x21
nil
end
end
class Xz < Archive
def self.match(slice)
return self if slice.size > 5 &&
slice[0] == 0xFD && slice[1] == 0x37 &&
slice[2] == 0x7A && slice[3] == 0x58 &&
slice[4] == 0x5A && slice[5] == 0x00
nil
end
end
class Sqlite < Archive
def self.match(slice)
return self if slice.size > 3 &&
slice[0] == 0x53 && slice[1] == 0x51 &&
slice[2] == 0x4C && slice[3] == 0x69
nil
end
end
class Deb < Archive
def self.match(slice)
return self if slice.size > 20 &&
slice[0] == 0x21 && slice[1] == 0x3C && slice[2] == 0x61 &&
slice[3] == 0x72 && slice[4] == 0x63 && slice[5] == 0x68 &&
slice[6] == 0x3E && slice[7] == 0x0A && slice[8] == 0x64 &&
slice[9] == 0x65 && slice[10] == 0x62 && slice[11] == 0x69 &&
slice[12] == 0x61 && slice[13] == 0x6E && slice[14] == 0x2D &&
slice[15] == 0x62 && slice[16] == 0x69 && slice[17] == 0x6E &&
slice[18] == 0x61 && slice[19] == 0x72 && slice[20] == 0x79
nil
end
end
class Ar < Archive
def self.match(slice)
return self if slice.size > 6 &&
slice[0] == 0x21 && slice[1] == 0x3C &&
slice[2] == 0x61 && slice[3] == 0x72 &&
slice[4] == 0x63 && slice[5] == 0x68 &&
slice[6] == 0x3E
nil
end
end
class Z < Archive
def self.match(slice)
return self if slice.size > 1 &&
((slice[0] == 0x1F && slice[1] == 0xA0) ||
(slice[0] == 0x1F && slice[1] == 0x9D))
nil
end
end
class Lz < Archive
def self.match(slice)
return self if slice.size > 3 &&
slice[0] == 0x4C && slice[1] == 0x5A &&
slice[2] == 0x49 && slice[3] == 0x50
nil
end
end
class Rpm < Archive
def self.match(slice)
return self if slice.size > 3 &&
slice[0] == 0xED && slice[1] == 0xAB &&
slice[2] == 0xEE && slice[3] == 0xDB
nil
end
end
class Elf < Archive
def self.match(slice)
return self if slice.size > 3 &&
slice[0] == 0x7F && slice[1] == 0x45 &&
slice[2] == 0x4C && slice[3] == 0x46
nil
end
end
end
end
class Filetype
class Audio < Filetype
class Midi < Audio
def self.match(slice)
return self if slice.size > 3 &&
slice[0] == 0x4D && slice[1] == 0x54 &&
slice[2] == 0x68 && slice[3] == 0x64
nil
end
end
class Mp3 < Audio
def self.match(slice)
return self if slice.size > 2 &&
((slice[0] == 0x49 && slice[1] == 0x44 && slice[2] == 0x33) ||
(slice[0] == 0xFF && slice[1] == 0xFB))
nil
end
end
class M4a < Audio
def self.match(slice)
return self if slice.size > 10 &&
((slice[4] == 0x66 && slice[5] == 0x74 && slice[6] == 0x79 &&
slice[7] == 0x70 && slice[8] == 0x4D && slice[9] == 0x34 && slice[10] == 0x41) ||
(slice[0] == 0x4D && slice[1] == 0x34 && slice[2] == 0x41 && slice[3] == 0x20))
nil
end
end
class Ogg < Audio
def self.match(slice)
return self if slice.size > 3 &&
slice[0] == 0x4F && slice[1] == 0x67 &&
slice[2] == 0x67 && slice[3] == 0x53
nil
end
end
class Flac < Audio
def self.match(slice)
return self if slice.size > 3 &&
slice[0] == 0x66 && slice[1] == 0x4C &&
slice[2] == 0x61 && slice[3] == 0x43
nil
end
end
class Wav < Audio
def self.match(slice)
return self if slice.size > 11 &&
slice[0] == 0x52 && slice[1] == 0x49 &&
slice[2] == 0x46 && slice[3] == 0x46 &&
slice[8] == 0x57 && slice[9] == 0x41 &&
slice[10] == 0x56 && slice[11] == 0x45
nil
end
end
class Amr < Audio
def self.match(slice)
return self if slice.size > 11 &&
slice[0] == 0x23 && slice[1] == 0x21 &&
slice[2] == 0x41 && slice[3] == 0x4D &&
slice[4] == 0x52 && slice[5] == 0x0A
nil
end
end
end
end
diff --git a/1.cr b/2.cr
index 55da586..6b94d9c 100644
--- a/1.cr
+++ b/2.cr
@@ -1,4 +1,5 @@
require "./audio"
+require "./archive"
class Filetype
def self.match(slice : Bytes) : (self.class | Nil)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment