Atlas-C++
Packed.h
1 // This file may be redistributed and modified only under the terms of
2 // the GNU Lesser General Public License (See COPYING for details).
3 // Copyright (C) 2000-2001 Stefanus Du Toit, Michael Day
4 
5 // $Id$
6 
7 #ifndef ATLAS_CODECS_PACKED_H
8 #define ATLAS_CODECS_PACKED_H
9 
10 #include <Atlas/Codecs/Utility.h>
11 #include <Atlas/Codec.h>
12 
13 #include <iosfwd>
14 #include <stack>
15 
16 namespace Atlas { namespace Codecs {
17 
18 /*
19 
20 The form for each element of this codec is as follows:
21 
22 [type][name=][data][|endtype]
23 
24 ( ) for lists
25 [ ] for maps
26 $ for string
27 @ for int
28 # for float
29 
30 Sample output for this codec: (whitespace added for clarity)
31 
32 [@id=17$name=Fred +28the +2b great+29#weight=1.5(args=@1@2@3)]
33 
34 The complete specification is located in cvs at:
35  forge/protocols/atlas/spec/packed_syntax.html
36 
37 */
38 
39 class Packed : public Codec
40 {
41 public:
42 
43  Packed(std::istream& in, std::ostream& out, Atlas::Bridge & b);
44 
45  void poll(bool can_read) override;
46 
47  void streamBegin() override;
48  void streamMessage() override;
49  void streamEnd() override;
50 
51  void mapMapItem(std::string name) override;
52  void mapListItem(std::string name) override;
53  void mapIntItem(std::string name, long) override;
54  void mapFloatItem(std::string name, double) override;
55  void mapStringItem(std::string name, std::string) override;
56  void mapEnd() override;
57 
58  void listMapItem() override;
59  void listListItem() override;
60  void listIntItem(long) override;
61  void listFloatItem(double) override;
62  void listStringItem(std::string) override;
63  void listEnd() override;
64 
65 protected:
66 
67  std::istream& m_istream;
68  std::ostream& m_ostream;
69  Bridge & m_bridge;
70 
71  enum State
72  {
73  PARSE_NOTHING,
74  PARSE_STREAM,
75  PARSE_MAP,
76  PARSE_LIST,
77  PARSE_MAP_BEGIN,
78  PARSE_LIST_BEGIN,
79  PARSE_INT,
80  PARSE_FLOAT,
81  PARSE_STRING,
82  PARSE_NAME
83  };
84 
85  std::stack<State> m_state;
86 
87  std::string m_name;
88  std::string m_data;
89 
93  std::string m_encoded;
97  std::string m_decoded;
101  char m_hex[3];
102 
103  void parsingBegins(char);
104  void parseStream(char);
105  void parseMap(char);
106  void parseList(char);
107  void parseMapBegin(char);
108  void parseListBegin(char);
109  void parseInt(char);
110  void parseFloat(char);
111  void parseString(char);
112  void parseName(char);
113 
114  inline std::string hexEncode(std::string data)
115  {
116 
117  for (size_t i = 0; i < data.size(); i++) {
118  char currentChar = data[i];
119 
120  switch(currentChar) {
121  case '+':
122  case '[':
123  case ']':
124  case '(':
125  case ')':
126  case '@':
127  case '#':
128  case '$':
129  case '=':
130  //First special character, use an encoded string instead
131  m_encoded.clear();
132  m_encoded.reserve(data.size() + (data.size() / 4));
133  m_encoded.assign(data, 0, i);
134  for (; i < data.size(); i++) {
135  currentChar = data[i];
136 
137  switch(currentChar) {
138  case '+':
139  case '[':
140  case ']':
141  case '(':
142  case ')':
143  case '@':
144  case '#':
145  case '$':
146  case '=':
147  //First special character, use an encoded string instead
148  m_encoded += '+';
149  m_encoded += charToHex(currentChar);
150  break;
151  default:
152  m_encoded += currentChar;
153  break;
154  }
155  }
156 
157  return std::move(m_encoded);
158  default:
159  break;
160  }
161  }
162 
163  //If no special character, just return the original string, avoiding any allocations.
164  return data;
165  }
166 
167  inline const std::string hexDecode(std::string data)
168  {
169 
170  for (size_t i = 0; i < data.size(); i++) {
171  char currentChar = data[i];
172  if (currentChar == '+') {
173  //First special character, use a decoded string instead
174  m_decoded.clear();
175  m_decoded.reserve(data.size());
176  m_decoded.assign(data, 0, i);
177 
178  for (; i < data.size(); i++) {
179  currentChar = data[i];
180  if (currentChar == '+') {
181  m_hex[0] = data[++i];
182  m_hex[1] = data[++i];
183  m_hex[2] = 0;
184  m_decoded += hexToChar(m_hex);
185  } else {
186  m_decoded += currentChar;
187  }
188  }
189 
190  return std::move(m_decoded);
191  }
192  }
193 
194  //If no special character, just return the original string, avoiding any allocations.
195  return data;
196  }
197 };
198 
199 } } // namespace Atlas::Codecs
200 
201 #endif
const std::string charToHex(char c)
Convert an ASCII char to its hexadecimal value.
Definition: Utility.h:26
Definition: Packed.h:39
std::string m_encoded
Preallocated to increase performance.
Definition: Packed.h:93
Atlas stream bridge.
Definition: Bridge.h:35
void listListItem() override
Starts a list object in the currently streamed list.
char m_hex[3]
Preallocated to increase performance.
Definition: Packed.h:101
Various utility functions for codec implementation.
void mapListItem(std::string name) override
Starts a list object to the currently streamed map.
void listFloatItem(double) override
Adds a float to the currently streamed list.
void streamMessage() override
Start a message in an Atlas stream.
void listEnd() override
Ends the currently streamed list.
void mapEnd() override
Ends the currently streamed map.
The Atlas namespace.
Definition: Bridge.h:20
Atlas stream codec.
Definition: Codec.h:27
void mapFloatItem(std::string name, double) override
Adds a float to the currently streamed map.
std::string m_decoded
Preallocated to increase performance.
Definition: Packed.h:97
void listStringItem(std::string) override
Adds a string to the currently streamed list.
void listMapItem() override
Starts a map object in the currently streamed list.
void streamBegin() override
Begin an Atlas stream.
char hexToChar(const char *hex)
Convert a string with a hexadecimal value (2 characters) to an ASCII char.
Definition: Utility.h:38
void mapMapItem(std::string name) override
Starts a map object to the currently streamed map.
void mapStringItem(std::string name, std::string) override
Adds a string to the currently streamed map.
void mapIntItem(std::string name, long) override
Adds an integer to the currently streames map.
void streamEnd() override
Ends the Atlas stream.
void listIntItem(long) override
Adds an integer to the currently streames list.

Copyright 2000-2004 the respective authors.

This document can be licensed under the terms of the GNU Free Documentation License or the GNU General Public License and may be freely distributed under the terms given by one of these licenses.