1/* Copyright (C) 2009 Codership Oy <info@codersihp.com>
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
15 */
16
17/*! @file Helper functions to deal with history UUID string representations */
18
19#include <errno.h>
20#include <ctype.h>
21#include <stdio.h>
22
23#include "wsrep_api.h"
24
25/*!
26 * Read UUID from string
27 * @return length of UUID string representation or -EINVAL in case of error
28 */
29int
30wsrep_uuid_scan (const char* str, size_t str_len, wsrep_uuid_t* uuid)
31{
32 unsigned int uuid_len = 0;
33 unsigned int uuid_offt = 0;
34
35 while (uuid_len + 1 < str_len) {
36 /* We are skipping potential '-' after uuid_offt == 4, 6, 8, 10
37 * which means
38 * (uuid_offt >> 1) == 2, 3, 4, 5,
39 * which in turn means
40 * (uuid_offt >> 1) - 2 <= 3
41 * since it is always >= 0, because uuid_offt is unsigned */
42 if (((uuid_offt >> 1) - 2) <= 3 && str[uuid_len] == '-') {
43 // skip dashes after 4th, 6th, 8th and 10th positions
44 uuid_len += 1;
45 continue;
46 }
47
48 if (isxdigit(str[uuid_len]) && isxdigit(str[uuid_len + 1])) {
49 // got hex digit, scan another byte to uuid, increment uuid_offt
50 sscanf (str + uuid_len, "%2hhx", uuid->data + uuid_offt);
51 uuid_len += 2;
52 uuid_offt += 1;
53 if (sizeof (uuid->data) == uuid_offt)
54 return uuid_len;
55 }
56 else {
57 break;
58 }
59 }
60
61 *uuid = WSREP_UUID_UNDEFINED;
62 return -EINVAL;
63}
64
65/*!
66 * Write UUID to string
67 * @return length of UUID string representation or -EMSGSIZE if string is too
68 * short
69 */
70int
71wsrep_uuid_print (const wsrep_uuid_t* uuid, char* str, size_t str_len)
72{
73 if (str_len > 36) {
74 const unsigned char* u = uuid->data;
75 return snprintf(str, str_len, "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
76 "%02x%02x-%02x%02x%02x%02x%02x%02x",
77 u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
78 u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15]);
79 }
80 else {
81 return -EMSGSIZE;
82 }
83}
84