[Crossplatfom] Get Mime Type for Windows or Linux
Posted: Sat Jul 26, 2008 2:21 am
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")