Page 1 of 1

[Crossplatfom] Get Mime Type for Windows or Linux

Posted: Sat Jul 26, 2008 2:21 am
by Straker
The Windows code was originally Kale's, but I needed a solution for Linux for an SMTP project, so I wrote one and bundled it with the Windows code.

Code: Select all

EnableExplicit
   
Procedure.s GetMimeType(pExt.s)
  ; Cross-Platform
  ; Windows code originally by Kale
  ; Linux code by Straker
  ;
  ; returns as default "application/octet-stream" if Mime Type is not found.
  ;
  Enumeration
    #MimeFile
  EndEnumeration

  Protected lRetVal.s, lMimeFile.s, lContinue.l
  Protected hKey.l, lKeyValue.s, lDataSize.l, lLoop.l
  Protected lLof.l, *lMemoryID.l, lBytesRead.l, lFileContents.s
  Protected lPos1.l, lPos2.l, lMimeLen.l, lMyChar.s, lDefault.s
  
  Protected Dim lExt.s(7)
  
  lContinue.l = 1
  lDefault.s = "application/octet-stream"
  
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Windows
    
      pExt.s = ("." + pExt.s)
      hKey.l = 0
      lKeyValue.s = Space(255)
      lDataSize.l = 255
      If (RegOpenKeyEx_(#HKEY_CLASSES_ROOT, pExt.s, 0, #KEY_READ, @hKey))
        lKeyValue.s = lDefault.s
      Else
        If RegQueryValueEx_(hKey, "Content Type", 0, 0, @lKeyValue, @lDataSize)
          lKeyValue.s = lDefault.s
        Else
          lKeyValue.s = Left(lKeyValue.s, (lDataSize.l - 1))
        EndIf
        RegCloseKey_(hKey)
      EndIf
      lRetVal.s = lKeyValue.s
      
    CompilerCase #PB_OS_Linux
      
      pExt.s = LCase(pExt.s)
      lRetVal.s = lDefault.s
      lMimeFile.s = "/etc/mime.types"
      lPos1.l = 0
      lPos2.l = 0
      lMimeLen.l = 0

      If (ReadFile(#MimeFile, lMimeFile.s))
        lLof.l = Lof(#MimeFile)
        *lMemoryID.l = AllocateMemory(lLof.l)
        If (*lMemoryID.l)
          lBytesRead.l = ReadData(#MimeFile, *lMemoryID.l, lLof.l)
          lFileContents.s = PeekS(*lMemoryID.l, lLof.l, #PB_UTF8)
          CloseFile(#MimeFile)
        Else
          lContinue.l = 0
        EndIf
      Else
        lContinue.l = 0
      EndIf
    
      If (lContinue.l = 1)
        ; find the extension in the /etc/mime.types file
        
        lExt.s(0) = (Space(1)+pExt.s+Space(1))
        lExt.s(1) = (Chr(9)+pExt.s+Chr(10))
        lExt.s(2) = (Chr(9)+pExt.s+Space(1))
        lExt.s(3) = (Chr(9)+pExt.s+Chr(9))
        lExt.s(4) = (Chr(9)+pExt.s)
        lExt.s(5) = (Space(1)+pExt.s+Chr(10))
        lExt.s(6) = (Space(1)+pExt.s+Chr(9))
        lExt.s(7) = (Space(1)+pExt.s)

        lContinue.l = 0
        
        For lLoop.l = 0 To 7 Step 1
          lPos1.l = FindString(lFileContents.s, lExt.s(lLoop.l), 1)
          If (lPos1.l > 0)
            lContinue.l = 1
            Break
          EndIf
        Next
        
      EndIf

      If (lContinue.l = 1)
        ; found the line - parse the mime type...
        For lLoop.l = 1 To 80 Step 1
          If (Mid(lFileContents.s, (lPos1.l - lLoop.l), 1) = Chr(10))
            lPos2.l = (lPos1.l - lLoop.l + 1)
            Break
          EndIf
        Next
      EndIf
      
      If (lPos2.l > 0)
        For lLoop.l = 1 To 80 Step 1
          lMyChar.s = Mid(lFileContents.s, (lPos2.l + lLoop.l), 1)
          If ((lMyChar.s = Chr(9)) Or (lMyChar.s = " "))
            lMimeLen.l = lLoop.l
            Break
          EndIf
        Next
      EndIf
      
      If (lMimeLen.l > 0)
        lRetVal.s = Trim(Mid(lFileContents.s, lPos2.l, lMimeLen.l))
        If (Left(lRetVal.s, 1) = "#")
          lRetVal.s = lDefault.s
        EndIf
      EndIf
      
      FreeMemory(*lMemoryID.l)
      
  CompilerEndSelect
  
  ProcedureReturn lRetVal.s
EndProcedure

Debug GetMimeType("bmp")
Debug GetMimeType("gif")
Debug GetMimeType("ai")
Debug GetMimeType("jpg")
Debug GetMimeType("ogg")
Debug GetMimeType("tiff")

Posted: Sat Jul 26, 2008 2:19 pm
by Kale
nice!

Posted: Sat Jul 26, 2008 9:33 pm
by ts-soft
:D very usefull

only the fileoperation should use #PB_Any, i think

greetings
Thomas