00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 struct MD5Context {
00031 struct AVMD5 *md5;
00032 };
00033
00034 static int md5_open(URLContext *h, const char *filename, int flags)
00035 {
00036 struct MD5Context *c = h->priv_data;
00037
00038 if (!(flags & AVIO_FLAG_WRITE))
00039 return AVERROR(EINVAL);
00040
00041 c->md5 = av_md5_alloc();
00042 if (!c->md5)
00043 return AVERROR(ENOMEM);
00044 av_md5_init(c->md5);
00045
00046 return 0;
00047 }
00048
00049 static int md5_write(URLContext *h, const unsigned char *buf, int size)
00050 {
00051 struct MD5Context *c = h->priv_data;
00052 av_md5_update(c->md5, buf, size);
00053 return size;
00054 }
00055
00056 static int md5_close(URLContext *h)
00057 {
00058 struct MD5Context *c = h->priv_data;
00059 const char *filename = h->filename;
00060 uint8_t md5[16], buf[64];
00061 URLContext *out;
00062 int i, err = 0;
00063
00064 av_md5_final(c->md5, md5);
00065 for (i = 0; i < sizeof(md5); i++)
00066 snprintf(buf + i*2, 3, "%02x", md5[i]);
00067 buf[i*2] = '\n';
00068
00069 av_strstart(filename, "md5:", &filename);
00070
00071 if (*filename) {
00072 err = ffurl_open(&out, filename, AVIO_FLAG_WRITE,
00073 &h->interrupt_callback, NULL);
00074 if (err)
00075 return err;
00076 err = ffurl_write(out, buf, i*2+1);
00077 ffurl_close(out);
00078 } else {
00079 if (fwrite(buf, 1, i*2+1, stdout) < i*2+1)
00080 err = AVERROR(errno);
00081 }
00082
00083 av_freep(&c->md5);
00084
00085 return err;
00086 }
00087
00088
00089 URLProtocol ff_md5_protocol = {
00090 .name = "md5",
00091 .url_open = md5_open,
00092 .url_write = md5_write,
00093 .url_close = md5_close,
00094 .priv_data_size = sizeof(struct MD5Context),
00095 };