Statistics
| Branch: | Revision:

ffmpeg / libavutil / file.c @ 490a022d

History | View | Annotate | Download (3.85 KB)

1
/*
2
 * This file is part of Libav.
3
 *
4
 * Libav is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2.1 of the License, or (at your option) any later version.
8
 *
9
 * Libav is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15
 * License along with Libav; if not, write to the Free Software
16
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
 */
18

    
19
#include "file.h"
20
#include <fcntl.h>
21
#include <sys/stat.h>
22
#include <unistd.h>
23
#if HAVE_MMAP
24
#include <sys/mman.h>
25
#elif HAVE_MAPVIEWOFFILE
26
#include <io.h>
27
#include <windows.h>
28
#endif
29

    
30
typedef struct {
31
    const AVClass *class;
32
    int   log_offset;
33
    void *log_ctx;
34
} FileLogContext;
35

    
36
static const AVClass file_log_ctx_class = {
37
    "FILE", av_default_item_name, NULL, LIBAVUTIL_VERSION_INT,
38
    offsetof(FileLogContext, log_offset), offsetof(FileLogContext, log_ctx)
39
};
40

    
41
int av_file_map(const char *filename, uint8_t **bufptr, size_t *size,
42
                int log_offset, void *log_ctx)
43
{
44
    FileLogContext file_log_ctx = { &file_log_ctx_class, log_offset, log_ctx };
45
    int err, fd = open(filename, O_RDONLY);
46
    struct stat st;
47
    av_unused void *ptr;
48
    off_t off_size;
49
    char errbuf[128];
50
    *bufptr = NULL;
51

    
52
    if (fd < 0) {
53
        err = AVERROR(errno);
54
        av_strerror(err, errbuf, sizeof(errbuf));
55
        av_log(&file_log_ctx, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename, errbuf);
56
        return err;
57
    }
58

    
59
    if (fstat(fd, &st) < 0) {
60
        err = AVERROR(errno);
61
        av_strerror(err, errbuf, sizeof(errbuf));
62
        av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in fstat(): %s\n", errbuf);
63
        close(fd);
64
        return err;
65
    }
66

    
67
    off_size = st.st_size;
68
    if (off_size > SIZE_MAX) {
69
        av_log(&file_log_ctx, AV_LOG_ERROR,
70
               "File size for file '%s' is too big\n", filename);
71
        close(fd);
72
        return AVERROR(EINVAL);
73
    }
74
    *size = off_size;
75

    
76
#if HAVE_MMAP
77
    ptr = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
78
    if ((int)(ptr) == -1) {
79
        err = AVERROR(errno);
80
        av_strerror(err, errbuf, sizeof(errbuf));
81
        av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in mmap(): %s\n", errbuf);
82
        close(fd);
83
        return err;
84
    }
85
    *bufptr = ptr;
86
#elif HAVE_MAPVIEWOFFILE
87
    {
88
        HANDLE mh, fh = (HANDLE)_get_osfhandle(fd);
89

    
90
        mh = CreateFileMapping(fh, NULL, PAGE_READONLY, 0, 0, NULL);
91
        if (!mh) {
92
            av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in CreateFileMapping()\n");
93
            close(fd);
94
            return -1;
95
        }
96

    
97
        ptr = MapViewOfFile(mh, FILE_MAP_READ, 0, 0, *size);
98
        CloseHandle(mh);
99
        if (!ptr) {
100
            av_log(&file_log_ctx, AV_LOG_ERROR, "Error occurred in MapViewOfFile()\n");
101
            close(fd);
102
            return -1;
103
        }
104

    
105
        *bufptr = ptr;
106
    }
107
#else
108
    *bufptr = av_malloc(*size);
109
    if (!*bufptr) {
110
        av_log(&file_log_ctx, AV_LOG_ERROR, "Memory allocation error occurred\n");
111
        close(fd);
112
        return AVERROR(ENOMEM);
113
    }
114
    read(fd, *bufptr, *size);
115
#endif
116

    
117
    close(fd);
118
    return 0;
119
}
120

    
121
void av_file_unmap(uint8_t *bufptr, size_t size)
122
{
123
#if HAVE_MMAP
124
    munmap(bufptr, size);
125
#elif HAVE_MAPVIEWOFFILE
126
    UnmapViewOfFile(bufptr);
127
#else
128
    av_free(bufptr);
129
#endif
130
}
131

    
132
#ifdef TEST
133

    
134
#undef printf
135

    
136
int main(void)
137
{
138
    uint8_t *buf;
139
    size_t size;
140
    if (av_file_map("file.c", &buf, &size, 0, NULL) < 0)
141
        return 1;
142

    
143
    buf[0] = 's';
144
    printf("%s", buf);
145
    av_file_unmap(buf, size);
146
    return 0;
147
}
148
#endif