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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_DBUS_IBUS_IBUS_OBJECT_H_
#define CHROMEOS_DBUS_IBUS_IBUS_OBJECT_H_
#include <map>
#include <string>
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/ibus/ibus_property.h"
#include "chromeos/dbus/ibus/ibus_text.h"
namespace base {
class Value;
} // namespace base
namespace dbus {
class MessageReader;
class MessageWriter;
} // namespace dbus
namespace chromeos {
// TODO(nona): Remove ibus namespace after complete libibus removal.
namespace ibus {
// The data structure of IBusObject is represented as variant in "(sav...)"
// signature. The IBusObject is constructed with two sections, header and
// contents. The header section is represent as "sav" which contains type name
// and attachment array. The contents section is corresponding to "..." in
// above signature, which can store arbitrary type values including IBusObject.
//
// DATA STRUCTURE OVERVIEW:
//
// variant // Handle with top_variant_writer_/top_variant_reader_.
// struct { // Handle with contents_writer_/contents_reader_.
// // Header section
// string typename // The type name of object, like "IBusText"
// array [ // attachment array.
// dict_entry (
// string "mozc.candidates" // The key in the dictionary entry.
// variant ... // The value in the dictionary entry.
// )
// ...
// ]
//
// // Contents section
// ... // The contents area.
// }
//
// EXAMPLE: IBusText
//
// variant struct {
// string "IBusText" // Header of IBusText
// array[]
// string "A" // The 1st value of IBusText
// variant struct { // THe 2nd value of IBusText
// string "IBusAttrList" // Header of IBusAttrList
// array[]
// array[ // The 1st value of IBusAttrList
// variant struct{
// string "IBusAttribute" // Header of IBusAttribute
// array[]
// uint32 1 // The 1st value of IBusAttribute
// uint32 1 // The 2nd value of IBusAttribute
// uint32 0 // The 3rd value of IBusAttribute
// uint32 1 // The 4th value of IBusAttribute
// }
// ]
// }
// }
//
// The IBusObjectReader class provides reading IBusObject including attachment
// field from dbus message. This class checks the IBusObject header structure
// and type name before reading contents.
//
// EXAPMLE USAGE:
// // Creates reader for IBusText
// IBusObjectReader object_reader("IBusText", &reader);
//
// // Initialize for reading attachment field.
// object_reader.Init();
//
// // Get attachment field.
// base::Value* value = object_reader.GetAttachment("annotation");
//
// std::string text;
// reader.PopString(&text); // Reading 1st value as string.
//
// // We can also read nested IBusObject.
// IBusObjectReader nested_object_reader("IBusAttrList", NULL);
// reader.PopIBusObject(&nested_object_reader);
class CHROMEOS_EXPORT IBusObjectReader {
public:
// |reader| must be released by caller.
IBusObjectReader(const std::string& type_name,
dbus::MessageReader* reader);
virtual ~IBusObjectReader();
// Reads IBusObject headers and checks if the type name is valid.
// Returns true on success. Uses InitWitAttachmentReader instead if you want
// to read attachment field.
bool Init();
// Reads IBusOBject with |reader| and checks if the type name is valid.
bool InitWithParentReader(dbus::MessageReader* reader);
// Returns true if the IBusObject is valid.
bool IsValid() const;
// The following functions delegate dbus::MessageReader's functions.
bool PopString(std::string* out);
bool PopUint32(uint32* out);
bool PopArray(dbus::MessageReader* reader);
bool PopBool(bool* out);
bool PopInt32(int32* out);
bool HasMoreData();
// Sets up |reader| for reading an IBusObject entry.
bool PopIBusObject(IBusObjectReader* reader);
// Pops a IBusText.
// Returns true on success.
bool PopIBusText(ibus::IBusText* text);
// Pops a IBusText and store it's text field into |text|. Use PopIBusText
// instead in the case of using any attribute entries in IBusText.
// Return true on success.
bool PopStringFromIBusText(std::string* text);
// Pops a IBusProperty.
bool PopIBusProperty(ibus::IBusProperty* property);
// Pops a IBusPropertyList.
bool PopIBusPropertyList(ibus::IBusPropertyList* property_list);
// Gets attachment entry corresponding to |key|. Do not free returned value.
// Returns NULL if there is no entry.
const base::Value* GetAttachment(const std::string& key);
private:
enum CheckResult {
IBUS_OBJECT_VALID, // Already checked and valid type.
IBUS_OBJECT_INVALID, // Already checked but invalid type.
IBUS_OBJECT_NOT_CHECKED, // Not checked yet.
};
std::string type_name_;
dbus::MessageReader* original_reader_;
scoped_ptr<dbus::MessageReader> top_variant_reader_;
scoped_ptr<dbus::MessageReader> contents_reader_;
CheckResult check_result_;
std::map<std::string, base::Value*> attachments_;
DISALLOW_COPY_AND_ASSIGN(IBusObjectReader);
};
// IBusObjectWriter class provides writing IBusObject to dbus message. This
// class appends header section before appending contents values.
// IBusObjectWriter does not support writing attachment field because writing
// attachment field is not used in Chrome.
//
// EXAMPLE USAGE:
// // Creates writer for IBusText
// IBusObjectWriter object_writer("IBusText", "sv", &writer);
//
// // Add some attachments.
// base::Value* value = base::Value::CreateStringValue("Noun");
// object_writer.AddAttachment("annotation", *value);
//
// // Close header section.
// object_writer.CloseHeader();
//
// const std::string text = "Sample Text";
// writer.AppendString(text);
//
// // We can also write nested IBusObject.
// IBusObjectWriter nested_object_writer("IBusAttrList", "av");
// object_writer.AppendIBusObject(&nested_object_writer);
// ... appends values
//
// nested_object_writer.CloseAll(); // To finish up, should call CloseAll.
// object_writer.CloseAll();
class CHROMEOS_EXPORT IBusObjectWriter {
public:
enum WriterState {
NOT_INITIALZED, // Created but not initialized.
HEADER_OPEN, // Ready for writing attachment field.
INITIALIZED // Ready for writing content values.
};
// |writer| must be released by caller.
IBusObjectWriter(const std::string& type_name,
const std::string& signature,
dbus::MessageWriter* writer);
virtual ~IBusObjectWriter();
// Closes header to write content values.
void CloseHeader();
// Appends IBusObject headers with |writer|, should be called once.
void InitWithParentWriter(dbus::MessageWriter* writer);
// Adds an attachment, this function can be called only before CloseHeader
// function call.
bool AddAttachment(const std::string& key, const base::Value& value);
// The following functions delegate dbus::MessageReader's functions.
void AppendString(const std::string& input);
void AppendUint32(uint32 value);
void AppendInt32(int32 value);
void AppendBool(bool value);
void OpenArray(const std::string& signature,
dbus::MessageWriter* writer);
void CloseContainer(dbus::MessageWriter* writer);
// Sets up |writer| for writing new IBusObject entry.
void AppendIBusObject(IBusObjectWriter* writer);
// Closes all opened containers.
void CloseAll();
// Appends a IBusText.
void AppendIBusText(const ibus::IBusText& text);
// Appends a string as IBusText without any attributes. Use AppendIBusText
// instead in the case of using any attribute entries.
void AppendStringAsIBusText(const std::string& text);
// Appends a IBusProperty.
void AppendIBusProperty(const ibus::IBusProperty& property);
// Appends a IBusPropertyList.
void AppendIBusPropertyList(const ibus::IBusPropertyList& property_list);
private:
// Appends IBusObject headers, should be called once.
void Init();
std::string type_name_;
std::string signature_;
dbus::MessageWriter* original_writer_;
WriterState state_;
scoped_ptr<dbus::MessageWriter> top_variant_writer_;
scoped_ptr<dbus::MessageWriter> contents_writer_;
scoped_ptr<dbus::MessageWriter> attachment_writer_;
DISALLOW_COPY_AND_ASSIGN(IBusObjectWriter);
};
} // namespace ibus
} // namespace chromeos
#endif // CHROMEOS_DBUS_IBUS_IBUS_OBJECT_H_
|