782 lines
43 KiB
C
782 lines
43 KiB
C
/*
|
|
* TIP MIME functions
|
|
*
|
|
* Copyright 2003 Giancarlo Niccolai <gian@niccolai.ws>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; see the file LICENSE.txt. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301 USA (or visit https://www.gnu.org/licenses/).
|
|
*
|
|
* As a special exception, the Harbour Project gives permission for
|
|
* additional uses of the text contained in its release of Harbour.
|
|
*
|
|
* The exception is that, if you link the Harbour libraries with other
|
|
* files to produce an executable, this does not by itself cause the
|
|
* resulting executable to be covered by the GNU General Public License.
|
|
* Your use of that executable is in no way restricted on account of
|
|
* linking the Harbour library code into it.
|
|
*
|
|
* This exception does not however invalidate any other reasons why
|
|
* the executable file might be covered by the GNU General Public License.
|
|
*
|
|
* This exception applies only to the code released by the Harbour
|
|
* Project under the name Harbour. If you copy code from other
|
|
* Harbour Project or Free Software Foundation releases into a copy of
|
|
* Harbour, as the General Public License permits, the exception does
|
|
* not apply to the code that you add in this way. To avoid misleading
|
|
* anyone as to the status of such modified files, you must delete
|
|
* this exception notice from them.
|
|
*
|
|
* If you write modifications of your own for Harbour, it is your choice
|
|
* whether to permit this exception to apply to your modifications.
|
|
* If you do not wish that, delete this exception notice.
|
|
*
|
|
*/
|
|
|
|
/* TODO: move to core and rename:
|
|
tip_FileMimeType() -> hb_mimeFile()
|
|
tip_FileNameMimeType() -> hb_mimeFName()
|
|
tip_MimeType() -> hb_mimeStr() */
|
|
|
|
#include "hbapi.h"
|
|
#include "hbapiitm.h"
|
|
#include "hbapierr.h"
|
|
#include "hbapifs.h"
|
|
|
|
/* Detects the MIME type of a given file */
|
|
|
|
typedef struct tag_mime
|
|
{
|
|
HB_SIZE pos; /* Position in stream from which the match begins */
|
|
const char * pattern; /* String to match */
|
|
const char * mime_type; /* MIME type if complete */
|
|
int next; /* following entry to determine a MIME type, relative to current position (or 0) */
|
|
int alternate; /* alternative entry to determine a MIME type, relative to current position (or 0) */
|
|
short unsigned int flags; /* flags for confrontation */
|
|
} MIME_ENTRY;
|
|
|
|
#define MIME_FLAG_CASESENS 0x0000
|
|
#define MIME_FLAG_TRIMSPACES 0x0001
|
|
#define MIME_FLAG_TRIMTABS 0x0002
|
|
#define MIME_FLAG_CASEINSENS 0x0004
|
|
#define MIME_FLAG_CONTINUE 0x0008
|
|
|
|
static const MIME_ENTRY s_mimeTable[] =
|
|
{
|
|
/* MS-DOS/Windows executable */
|
|
/* 0 */ { 0, "MZ", "application/x-dosexec", 0, 0, 0 },
|
|
|
|
/* ELF file */
|
|
/* 1 */ { 0, "\177ELF", NULL, 1, 0, 0 },
|
|
/* 2 */ { 4, "\x00", NULL, 3, 1, MIME_FLAG_CONTINUE },
|
|
/* 3 */ { 4, "\x01", NULL, 2, 1, MIME_FLAG_CONTINUE },
|
|
/* 4 */ { 4, "\x02", NULL, 1, 0, MIME_FLAG_CONTINUE },
|
|
/* 5 */ { 5, "\x00", NULL, 2, 1, MIME_FLAG_CONTINUE },
|
|
/* 6 */ { 5, "\x01", NULL, 1, 0, MIME_FLAG_CONTINUE },
|
|
/* 7 */ { 16, "\x00", "application/x-object", 0, 1, MIME_FLAG_CONTINUE },
|
|
/* 8 */ { 16, "\x01", "application/x-object", 0, 1, MIME_FLAG_CONTINUE },
|
|
/* 9 */ { 16, "\x02", "application/x-executable", 0, 1, MIME_FLAG_CONTINUE },
|
|
/* 10 */ { 16, "\x03", "application/x-sharedlib", 0, 1, MIME_FLAG_CONTINUE },
|
|
/* 11 */ { 16, "\x04", "application/x-coredump", 0, 0, MIME_FLAG_CONTINUE },
|
|
|
|
/* Shell script */
|
|
/* 12 */ { 0, "#!/bin/sh", "application/x-shellscript", 0, 0, 0 },
|
|
/* 13 */ { 0, "#! /bin/sh", "application/x-shellscript", 0, 0, 0 },
|
|
/* 14 */ { 0, "#!/bin/csh", "application/x-shellscript", 0, 0, 0 },
|
|
/* 15 */ { 0, "#! /bin/csh", "application/x-shellscript", 0, 0, 0 },
|
|
/* 16 */ { 0, "#!/bin/ksh", "application/x-shellscript", 0, 0, 0 },
|
|
/* 17 */ { 0, "#! /bin/ksh", "application/x-shellscript", 0, 0, 0 },
|
|
/* 18 */ { 0, "#!/bin/tcsh", "application/x-shellscript", 0, 0, 0 },
|
|
/* 19 */ { 0, "#! /bin/tcsh", "application/x-shellscript", 0, 0, 0 },
|
|
/* 20 */ { 0, "#!/usr/local/bin/tcsh", "application/x-shellscript", 0, 0, 0 },
|
|
/* 21 */ { 0, "#! /usr/local/bin/tcsh", "application/x-shellscript", 0, 0, 0 },
|
|
/* 22 */ { 0, "#!/bin/bash", "application/x-shellscript", 0, 0, 0 },
|
|
/* 23 */ { 0, "#! /bin/bash", "application/x-shellscript", 0, 0, 0 },
|
|
/* 24 */ { 0, "#!/usr/local/bin/bash", "application/x-shellscript", 0, 0, 0 },
|
|
/* 25 */ { 0, "#! /usr/local/bin/bash", "application/x-shellscript", 0, 0, 0 },
|
|
|
|
/* Java object code*/
|
|
/* 26 */ { 0, "\xCA\xFE\xBA\xBE", "application/java", 0, 0, 0 },
|
|
|
|
/* Perl */
|
|
/* 27 */ { 0, "#!/bin/perl", "application/x-perl", 0, 0, 0 },
|
|
/* 28 */ { 0, "#! /bin/perl", "application/x-perl", 0, 0, 0 },
|
|
/* 29 */ { 0, "eval \"exec /bin/perl", "application/x-perl", 0, 0, 0 },
|
|
/* 30 */ { 0, "#!/usr/bin/perl", "application/x-perl", 0, 0, 0 },
|
|
/* 31 */ { 0, "#! /usr/bin/perl", "application/x-perl", 0, 0, 0 },
|
|
/* 32 */ { 0, "eval \"exec /usr/bin/perl", "application/x-perl", 0, 0, 0 },
|
|
/* 33 */ { 0, "#!/usr/local/bin/perl", "application/x-perl", 0, 0, 0 },
|
|
/* 34 */ { 0, "#! /usr/local/bin/perl", "application/x-perl", 0, 0, 0 },
|
|
/* 35 */ { 0, "eval \"exec /usr/local/bin/perl", "application/x-perl", 0, 0, 0 },
|
|
|
|
/* Python */
|
|
/* 36 */ { 0, "#!/bin/python", "application/x-python", 0, 0, 0 },
|
|
/* 37 */ { 0, "#! /bin/python", "application/x-python", 0, 0, 0 },
|
|
/* 38 */ { 0, "eval \"exec /bin/python", "application/x-python", 0, 0, 0 },
|
|
/* 39 */ { 0, "#!/usr/bin/python", "application/x-python", 0, 0, 0 },
|
|
/* 40 */ { 0, "#! /usr/bin/python", "application/x-python", 0, 0, 0 },
|
|
/* 41 */ { 0, "eval \"exec /usr/bin/python", "application/x-python", 0, 0, 0 },
|
|
/* 42 */ { 0, "#!/usr/local/bin/python", "application/x-python", 0, 0, 0 },
|
|
/* 43 */ { 0, "#! /usr/local/bin/python", "application/x-python", 0, 0, 0 },
|
|
/* 44 */ { 0, "eval \"exec /usr/local/bin/python", "application/x-python", 0, 0, 0 },
|
|
|
|
/* Unix compress (.z) */
|
|
/* 45 */ { 0, "\x1F\x9D", "application/x-compress", 0, 0, 0 },
|
|
|
|
/* Unix gzip */
|
|
/* 46 */ { 0, "\x1F\x8B", "application/x-gzip", 0, 0, 0 },
|
|
|
|
/* PKzip */
|
|
/* 47 { 0, "PK\x03\x04", "application/x-zip", 0, 0, 0 }, 2010-12-15 support of xlsx/ods */
|
|
|
|
/* xml */
|
|
/* 48 */ { 0, "<?xml", "application/xml", 0, 0, MIME_FLAG_TRIMSPACES | MIME_FLAG_TRIMTABS | MIME_FLAG_CASEINSENS },
|
|
|
|
/* html */
|
|
/* 49 */ { 0, "<html", "text/html", 0, 0, MIME_FLAG_TRIMSPACES | MIME_FLAG_TRIMTABS | MIME_FLAG_CASEINSENS },
|
|
/* 50 */ { 0, "<title", "text/html", 0, 0, MIME_FLAG_TRIMSPACES | MIME_FLAG_TRIMTABS | MIME_FLAG_CASEINSENS },
|
|
/* 51 */ { 0, "<head", "text/html", 0, 0, MIME_FLAG_TRIMSPACES | MIME_FLAG_TRIMTABS | MIME_FLAG_CASEINSENS },
|
|
/* 52 */ { 0, "<body", "text/html", 0, 0, MIME_FLAG_TRIMSPACES | MIME_FLAG_TRIMTABS | MIME_FLAG_CASEINSENS },
|
|
/* 53 */ { 0, "<!--", "text/html", 0, 0, MIME_FLAG_TRIMSPACES | MIME_FLAG_TRIMTABS },
|
|
/* 54 */ { 0, "<h", "text/html", 0, 0, MIME_FLAG_TRIMSPACES | MIME_FLAG_TRIMTABS | MIME_FLAG_CASEINSENS },
|
|
/* 55 */ { 0, "<!", "text/html", 0, 0, MIME_FLAG_TRIMSPACES | MIME_FLAG_TRIMTABS | MIME_FLAG_CASEINSENS },
|
|
|
|
/* Postscript */
|
|
/* 56 */ { 0, "%!", "application/postscript", 0, 0, 0 },
|
|
/* 57 */ { 0, "\x04%!", "application/postscript", 0, 0, 0 },
|
|
|
|
/* PDF */
|
|
/* 58 */ { 0, "%PDF-", "application/pdf", 0, 0, 0 },
|
|
|
|
/* DVI */
|
|
/* 59 */ { 0, "\xF7\x02", "application/dvi", 0, 0, 0 },
|
|
|
|
/* PNG image */
|
|
/* 60 */ { 0, "\x89PNG", "image/png", 0, 0, 0 },
|
|
|
|
/* XPM image */
|
|
/* 61 */ { 0, "/* XPM", "image/x-xpm", 0, 0, 0 },
|
|
|
|
/* TIFF image */
|
|
/* 62 */ { 0, "II", "image/tiff", 0, 0, 0 },
|
|
/* 63 */ { 0, "MM", "image/tiff", 0, 0, 0 },
|
|
|
|
/* GIF image */
|
|
/* 64 */ { 0, "GIF89z", "image/x-compressed-gif", 0, 0, 0 },
|
|
/* 65 */ { 0, "GIF", "image/gif", 0, 0, 0 },
|
|
|
|
/* JPEG image */
|
|
/* 66 */ { 0, "\xFF\xD8", "image/jpeg", 0, 0, 0 },
|
|
|
|
/* ICO image */
|
|
/* 67 */ { 2, "\x01\x00", "image/x-icon", 0, 0, 0 },
|
|
|
|
/* OGG file */
|
|
/* 68 */ { 0, "OggS", "application/ogg", 0, 0, 0 },
|
|
|
|
/* FLV file */
|
|
/* 69 */ { 0, "FLV", "video/x-flv", 0, 0, 0 },
|
|
|
|
/* SWF compressed file */
|
|
/* 70 */ { 0, "CWS", "application/x-shockwave-flash", 0, 0, 0 },
|
|
|
|
/* SWF uncompressed file */
|
|
/* 71 */ { 0, "FWS", "application/x-shockwave-flash", 0, 0, 0 }
|
|
};
|
|
|
|
/* Find MIME by extension */
|
|
|
|
typedef struct tag_mime_ext
|
|
{
|
|
const char * pattern; /* Extension to match */
|
|
HB_USHORT flags; /* flags for confrontation */
|
|
const char * mime_type; /* MIME type if complete */
|
|
} EXT_MIME_ENTRY;
|
|
|
|
/* https://www.iana.org/assignments/media-types/media-types.xhtml */
|
|
|
|
/* keep this table well sorted, it's necessary for binary search algorithm */
|
|
|
|
static const EXT_MIME_ENTRY s_extMimeTable[] =
|
|
{
|
|
{ "3dm" , MIME_FLAG_CASEINSENS, "x-world/x-3dmf" },
|
|
{ "3dmf" , MIME_FLAG_CASEINSENS, "x-world/x-3dmf" },
|
|
{ "3gp" , MIME_FLAG_CASEINSENS, "video/3gpp" },
|
|
{ "3gpp" , MIME_FLAG_CASEINSENS, "video/3gpp" },
|
|
{ "7z" , MIME_FLAG_CASEINSENS, "application/x-7z-compressed" },
|
|
{ "aab" , MIME_FLAG_CASEINSENS, "application/x-authorware-bin" },
|
|
{ "aam" , MIME_FLAG_CASEINSENS, "application/x-authorware-map" },
|
|
{ "aas" , MIME_FLAG_CASEINSENS, "application/x-authorware-map" },
|
|
{ "adr" , MIME_FLAG_CASEINSENS, "application/x-msaddr" },
|
|
{ "afl" , MIME_FLAG_CASEINSENS, "video/animaflex" },
|
|
{ "ai" , MIME_FLAG_CASEINSENS, "application/postscript" },
|
|
{ "aif" , MIME_FLAG_CASEINSENS, "audio/x-aiff" },
|
|
{ "aifc" , MIME_FLAG_CASEINSENS, "audio/x-aiff" },
|
|
{ "aiff" , MIME_FLAG_CASEINSENS, "audio/x-aiff" },
|
|
{ "alt" , MIME_FLAG_CASEINSENS, "application/x-up-alert" },
|
|
{ "arj" , MIME_FLAG_CASEINSENS, "application/x-arj" },
|
|
{ "asc" , MIME_FLAG_CASEINSENS, "text/plain" },
|
|
{ "asd" , MIME_FLAG_CASEINSENS, "application/astound" },
|
|
{ "asf" , MIME_FLAG_CASEINSENS, "video/x-ms-asf" },
|
|
{ "asn" , MIME_FLAG_CASEINSENS, "application/astound" },
|
|
{ "asp" , MIME_FLAG_CASEINSENS, "application/x-asap" },
|
|
{ "asx" , MIME_FLAG_CASEINSENS, "video/x-ms-asf" },
|
|
{ "asz" , MIME_FLAG_CASEINSENS, "application/astound" },
|
|
{ "atom" , MIME_FLAG_CASEINSENS, "application/atom+xml" },
|
|
{ "au" , MIME_FLAG_CASEINSENS, "audio/basic" },
|
|
{ "avi" , MIME_FLAG_CASEINSENS, "video/x-msvideo" },
|
|
{ "axs" , MIME_FLAG_CASEINSENS, "application/olescript" },
|
|
{ "bcpio" , MIME_FLAG_CASEINSENS, "application/x-bcpio" },
|
|
{ "bin" , MIME_FLAG_CASEINSENS, "application/octet-stream" },
|
|
{ "bmp" , MIME_FLAG_CASEINSENS, "image/x-ms-bmp" },
|
|
{ "bz2" , MIME_FLAG_CASEINSENS, "application/x-bzip2" },
|
|
{ "c" , MIME_FLAG_CASEINSENS, "text/x-csrc" },
|
|
{ "c++" , MIME_FLAG_CASEINSENS, "text/x-c++src" },
|
|
{ "cco" , MIME_FLAG_CASEINSENS, "application/x-cocoa" },
|
|
{ "ccs" , MIME_FLAG_CASEINSENS, "text/ccs" },
|
|
{ "cdf" , MIME_FLAG_CASEINSENS, "application/x-netcdf" },
|
|
{ "chat" , MIME_FLAG_CASEINSENS, "application/x-chat" },
|
|
{ "che" , MIME_FLAG_CASEINSENS, "application/x-up-cacheop" },
|
|
{ "cht" , MIME_FLAG_CASEINSENS, "audio/x-dspeech" },
|
|
{ "class" , MIME_FLAG_CASESENS , "application/java-vm" },
|
|
{ "cnc" , MIME_FLAG_CASEINSENS, "application/x-cnc" },
|
|
{ "cod" , MIME_FLAG_CASEINSENS, "image/cis-cod" },
|
|
{ "coda" , MIME_FLAG_CASEINSENS, "application/x-coda" },
|
|
{ "con" , MIME_FLAG_CASEINSENS, "application/x-connector" },
|
|
{ "cpi" , MIME_FLAG_CASEINSENS, "image/cpi" },
|
|
{ "cpio" , MIME_FLAG_CASEINSENS, "application/x-cpio" },
|
|
{ "cpp" , MIME_FLAG_CASEINSENS, "text/x-c++src" },
|
|
{ "crt" , MIME_FLAG_CASEINSENS, "application/x-x509-ca-cert" },
|
|
{ "csh" , MIME_FLAG_CASEINSENS, "application/x-csh" },
|
|
{ "csm" , MIME_FLAG_CASEINSENS, "application/x-cu-seeme" },
|
|
{ "css" , MIME_FLAG_CASEINSENS, "text/css" },
|
|
{ "csv" , MIME_FLAG_CASEINSENS, "text/csv" },
|
|
{ "cu" , MIME_FLAG_CASEINSENS, "application/x-cu-seeme" },
|
|
{ "cxx" , MIME_FLAG_CASEINSENS, "text/x-c++src" },
|
|
{ "dbf" , MIME_FLAG_CASEINSENS, "application/octet-stream" },
|
|
{ "dcr" , MIME_FLAG_CASEINSENS, "application/x-director" },
|
|
{ "deb" , MIME_FLAG_CASEINSENS, "application/octet-stream" },
|
|
{ "der" , MIME_FLAG_CASEINSENS, "application/x-x509-ca-cert" },
|
|
{ "dig" , MIME_FLAG_CASEINSENS, "multipart/mixed" },
|
|
{ "dir" , MIME_FLAG_CASEINSENS, "application/x-director" },
|
|
{ "djv" , MIME_FLAG_CASEINSENS, "image/vnd.djvu" },
|
|
{ "djvu" , MIME_FLAG_CASEINSENS, "image/vnd.djvu" },
|
|
{ "dll" , MIME_FLAG_CASEINSENS, "application/octet-stream" },
|
|
{ "dmg" , MIME_FLAG_CASEINSENS, "application/octet-stream" },
|
|
{ "doc" , MIME_FLAG_CASEINSENS, "application/msword" },
|
|
{ "docx" , MIME_FLAG_CASEINSENS, "application/vnd.openxmlformats-officedocument.wordprocessingml.document" },
|
|
{ "dsf" , MIME_FLAG_CASEINSENS, "image/x-mgx-dsf" },
|
|
{ "dst" , MIME_FLAG_CASEINSENS, "application/tajima" },
|
|
{ "dus" , MIME_FLAG_CASEINSENS, "audio/x-dspeech" },
|
|
{ "dvi" , MIME_FLAG_CASEINSENS, "application/x-dvi" },
|
|
{ "dwf" , MIME_FLAG_CASEINSENS, "drawing/x-dwf" },
|
|
{ "dwg" , MIME_FLAG_CASEINSENS, "image/vnd" },
|
|
{ "dxf" , MIME_FLAG_CASEINSENS, "image/vnd" },
|
|
{ "dxr" , MIME_FLAG_CASEINSENS, "application/x-director" },
|
|
{ "ear" , MIME_FLAG_CASEINSENS, "application/java-archive" },
|
|
{ "ebk" , MIME_FLAG_CASEINSENS, "application/x-expandedbook" },
|
|
{ "eot" , MIME_FLAG_CASEINSENS, "application/octet-stream" },
|
|
{ "eps" , MIME_FLAG_CASEINSENS, "application/postscript" },
|
|
{ "es" , MIME_FLAG_CASEINSENS, "audio/echospeech" },
|
|
{ "etf" , MIME_FLAG_CASEINSENS, "image/x-etf" },
|
|
{ "etx" , MIME_FLAG_CASEINSENS, "text/x-setext" },
|
|
{ "evy" , MIME_FLAG_CASEINSENS, "application/x-envoy" },
|
|
{ "exe" , MIME_FLAG_CASEINSENS, "application/octet-stream" },
|
|
{ "fh4" , MIME_FLAG_CASEINSENS, "image/x-freehand" },
|
|
{ "fh5" , MIME_FLAG_CASEINSENS, "image/x-freehand" },
|
|
{ "fhc" , MIME_FLAG_CASEINSENS, "image/x-freehand" },
|
|
{ "fif" , MIME_FLAG_CASEINSENS, "image/fif" },
|
|
{ "flv" , MIME_FLAG_CASEINSENS, "video/x-flv" },
|
|
{ "fpx" , MIME_FLAG_CASEINSENS, "image/x-fpx" },
|
|
{ "frl" , MIME_FLAG_CASEINSENS, "application/freeloader" },
|
|
{ "gif" , MIME_FLAG_CASEINSENS, "image/gif" },
|
|
{ "gsd" , MIME_FLAG_CASEINSENS, "audio/gsm" },
|
|
{ "gsm" , MIME_FLAG_CASEINSENS, "audio/gsm" },
|
|
{ "gtar" , MIME_FLAG_CASEINSENS, "application/x-gtar" },
|
|
{ "gz" , MIME_FLAG_CASEINSENS, "application/x-gzip" },
|
|
{ "h" , MIME_FLAG_CASEINSENS, "text/x-chdr" },
|
|
{ "hdf" , MIME_FLAG_CASEINSENS, "application/x-hdf" },
|
|
{ "hdml" , MIME_FLAG_CASEINSENS, "text/x-hdml" },
|
|
{ "hpp" , MIME_FLAG_CASEINSENS, "text/x-c++hdr" },
|
|
{ "hqx" , MIME_FLAG_CASEINSENS, "application/mac-binhex40" },
|
|
{ "htc" , MIME_FLAG_CASEINSENS, "text/x-component" },
|
|
{ "htm" , MIME_FLAG_CASEINSENS, "text/html" },
|
|
{ "html" , MIME_FLAG_CASEINSENS, "text/html" },
|
|
{ "hxx" , MIME_FLAG_CASEINSENS, "text/x-c++hdr" },
|
|
{ "ica" , MIME_FLAG_CASEINSENS, "application/x-ica" },
|
|
{ "ico" , MIME_FLAG_CASEINSENS, "image/x-icon" },
|
|
{ "ics" , MIME_FLAG_CASEINSENS, "text/calendar" },
|
|
{ "ief" , MIME_FLAG_CASEINSENS, "image/ief" },
|
|
{ "img" , MIME_FLAG_CASEINSENS, "application/octet-stream" },
|
|
{ "ins" , MIME_FLAG_CASEINSENS, "application/x-NET-Install" },
|
|
{ "ips" , MIME_FLAG_CASEINSENS, "application/x-ipscript" },
|
|
{ "ipx" , MIME_FLAG_CASEINSENS, "application/x-ipix" },
|
|
{ "iso" , MIME_FLAG_CASEINSENS, "application/octet-stream" },
|
|
{ "ivr" , MIME_FLAG_CASEINSENS, "i-world/i-vrml" },
|
|
{ "jad" , MIME_FLAG_CASEINSENS, "text/vnd.sun.j2me.app-descriptor" },
|
|
{ "jar" , MIME_FLAG_CASEINSENS, "application/java-archive" },
|
|
{ "jardiff" , MIME_FLAG_CASEINSENS, "application/x-java-archive-diff" },
|
|
{ "java" , MIME_FLAG_CASESENS , "text/java" },
|
|
{ "jng" , MIME_FLAG_CASEINSENS, "image/x-jng" },
|
|
{ "jnlp" , MIME_FLAG_CASEINSENS, "application/x-java-jnlp-file" },
|
|
{ "jpe" , MIME_FLAG_CASEINSENS, "image/jpeg" },
|
|
{ "jpeg" , MIME_FLAG_CASEINSENS, "image/jpeg" },
|
|
{ "jpg" , MIME_FLAG_CASEINSENS, "image/jpeg" },
|
|
{ "js" , MIME_FLAG_CASEINSENS, "application/javascript" },
|
|
{ "kar" , MIME_FLAG_CASEINSENS, "audio/midi" },
|
|
{ "kml" , MIME_FLAG_CASEINSENS, "application/vnd.google-earth.kml+xml" },
|
|
{ "kmz" , MIME_FLAG_CASEINSENS, "application/vnd.google-earth.kmz" },
|
|
{ "latex" , MIME_FLAG_CASEINSENS, "application/x-latex" },
|
|
{ "lha" , MIME_FLAG_CASEINSENS, "application/octet-stream" },
|
|
{ "log" , MIME_FLAG_CASEINSENS, "text/plain" },
|
|
{ "lzh" , MIME_FLAG_CASEINSENS, "application/octet-stream" },
|
|
{ "lzx" , MIME_FLAG_CASEINSENS, "application/octet-stream" },
|
|
{ "m3u" , MIME_FLAG_CASEINSENS, "audio/x-mpegurl" },
|
|
{ "m4a" , MIME_FLAG_CASEINSENS, "audio/x-m4a" },
|
|
{ "m4v" , MIME_FLAG_CASEINSENS, "video/x-m4v" },
|
|
{ "man" , MIME_FLAG_CASEINSENS, "application/x-troff-man" },
|
|
{ "map" , MIME_FLAG_CASEINSENS, "application/x-httpd-imap" },
|
|
{ "markdown", MIME_FLAG_CASEINSENS, "text/x-markdown" },
|
|
{ "mbd" , MIME_FLAG_CASEINSENS, "application/mbedlet" },
|
|
{ "mcf" , MIME_FLAG_CASEINSENS, "image/vasa" },
|
|
{ "md" , MIME_FLAG_CASEINSENS, "text/x-markdown" },
|
|
{ "me" , MIME_FLAG_CASEINSENS, "application/x-troff-me" },
|
|
{ "mfp" , MIME_FLAG_CASEINSENS, "application/mirage" },
|
|
{ "mid" , MIME_FLAG_CASEINSENS, "audio/midi" },
|
|
{ "midi" , MIME_FLAG_CASEINSENS, "audio/midi" },
|
|
{ "mif" , MIME_FLAG_CASEINSENS, "application/x-mif" },
|
|
{ "mml" , MIME_FLAG_CASEINSENS, "text/mathml" },
|
|
{ "mng" , MIME_FLAG_CASEINSENS, "video/x-mng" },
|
|
{ "mol" , MIME_FLAG_CASEINSENS, "chemical/x-mdl-molfile" },
|
|
{ "mov" , MIME_FLAG_CASEINSENS, "video/quicktime" },
|
|
{ "movie" , MIME_FLAG_CASEINSENS, "video/x-sgi-movie" },
|
|
{ "mp2" , MIME_FLAG_CASEINSENS, "audio/x-mpeg" },
|
|
{ "mp3" , MIME_FLAG_CASEINSENS, "audio/mpeg" },
|
|
{ "mp4" , MIME_FLAG_CASEINSENS, "video/mp4" },
|
|
{ "mpe" , MIME_FLAG_CASEINSENS, "video/mpeg" },
|
|
{ "mpeg" , MIME_FLAG_CASEINSENS, "video/mpeg" },
|
|
{ "mpg" , MIME_FLAG_CASEINSENS, "video/mpeg" },
|
|
{ "mpire" , MIME_FLAG_CASEINSENS, "application/x-mpire" },
|
|
{ "mpl" , MIME_FLAG_CASEINSENS, "application/x-mpire" },
|
|
{ "ms" , MIME_FLAG_CASEINSENS, "application/x-troff-ms" },
|
|
{ "msi" , MIME_FLAG_CASEINSENS, "application/octet-stream" },
|
|
{ "msm" , MIME_FLAG_CASEINSENS, "application/octet-stream" },
|
|
{ "msp" , MIME_FLAG_CASEINSENS, "application/octet-stream" },
|
|
{ "n2p" , MIME_FLAG_CASEINSENS, "application/n2p" },
|
|
{ "nc" , MIME_FLAG_CASEINSENS, "application/x-netcdf" },
|
|
{ "npx" , MIME_FLAG_CASEINSENS, "application/x-netfpx" },
|
|
{ "nsc" , MIME_FLAG_CASEINSENS, "application/x-nschat" },
|
|
{ "oda" , MIME_FLAG_CASEINSENS, "application/oda" },
|
|
{ "odb" , MIME_FLAG_CASEINSENS, "application/vnd.oasis.opendocument.database" },
|
|
{ "odc" , MIME_FLAG_CASEINSENS, "application/vnd.oasis.opendocument.chart" },
|
|
{ "odf" , MIME_FLAG_CASEINSENS, "application/vnd.oasis.opendocument.formula" },
|
|
{ "odg" , MIME_FLAG_CASEINSENS, "application/vnd.oasis.opendocument.graphics" },
|
|
{ "odi" , MIME_FLAG_CASEINSENS, "application/vnd.oasis.opendocument.image" },
|
|
{ "odm" , MIME_FLAG_CASEINSENS, "application/vnd.oasis.opendocument.text-master" },
|
|
{ "odp" , MIME_FLAG_CASEINSENS, "application/vnd.oasis.opendocument.presentation" },
|
|
{ "ods" , MIME_FLAG_CASEINSENS, "application/vnd.oasis.opendocument.spreadsheet" },
|
|
{ "odt" , MIME_FLAG_CASEINSENS, "application/vnd.oasis.opendocument.text" },
|
|
{ "ofml" , MIME_FLAG_CASEINSENS, "application/fml" },
|
|
{ "ogg" , MIME_FLAG_CASEINSENS, "audio/ogg" },
|
|
{ "oth" , MIME_FLAG_CASEINSENS, "application/vnd.oasis.opendocument.text-web" },
|
|
{ "oxt" , MIME_FLAG_CASEINSENS, "application/vnd.openofficeorg.extension" },
|
|
{ "p7s" , MIME_FLAG_CASEINSENS, "application/pkcs7-signature" },
|
|
{ "page" , MIME_FLAG_CASEINSENS, "application/x-coda" },
|
|
{ "pbm" , MIME_FLAG_CASEINSENS, "image/x-portable-bitmap" },
|
|
{ "pdb" , MIME_FLAG_CASEINSENS, "application/x-pilot" },
|
|
{ "pdf" , MIME_FLAG_CASEINSENS, "application/pdf" },
|
|
{ "pem" , MIME_FLAG_CASEINSENS, "application/x-x509-ca-cert" },
|
|
{ "pfr" , MIME_FLAG_CASEINSENS, "application/font-tdpfr" },
|
|
{ "pgm" , MIME_FLAG_CASEINSENS, "image/x-portable-graymap" },
|
|
{ "pgp" , MIME_FLAG_CASEINSENS, "application/x-pgp-plugin" },
|
|
{ "pgr" , MIME_FLAG_CASEINSENS, "text/parsnegar-document" },
|
|
{ "php3" , MIME_FLAG_CASEINSENS, "application/x-httpd-php3" },
|
|
{ "phtml" , MIME_FLAG_CASEINSENS, "application/x-httpd-php" },
|
|
{ "pl" , MIME_FLAG_CASEINSENS, "application/x-perl" },
|
|
{ "pm" , MIME_FLAG_CASEINSENS, "application/x-perl" },
|
|
{ "png" , MIME_FLAG_CASEINSENS, "image/png" },
|
|
{ "pnm" , MIME_FLAG_CASEINSENS, "image/x-portable-anymap" },
|
|
{ "pot" , MIME_FLAG_CASEINSENS, "application/mspowerpoint" },
|
|
{ "ppm" , MIME_FLAG_CASEINSENS, "image/x-portable-pixmap" },
|
|
{ "pps" , MIME_FLAG_CASEINSENS, "application/mspowerpoint" },
|
|
{ "ppsx" , MIME_FLAG_CASEINSENS, "application/vnd.openxmlformats-officedocument.presentationml.slideshow" },
|
|
{ "ppt" , MIME_FLAG_CASEINSENS, "application/powerpoint" },
|
|
{ "pptx" , MIME_FLAG_CASEINSENS, "application/vnd.openxmlformats-officedocument.presentationml.presentation" },
|
|
{ "ppz" , MIME_FLAG_CASEINSENS, "application/mspowerpoint" },
|
|
{ "pqf" , MIME_FLAG_CASEINSENS, "application/x-cprplayer" },
|
|
{ "pqi" , MIME_FLAG_CASEINSENS, "application/cprplayer" },
|
|
{ "prc" , MIME_FLAG_CASEINSENS, "application/x-pilot" },
|
|
{ "ps" , MIME_FLAG_CASEINSENS, "application/postscript" },
|
|
{ "ptlk" , MIME_FLAG_CASEINSENS, "application/listenup" },
|
|
{ "push" , MIME_FLAG_CASEINSENS, "multipart/x-mixed-replace" },
|
|
{ "qd3" , MIME_FLAG_CASEINSENS, "x-world/x-3dmf" },
|
|
{ "qd3d" , MIME_FLAG_CASEINSENS, "x-world/x-3dmf" },
|
|
{ "qrt" , MIME_FLAG_CASEINSENS, "application/quest" },
|
|
{ "qt" , MIME_FLAG_CASEINSENS, "video/quicktime" },
|
|
{ "ra" , MIME_FLAG_CASEINSENS, "audio/x-realaudio" },
|
|
{ "ram" , MIME_FLAG_CASEINSENS, "audio/x-realaudio" },
|
|
{ "rar" , MIME_FLAG_CASEINSENS, "application/x-rar-compressed" },
|
|
{ "ras" , MIME_FLAG_CASEINSENS, "image/x-cmu-raster" },
|
|
{ "rgb" , MIME_FLAG_CASEINSENS, "image/x-rgb" },
|
|
{ "rip" , MIME_FLAG_CASEINSENS, "image/rip" },
|
|
{ "rmf" , MIME_FLAG_CASEINSENS, "audio/x-rmf" },
|
|
{ "roff" , MIME_FLAG_CASEINSENS, "application/x-troff" },
|
|
{ "rpm" , MIME_FLAG_CASEINSENS, "application/x-redhat-package-manager" },
|
|
{ "rrf" , MIME_FLAG_CASEINSENS, "application/x-InstallFromTheWeb" },
|
|
{ "rss" , MIME_FLAG_CASEINSENS, "application/rss+xml" },
|
|
{ "rst" , MIME_FLAG_CASEINSENS, "text/plain" },
|
|
{ "rtc" , MIME_FLAG_CASEINSENS, "application/rtc" },
|
|
{ "rtf" , MIME_FLAG_CASEINSENS, "text/rtf" },
|
|
{ "rtx" , MIME_FLAG_CASEINSENS, "text/richtext" },
|
|
{ "run" , MIME_FLAG_CASEINSENS, "application/x-makeself" },
|
|
{ "sca" , MIME_FLAG_CASEINSENS, "application/x-supercard" },
|
|
{ "sea" , MIME_FLAG_CASEINSENS, "application/x-sea" },
|
|
{ "sh" , MIME_FLAG_CASEINSENS, "application/x-sh" },
|
|
{ "shar" , MIME_FLAG_CASEINSENS, "application/x-shar" },
|
|
{ "shtml" , MIME_FLAG_CASEINSENS, "text/html" },
|
|
{ "shw" , MIME_FLAG_CASEINSENS, "application/presentations" },
|
|
{ "sit" , MIME_FLAG_CASEINSENS, "application/x-stuffit" },
|
|
{ "sml" , MIME_FLAG_CASEINSENS, "application/fml" },
|
|
{ "smp" , MIME_FLAG_CASEINSENS, "application/studiom" },
|
|
{ "snd" , MIME_FLAG_CASEINSENS, "audio/basic" },
|
|
{ "spc" , MIME_FLAG_CASEINSENS, "text/x-speech" },
|
|
{ "spl" , MIME_FLAG_CASEINSENS, "application/futuresplash" },
|
|
{ "spr" , MIME_FLAG_CASEINSENS, "application/x-sprite" },
|
|
{ "sprite" , MIME_FLAG_CASEINSENS, "application/x-sprite" },
|
|
{ "src" , MIME_FLAG_CASEINSENS, "application/x-wais-source" },
|
|
{ "stk" , MIME_FLAG_CASEINSENS, "application/hstu" },
|
|
{ "stream" , MIME_FLAG_CASEINSENS, "audio/x-qt-stream" },
|
|
{ "sv4cpio" , MIME_FLAG_CASEINSENS, "application/x-sv4cpio" },
|
|
{ "sv4crc" , MIME_FLAG_CASEINSENS, "application/x-sv4crc" },
|
|
{ "svf" , MIME_FLAG_CASEINSENS, "image/vnd" },
|
|
{ "svg" , MIME_FLAG_CASEINSENS, "image/svg+xml" },
|
|
{ "svgz" , MIME_FLAG_CASEINSENS, "image/svg+xml" },
|
|
{ "svh" , MIME_FLAG_CASEINSENS, "image/svh" },
|
|
{ "svr" , MIME_FLAG_CASEINSENS, "x-world/x-svr" },
|
|
{ "swa" , MIME_FLAG_CASEINSENS, "application/x-director" },
|
|
{ "swf" , MIME_FLAG_CASEINSENS, "application/x-shockwave-flash" },
|
|
{ "t" , MIME_FLAG_CASEINSENS, "application/x-troff" },
|
|
{ "talk" , MIME_FLAG_CASEINSENS, "text/x-speech" },
|
|
{ "tar" , MIME_FLAG_CASEINSENS, "application/x-tar" },
|
|
{ "tbk" , MIME_FLAG_CASEINSENS, "application/toolbook" },
|
|
{ "tcl" , MIME_FLAG_CASEINSENS, "application/x-tcl" },
|
|
{ "tex" , MIME_FLAG_CASEINSENS, "application/x-tex" },
|
|
{ "texi" , MIME_FLAG_CASEINSENS, "application/x-texinfo" },
|
|
{ "texinfo" , MIME_FLAG_CASEINSENS, "application/x-texinfo" },
|
|
{ "text" , MIME_FLAG_CASEINSENS, "text/plain" },
|
|
{ "tgz" , MIME_FLAG_CASEINSENS, "application/x-gtar" },
|
|
{ "tif" , MIME_FLAG_CASEINSENS, "image/tiff" },
|
|
{ "tiff" , MIME_FLAG_CASEINSENS, "image/tiff" },
|
|
{ "tk" , MIME_FLAG_CASEINSENS, "application/x-tcl" },
|
|
{ "tlk" , MIME_FLAG_CASEINSENS, "application/x-tlk" },
|
|
{ "tmv" , MIME_FLAG_CASEINSENS, "application/x-Parable-Thing" },
|
|
{ "tr" , MIME_FLAG_CASEINSENS, "application/x-troff" },
|
|
{ "tsi" , MIME_FLAG_CASEINSENS, "audio/tsplayer" },
|
|
{ "tsp" , MIME_FLAG_CASEINSENS, "application/dsptype" },
|
|
{ "tsv" , MIME_FLAG_CASEINSENS, "text/tab-separated-values" },
|
|
{ "txt" , MIME_FLAG_CASEINSENS, "text/plain" },
|
|
{ "ustar" , MIME_FLAG_CASEINSENS, "application/x-ustar" },
|
|
{ "vbd" , MIME_FLAG_CASEINSENS, "application/activexdocument" },
|
|
{ "vcd" , MIME_FLAG_CASEINSENS, "application/x-cdlink" },
|
|
{ "vcf" , MIME_FLAG_CASEINSENS, "text/directory" },
|
|
{ "vgm" , MIME_FLAG_CASEINSENS, "video/x-videogram" },
|
|
{ "vgp" , MIME_FLAG_CASEINSENS, "video/x-videogram-plugin" },
|
|
{ "vgx" , MIME_FLAG_CASEINSENS, "video/x-videogram" },
|
|
{ "viv" , MIME_FLAG_CASEINSENS, "video/vnd.vivo" },
|
|
{ "vivo" , MIME_FLAG_CASEINSENS, "video/vnd.vivo" },
|
|
{ "vmd" , MIME_FLAG_CASEINSENS, "application/vocaltec-media-desc" },
|
|
{ "vmf" , MIME_FLAG_CASEINSENS, "application/vocaltec-media-file" },
|
|
{ "vox" , MIME_FLAG_CASEINSENS, "audio/voxware" },
|
|
{ "vqe" , MIME_FLAG_CASEINSENS, "audio/x-twinvq-plugin" },
|
|
{ "vqf" , MIME_FLAG_CASEINSENS, "audio/x-twinvq" },
|
|
{ "vql" , MIME_FLAG_CASEINSENS, "audio/x-twinvq" },
|
|
{ "vrt" , MIME_FLAG_CASEINSENS, "x-world/x-vrt" },
|
|
{ "vts" , MIME_FLAG_CASEINSENS, "workbook/formulaone" },
|
|
{ "vtts" , MIME_FLAG_CASEINSENS, "workbook/formulaone" },
|
|
{ "waf" , MIME_FLAG_CASEINSENS, "plugin/wanimate" },
|
|
{ "wan" , MIME_FLAG_CASEINSENS, "plugin/wanimate" },
|
|
{ "war" , MIME_FLAG_CASEINSENS, "application/java-archive" },
|
|
{ "wav" , MIME_FLAG_CASEINSENS, "audio/x-wav" },
|
|
{ "wbmp" , MIME_FLAG_CASEINSENS, "image/vnd.wap.wbmp" },
|
|
{ "webm" , MIME_FLAG_CASEINSENS, "video/webm" },
|
|
{ "webp" , MIME_FLAG_CASEINSENS, "image/webp" },
|
|
{ "wi" , MIME_FLAG_CASEINSENS, "image/wavelet" },
|
|
{ "wid" , MIME_FLAG_CASEINSENS, "application/x-DemoShield" },
|
|
{ "wis" , MIME_FLAG_CASEINSENS, "application/x-InstallShield" },
|
|
{ "wlt" , MIME_FLAG_CASEINSENS, "application/x-mswallet" },
|
|
{ "wml" , MIME_FLAG_CASEINSENS, "text/vnd.wap.wml" },
|
|
{ "wmlc" , MIME_FLAG_CASEINSENS, "application/vnd.wap.wmlc" },
|
|
{ "wmv" , MIME_FLAG_CASEINSENS, "video/x-ms-wmv" },
|
|
{ "wri" , MIME_FLAG_CASEINSENS, "application/write" },
|
|
{ "wrl" , MIME_FLAG_CASEINSENS, "x-world/x-vrml" },
|
|
{ "wrz" , MIME_FLAG_CASEINSENS, "x-world/x-vrml" },
|
|
{ "wtx" , MIME_FLAG_CASEINSENS, "audio/x-wtx" },
|
|
{ "xbm" , MIME_FLAG_CASEINSENS, "image/x-xbitmap" },
|
|
{ "xdr" , MIME_FLAG_CASEINSENS, "video/x-videogram" },
|
|
{ "xhtml" , MIME_FLAG_CASEINSENS, "application/xhtml+xml" },
|
|
{ "xls" , MIME_FLAG_CASEINSENS, "application/excel" },
|
|
{ "xlsx" , MIME_FLAG_CASEINSENS, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" },
|
|
{ "xlt" , MIME_FLAG_CASEINSENS, "application/xlt" },
|
|
{ "xml" , MIME_FLAG_CASEINSENS, "application/xml" },
|
|
{ "xpi" , MIME_FLAG_CASEINSENS, "application/x-xpinstall" },
|
|
{ "xpm" , MIME_FLAG_CASEINSENS, "image/x-xpixmap" },
|
|
{ "xwd" , MIME_FLAG_CASEINSENS, "image/x-xwindowdump" },
|
|
{ "z" , MIME_FLAG_CASEINSENS, "application/x-compress" },
|
|
{ "zip" , MIME_FLAG_CASEINSENS, "application/zip" },
|
|
{ "zpa" , MIME_FLAG_CASEINSENS, "application/pcphoto" }
|
|
};
|
|
|
|
static const char * s_findExtMimeType( const char * szFileExt )
|
|
{
|
|
HB_UINT uiFirst = 0, uiLast = HB_SIZEOFARRAY( s_extMimeTable );
|
|
char szExt[ 16 ];
|
|
|
|
if( *szFileExt == '.' )
|
|
++szFileExt;
|
|
hb_strncpyLower( szExt, szFileExt, sizeof( szExt ) - 1 );
|
|
|
|
do
|
|
{
|
|
HB_UINT uiMiddle;
|
|
int i;
|
|
|
|
uiMiddle = ( uiFirst + uiLast ) >> 1;
|
|
i = strcmp( szExt, s_extMimeTable[ uiMiddle ].pattern );
|
|
if( i == 0 )
|
|
{
|
|
if( s_extMimeTable[ uiMiddle ].flags == MIME_FLAG_CASEINSENS ||
|
|
strcmp( szExt, szFileExt ) == 0 )
|
|
return s_extMimeTable[ uiMiddle ].mime_type;
|
|
break;
|
|
}
|
|
else if( i < 0 )
|
|
uiLast = uiMiddle;
|
|
else /* if( i > 0 ) */
|
|
uiFirst = uiMiddle + 1;
|
|
}
|
|
while( uiFirst < uiLast );
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static const char * s_findMimeStringInTree( const char * cData, HB_SIZE nLen, int iElem )
|
|
{
|
|
const MIME_ENTRY * elem = s_mimeTable + iElem;
|
|
HB_SIZE nPos = elem->pos;
|
|
HB_SIZE nDataLen = strlen( elem->pattern );
|
|
|
|
/* allow \0 to be used for matches */
|
|
if( nDataLen == 0 )
|
|
nDataLen = 1;
|
|
|
|
/* trim spaces if required */
|
|
while( nPos < nLen &&
|
|
( ( ( elem->flags & MIME_FLAG_TRIMSPACES ) != 0 && (
|
|
cData[ nPos ] == ' ' || cData[ nPos ] == '\r' || cData[ nPos ] == '\n' ) ) ||
|
|
( ( elem->flags & MIME_FLAG_TRIMTABS ) != 0 && cData[ nPos ] == '\t' ) ) )
|
|
{
|
|
nPos++;
|
|
}
|
|
|
|
if( nPos < nLen && ( nLen - nPos ) >= nDataLen )
|
|
{
|
|
if( ( elem->flags & MIME_FLAG_CASEINSENS ) != 0 )
|
|
{
|
|
if( ( *elem->pattern == 0 && cData[ nPos ] == 0 ) || hb_strnicmp( cData + nPos, elem->pattern, nDataLen ) == 0 )
|
|
{
|
|
/* is this the begin of a match tree? */
|
|
if( elem->next != 0 )
|
|
return s_findMimeStringInTree( cData, nLen, iElem + elem->next );
|
|
else
|
|
return elem->mime_type;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( ( *elem->pattern == 0 && cData[ nPos ] == 0 ) || strncmp( cData + nPos, elem->pattern, nDataLen ) == 0 )
|
|
{
|
|
if( elem->next != 0 )
|
|
return s_findMimeStringInTree( cData, nLen, iElem + elem->next );
|
|
else
|
|
return elem->mime_type;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* match failed! */
|
|
if( elem->alternate != 0 )
|
|
return s_findMimeStringInTree( cData, nLen, iElem + elem->alternate );
|
|
|
|
return NULL; /* give up */
|
|
}
|
|
|
|
static const char * s_findStringMimeType( const char * cData, HB_SIZE nLen )
|
|
{
|
|
unsigned int uiCount;
|
|
|
|
for( uiCount = 0; uiCount < HB_SIZEOFARRAY( s_mimeTable ); uiCount++ )
|
|
{
|
|
const MIME_ENTRY * elem = s_mimeTable + uiCount;
|
|
HB_SIZE nPos = elem->pos;
|
|
HB_SIZE nDataLen = ( HB_SIZE ) strlen( elem->pattern );
|
|
|
|
if( ( elem->flags & MIME_FLAG_CONTINUE ) != 0 )
|
|
continue;
|
|
|
|
/* trim spaces if required */
|
|
while( nPos < nLen &&
|
|
( ( ( elem->flags & MIME_FLAG_TRIMSPACES ) != 0 && (
|
|
cData[ nPos ] == ' ' || cData[ nPos ] == '\r' || cData[ nPos ] == '\n' ) ) ||
|
|
( ( elem->flags & MIME_FLAG_TRIMTABS ) != 0 && cData[ nPos ] == '\t' ) ) )
|
|
{
|
|
nPos++;
|
|
}
|
|
|
|
if( nPos >= nLen )
|
|
continue;
|
|
|
|
if( nLen - nPos < nDataLen )
|
|
continue;
|
|
|
|
if( ( elem->flags & MIME_FLAG_CASEINSENS ) != 0 )
|
|
{
|
|
if( ( *elem->pattern == 0 && cData[ nPos ] == 0 ) || hb_strnicmp( cData + nPos, elem->pattern, nDataLen ) == 0 )
|
|
{
|
|
/* is this the begin of a match tree? */
|
|
if( elem->next != 0 )
|
|
return s_findMimeStringInTree( cData, nLen, uiCount + elem->next );
|
|
else
|
|
return elem->mime_type;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( ( *elem->pattern == 0 && cData[ nPos ] == 0 ) || strncmp( cData + nPos, elem->pattern, nDataLen ) == 0 )
|
|
{
|
|
if( elem->next != 0 )
|
|
return s_findMimeStringInTree( cData, nLen, uiCount + elem->next );
|
|
else
|
|
return elem->mime_type;
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static const char * s_findFileMimeType( PHB_FILE fileIn )
|
|
{
|
|
char buf[ 512 ];
|
|
|
|
HB_FOFFSET nPos = hb_fileSeek( fileIn, 0, FS_RELATIVE );
|
|
HB_SIZE nLen = hb_fileResult( hb_fileReadAt( fileIn, buf, sizeof( buf ), 0 ) );
|
|
|
|
if( nLen > 0 )
|
|
{
|
|
hb_fileSeek( fileIn, nPos, FS_SET );
|
|
return s_findStringMimeType( buf, nLen );
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
HB_FUNC( TIP_MIMETYPE )
|
|
{
|
|
PHB_ITEM pData = hb_param( 1, HB_IT_STRING );
|
|
|
|
if( pData )
|
|
{
|
|
const char * magic_type = s_findStringMimeType( hb_itemGetCPtr( pData ), hb_itemGetCLen( pData ) );
|
|
|
|
if( magic_type )
|
|
hb_retc_const( magic_type );
|
|
else if( HB_ISCHAR( 2 ) )
|
|
hb_retc( hb_parc( 2 ) );
|
|
else
|
|
hb_retc_const( "unknown" ); /* FIXME: change to "application/unknown" */
|
|
}
|
|
else
|
|
hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
HB_FUNC( TIP_FILENAMEMIMETYPE )
|
|
{
|
|
const char * fname = hb_parc( 1 );
|
|
|
|
if( fname )
|
|
{
|
|
PHB_FNAME pFileName = hb_fsFNameSplit( fname );
|
|
const char * ext_type = pFileName->szExtension ? s_findExtMimeType( pFileName->szExtension ) : NULL;
|
|
hb_xfree( pFileName );
|
|
|
|
if( ext_type )
|
|
hb_retc_const( ext_type );
|
|
else if( HB_ISCHAR( 2 ) )
|
|
hb_retc( hb_parc( 2 ) );
|
|
else
|
|
hb_retc_const( "unknown" ); /* FIXME: change to "application/unknown" */
|
|
}
|
|
else
|
|
hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|
|
|
|
HB_FUNC( TIP_FILEMIMETYPE )
|
|
{
|
|
PHB_ITEM pFile = hb_param( 1, HB_IT_STRING | HB_IT_POINTER | HB_IT_NUMERIC );
|
|
|
|
if( pFile )
|
|
{
|
|
const char * ext_type = NULL;
|
|
const char * magic_type = NULL;
|
|
|
|
if( HB_IS_STRING( pFile ) )
|
|
{
|
|
const char * fname = hb_itemGetCPtr( pFile );
|
|
|
|
PHB_FNAME pFileName = hb_fsFNameSplit( fname );
|
|
PHB_FILE fileIn;
|
|
|
|
ext_type = pFileName->szExtension ? s_findExtMimeType( pFileName->szExtension ) : NULL;
|
|
hb_xfree( pFileName );
|
|
|
|
if( ( fileIn = hb_fileExtOpen( fname, NULL,
|
|
FO_READ | FO_SHARED | FO_PRIVATE |
|
|
FXO_SHARELOCK,
|
|
NULL, NULL ) ) != NULL )
|
|
{
|
|
magic_type = s_findFileMimeType( fileIn );
|
|
hb_fileClose( fileIn );
|
|
}
|
|
}
|
|
else if( hb_fileItemGet( pFile ) )
|
|
magic_type = s_findFileMimeType( hb_fileItemGet( pFile ) );
|
|
else
|
|
{
|
|
PHB_FILE fileIn = hb_fileFromHandle( hb_numToHandle( hb_itemGetNInt( pFile ) ) );
|
|
magic_type = s_findFileMimeType( fileIn );
|
|
hb_fileDetach( fileIn );
|
|
}
|
|
|
|
if( magic_type )
|
|
hb_retc_const( magic_type );
|
|
else if( ext_type )
|
|
hb_retc_const( ext_type );
|
|
else if( HB_ISCHAR( 2 ) )
|
|
hb_retc( hb_parc( 2 ) );
|
|
else
|
|
hb_retc_const( "unknown" ); /* FIXME: change to "application/unknown" */
|
|
}
|
|
else
|
|
hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
|
|
}
|