summaryrefslogtreecommitdiff
path: root/riscos/filetype.c
blob: 13b2f9aca19bb3b83d5edf8621a6bcb75344ff4c (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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/*
 * This file is part of NetSurf, http://netsurf.sourceforge.net/
 * Licensed under the GNU General Public License,
 *                http://www.opensource.org/licenses/gpl-license
 * Copyright 2004 James Bursa <bursa@users.sourceforge.net>
 */

#include <stdlib.h>
#include <string.h>
#include <unixlib/local.h>
#include "oslib/mimemap.h"
#include "oslib/osfile.h"
#include "netsurf/content/content.h"
#include "netsurf/content/fetch.h"
#include "netsurf/riscos/gui.h"
#include "netsurf/utils/config.h"
#include "netsurf/utils/log.h"
#include "netsurf/utils/utils.h"

/* type_map must be in sorted order by file_type */
struct type_entry {
	bits file_type;
	char mime_type[40];
};
static const struct type_entry type_map[] = {
        {0x188, "application/x-shockwave-flash"},
	{0x695, "image/gif"},
	{0xaff, "image/x-drawfile"},
	{0xb60, "image/png"},
	{0xc85, "image/jpeg"},
	{0xf78, "image/jng"},
	{0xf79, "text/css"},
	{0xf83, "image/mng"},
	{0xfaf, "text/html"},
	{0xff9, "image/x-riscos-sprite"},
	{0xfff, "text/plain"},
};
#define TYPE_MAP_COUNT (sizeof(type_map) / sizeof(type_map[0]))


static int cmp_type(const void *x, const void *y);


/**
 * Determine the MIME type of a local file.
 */

const char *fetch_filetype(const char *unix_path)
{
	struct type_entry *t;
	unsigned int len = strlen(unix_path) + 100;
	char *path = calloc(len, 1);
	char *r;
	os_error *error;
	bits file_type;

	if (!path) {
	  	LOG(("Insuficient memory for calloc"));
	  	warn_user("NoMemory", 0);
	  	return "application/riscos";
	}
	LOG(("unix_path = '%s'", unix_path));

	/* convert path to RISC OS format and read file type */
	r = __riscosify(unix_path, 0, __RISCOSIFY_NO_SUFFIX, path, len, 0);
	if (r == 0) {
		LOG(("__riscosify failed"));
		return "application/riscos";
	}
	LOG(("riscos path '%s'", path));

	error = xosfile_read_stamped_no_path(path, 0, 0, 0, 0, 0, &file_type);
	if (error != 0) {
		LOG(("xosfile_read_stamped_no_path failed: %s", error->errmess));
		return "application/riscos";
	}

	/* search for MIME type */
	t = bsearch(&file_type, type_map, TYPE_MAP_COUNT, sizeof(type_map[0]), cmp_type);
	if (t == 0)
		return "application/riscos";
	LOG(("mime type '%s'", t->mime_type));
	return t->mime_type;
}


char *fetch_mimetype(const char *ro_path) {

        os_error *e;
        bits filetype = 0, load;
        int objtype;
        char *mime = calloc(256, sizeof(char));

	if (!mime) {
	  	LOG(("Insuficient memory for calloc"));
	  	warn_user("NoMemory", 0);
	  	return 0;
	}

        e = xosfile_read_no_path(ro_path, &objtype, &load, 0, 0, 0);
        if (e) return 0;

        if (objtype == 0x2) return 0; /* directories are pointless */

        if ((load >> 20) & 0xFFF) {
                filetype = (load>>8) & 0x000FFF;
        }
        else {
                return 0; /* no idea */
        }

        e = xmimemaptranslate_filetype_to_mime_type(filetype, mime);
        if (e) return 0;

        return mime;
}


int cmp_type(const void *x, const void *y)
{
	const bits *p = x;
	const struct type_entry *q = y;
	return *p < q->file_type ? -1 : (*p == q->file_type ? 0 : +1);
}


/**
 * Determine the RISC OS filetype for a content.
 */

int ro_content_filetype(struct content *content)
{
	int file_type;
	os_error *error;

	switch (content->type) {
		case CONTENT_HTML:	return 0xfaf;
		case CONTENT_TEXTPLAIN:	return 0xfff;
		case CONTENT_CSS:	return 0xf79;
#ifdef WITH_MNG
		case CONTENT_JNG:	return 0xf78;
		case CONTENT_MNG:	return 0xf84;
#endif
#ifdef WITH_JPEG
		case CONTENT_JPEG:	return 0xc85;
#endif
#ifdef WITH_PNG
		case CONTENT_PNG:	return 0xb60;
#endif
#ifdef WITH_GIF
		case CONTENT_GIF:	return 0x695;
#endif
#ifdef WITH_SPRITE
		case CONTENT_SPRITE:	return 0xff9;
#endif
#ifdef WITH_DRAW
		case CONTENT_DRAW:	return 0xaff;
#endif
		default:		break;
	}

	error = xmimemaptranslate_mime_type_to_filetype(content->mime_type,
			&file_type);
	if (error)
		return 0xffd;
	return file_type;
}