# Copyright (c) 2007 ActiveState Software Inc.
# See the file LICENSE.txt for licensing information.

"""LangInfo definitions for some binary file types."""

from langinfo import LangInfo



class ELFLangInfo(LangInfo):
    """ELF-format binary (e.g. a standard executable on Linux)"""
    name = "ELF"

    # From '/usr/share/file/magic':
    #   0	string		\177ELF		ELF
    magic_numbers = [(0, 'string', '\177ELF')]

class ArchiveLibLangInfo(LangInfo):
    """Archive library (ar)"""
    name = "ar"
    exts = [".a"]
    magic_numbers = [(0, 'string', '!<arch>')]

class MachOUniversalLangInfo(LangInfo):
    name = "Mach-O universal"

    # See '/usr/share/file/magic' for the full details on collision
    # between compiled Java class data and Mach-O universal binaries and
    # the hack to distinguish them.
    #   0	belong		0xcafebabe
    #TODO: check with a 64-bit Mach-O universal
    magic_numbers = [(0, '>L', int('0xcafebabe', 16))]

class MachOLangInfo(LangInfo):
    name = "Mach-O"

    # From '/usr/share/file/magic':
    #   0	lelong&0xfffffffe	0xfeedface	Mach-O
    #   0	belong&0xfffffffe	0xfeedface	Mach-O
    # Note: We are not current handling the '&0xfffffffe'.
    #
    #TODO: check with a 64-bit Mach-O
    magic_numbers = [(0, '<L', int('0xfeedface', 16)),
                     (0, '>L', int('0xfeedface', 16))]

class WindowsExeLangInfo(LangInfo):
    name = "Windows executable"
    exts = [".exe", ".dll"]

    # From '/usr/share/file/magic':
    #   0	string	MZ		MS-DOS executable (EXE)
    magic_numbers = [(0, "string", "MZ")]

class CompiledJavaClassLangInfo(LangInfo):
    name = "compiled Java class"
    exts = [".class"]
    # See MachOUniversalLangInfo above. There is a collision in the
    # magic number of Mach-O universal binaries and Java .class files.
    # For now we rely on the '.class' extension to properly identify
    # before magic number checking is done.
    magic_numbers = None

class ZipLangInfo(LangInfo):
    name = "Zip archive"
    exts = [".zip"]
    magic_numbers = [(0, "string", "PK\003\004")]

class GZipLangInfo(LangInfo):
    name = "gzip archive"
    exts = [".gz", ".tgz"]
    magic_numbers = [(0, "string", "\037\213")]

class BZip2LangInfo(LangInfo):
    name = "bzip2 compressed data"
    exts = [".bz2"]
    magic_numbers = [(0, "string", "BZh")]

class MSILangInfo(LangInfo):
    """Microsoft Installer Package"""
    name = "MSI"
    exts = [".msi"]

class JarLangInfo(ZipLangInfo):
    name = "Jar archive"
    exts = [".jar"]

class IcoLangInfo(LangInfo):
    name = "Windows icon"
    exts = [".ico"]

class IcnsLangInfo(LangInfo):
    name = "Mac icon"
    exts = [".icns"]

class XPMLangInfo(LangInfo):
    name = "XPM"
    exts = [".xpm"]
    magic_numbers = [(0, "string", "/* XPM */")]

class PSDLangInfo(LangInfo):
    name = "Adobe Photoshop Document"
    exts = [".psd"]
    magic_numbers = [(0, "string", "8BPS")]

class PNGLangInfo(LangInfo):
    name = "PNG"
    exts = [".png"]
    magic_numbers = [(0, "string", "\x89PNG")]

class GIFLangInfo(LangInfo):
    name = "GIF"
    exts = [".gif"]
    magic_numbers = [(0, "string", "GIF8")]

class JPEGLangInfo(LangInfo):
    name = "JPEG"
    exts = [".jpg", ".jpeg"]
    # From '/usr/share/file/magic':
    #   0	beshort		0xffd8		JPEG image data
    magic_numbers = [(0, ">H", int("0xffd8", 16))]

class BMPLangInfo(LangInfo):
    name = "Bitmap image"
    exts = [".bmp"]
    magic_numbers = [(0, "string", "BM")]

class TIFFLangInfo(LangInfo):
    """TIFF image format"""
    name = "TIFF"
    exts = [".tiff", ".tif"]
    magic_numbers = [
        (0, "string", "MM\x00\x2a"), # TIFF image data, big-endian
        (0, "string", "II\x2a\x00"), # TIFF image data, little-endian
    ]

class DSStoreLangInfo(LangInfo):
    """Mac OS X filesystem directory metadata files."""
    name = "DSStore"
    filename_patterns = [".DS_Store"]

class BOMLangInfo(LangInfo):
    """Mac OS X/BSD 'Bill of Materials' file."""
    name = "BOM"
    exts = [".bom"]
    magic_numbers = [(0, "string", "BOMStore")]

