Home | History | Annotate | Download | only in ibus
      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