1251881Speter/* id.c : operations on node-revision IDs
2251881Speter *
3251881Speter * ====================================================================
4251881Speter *    Licensed to the Apache Software Foundation (ASF) under one
5251881Speter *    or more contributor license agreements.  See the NOTICE file
6251881Speter *    distributed with this work for additional information
7251881Speter *    regarding copyright ownership.  The ASF licenses this file
8251881Speter *    to you under the Apache License, Version 2.0 (the
9251881Speter *    "License"); you may not use this file except in compliance
10251881Speter *    with the License.  You may obtain a copy of the License at
11251881Speter *
12251881Speter *      http://www.apache.org/licenses/LICENSE-2.0
13251881Speter *
14251881Speter *    Unless required by applicable law or agreed to in writing,
15251881Speter *    software distributed under the License is distributed on an
16251881Speter *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17251881Speter *    KIND, either express or implied.  See the License for the
18251881Speter *    specific language governing permissions and limitations
19251881Speter *    under the License.
20251881Speter * ====================================================================
21251881Speter */
22251881Speter
23251881Speter#include <string.h>
24251881Speter#include <stdlib.h>
25251881Speter
26251881Speter#include "id.h"
27251881Speter#include "../libsvn_fs/fs-loader.h"
28251881Speter
29251881Speter
30251881Speter
31251881Spetertypedef struct id_private_t {
32251881Speter  const char *node_id;
33251881Speter  const char *copy_id;
34251881Speter  const char *txn_id;
35251881Speter} id_private_t;
36251881Speter
37251881Speter
38251881Speter/* Accessing ID Pieces.  */
39251881Speter
40251881Speterconst char *
41251881Spetersvn_fs_base__id_node_id(const svn_fs_id_t *id)
42251881Speter{
43251881Speter  id_private_t *pvt = id->fsap_data;
44251881Speter
45251881Speter  return pvt->node_id;
46251881Speter}
47251881Speter
48251881Speter
49251881Speterconst char *
50251881Spetersvn_fs_base__id_copy_id(const svn_fs_id_t *id)
51251881Speter{
52251881Speter  id_private_t *pvt = id->fsap_data;
53251881Speter
54251881Speter  return pvt->copy_id;
55251881Speter}
56251881Speter
57251881Speter
58251881Speterconst char *
59251881Spetersvn_fs_base__id_txn_id(const svn_fs_id_t *id)
60251881Speter{
61251881Speter  id_private_t *pvt = id->fsap_data;
62251881Speter
63251881Speter  return pvt->txn_id;
64251881Speter}
65251881Speter
66251881Speter
67251881Spetersvn_string_t *
68251881Spetersvn_fs_base__id_unparse(const svn_fs_id_t *id,
69251881Speter                        apr_pool_t *pool)
70251881Speter{
71251881Speter  id_private_t *pvt = id->fsap_data;
72251881Speter
73251881Speter  return svn_string_createf(pool, "%s.%s.%s",
74251881Speter                            pvt->node_id, pvt->copy_id, pvt->txn_id);
75251881Speter}
76251881Speter
77251881Speter
78251881Speter/*** Comparing node IDs ***/
79251881Speter
80251881Spetersvn_boolean_t
81251881Spetersvn_fs_base__id_eq(const svn_fs_id_t *a,
82251881Speter                   const svn_fs_id_t *b)
83251881Speter{
84251881Speter  id_private_t *pvta = a->fsap_data, *pvtb = b->fsap_data;
85251881Speter
86251881Speter  if (a == b)
87251881Speter    return TRUE;
88251881Speter  if (strcmp(pvta->node_id, pvtb->node_id) != 0)
89251881Speter     return FALSE;
90251881Speter  if (strcmp(pvta->copy_id, pvtb->copy_id) != 0)
91251881Speter    return FALSE;
92251881Speter  if (strcmp(pvta->txn_id, pvtb->txn_id) != 0)
93251881Speter    return FALSE;
94251881Speter  return TRUE;
95251881Speter}
96251881Speter
97251881Speter
98251881Spetersvn_boolean_t
99251881Spetersvn_fs_base__id_check_related(const svn_fs_id_t *a,
100251881Speter                              const svn_fs_id_t *b)
101251881Speter{
102251881Speter  id_private_t *pvta = a->fsap_data, *pvtb = b->fsap_data;
103251881Speter
104251881Speter  if (a == b)
105251881Speter    return TRUE;
106251881Speter
107251881Speter  return (strcmp(pvta->node_id, pvtb->node_id) == 0);
108251881Speter}
109251881Speter
110251881Speter
111251881Speterint
112251881Spetersvn_fs_base__id_compare(const svn_fs_id_t *a,
113251881Speter                        const svn_fs_id_t *b)
114251881Speter{
115251881Speter  if (svn_fs_base__id_eq(a, b))
116251881Speter    return 0;
117251881Speter  return (svn_fs_base__id_check_related(a, b) ? 1 : -1);
118251881Speter}
119251881Speter
120251881Speter
121251881Speter
122251881Speter/* Creating ID's.  */
123251881Speter
124251881Speterstatic id_vtable_t id_vtable = {
125251881Speter  svn_fs_base__id_unparse,
126251881Speter  svn_fs_base__id_compare
127251881Speter};
128251881Speter
129251881Speter
130251881Spetersvn_fs_id_t *
131251881Spetersvn_fs_base__id_create(const char *node_id,
132251881Speter                       const char *copy_id,
133251881Speter                       const char *txn_id,
134251881Speter                       apr_pool_t *pool)
135251881Speter{
136251881Speter  svn_fs_id_t *id = apr_palloc(pool, sizeof(*id));
137251881Speter  id_private_t *pvt = apr_palloc(pool, sizeof(*pvt));
138251881Speter
139251881Speter  pvt->node_id = apr_pstrdup(pool, node_id);
140251881Speter  pvt->copy_id = apr_pstrdup(pool, copy_id);
141251881Speter  pvt->txn_id = apr_pstrdup(pool, txn_id);
142251881Speter  id->vtable = &id_vtable;
143251881Speter  id->fsap_data = pvt;
144251881Speter  return id;
145251881Speter}
146251881Speter
147251881Speter
148251881Spetersvn_fs_id_t *
149251881Spetersvn_fs_base__id_copy(const svn_fs_id_t *id, apr_pool_t *pool)
150251881Speter{
151251881Speter  svn_fs_id_t *new_id = apr_palloc(pool, sizeof(*new_id));
152251881Speter  id_private_t *new_pvt = apr_palloc(pool, sizeof(*new_pvt));
153251881Speter  id_private_t *pvt = id->fsap_data;
154251881Speter
155251881Speter  new_pvt->node_id = apr_pstrdup(pool, pvt->node_id);
156251881Speter  new_pvt->copy_id = apr_pstrdup(pool, pvt->copy_id);
157251881Speter  new_pvt->txn_id = apr_pstrdup(pool, pvt->txn_id);
158251881Speter  new_id->vtable = &id_vtable;
159251881Speter  new_id->fsap_data = new_pvt;
160251881Speter  return new_id;
161251881Speter}
162251881Speter
163251881Speter
164251881Spetersvn_fs_id_t *
165251881Spetersvn_fs_base__id_parse(const char *data,
166251881Speter                      apr_size_t len,
167251881Speter                      apr_pool_t *pool)
168251881Speter{
169251881Speter  svn_fs_id_t *id;
170251881Speter  id_private_t *pvt;
171251881Speter  char *data_copy, *str;
172251881Speter
173251881Speter  /* Dup the ID data into POOL.  Our returned ID will have references
174251881Speter     into this memory. */
175251881Speter  data_copy = apr_pstrmemdup(pool, data, len);
176251881Speter
177251881Speter  /* Alloc a new svn_fs_id_t structure. */
178251881Speter  id = apr_palloc(pool, sizeof(*id));
179251881Speter  pvt = apr_palloc(pool, sizeof(*pvt));
180251881Speter  id->vtable = &id_vtable;
181251881Speter  id->fsap_data = pvt;
182251881Speter
183251881Speter  /* Now, we basically just need to "split" this data on `.'
184251881Speter     characters.  We will use svn_cstring_tokenize, which will put
185251881Speter     terminators where each of the '.'s used to be.  Then our new
186251881Speter     id field will reference string locations inside our duplicate
187251881Speter     string.*/
188251881Speter
189251881Speter  /* Node Id */
190251881Speter  str = svn_cstring_tokenize(".", &data_copy);
191251881Speter  if (str == NULL)
192251881Speter    return NULL;
193251881Speter  pvt->node_id = str;
194251881Speter
195251881Speter  /* Copy Id */
196251881Speter  str = svn_cstring_tokenize(".", &data_copy);
197251881Speter  if (str == NULL)
198251881Speter    return NULL;
199251881Speter  pvt->copy_id = str;
200251881Speter
201251881Speter  /* Txn Id */
202251881Speter  str = svn_cstring_tokenize(".", &data_copy);
203251881Speter  if (str == NULL)
204251881Speter    return NULL;
205251881Speter  pvt->txn_id = str;
206251881Speter
207251881Speter  return id;
208251881Speter}
209