OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 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 #include "ppapi/proxy/serialized_flash_menu.h" | |
6 | |
7 #include "ipc/ipc_message.h" | |
8 #include "ppapi/c/private/ppb_flash_menu.h" | |
9 #include "ppapi/proxy/ppapi_param_traits.h" | |
10 | |
11 namespace pp { | |
12 namespace proxy { | |
13 | |
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 | |
19 bool CheckMenu(int depth, const PP_Flash_Menu* menu); | |
20 void FreeMenu(PP_Flash_Menu* menu); | |
21 void WriteMenu(IPC::Message* m, const PP_Flash_Menu* menu); | |
22 PP_Flash_Menu* ReadMenu(int depth, const IPC::Message* m, void** iter); | |
23 | |
viettrungluu
2011/02/08 18:18:09
Extra blank line.
piman
2011/02/15 02:11:22
Done.
| |
24 | |
25 bool CheckMenuItem(int depth, const PP_Flash_MenuItem* item) { | |
26 if (item->type == PP_FLASH_MENUITEM_TYPE_SUBMENU) | |
27 return CheckMenu(depth, item->submenu); | |
28 return true; | |
29 } | |
30 | |
31 bool CheckMenu(int depth, const PP_Flash_Menu* menu) { | |
32 if (depth > kMaxMenuDepth) | |
viettrungluu
2011/02/08 18:18:09
I wonder if we should handle |menu| (or |item->sub
piman
2011/02/15 02:11:22
Done. I made it to fail. Note that I changed the n
| |
33 return false; | |
34 ++depth; | |
35 | |
36 for (uint32_t i = 0; i < menu->count; ++i) { | |
37 if (!CheckMenuItem(depth, menu->items + i)) | |
38 return false; | |
39 } | |
40 return true; | |
41 } | |
42 | |
43 void WriteMenuItem(IPC::Message* m, const PP_Flash_MenuItem* menu_item) { | |
44 PP_Flash_MenuItem_Type type = menu_item->type; | |
45 m->WriteUInt32(type); | |
46 m->WriteString(menu_item->name ? menu_item->name : ""); | |
47 m->WriteInt(menu_item->id); | |
48 IPC::ParamTraits<PP_Bool>::Write(m, menu_item->enabled); | |
49 IPC::ParamTraits<PP_Bool>::Write(m, menu_item->checked); | |
50 if (type == PP_FLASH_MENUITEM_TYPE_SUBMENU) | |
51 WriteMenu(m, menu_item->submenu); | |
52 } | |
53 | |
54 void WriteMenu(IPC::Message* m, const PP_Flash_Menu* menu) { | |
55 m->WriteUInt32(menu->count); | |
56 for (uint32_t i = 0; i < menu->count; ++i) | |
57 WriteMenuItem(m, menu->items + i); | |
58 } | |
59 | |
60 void FreeMenuItem(PP_Flash_MenuItem* menu_item) { | |
61 if (menu_item->name) | |
62 delete [] menu_item->name; | |
63 if (menu_item->submenu) | |
64 FreeMenu(menu_item->submenu); | |
65 delete menu_item; | |
66 } | |
67 | |
68 void FreeMenu(PP_Flash_Menu* menu) { | |
69 if (menu->items) { | |
70 for (uint32_t i = 0; i < menu->count; ++i) | |
71 FreeMenuItem(menu->items + i); | |
72 } | |
73 delete menu; | |
74 } | |
75 | |
76 class MenuDeallocator { | |
77 public: | |
78 void operator()(PP_Flash_Menu* menu) const { | |
79 if (menu) | |
80 FreeMenu(menu); | |
81 } | |
82 }; | |
83 | |
84 bool ReadMenuItem(int depth, | |
85 const IPC::Message* m, | |
86 void** iter, | |
87 PP_Flash_MenuItem* menu_item) { | |
88 uint32_t type; | |
89 if (!m->ReadUInt32(iter, &type)) | |
90 return false; | |
91 if (type > PP_FLASH_MENUITEM_TYPE_SUBMENU) | |
92 return false; | |
93 menu_item->type = static_cast<PP_Flash_MenuItem_Type>(type); | |
94 std::string name; | |
95 if (!m->ReadString(iter, &name)) | |
96 return false; | |
97 menu_item->name = new char[name.size() + 1]; | |
98 std::copy(name.begin(), name.end(), menu_item->name); | |
99 menu_item->name[name.size()] = 0; | |
100 if (!m->ReadInt(iter, &menu_item->id)) | |
101 return false; | |
102 if (!IPC::ParamTraits<PP_Bool>::Read(m, iter, &menu_item->enabled)) | |
103 return false; | |
104 if (!IPC::ParamTraits<PP_Bool>::Read(m, iter, &menu_item->checked)) | |
105 return false; | |
106 if (type == PP_FLASH_MENUITEM_TYPE_SUBMENU) { | |
107 menu_item->submenu = ReadMenu(depth, m, iter); | |
108 if (!menu_item->submenu) | |
109 return false; | |
110 } | |
111 return true; | |
112 } | |
113 | |
114 PP_Flash_Menu* ReadMenu(int depth, const IPC::Message* m, void** iter) { | |
115 if (depth > kMaxMenuDepth) | |
116 return NULL; | |
117 ++depth; | |
118 | |
119 scoped_ptr_malloc<PP_Flash_Menu, MenuDeallocator> menu(new PP_Flash_Menu); | |
viettrungluu
2011/02/08 18:18:09
This seems heavyweight and slightly hazardous (sin
piman
2011/02/15 02:11:22
Done.
| |
120 menu->items = NULL; | |
121 | |
122 if (!m->ReadUInt32(iter, &menu->count)) | |
123 return NULL; | |
124 | |
125 if (menu->count == 0) | |
126 return menu.release(); | |
127 | |
128 menu->items = new PP_Flash_MenuItem[menu->count]; | |
129 memset(menu->items, 0, sizeof(PP_Flash_MenuItem) * menu->count); | |
130 for (uint32_t i = 0; i < menu->count; ++i) { | |
131 if (!ReadMenuItem(depth, m, iter, menu->items + i)) | |
132 return NULL; | |
133 } | |
134 return menu.release(); | |
135 } | |
136 | |
137 } // anonymous namespace | |
138 | |
139 SerializedFlashMenu::SerializedFlashMenu() | |
140 : pp_menu_(NULL), | |
141 own_menu_(false) { | |
142 } | |
143 | |
144 SerializedFlashMenu::~SerializedFlashMenu() { | |
145 } | |
viettrungluu
2011/02/08 18:18:09
Shouldn't you be checking |own_menu_| and possibly
piman
2011/02/15 02:11:22
Done.
| |
146 | |
147 bool SerializedFlashMenu::SetPPMenu(const PP_Flash_Menu* menu) { | |
148 DCHECK(!pp_menu_); | |
149 if (!CheckMenu(0, menu)) | |
150 return false; | |
151 pp_menu_ = menu; | |
152 return true; | |
viettrungluu
2011/02/08 18:18:09
What about |own_menu_|? (I guess since |pp_menu_|
piman
2011/02/15 02:11:22
Done. I changed it to be explicit.
| |
153 } | |
154 | |
155 | |
156 void SerializedFlashMenu::WriteToMessage(IPC::Message* m) const { | |
157 WriteMenu(m, pp_menu_); | |
158 } | |
159 | |
160 bool SerializedFlashMenu::ReadFromMessage(const IPC::Message* m, void** iter) { | |
161 DCHECK(!pp_menu_); | |
162 pp_menu_ = ReadMenu(0, m, iter); | |
163 own_menu_ = true; | |
164 return !!pp_menu_; | |
165 } | |
166 | |
167 } // namespace proxy | |
168 } // namespace pp | |
OLD | NEW |