Xpace
translate_string_node.h
Go to the documentation of this file.
1 
2 /**********************************************************//**
3  **
4  ** @file data/translate_string_node.h
5  **
6  ** Copyright (C) 2012 Xpace, LLC. All rights reserved
7  **
8  ** www.xpace.net
9  **
10  **************************************************************/
11 
12 #ifndef XPACE_TRANSLATE_STRING_NODE_H
13 #define XPACE_TRANSLATE_STRING_NODE_H
14 
15 #include <iterator>
16 
17 #include <QtCore/qstring.h>
18 
19 #include "data/data.h"
20 #include "base/config.h"
21 #include "base/integer.h"
22 #include "base/datetime.h"
23 #include "util/matchstring.h"
24 
25 #if _WIN32 || _WIN64
26 # pragma warning(push)
27 # pragma warning(disable : 4355)
28 #endif
29 
30 namespace Xpace
31 {
32  // ================================ TRANSLATIONS ============
33 
34  /// Called on translation error
35  /// @param ch the offending character
36  /// @param term the offending term
37  /// @return true to accept the term as far as possible, false to skip it
38  typedef std::function<bool(utf16_t ch, const String& term)> TranslationError;
39 
40  /// Default error handler
41  inline
42  bool default_on_error
44  const String&)
45  {
46  return true;
47  }
48 
50  {
51  static const char *VECTOR_TAG, *SUBTYPE_TAG, *COUNT_TAG;
53  static const char *NUMERAL_TAG;
54  static const char *DELIMS_TAG;
55  };
56 
57  /// Translate content
58  /// Input can be anything
59  /// Output is to a Sink<LOC> so must be one of its supported types
60  template <typename LOC>
61  class TranslateNode
62  {
63  public:
64  virtual ~TranslateNode
65  ()
66  {
67  }
68 
69  // the output type of this translator
70  const BaseDataType& getType
71  ()
72  const
73  {
74  return type;
75  }
76 
77  class unknownType : public Exception
78  {
79  public:
82  Exception("Unknown type \"%1\".")
83  {
84  addParam(type);
85  }
86  };
87 
88  protected:
90  (const BaseDataType& t,
91  Sink<LOC>* s,
92  TranslationError onErr = default_on_error) :
93  type(t),
94  sink(s)
95  {
96  }
97 
98  TranslationError onError;
99 
100  private:
101  const BaseDataType type;
102 
103  protected:
105  LOC loc;
106  };
107 
108  // ================================ FROM STRING =============
109 
110  template<typename LOC, typename STR>
111  class TranslateString : public TranslateNode<LOC>
112  {
113  public:
114  static
115  TranslateString* create
116  (const Configuration& config,
117  Sink<LOC>* sink,
118  TranslationError onError = default_on_error);
119 
120  virtual bool operator()
121  (const STR)
122  = 0;
123 
124  protected:
127  Sink<LOC>* sink,
128  TranslationError onError) :
129  TranslateNode<LOC>(t, sink, onError)
130  {
131  }
132  };
133 
134  template<typename LOC, typename STR>
135  class SkipStringNode : public TranslateString<LOC, STR>
136  {
137  public:
139  () :
141  {
142  }
143 
144  virtual bool operator()
145  (const STR) override
146  {
147  return true;
148  }
149  };
150 
151  // ================================ STRING ==================
152 
153  template<typename LOC, typename STR>
154  class TranslateStringString : public TranslateString<LOC, STR>
155  {
156  public:
158  (const String& name,
159  Sink<LOC>* s,
160  TranslationError onError = default_on_error) :
161  TranslateString<LOC, STR>(BaseDataType::stringType<STR>().getBaseType(), s, onError)
162  {
163  this->loc = this->sink->add(name, BaseDataType::stringType<STR>().getBaseType(), ~0);
164  }
165 
167  (const Configuration& config,
168  Sink<LOC>* sink,
169  TranslationError onError = default_on_error) :
170  TranslateString<LOC, STR>(BaseDataType::stringType<STR>().getBaseType(), sink, onError)
171  {
172  this->loc = sink->add(config, ~0);
173  }
174 
175  bool operator()
176  (const STR val) override
177  {
178  return this->sink->set(this->loc, val);
179  }
180  };
181 
182  // ================================ INTEGER =================
183 
184  template<typename LOC, typename STR>
185  class TranslateStringUint : public TranslateString<LOC, STR>
186  {
187  public:
189  (uint size,
190  uint radix,
191  Sink<LOC>* s,
192  TranslationError onErr = default_on_error) :
194  radix(radix)
195  {
196  this->loc = this->sink->add(this->name, BaseDataType::btUint, ~0);
197  }
198 
200  (const Configuration& config,
201  Sink<LOC>* s,
202  TranslationError onErr) :
203  TranslateString<LOC, STR>(BaseDataType(BaseDataType::btUint, size_t(config.getValueInt(TranslateNames::SIZE_TAG, 8))), s, onErr),
204  radix(uint(config.getValueInt(TranslateNames::RADIX_TAG, 10)))
205  {
206  this->loc = this->sink->add(config, ~0);
207  }
208 
209  bool operator()
210  (const STR val) override
211  {
212  if (!stringToUint(val, radix, &buf))
213  return true;
214 
215  return (buf.size() <= 1)
216  ? this->sink->set(this->loc, buf[0])
217  : this->sink->set(this->loc, BytesRef(reinterpret_cast<byte*>(&buf[0]), sizeof(buf[0]) * buf.size()));
218  }
219 
220  private:
221  const uint radix;
222  std::vector<uint64> buf;
223  };
224 
225  template<typename LOC, typename STR>
226  class TranslateStringInt : public TranslateString<LOC, STR>
227  {
228  public:
230  (uint size,
231  uint radix,
232  Sink<LOC>* s,
233  TranslationError onErr = default_on_error) :
235  radix(radix)
236  {
237  this->loc = this->sink->add(this->name, BaseDataType::btInt, ~0);
238  }
239 
241  (const Configuration& config,
242  Sink<LOC>* s,
243  TranslationError onErr) :
245  radix(uint(config.getValueInt(TranslateNames::RADIX_TAG, 10)))
246  {
247  this->loc = this->sink->add(config, ~0);
248  }
249 
250  virtual bool operator()
251  (const STR val) override
252  {
253  if (!stringToInt(val, radix, &buf))
254  return true;
255 
256  return (buf.size() <= 1)
257  ? this->sink->set(this->loc, int64(buf[0]))
258  : this->sink->set(this->loc, BytesRef(reinterpret_cast<byte*>(&buf[0]), sizeof(buf[0]) * buf.size()));
259  }
260 
261  private:
262  const uint radix;
263  std::vector<uint64> buf;
264  };
265 
266  #ifdef XPACE_DECIMAL_FLOAT_H
267  // ================================ FLOAT ===================
268 
269  template<typename LOC, typename STR>
270  class TranslateStringFloat : public TranslateString<LOC, STR>
271  {
272  public:
273  TranslateStringFloat
274  (const Configuration& config,
275  Sink<LOC>* s,
276  TranslationError onErr) :
278  precision(uint(config.getValueInt(PRECISION_TAG)))
279  {
280  this->loc = this->sink->add(config, ~0);
281  }
282 
283  bool operator()
284  (const STR val) override
285  {
286  return this->sink->set(this->loc, DecimalFloat(val));
287  }
288 
289  private:
290  const String PRECISION_TAG;
291  const uint precision;
292  };
293  #endif
294 
295  // ================================ DATE-TIME ===============
296 
297  template<typename LOC, typename STR>
298  class TranslateStringDateTime : public TranslateString<LOC, STR>
299  {
300  public:
302  (const String& fmt,
303  Sink<LOC>* s,
304  TranslationError onErr) :
306  format(fmt)
307  {
308  this->loc = this->sink->add(this->name, BaseDataType::btInt, ~0);
309  }
310 
312  (const Configuration& config,
313  Sink<LOC>* s,
314  TranslationError onErr) :
315  TranslateString<LOC, STR>(BaseDataType(BaseDataType::btInt, sizeof(int64)), s, onErr),
316  format(config.getValue(TranslateNames::FORMAT_TAG))
317  {
318  if (!format)
320  this->loc = this->sink->add(config, ~0);
321  }
322 
323  virtual bool operator()
324  (const STR val) override
325  {
326  return this->sink->set(this->loc, DateTime(String(val.data, val.length), format).toInt());
327  }
328 
329  private:
330  const String format;
331  };
332 
333  // ================================ IPv4 ====================
334 
335  template<typename LOC, typename STR>
336  class TranslateStringIPv4 : public TranslateString<LOC, STR>
337  {
338  public:
340  (const Configuration& config,
341  Sink<LOC>* s,
342  TranslationError onErr) :
343  TranslateString<LOC, STR>(BaseDataType(BaseDataType::btInt, sizeof(int64)), s, onErr),
344  matcher(!!config.getValue(TranslateNames::FORMAT_TAG) ? config.getValue(TranslateNames::FORMAT_TAG) : "a.a.a.a"),
345  has_addrs(matcher.add(typename STR::charType('a'), IntWrapper<_addrs>(&addrs))),
346  has_port(matcher.add(typename STR::charType('p'), IntWrapper<_num>(&port))),
347  has_xnum(matcher.add(typename STR::charType('n'), IntWrapper<_num>(&xnum)))
348  {
349  QString name(config.getTag());
350  if (!!has_addrs)
351  addrs_loc = this->sink->add(name + ".addrs", DerivedDataType::dtIPv4, ~0);
352  if (!!has_port)
353  port_loc = this->sink->add(name + ".port", BaseDataType::btUint, ~0);
354  if (!!has_xnum)
355  xnum_loc = this->sink->add(name + ".xnum", BaseDataType::btUint, ~0);
356  }
357 
358  virtual bool operator()
359  (const STR val) override
360  {
361  addrs.reset();
362  port.reset();
363  if (matcher.match(val))
364  {
365  int64 n;
366  return (!has_addrs || !addrs.get(&n) || this->sink->set(addrs_loc, n)) &&
367  (!has_port || !port.get(&n) || this->sink->set(port_loc, n)) &&
368  (!has_xnum || !xnum.get(&n) || this->sink->set(xnum_loc, n));
369  }
370  return true;
371  }
372 
373  private:
374  const String format;
375 
376  MatchString<STR> matcher;
377 
378  bool has_addrs, has_port, has_xnum;
379  uint addrs_loc, port_loc, xnum_loc;
380 
381  struct _addrs
382  {
383  void reset
384  ()
385  {
386  val = cnt = 0;
387  }
388 
389  bool operator()
390  (int64 n)
391  {
392  ++cnt;
393  assert(n < 256);
394  val <<= 8;
395  val += n;
396  return true;
397  }
398 
399  bool get
400  (int64* n)
401  const
402  {
403  return (cnt == 4) ? (*n = val, true) : false;
404  }
405 
406  int64 val;
407  uint cnt;
408 
409  } addrs;
410 
411  struct _num
412  {
413  void reset
414  ()
415  {
416  num = -1;
417  }
418 
419  bool operator()
420  (int64 n)
421  {
422  num = n;
423  return true;
424  }
425 
426  bool get
427  (int64* n)
428  {
429  return (num == -1) ? false : (*n = num, true);
430  }
431 
432  int64 num;
433 
434  } port, xnum;
435  };
436 
437  // ==========================================================
438  // ==========================================================
439  // ==========================================================
440 
441  template<typename LOC, typename STR>
442  inline
444  (const Configuration& config,
445  Sink<LOC>* sink,
446  TranslationError onError)
447  {
449 
450  #ifndef NDEBUG
451  QString qconfig(config.toString());
452  QString qtype(type);
453  #endif
454 
455  DerivedDataType dt(type);
456  switch (dt.getDerivedType())
457  {
459  return new TranslateStringDateTime<LOC, STR>(config, sink, onError);
461  return new TranslateStringIPv4<LOC, STR>(config, sink, onError);
462  default:
463  break;
464  }
465  switch (dt.getBaseType())
466  {
469  return new TranslateStringString<LOC, STR>(config, sink, onError);
470  case BaseDataType::btUint:
471  return new TranslateStringUint<LOC, STR>(config, sink, onError);
472  case BaseDataType::btInt:
473  return new TranslateStringInt<LOC, STR>(config, sink, onError);
474  #ifdef XPACE_DECIMAL_FLOAT_H
476  return new TranslateStringFloat<LOC, STR>(config, sink, onError);
477  #endif
478  default:
479  break;
480  }
481 
482  return new SkipStringNode<LOC, STR>();
483  }
484 }
485 
486 #if _WIN32 || _WIN64
487 # pragma warning(pop)
488 #endif
489 
490 #endif
const Xpace_Char16 Xpace_Data_Type type
Definition: table_c.h:141
virtual RET set(LOC location, int64 value)
Write an int64.
Definition: data.h:357
Ref< byte > BytesRef
Definition: types.h:180
unsigned int uint
Definition: types.h:75
type getBaseType() const
Definition: data.h:517
Copyright (C) 2012 Xpace, LLC.
Each high-level Xpace object has a Configuration.
Definition: config.h:29
static const char * FORMAT_TAG
A string, Unicode UTF-16 and reference-counted.
Definition: types.h:269
static const char * COUNT_TAG
unsigned short utf16_t
Definition: types.h:146
A floatimg-point number with explicit mantissa and decimals TODO: normalize.
Definition: decimalfloat.h:33
static const char * PRECISION_TAG
Copyright (C) 2012 Xpace, LLC.
type getDerivedType() const
Definition: data.h:551
Can&#39;t find a named value.
Definition: config.h:283
bool stringToInt(const String8 &str, uint radix, std::vector< uint64 > *val)
int64 getValueInt(const String &tag=String(), int64 def=0, bool *ok=0) const
String getValue(const String &tag=String()) const
get a node&#39;s value or an attribute search for attribute first, then child value
static TranslateString * create(const Configuration &config, Sink< LOC > *sink, TranslationError onError=default_on_error)
static const char * RADIX_TAG
static const char * NUMERAL_TAG
const Xpace_Char16 * name
Sink callbacks for table data.
Definition: table_c.h:141
bool stringToUint(const String8 &str, uint radix, std::vector< uint64 > *val)
static const char * DELIMS_TAG
static const char * SUBTYPE_TAG
static const char * SIZE_TAG
static const char * VECTOR_TAG
String toString() const
static const char * TYPE_TAG
Definition: data.h:469
long long int64
Definition: types.h:86
static const char * LENGTH_TAG
uint uint64 Xpace_Table_Sink * sink
Definition: table_c.h:340
String getTag() const
virtual LOC add(const String &name, DerivedDataType type, LOC location, bool *added=0)
Add a field by name.
Definition: data.h:319
Translate content Input can be anything Output is to a Sink<LOC> so must be one of its supported type...
Definition: node.h:82
std::function< bool(utf16_t ch, const String &term)> TranslationError
Called on translation error.
Xpace project main namespace
Definition: datetime.h:18
class XPACE_EXPORT DateTime
Definition: datetime.h:20
bool default_on_error(utf16_t, const String &)
Default error handler.

current as of Wed Jun 10 2026 12:00:05