summaryrefslogtreecommitdiff
path: root/src/IO/mime.c
blob: 3d88429e85625bcd958312da3596d5fd3bbaa4ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
 * File: mime.c
 *
 * Copyright (C) 2000-2007 Jorge Arellano Cid <jcid@dillo.org>
 * Copyright (C) 2024 Rodrigo Arias Mallo <rodarima@gmail.com>
 *
 * 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 3 of the License, or
 * (at your option) any later version.
 */

#include "mime.h"
#include "../list.h"


typedef struct {
   const char *Name;   /* MIME type name */
   Viewer_t Data;      /* Pointer to a function */
} MimeItem_t;


/*
 *  Local data
 */
static int MimeMinItemsSize = 0, MimeMinItemsMax = 8;
static MimeItem_t *MimeMinItems = NULL;

static int MimeMajItemsSize = 0, MimeMajItemsMax = 8;
static MimeItem_t *MimeMajItems = NULL;


/**
 * Add a specific MIME type (as "image/png") to our viewer list.
 * 'Key' is the content-type string that identifies the MIME type
 * 'Method' is the function that handles it
 */
static int Mime_add_minor_type(const char *Key, Viewer_t Method)
{
   a_List_add(MimeMinItems, MimeMinItemsSize, MimeMinItemsMax);
   MimeMinItems[MimeMinItemsSize].Name = Key;
   MimeMinItems[MimeMinItemsSize].Data = Method;
   MimeMinItemsSize++;
   return 0;
}

/**
 * Add a major MIME type (as "text") to our viewer list.
 * 'Key' is the content-type string that identifies the MIME type
 * 'Method' is the function that handles it
 */
static int Mime_add_major_type(const char *Key, Viewer_t Method)
{
   a_List_add(MimeMajItems, MimeMajItemsSize, MimeMajItemsMax);
   MimeMajItems[MimeMajItemsSize].Name = Key;
   MimeMajItems[MimeMajItemsSize].Data = Method;
   MimeMajItemsSize++;
   return 0;
}

/**
 * Search the list of specific MIME viewers for a Method that matches 'Key'.
 * 'Key' is the content-type string that identifies the MIME type
 */
static Viewer_t Mime_minor_type_fetch(const char *Key, uint_t Size)
{
   int i;

   if (Size) {
      for ( i = 0; i < MimeMinItemsSize; ++i )
         if (dStrnAsciiCasecmp(Key, MimeMinItems[i].Name, Size) == 0)
            return MimeMinItems[i].Data;
   }
   return NULL;
}

/**
 * Search the list of major MIME viewers for a Method that matches 'Key'.
 * 'Key' is the content-type string that identifies the MIME type
 */
static Viewer_t Mime_major_type_fetch(const char *Key, uint_t Size)
{
   int i;

   if (Size) {
      for ( i = 0; i < MimeMajItemsSize; ++i )
         if (dStrnAsciiCasecmp(Key, MimeMajItems[i].Name, Size) == 0)
            return MimeMajItems[i].Data;
   }
   return NULL;
}


/**
 * Initializes Mime module and, sets the supported Mime types.
 */
void a_Mime_init(void)
{
#ifdef ENABLE_GIF
   Mime_add_minor_type("image/gif", a_Dicache_gif_image);
#endif
#ifdef ENABLE_JPEG
   Mime_add_minor_type("image/jpeg", a_Dicache_jpeg_image);
   Mime_add_minor_type("image/pjpeg", a_Dicache_jpeg_image);
   Mime_add_minor_type("image/jpg", a_Dicache_jpeg_image);
#endif
#ifdef ENABLE_PNG
   Mime_add_minor_type("image/png", a_Dicache_png_image);
   Mime_add_minor_type("image/x-png", a_Dicache_png_image);    /* deprecated */
#endif
#ifdef ENABLE_WEBP
   Mime_add_minor_type("image/webp", a_Dicache_webp_image);
#endif
#ifdef ENABLE_SVG
   Mime_add_minor_type("image/svg+xml", a_Dicache_svg_image);
#endif
   Mime_add_minor_type("text/html", a_Html_text);
   Mime_add_minor_type("application/xhtml+xml", a_Html_text);
   Mime_add_minor_type("application/json", a_Plain_text);

   /* Add a major type to handle all the text stuff */
   Mime_add_major_type("text", a_Plain_text);
}


/**
 * Get the handler for the MIME type.
 *
 * Return Value:
 *   On success: viewer
 *   On failure: NULL
 */
Viewer_t a_Mime_get_viewer(const char *content_type)
{
   Viewer_t viewer;
   uint_t MinSize, MajSize, i;
   const char *str = content_type;

   MajSize = 0;
   for (i = 0; str[i] && str[i] != ' ' && str[i] != ';'; ++i) {
      if (str[i] == '/' && !MajSize)
         MajSize = i;
   }
   MinSize = i;

   viewer = Mime_minor_type_fetch(content_type, MinSize);
   if (!viewer)
      viewer = Mime_major_type_fetch(content_type, MajSize);

   return viewer;
}