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 | */ |
29 | int |
30 | wsrep_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 | */ |
70 | int |
71 | wsrep_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 | |