Elim cr-checkbox
[chromium-blink-merge.git] / ppapi / proxy / serialized_flash_menu.cc
blobcda9545c89db2909624973aba3835ef92759d9d3
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.
5 #include "ppapi/proxy/serialized_flash_menu.h"
7 #include "ipc/ipc_message.h"
8 #include "ppapi/c/private/ppb_flash_menu.h"
9 #include "ppapi/proxy/ppapi_param_traits.h"
11 namespace ppapi {
12 namespace proxy {
14 namespace {
15 // Maximum depth of submenus allowed (e.g., 1 indicates that submenus are
16 // allowed, but not sub-submenus).
17 const int kMaxMenuDepth = 2;
18 const uint32_t kMaxMenuEntries = 1000;
20 bool CheckMenu(int depth, const PP_Flash_Menu* menu);
21 void FreeMenu(const PP_Flash_Menu* menu);
22 void WriteMenu(IPC::Message* m, const PP_Flash_Menu* menu);
23 PP_Flash_Menu* ReadMenu(int depth,
24 const IPC::Message* m,
25 base::PickleIterator* iter);
27 bool CheckMenuItem(int depth, const PP_Flash_MenuItem* item) {
28 if (item->type == PP_FLASH_MENUITEM_TYPE_SUBMENU)
29 return CheckMenu(depth, item->submenu);
30 return true;
33 bool CheckMenu(int depth, const PP_Flash_Menu* menu) {
34 if (depth > kMaxMenuDepth || !menu)
35 return false;
36 ++depth;
38 if (menu->count && !menu->items)
39 return false;
41 for (uint32_t i = 0; i < menu->count; ++i) {
42 if (!CheckMenuItem(depth, menu->items + i))
43 return false;
45 return true;
48 void WriteMenuItem(IPC::Message* m, const PP_Flash_MenuItem* menu_item) {
49 PP_Flash_MenuItem_Type type = menu_item->type;
50 m->WriteUInt32(type);
51 m->WriteString(menu_item->name ? menu_item->name : "");
52 m->WriteInt(menu_item->id);
53 IPC::ParamTraits<PP_Bool>::Write(m, menu_item->enabled);
54 IPC::ParamTraits<PP_Bool>::Write(m, menu_item->checked);
55 if (type == PP_FLASH_MENUITEM_TYPE_SUBMENU)
56 WriteMenu(m, menu_item->submenu);
59 void WriteMenu(IPC::Message* m, const PP_Flash_Menu* menu) {
60 m->WriteUInt32(menu->count);
61 for (uint32_t i = 0; i < menu->count; ++i)
62 WriteMenuItem(m, menu->items + i);
65 void FreeMenuItem(const PP_Flash_MenuItem* menu_item) {
66 if (menu_item->name)
67 delete [] menu_item->name;
68 if (menu_item->submenu)
69 FreeMenu(menu_item->submenu);
72 void FreeMenu(const PP_Flash_Menu* menu) {
73 if (menu->items) {
74 for (uint32_t i = 0; i < menu->count; ++i)
75 FreeMenuItem(menu->items + i);
76 delete [] menu->items;
78 delete menu;
81 bool ReadMenuItem(int depth,
82 const IPC::Message* m,
83 base::PickleIterator* iter,
84 PP_Flash_MenuItem* menu_item) {
85 uint32_t type;
86 if (!iter->ReadUInt32(&type))
87 return false;
88 if (type > PP_FLASH_MENUITEM_TYPE_SUBMENU)
89 return false;
90 menu_item->type = static_cast<PP_Flash_MenuItem_Type>(type);
91 std::string name;
92 if (!iter->ReadString(&name))
93 return false;
94 menu_item->name = new char[name.size() + 1];
95 std::copy(name.begin(), name.end(), menu_item->name);
96 menu_item->name[name.size()] = 0;
97 if (!iter->ReadInt(&menu_item->id))
98 return false;
99 if (!IPC::ParamTraits<PP_Bool>::Read(m, iter, &menu_item->enabled))
100 return false;
101 if (!IPC::ParamTraits<PP_Bool>::Read(m, iter, &menu_item->checked))
102 return false;
103 if (type == PP_FLASH_MENUITEM_TYPE_SUBMENU) {
104 menu_item->submenu = ReadMenu(depth, m, iter);
105 if (!menu_item->submenu)
106 return false;
108 return true;
111 PP_Flash_Menu* ReadMenu(int depth,
112 const IPC::Message* m,
113 base::PickleIterator* iter) {
114 if (depth > kMaxMenuDepth)
115 return NULL;
116 ++depth;
118 PP_Flash_Menu* menu = new PP_Flash_Menu;
119 menu->items = NULL;
121 if (!iter->ReadUInt32(&menu->count)) {
122 FreeMenu(menu);
123 return NULL;
126 if (menu->count == 0)
127 return menu;
129 if (menu->count > kMaxMenuEntries) {
130 FreeMenu(menu);
131 return NULL;
134 menu->items = new PP_Flash_MenuItem[menu->count];
135 memset(menu->items, 0, sizeof(PP_Flash_MenuItem) * menu->count);
136 for (uint32_t i = 0; i < menu->count; ++i) {
137 if (!ReadMenuItem(depth, m, iter, menu->items + i)) {
138 FreeMenu(menu);
139 return NULL;
142 return menu;
145 } // anonymous namespace
147 SerializedFlashMenu::SerializedFlashMenu()
148 : pp_menu_(NULL),
149 own_menu_(false) {
152 SerializedFlashMenu::~SerializedFlashMenu() {
153 if (own_menu_)
154 FreeMenu(pp_menu_);
157 bool SerializedFlashMenu::SetPPMenu(const PP_Flash_Menu* menu) {
158 DCHECK(!pp_menu_);
159 if (!CheckMenu(0, menu))
160 return false;
161 pp_menu_ = menu;
162 own_menu_ = false;
163 return true;
167 void SerializedFlashMenu::WriteToMessage(IPC::Message* m) const {
168 WriteMenu(m, pp_menu_);
171 bool SerializedFlashMenu::ReadFromMessage(const IPC::Message* m,
172 base::PickleIterator* iter) {
173 DCHECK(!pp_menu_);
174 pp_menu_ = ReadMenu(0, m, iter);
175 if (!pp_menu_)
176 return false;
178 own_menu_ = true;
179 return true;
182 } // namespace proxy
183 } // namespace ppapi