1/* 2 * Copyright (c) 2022 Pierre-Anthony Lemieux <pal@palemieux.com> 3 * Zane van Iperen <zane@zanevaniperen.com> 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/* 23 * Copyright (C) 1996, 1997 Theodore Ts'o. 24 * 25 * Redistribution and use in source and binary forms, with or without 26 * modification, are permitted provided that the following conditions 27 * are met: 28 * 1. Redistributions of source code must retain the above copyright 29 * notice, and the entire permission notice in its entirety, 30 * including the disclaimer of warranties. 31 * 2. Redistributions in binary form must reproduce the above copyright 32 * notice, this list of conditions and the following disclaimer in the 33 * documentation and/or other materials provided with the distribution. 34 * 3. The name of the author may not be used to endorse or promote 35 * products derived from this software without specific prior 36 * written permission. 37 * 38 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 39 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 40 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF 41 * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE 42 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 43 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 44 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 45 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 46 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 47 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 48 * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH 49 * DAMAGE. 50 */ 51 52/** 53 * @file 54 * UUID parsing and serialization utilities. 55 * The library treat the UUID as an opaque sequence of 16 unsigned bytes, 56 * i.e. ignoring the internal layout of the UUID, which depends on the type 57 * of the UUID. 58 * 59 * @author Pierre-Anthony Lemieux <pal@palemieux.com> 60 * @author Zane van Iperen <zane@zanevaniperen.com> 61 */ 62 63#include "uuid.h" 64#include "error.h" 65#include "avstring.h" 66 67int av_uuid_parse(const char *in, AVUUID uu) 68{ 69 if (strlen(in) != 36) 70 return AVERROR(EINVAL); 71 72 return av_uuid_parse_range(in, in + 36, uu); 73} 74 75static int xdigit_to_int(char c) 76{ 77 c = av_tolower(c); 78 79 if (c >= 'a' && c <= 'f') 80 return c - 'a' + 10; 81 82 if (c >= '0' && c <= '9') 83 return c - '0'; 84 85 return -1; 86} 87 88int av_uuid_parse_range(const char *in_start, const char *in_end, AVUUID uu) 89{ 90 int i; 91 const char *cp; 92 93 if ((in_end - in_start) != 36) 94 return AVERROR(EINVAL); 95 96 for (i = 0, cp = in_start; i < 16; i++) { 97 int hi; 98 int lo; 99 100 if (i == 4 || i == 6 || i == 8 || i == 10) 101 cp++; 102 103 hi = xdigit_to_int(*cp++); 104 lo = xdigit_to_int(*cp++); 105 106 if (hi == -1 || lo == -1) 107 return AVERROR(EINVAL); 108 109 uu[i] = (hi << 4) + lo; 110 } 111 112 return 0; 113} 114 115static const char hexdigits_lower[16] = "0123456789abcdef"; 116 117void av_uuid_unparse(const AVUUID uuid, char *out) 118{ 119 char *p = out; 120 121 for (int i = 0; i < 16; i++) { 122 uint8_t tmp; 123 124 if (i == 4 || i == 6 || i == 8 || i == 10) 125 *p++ = '-'; 126 127 tmp = uuid[i]; 128 *p++ = hexdigits_lower[tmp >> 4]; 129 *p++ = hexdigits_lower[tmp & 15]; 130 } 131 132 *p = '\0'; 133} 134 135int av_uuid_urn_parse(const char *in, AVUUID uu) 136{ 137 if (av_stristr(in, "urn:uuid:") != in) 138 return AVERROR(EINVAL); 139 140 return av_uuid_parse(in + 9, uu); 141} 142