1 /* id.c : operations on node-revision IDs
2 *
3 * ====================================================================
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 * ====================================================================
21 */
22
23 #include <string.h>
24 #include <stdlib.h>
25
26 #include "id.h"
27 #include "../libsvn_fs/fs-loader.h"
28
29
30
31 typedef struct id_private_t {
32 const char *node_id;
33 const char *copy_id;
34 const char *txn_id;
35 } id_private_t;
36
37
38 /* Accessing ID Pieces. */
39
40 const char *
svn_fs_base__id_node_id(const svn_fs_id_t * id)41 svn_fs_base__id_node_id(const svn_fs_id_t *id)
42 {
43 id_private_t *pvt = id->fsap_data;
44
45 return pvt->node_id;
46 }
47
48
49 const char *
svn_fs_base__id_copy_id(const svn_fs_id_t * id)50 svn_fs_base__id_copy_id(const svn_fs_id_t *id)
51 {
52 id_private_t *pvt = id->fsap_data;
53
54 return pvt->copy_id;
55 }
56
57
58 const char *
svn_fs_base__id_txn_id(const svn_fs_id_t * id)59 svn_fs_base__id_txn_id(const svn_fs_id_t *id)
60 {
61 id_private_t *pvt = id->fsap_data;
62
63 return pvt->txn_id;
64 }
65
66
67 svn_string_t *
svn_fs_base__id_unparse(const svn_fs_id_t * id,apr_pool_t * pool)68 svn_fs_base__id_unparse(const svn_fs_id_t *id,
69 apr_pool_t *pool)
70 {
71 id_private_t *pvt = id->fsap_data;
72
73 return svn_string_createf(pool, "%s.%s.%s",
74 pvt->node_id, pvt->copy_id, pvt->txn_id);
75 }
76
77
78 /*** Comparing node IDs ***/
79
80 svn_boolean_t
svn_fs_base__id_eq(const svn_fs_id_t * a,const svn_fs_id_t * b)81 svn_fs_base__id_eq(const svn_fs_id_t *a,
82 const svn_fs_id_t *b)
83 {
84 id_private_t *pvta = a->fsap_data, *pvtb = b->fsap_data;
85
86 if (a == b)
87 return TRUE;
88 if (strcmp(pvta->node_id, pvtb->node_id) != 0)
89 return FALSE;
90 if (strcmp(pvta->copy_id, pvtb->copy_id) != 0)
91 return FALSE;
92 if (strcmp(pvta->txn_id, pvtb->txn_id) != 0)
93 return FALSE;
94 return TRUE;
95 }
96
97
98 svn_boolean_t
svn_fs_base__id_check_related(const svn_fs_id_t * a,const svn_fs_id_t * b)99 svn_fs_base__id_check_related(const svn_fs_id_t *a,
100 const svn_fs_id_t *b)
101 {
102 id_private_t *pvta = a->fsap_data, *pvtb = b->fsap_data;
103
104 if (a == b)
105 return TRUE;
106
107 return (strcmp(pvta->node_id, pvtb->node_id) == 0);
108 }
109
110
111 svn_fs_node_relation_t
svn_fs_base__id_compare(const svn_fs_id_t * a,const svn_fs_id_t * b)112 svn_fs_base__id_compare(const svn_fs_id_t *a,
113 const svn_fs_id_t *b)
114 {
115 if (svn_fs_base__id_eq(a, b))
116 return svn_fs_node_unchanged;
117 return (svn_fs_base__id_check_related(a, b) ? svn_fs_node_common_ancestor
118 : svn_fs_node_unrelated);
119 }
120
121
122
123 /* Creating ID's. */
124
125 static id_vtable_t id_vtable = {
126 svn_fs_base__id_unparse,
127 svn_fs_base__id_compare
128 };
129
130
131 svn_fs_id_t *
svn_fs_base__id_create(const char * node_id,const char * copy_id,const char * txn_id,apr_pool_t * pool)132 svn_fs_base__id_create(const char *node_id,
133 const char *copy_id,
134 const char *txn_id,
135 apr_pool_t *pool)
136 {
137 svn_fs_id_t *id = apr_palloc(pool, sizeof(*id));
138 id_private_t *pvt = apr_palloc(pool, sizeof(*pvt));
139
140 pvt->node_id = apr_pstrdup(pool, node_id);
141 pvt->copy_id = apr_pstrdup(pool, copy_id);
142 pvt->txn_id = apr_pstrdup(pool, txn_id);
143 id->vtable = &id_vtable;
144 id->fsap_data = pvt;
145 return id;
146 }
147
148
149 svn_fs_id_t *
svn_fs_base__id_copy(const svn_fs_id_t * id,apr_pool_t * pool)150 svn_fs_base__id_copy(const svn_fs_id_t *id, apr_pool_t *pool)
151 {
152 svn_fs_id_t *new_id = apr_palloc(pool, sizeof(*new_id));
153 id_private_t *new_pvt = apr_palloc(pool, sizeof(*new_pvt));
154 id_private_t *pvt = id->fsap_data;
155
156 new_pvt->node_id = apr_pstrdup(pool, pvt->node_id);
157 new_pvt->copy_id = apr_pstrdup(pool, pvt->copy_id);
158 new_pvt->txn_id = apr_pstrdup(pool, pvt->txn_id);
159 new_id->vtable = &id_vtable;
160 new_id->fsap_data = new_pvt;
161 return new_id;
162 }
163
164
165 svn_fs_id_t *
svn_fs_base__id_parse(const char * data,apr_size_t len,apr_pool_t * pool)166 svn_fs_base__id_parse(const char *data,
167 apr_size_t len,
168 apr_pool_t *pool)
169 {
170 svn_fs_id_t *id;
171 id_private_t *pvt;
172 char *data_copy, *str;
173
174 /* Dup the ID data into POOL. Our returned ID will have references
175 into this memory. */
176 data_copy = apr_pstrmemdup(pool, data, len);
177
178 /* Alloc a new svn_fs_id_t structure. */
179 id = apr_palloc(pool, sizeof(*id));
180 pvt = apr_palloc(pool, sizeof(*pvt));
181 id->vtable = &id_vtable;
182 id->fsap_data = pvt;
183
184 /* Now, we basically just need to "split" this data on `.'
185 characters. We will use svn_cstring_tokenize, which will put
186 terminators where each of the '.'s used to be. Then our new
187 id field will reference string locations inside our duplicate
188 string.*/
189
190 /* Node Id */
191 str = svn_cstring_tokenize(".", &data_copy);
192 if (str == NULL)
193 return NULL;
194 pvt->node_id = str;
195
196 /* Copy Id */
197 str = svn_cstring_tokenize(".", &data_copy);
198 if (str == NULL)
199 return NULL;
200 pvt->copy_id = str;
201
202 /* Txn Id */
203 str = svn_cstring_tokenize(".", &data_copy);
204 if (str == NULL)
205 return NULL;
206 pvt->txn_id = str;
207
208 return id;
209 }
210