monotone

monotone Mtn Source Tree

Root/src/vocab.cc

1// Copyright (C) 2002 Graydon Hoare <graydon@pobox.com>
2//
3// This program is made available under the GNU GPL version 2.0 or
4// greater. See the accompanying file COPYING for details.
5//
6// This program is distributed WITHOUT ANY WARRANTY; without even the
7// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8// PURPOSE.
9
10
11#include "base.hh"
12#include "constants.hh"
13#include "hash_map.hh"
14#include "sanity.hh"
15#include "vocab.hh"
16#include "char_classifiers.hh"
17#include "transforms.hh"
18
19using std::string;
20
21std::string immutable_string::empty;
22
23// verifiers for various types of data
24
25// Every ENCODING and ATOMIC type not defined with the _NOVERIFY variant in
26// vocab_terms.hh must have a verify function defined here. DECORATE types
27// use the verify function of their inner type.
28
29// ENCODING types ... hexenc<id> has a fixed size, hexenc<other> doesn't.
30template <typename INNER>
31inline void
32verify(hexenc<INNER> const & val)
33{
34 for (string::const_iterator i = val().begin(); i != val().end(); ++i)
35 {
36 E(is_xdigit(*i), val.made_from,
37 F("bad character '%c' in '%s'") % *i % val);
38 }
39}
40
41template <>
42inline void
43verify(hexenc<id> const & val)
44{
45 if (val().empty())
46 return;
47
48 E(val().size() == constants::idlen, val.made_from,
49 F("hex encoded ID '%s' size != %d") % val % constants::idlen);
50 for (string::const_iterator i = val().begin(); i != val().end(); ++i)
51 {
52 E(is_xdigit(*i), val.made_from,
53 F("bad character '%c' in id name '%s'") % *i % val);
54 }
55}
56
57// ATOMIC types ...
58inline void
59verify(id & val)
60{
61 if (val().empty())
62 return;
63
64 E(val().size() == constants::idlen_bytes, val.made_from,
65 F("invalid ID '%s'") % val);
66}
67
68inline void
69verify(symbol const & val)
70{
71 for (string::const_iterator i = val().begin(); i != val().end(); ++i)
72 {
73 E(is_alnum(*i) || *i == '_', val.made_from,
74 F("bad character '%c' in symbol '%s'") % *i % val);
75 }
76}
77
78inline void
79verify(cert_name const & val)
80{
81 string::size_type pos = val().find_first_not_of(constants::legal_cert_name_bytes);
82 E(pos == string::npos, val.made_from,
83 F("bad character '%c' in cert name '%s'") % val().at(pos) % val);
84}
85
86inline void
87verify(key_name const & val)
88{
89 string::size_type pos = val().find_first_not_of(constants::legal_key_name_bytes);
90 E(pos == string::npos, val.made_from,
91 F("bad character '%c' in key name '%s'") % val().at(pos) % val);
92}
93
94// These two may modify their argument, to set a more sensible value when
95// initializing from the empty string or the default constructor; therefore
96// they cannot take a const argument and must be friends with their class.
97
98inline void
99verify(netsync_session_key & val)
100{
101 if (val().empty())
102 {
103 val.s = std::string(constants::netsync_session_key_length_in_bytes, 0);
104 return;
105 }
106
107 E(val().size() == constants::netsync_session_key_length_in_bytes,
108 val.made_from,
109 F("invalid key length of %d bytes") % val().length());
110}
111
112inline void
113verify(netsync_hmac_value & val)
114{
115 if (val().empty())
116 {
117 val.s = std::string(constants::netsync_hmac_value_length_in_bytes, 0);
118 return;
119 }
120
121 E(val().size() == constants::netsync_hmac_value_length_in_bytes,
122 val.made_from,
123 F("invalid hmac length of %d bytes") % val().length());
124}
125
126
127// Note that ATOMIC types each keep a static symbol-table object and a
128// counter of activations, and when there is an activation, the
129// members of the ATOMIC type initialize their internal string using a
130// copy of the string found in the symtab. Since some (all?) C++
131// string implementations are copy-on-write, this has the affect
132// of making the ATOMIC(foo) values constructed within a symbol table
133// scope share string storage.
134struct
135symtab_impl
136{
137 typedef hashmap::hash_set<string> hset;
138 hset vals;
139 symtab_impl() : vals() {}
140 void clear() { vals.clear(); }
141 string const & unique(string const & in)
142 {
143 // This produces a pair <iter,bool> where iter points to an
144 // element of the table; the bool indicates whether the element is
145 // new, but we don't actually care. We just want the iter.
146 return *(vals.insert(in).first);
147 }
148};
149
150// Sometimes it's handy to have a non-colliding, meaningless id.
151
152id
153fake_id()
154{
155 static u32 counter = 0;
156 ++counter;
157 I(counter >= 1); // detect overflow
158 string s((FL("00000000000000000000000000000000%08x") % counter).str());
159 return id(decode_hexenc(s, origin::internal), origin::internal);
160}
161
162// instantiation of various vocab functions
163
164
165
166#include "vocab_macros.hh"
167#define ENCODING(enc) cc_ENCODING(enc)
168#define ENCODING_NOVERIFY(enc) cc_ENCODING_NOVERIFY(enc)
169#define DECORATE(dec) cc_DECORATE(dec)
170#define ATOMIC(ty) cc_ATOMIC(ty)
171#define ATOMIC_HOOKED(ty,hook) cc_ATOMIC(ty)
172#define ATOMIC_NOVERIFY(ty) cc_ATOMIC_NOVERIFY(ty)
173#define ATOMIC_BINARY(ty) cc_ATOMIC_BINARY(ty)
174
175#undef EXTERN
176#define EXTERN
177
178#include "vocab_terms.hh"
179
180#undef EXTERN
181#undef ATOMIC
182#undef ATOMIC_HOOKED
183#undef ATOMIC_NOVERIFY
184#undef DECORATE
185#undef ENCODING
186#undef ENCODING_NOVERIFY
187
188template void dump(revision_id const & r, string &);
189template void dump(manifest_id const & r, string &);
190template void dump(file_id const & r, string &);
191template void dump(hexenc<id> const & r, string &);
192template void dump(key_id const & r, string &);
193template void dump(rsa_pub_key const&, string &);
194template void dump(roster_data const & d, string &);
195template void dump(roster_delta const & d, string &);
196template void dump(manifest_data const & d, string &);
197template void dump(revision_data const & d, string &);
198
199template std::ostream & operator<< <>(std::ostream &, epoch<id> const &);
200template std::ostream & operator<< <>(std::ostream &, file<id> const &);
201template std::ostream & operator<< <>(std::ostream &, hexenc<id> const &);
202template std::ostream & operator<< <>(std::ostream &, key<id> const &);
203template std::ostream & operator<< <>(std::ostream &, manifest<id> const &);
204template std::ostream & operator<< <>(std::ostream &, revision<id> const &);
205template std::ostream & operator<< <>(std::ostream &, roster<id> const &);
206
207template std::ostream & operator<< <>(std::ostream &, epoch<data> const &);
208template std::ostream & operator<< <>(std::ostream &, file<data> const &);
209template std::ostream & operator<< <>(std::ostream &, manifest<data> const &);
210template std::ostream & operator<< <>(std::ostream &, revision<data> const &);
211template std::ostream & operator<< <>(std::ostream &, roster<data> const &);
212
213/*
214 * specializations for id, which allows the encoded id
215 * to be dumped out as a human readable, hex encoded
216 * string.
217 */
218template <>
219void dump (id const & obj, std::string & out)
220{
221 out = encode_hexenc(obj(), obj.made_from);
222}
223
224
225// Local Variables:
226// mode: C++
227// fill-column: 76
228// c-file-style: "gnu"
229// indent-tabs-mode: nil
230// End:
231// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status