class PDFLangInfo(LangInfo):
    name = "PDF"
    exts = [".pdf"]

class RIFFLangInfo(LangInfo):
    """Resource Interchange File Format -- a generic meta-format for
    storing data in tagged chunks.

    http://en.wikipedia.org/wiki/RIFF_(File_format)
    """
    name = "RIFF"
    magic_numbers = [
        (0, "string", "RIFX"),  # RIFF (big-endian) data
        (0, "string", "RIFF"),  # RIFF (little-endian) data
    ]

class WAVLangInfo(LangInfo):
    """Waveform (WAVE) Audio format"""
    name = "WAV"
    conforms_to_bases = ["RIFF"]
    exts = [".wav"]

class AVILangInfo(LangInfo):
    """Audio Video Interleave"""
    name = "AVI"
    conforms_to_bases = ["RIFF"]
    exts = [".avi"]


class MacHelpIndexLangInfo(LangInfo):
    """Mac OS X Help Index"""
    name = "Mac Help Index"
    exts = [".helpindex"]

class AppleBinaryPListLangInfo(LangInfo):
    name = "Apple Binary Property List"
    magic_numbers = [(0, "string", "bplist00")]

class MacOSXDiskImageLangInfo(LangInfo):
    name = "Mac OS X Disk Image"
    exts = [".dmg"]

class OggLangInfo(LangInfo):
    name = "Ogg data"
    exts = [".ogg"]
    magic_numbers = [(0, "string", "OggS")]

class FlashVideoLangInfo(LangInfo):
    """Macromedia Flash FLV Video File Format
   
    http://www.digitalpreservation.gov/formats/fdd/fdd000131.shtml
    """
    name = "Flash Video"
    exts = [".flv"]
    magic_numbers = [(0, "string", "FLV")]

class FlashSWFLangInfo(LangInfo):
    """Macromedia Flash SWF File Format
    
    http://www.digitalpreservation.gov/formats/fdd/fdd000248.shtml
    """
    name = "Flash SWF"
    exts = [".swf"]
    magic_numbers = [
        (0, "string", "FWS"),   # uncompressed
        (0, "string", "CWS"),   # compressed
    ]

class MP3LangInfo(LangInfo):
    """MPEG 1.0 Layer 3 audio encoding"""
    name = "MP3"
    exts = [".mp3"]
    magic_numbers = [
        (0, "string", "ID3"),  # MP3 file with ID3 version 2.
    ]

class MPEGLangInfo(LangInfo):
    """MPEG video"""
    name = "MPEG"
    exts = [".mpg", ".mpeg"]
    magic_numbers = [
        (0, '>L', int('0x000001b3', 16)),   # belong; MPEG video stream data
        (0, '>L', int('0x000001ba', 16)),   # belong; MPEG system stream data
    ]

class AACLangInfo(LangInfo):
    """MPEG-4 Advanced Audio Coding file"""
    name = "AAC"
    exts = [".m4a"]
    magic_numbers = [
        (16, "string", "M4A"),
    ]

class QuickTimeMovieLangInfo(LangInfo):
    """Apple QuickTime movie"""
    name = "QuickTime Movie"
    exts = [".mov"]
    # Note: Excluding these checks as an optimization and to avoid possible
    # false positives.
    #magic_numbers = [
    #    (4, "string", "moov"),
    #    (4, "string", "mdat"),
    #    (4, "string", "ftyp"),
    #    (4, "string", "free"),
    #    (4, "string", "junk"),
    #    (4, "string", "pnot"),
    #    (4, "string", "skip"),
    #    (4, "string", "wide"),
    #    (4, "string", "pict"),
    #]

class WindowsThumbnailCacheLangInfo(LangInfo):
    """Microsoft Windows directory thumbnail cache."""
    name = "Windows thumbnail cache"
    filename_patterns = ["Thumbs.db"]


class GettextMOLangInfo(LangInfo):
    """GNU Gettext message catalog

    http://www.gnu.org/software/gettext/manual/gettext.html#MO-Files
    """
    name = "GNU message catalog"
    exts = [".mo"]
    magic_numbers = [
        (0, "string", "\336\22\4\225"), # GNU message catalog (little endian)
        (0, "string", "\225\4\22\336"), # GNU message catalog (big endian),
    ]


class MSOfficeDocumentLangInfo(LangInfo):
    name = "MS Office Document"
    magic_numbers = [
        (0, "string", "\376\067\0\043"),
        (0, "string", "\320\317\021\340\241\261\032\341"),
        (0, "string", "\333\245-\0\0\0"),
    ]

class ExcelDocumentLangInfo(MSOfficeDocumentLangInfo):
    name = "MS Excel Document"
    exts = [".xls"]

class MSWordDocumentLangInfo(MSOfficeDocumentLangInfo):
    name = "MS Word Document"
    #TODO: consider extended 'specialization' facility to look at ext as well.
    # Can cause false positives for, e.g., a text document that uses '.doc'.
    #exts = [".doc"]


