File: vocab.cc

package info (click to toggle)
monotone 0.48-3
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 20,096 kB
  • ctags: 8,077
  • sloc: cpp: 81,000; sh: 6,402; perl: 1,241; lisp: 1,045; makefile: 655; python: 566; sql: 112; ansic: 52
file content (231 lines) | stat: -rw-r--r-- 6,911 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
// Copyright (C) 2002 Graydon Hoare <graydon@pobox.com>
//
// This program is made available under the GNU GPL version 2.0 or
// greater. See the accompanying file COPYING for details.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE.


#include "base.hh"
#include "constants.hh"
#include "hash_map.hh"
#include "sanity.hh"
#include "vocab.hh"
#include "char_classifiers.hh"
#include "transforms.hh"

using std::string;

std::string immutable_string::empty;

// verifiers for various types of data

// Every ENCODING and ATOMIC type not defined with the _NOVERIFY variant in
// vocab_terms.hh must have a verify function defined here.  DECORATE types
// use the verify function of their inner type.

// ENCODING types ... hexenc<id> has a fixed size, hexenc<other> doesn't.
template <typename INNER>
inline void
verify(hexenc<INNER> const & val)
{
  for (string::const_iterator i = val().begin(); i != val().end(); ++i)
    {
      E(is_xdigit(*i), val.made_from,
        F("bad character '%c' in '%s'") % *i % val);
    }
}

template <>
inline void
verify(hexenc<id> const & val)
{
  if (val().empty())
    return;

  E(val().size() == constants::idlen, val.made_from,
    F("hex encoded ID '%s' size != %d") % val % constants::idlen);
  for (string::const_iterator i = val().begin(); i != val().end(); ++i)
    {
      E(is_xdigit(*i), val.made_from,
        F("bad character '%c' in id name '%s'") % *i % val);
    }
}

// ATOMIC types ...
inline void
verify(id & val)
{
  if (val().empty())
    return;

  E(val().size() == constants::idlen_bytes, val.made_from,
    F("invalid ID '%s'") % val);
}

inline void
verify(symbol const & val)
{
  for (string::const_iterator i = val().begin(); i != val().end(); ++i)
    {
      E(is_alnum(*i) || *i == '_', val.made_from,
        F("bad character '%c' in symbol '%s'") % *i % val);
    }
}

inline void
verify(cert_name const & val)
{
  string::size_type pos = val().find_first_not_of(constants::legal_cert_name_bytes);
  E(pos == string::npos, val.made_from,
    F("bad character '%c' in cert name '%s'") % val().at(pos) % val);
}

inline void
verify(key_name const & val)
{
  string::size_type pos = val().find_first_not_of(constants::legal_key_name_bytes);
  E(pos == string::npos, val.made_from,
    F("bad character '%c' in key name '%s'") % val().at(pos) % val);
}

// These two may modify their argument, to set a more sensible value when
// initializing from the empty string or the default constructor; therefore
// they cannot take a const argument and must be friends with their class.

inline void
verify(netsync_session_key & val)
{
  if (val().empty())
    {
      val.s = std::string(constants::netsync_session_key_length_in_bytes, 0);
      return;
    }

  E(val().size() == constants::netsync_session_key_length_in_bytes,
    val.made_from,
    F("Invalid key length of %d bytes") % val().length());
}

inline void
verify(netsync_hmac_value & val)
{
  if (val().empty())
    {
      val.s = std::string(constants::netsync_hmac_value_length_in_bytes, 0);
      return;
    }

  E(val().size() == constants::netsync_hmac_value_length_in_bytes,
    val.made_from,
    F("Invalid hmac length of %d bytes") % val().length());
}


// Note that ATOMIC types each keep a static symbol-table object and a
// counter of activations, and when there is an activation, the
// members of the ATOMIC type initialize their internal string using a
// copy of the string found in the symtab. Since some (all?) C++
// string implementations are copy-on-write, this has the affect
// of making the ATOMIC(foo) values constructed within a symbol table
// scope share string storage.
struct
symtab_impl
{
  typedef hashmap::hash_set<string> hset;
  hset vals;
  symtab_impl() : vals() {}
  void clear() { vals.clear(); }
  string const & unique(string const & in)
  {
    // This produces a pair <iter,bool> where iter points to an
    // element of the table; the bool indicates whether the element is
    // new, but we don't actually care. We just want the iter.
    return *(vals.insert(in).first);
  }
};

// Sometimes it's handy to have a non-colliding, meaningless id.

id
fake_id()
{
  static u32 counter = 0;
  ++counter;
  I(counter >= 1); // detect overflow
  string s((FL("00000000000000000000000000000000%08x") % counter).str());
  return id(decode_hexenc(s, origin::internal), origin::internal);
}

// instantiation of various vocab functions



#include "vocab_macros.hh"
#define ENCODING(enc) cc_ENCODING(enc)
#define ENCODING_NOVERIFY(enc) cc_ENCODING_NOVERIFY(enc)
#define DECORATE(dec) cc_DECORATE(dec)
#define ATOMIC(ty) cc_ATOMIC(ty)
#define ATOMIC_HOOKED(ty,hook) cc_ATOMIC(ty)
#define ATOMIC_NOVERIFY(ty) cc_ATOMIC_NOVERIFY(ty)
#define ATOMIC_BINARY(ty) cc_ATOMIC_BINARY(ty)

#undef EXTERN
#define EXTERN

#include "vocab_terms.hh"

#undef EXTERN
#undef ATOMIC
#undef ATOMIC_HOOKED
#undef ATOMIC_NOVERIFY
#undef DECORATE
#undef ENCODING
#undef ENCODING_NOVERIFY

template void dump(revision_id const & r, string &);
template void dump(manifest_id const & r, string &);
template void dump(file_id const & r, string &);
template void dump(hexenc<id> const & r, string &);
template void dump(key_id const & r, string &);
template void dump(rsa_pub_key const&, string &);
template void dump(roster_data const & d, string &);
template void dump(roster_delta const & d, string &);
template void dump(manifest_data const & d, string &);
template void dump(revision_data const & d, string &);

template std::ostream & operator<< <>(std::ostream &,    epoch<id> const &);
template std::ostream & operator<< <>(std::ostream &,     file<id> const &);
template std::ostream & operator<< <>(std::ostream &,   hexenc<id> const &);
template std::ostream & operator<< <>(std::ostream &,      key<id> const &);
template std::ostream & operator<< <>(std::ostream &, manifest<id> const &);
template std::ostream & operator<< <>(std::ostream &, revision<id> const &);
template std::ostream & operator<< <>(std::ostream &,   roster<id> const &);

template std::ostream & operator<< <>(std::ostream &,    epoch<data> const &);
template std::ostream & operator<< <>(std::ostream &,     file<data> const &);
template std::ostream & operator<< <>(std::ostream &, manifest<data> const &);
template std::ostream & operator<< <>(std::ostream &, revision<data> const &);
template std::ostream & operator<< <>(std::ostream &,   roster<data> const &);

/*
 * specializations for id, which allows the encoded id
 * to be dumped out as a human readable, hex encoded
 * string.
 */
template <>
void dump (id const & obj, std::string & out)
{
  out = encode_hexenc(obj(), obj.made_from);
}


// Local Variables:
// mode: C++
// fill-column: 76
// c-file-style: "gnu"
// indent-tabs-mode: nil
// End:
// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s: