1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROMEOS_DBUS_IBUS_IBUS_OBJECT_H_ 6 #define CHROMEOS_DBUS_IBUS_IBUS_OBJECT_H_ 7 8 #include <map> 9 #include <string> 10 11 #include "base/basictypes.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "chromeos/chromeos_export.h" 14 #include "chromeos/dbus/ibus/ibus_property.h" 15 #include "chromeos/dbus/ibus/ibus_text.h" 16 17 namespace base { 18 class Value; 19 } // namespace base 20 21 namespace dbus { 22 class MessageReader; 23 class MessageWriter; 24 } // namespace dbus 25 26 namespace chromeos { 27 28 // The data structure of IBusObject is represented as variant in "(sav...)" 29 // signature. The IBusObject is constructed with two sections, header and 30 // contents. The header section is represent as "sav" which contains type name 31 // and attachment array. The contents section is corresponding to "..." in 32 // above signature, which can store arbitrary type values including IBusObject. 33 // 34 // DATA STRUCTURE OVERVIEW: 35 // 36 // variant // Handle with top_variant_writer_/top_variant_reader_. 37 // struct { // Handle with contents_writer_/contents_reader_. 38 // // Header section 39 // string typename // The type name of object, like "IBusText" 40 // array [ // attachment array. 41 // dict_entry ( 42 // string "mozc.candidates" // The key in the dictionary entry. 43 // variant ... // The value in the dictionary entry. 44 // ) 45 // ... 46 // ] 47 // 48 // // Contents section 49 // ... // The contents area. 50 // } 51 // 52 // EXAMPLE: IBusText 53 // 54 // variant struct { 55 // string "IBusText" // Header of IBusText 56 // array[] 57 // string "A" // The 1st value of IBusText 58 // variant struct { // THe 2nd value of IBusText 59 // string "IBusAttrList" // Header of IBusAttrList 60 // array[] 61 // array[ // The 1st value of IBusAttrList 62 // variant struct{ 63 // string "IBusAttribute" // Header of IBusAttribute 64 // array[] 65 // uint32 1 // The 1st value of IBusAttribute 66 // uint32 1 // The 2nd value of IBusAttribute 67 // uint32 0 // The 3rd value of IBusAttribute 68 // uint32 1 // The 4th value of IBusAttribute 69 // } 70 // ] 71 // } 72 // } 73 // 74 // The IBusObjectReader class provides reading IBusObject including attachment 75 // field from dbus message. This class checks the IBusObject header structure 76 // and type name before reading contents. 77 // 78 // EXAPMLE USAGE: 79 // // Creates reader for IBusText 80 // IBusObjectReader object_reader("IBusText", &reader); 81 // 82 // // Initialize for reading attachment field. 83 // object_reader.Init(); 84 // 85 // // Get attachment field. 86 // base::Value* value = object_reader.GetAttachment("annotation"); 87 // 88 // std::string text; 89 // reader.PopString(&text); // Reading 1st value as string. 90 // 91 // // We can also read nested IBusObject. 92 // IBusObjectReader nested_object_reader("IBusAttrList", NULL); 93 // reader.PopIBusObject(&nested_object_reader); 94 class CHROMEOS_EXPORT IBusObjectReader { 95 public: 96 // |reader| must be released by caller. 97 IBusObjectReader(const std::string& type_name, 98 dbus::MessageReader* reader); 99 virtual ~IBusObjectReader(); 100 101 // Reads IBusObject headers and checks if the type name is valid. 102 // Returns true on success. Uses InitWitAttachmentReader instead if you want 103 // to read attachment field. 104 bool Init(); 105 106 // Reads IBusOBject with |reader| and checks if the type name is valid. 107 bool InitWithParentReader(dbus::MessageReader* reader); 108 109 // Returns true if the IBusObject is valid. 110 bool IsValid() const; 111 112 // The following functions delegate dbus::MessageReader's functions. 113 bool PopString(std::string* out); 114 bool PopUint32(uint32* out); 115 bool PopArray(dbus::MessageReader* reader); 116 bool PopBool(bool* out); 117 bool PopInt32(int32* out); 118 bool HasMoreData(); 119 120 // Sets up |reader| for reading an IBusObject entry. 121 bool PopIBusObject(IBusObjectReader* reader); 122 123 // Pops a IBusText. 124 // Returns true on success. 125 bool PopIBusText(IBusText* text); 126 127 // Pops a IBusText and store it's text field into |text|. Use PopIBusText 128 // instead in the case of using any attribute entries in IBusText. 129 // Return true on success. 130 bool PopStringFromIBusText(std::string* text); 131 132 // Pops a IBusProperty. 133 bool PopIBusProperty(IBusProperty* property); 134 135 // Pops a IBusPropertyList. 136 bool PopIBusPropertyList(IBusPropertyList* property_list); 137 138 // Gets attachment entry corresponding to |key|. Do not free returned value. 139 // Returns NULL if there is no entry. 140 const base::Value* GetAttachment(const std::string& key); 141 142 private: 143 enum CheckResult { 144 IBUS_OBJECT_VALID, // Already checked and valid type. 145 IBUS_OBJECT_INVALID, // Already checked but invalid type. 146 IBUS_OBJECT_NOT_CHECKED, // Not checked yet. 147 }; 148 149 std::string type_name_; 150 dbus::MessageReader* original_reader_; 151 scoped_ptr<dbus::MessageReader> top_variant_reader_; 152 scoped_ptr<dbus::MessageReader> contents_reader_; 153 CheckResult check_result_; 154 std::map<std::string, base::Value*> attachments_; 155 156 DISALLOW_COPY_AND_ASSIGN(IBusObjectReader); 157 }; 158 159 // IBusObjectWriter class provides writing IBusObject to dbus message. This 160 // class appends header section before appending contents values. 161 // IBusObjectWriter does not support writing attachment field because writing 162 // attachment field is not used in Chrome. 163 // 164 // EXAMPLE USAGE: 165 // // Creates writer for IBusText 166 // IBusObjectWriter object_writer("IBusText", "sv", &writer); 167 // 168 // // Add some attachments. 169 // base::Value* value = base::Value::CreateStringValue("Noun"); 170 // object_writer.AddAttachment("annotation", *value); 171 // 172 // // Close header section. 173 // object_writer.CloseHeader(); 174 // 175 // const std::string text = "Sample Text"; 176 // writer.AppendString(text); 177 // 178 // // We can also write nested IBusObject. 179 // IBusObjectWriter nested_object_writer("IBusAttrList", "av"); 180 // object_writer.AppendIBusObject(&nested_object_writer); 181 // ... appends values 182 // 183 // nested_object_writer.CloseAll(); // To finish up, should call CloseAll. 184 // object_writer.CloseAll(); 185 class CHROMEOS_EXPORT IBusObjectWriter { 186 public: 187 enum WriterState { 188 NOT_INITIALZED, // Created but not initialized. 189 HEADER_OPEN, // Ready for writing attachment field. 190 INITIALIZED // Ready for writing content values. 191 }; 192 193 // |writer| must be released by caller. 194 IBusObjectWriter(const std::string& type_name, 195 const std::string& signature, 196 dbus::MessageWriter* writer); 197 virtual ~IBusObjectWriter(); 198 199 // Closes header to write content values. 200 void CloseHeader(); 201 202 // Appends IBusObject headers with |writer|, should be called once. 203 void InitWithParentWriter(dbus::MessageWriter* writer); 204 205 // Adds an attachment, this function can be called only before CloseHeader 206 // function call. 207 bool AddAttachment(const std::string& key, const base::Value& value); 208 209 // The following functions delegate dbus::MessageReader's functions. 210 void AppendString(const std::string& input); 211 void AppendUint32(uint32 value); 212 void AppendInt32(int32 value); 213 void AppendBool(bool value); 214 void OpenArray(const std::string& signature, 215 dbus::MessageWriter* writer); 216 void CloseContainer(dbus::MessageWriter* writer); 217 218 // Sets up |writer| for writing new IBusObject entry. 219 void AppendIBusObject(IBusObjectWriter* writer); 220 221 // Closes all opened containers. 222 void CloseAll(); 223 224 // Appends a IBusText. 225 void AppendIBusText(const IBusText& text); 226 227 // Appends a string as IBusText without any attributes. Use AppendIBusText 228 // instead in the case of using any attribute entries. 229 void AppendStringAsIBusText(const std::string& text); 230 231 // Appends a IBusProperty. 232 void AppendIBusProperty(const IBusProperty& property); 233 234 // Appends a IBusPropertyList. 235 void AppendIBusPropertyList(const IBusPropertyList& property_list); 236 237 private: 238 // Appends IBusObject headers, should be called once. 239 void Init(); 240 241 std::string type_name_; 242 std::string signature_; 243 dbus::MessageWriter* original_writer_; 244 WriterState state_; 245 scoped_ptr<dbus::MessageWriter> top_variant_writer_; 246 scoped_ptr<dbus::MessageWriter> contents_writer_; 247 scoped_ptr<dbus::MessageWriter> attachment_writer_; 248 249 DISALLOW_COPY_AND_ASSIGN(IBusObjectWriter); 250 }; 251 252 } // namespace chromeos 253 254 #endif // CHROMEOS_DBUS_IBUS_IBUS_OBJECT_H_ 255