Libav 0.7.1
libavformat/md5proto.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2010 Mans Rullgard
00003  *
00004  * This file is part of Libav.
00005  *
00006  * Libav is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * Libav is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with Libav; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00019  */
00020 
00021 #include <stdio.h>
00022 #include "libavutil/avstring.h"
00023 #include "libavutil/md5.h"
00024 #include "libavutil/mem.h"
00025 #include "libavutil/error.h"
00026 #include "avformat.h"
00027 #include "avio.h"
00028 #include "url.h"
00029 
00030 #define PRIV_SIZE 128
00031 
00032 static int md5_open(URLContext *h, const char *filename, int flags)
00033 {
00034     if (PRIV_SIZE < av_md5_size) {
00035         av_log(NULL, AV_LOG_ERROR, "Insuffient size for MD5 context\n");
00036         return -1;
00037     }
00038 
00039     if (!flags & AVIO_FLAG_WRITE)
00040         return AVERROR(EINVAL);
00041 
00042     av_md5_init(h->priv_data);
00043 
00044     return 0;
00045 }
00046 
00047 static int md5_write(URLContext *h, const unsigned char *buf, int size)
00048 {
00049     av_md5_update(h->priv_data, buf, size);
00050     return size;
00051 }
00052 
00053 static int md5_close(URLContext *h)
00054 {
00055     const char *filename = h->filename;
00056     uint8_t md5[16], buf[64];
00057     URLContext *out;
00058     int i, err = 0;
00059 
00060     av_md5_final(h->priv_data, md5);
00061     for (i = 0; i < sizeof(md5); i++)
00062         snprintf(buf + i*2, 3, "%02x", md5[i]);
00063     buf[i*2] = '\n';
00064 
00065     av_strstart(filename, "md5:", &filename);
00066 
00067     if (*filename) {
00068         err = ffurl_open(&out, filename, AVIO_FLAG_WRITE);
00069         if (err)
00070             return err;
00071         err = ffurl_write(out, buf, i*2+1);
00072         ffurl_close(out);
00073     } else {
00074         if (fwrite(buf, 1, i*2+1, stdout) < i*2+1)
00075             err = AVERROR(errno);
00076     }
00077 
00078     return err;
00079 }
00080 
00081 static int md5_get_handle(URLContext *h)
00082 {
00083     return (intptr_t)h->priv_data;
00084 }
00085 
00086 URLProtocol ff_md5_protocol = {
00087     .name                = "md5",
00088     .url_open            = md5_open,
00089     .url_write           = md5_write,
00090     .url_close           = md5_close,
00091     .url_get_file_handle = md5_get_handle,
00092     .priv_data_size      = PRIV_SIZE,
00093 };