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"
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
, const IPC::Message
* m
, PickleIterator
* iter
);
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
);
31 bool CheckMenu(int depth
, const PP_Flash_Menu
* menu
) {
32 if (depth
> kMaxMenuDepth
|| !menu
)
36 if (menu
->count
&& !menu
->items
)
39 for (uint32_t i
= 0; i
< menu
->count
; ++i
) {
40 if (!CheckMenuItem(depth
, menu
->items
+ i
))
46 void WriteMenuItem(IPC::Message
* m
, const PP_Flash_MenuItem
* menu_item
) {
47 PP_Flash_MenuItem_Type type
= menu_item
->type
;
49 m
->WriteString(menu_item
->name
? menu_item
->name
: "");
50 m
->WriteInt(menu_item
->id
);
51 IPC::ParamTraits
<PP_Bool
>::Write(m
, menu_item
->enabled
);
52 IPC::ParamTraits
<PP_Bool
>::Write(m
, menu_item
->checked
);
53 if (type
== PP_FLASH_MENUITEM_TYPE_SUBMENU
)
54 WriteMenu(m
, menu_item
->submenu
);
57 void WriteMenu(IPC::Message
* m
, const PP_Flash_Menu
* menu
) {
58 m
->WriteUInt32(menu
->count
);
59 for (uint32_t i
= 0; i
< menu
->count
; ++i
)
60 WriteMenuItem(m
, menu
->items
+ i
);
63 void FreeMenuItem(const PP_Flash_MenuItem
* menu_item
) {
65 delete [] menu_item
->name
;
66 if (menu_item
->submenu
)
67 FreeMenu(menu_item
->submenu
);
70 void FreeMenu(const PP_Flash_Menu
* menu
) {
72 for (uint32_t i
= 0; i
< menu
->count
; ++i
)
73 FreeMenuItem(menu
->items
+ i
);
74 delete [] menu
->items
;
79 bool ReadMenuItem(int depth
,
80 const IPC::Message
* m
,
82 PP_Flash_MenuItem
* menu_item
) {
84 if (!m
->ReadUInt32(iter
, &type
))
86 if (type
> PP_FLASH_MENUITEM_TYPE_SUBMENU
)
88 menu_item
->type
= static_cast<PP_Flash_MenuItem_Type
>(type
);
90 if (!m
->ReadString(iter
, &name
))
92 menu_item
->name
= new char[name
.size() + 1];
93 std::copy(name
.begin(), name
.end(), menu_item
->name
);
94 menu_item
->name
[name
.size()] = 0;
95 if (!m
->ReadInt(iter
, &menu_item
->id
))
97 if (!IPC::ParamTraits
<PP_Bool
>::Read(m
, iter
, &menu_item
->enabled
))
99 if (!IPC::ParamTraits
<PP_Bool
>::Read(m
, iter
, &menu_item
->checked
))
101 if (type
== PP_FLASH_MENUITEM_TYPE_SUBMENU
) {
102 menu_item
->submenu
= ReadMenu(depth
, m
, iter
);
103 if (!menu_item
->submenu
)
109 PP_Flash_Menu
* ReadMenu(int depth
,
110 const IPC::Message
* m
,
111 PickleIterator
* iter
) {
112 if (depth
> kMaxMenuDepth
)
116 PP_Flash_Menu
* menu
= new PP_Flash_Menu
;
119 if (!m
->ReadUInt32(iter
, &menu
->count
)) {
124 if (menu
->count
== 0)
127 if (menu
->count
> kMaxMenuEntries
) {
132 menu
->items
= new PP_Flash_MenuItem
[menu
->count
];
133 memset(menu
->items
, 0, sizeof(PP_Flash_MenuItem
) * menu
->count
);
134 for (uint32_t i
= 0; i
< menu
->count
; ++i
) {
135 if (!ReadMenuItem(depth
, m
, iter
, menu
->items
+ i
)) {
143 } // anonymous namespace
145 SerializedFlashMenu::SerializedFlashMenu()
150 SerializedFlashMenu::~SerializedFlashMenu() {
155 bool SerializedFlashMenu::SetPPMenu(const PP_Flash_Menu
* menu
) {
157 if (!CheckMenu(0, menu
))
165 void SerializedFlashMenu::WriteToMessage(IPC::Message
* m
) const {
166 WriteMenu(m
, pp_menu_
);
169 bool SerializedFlashMenu::ReadFromMessage(const IPC::Message
* m
,
170 PickleIterator
* iter
) {
172 pp_menu_
= ReadMenu(0, m
, iter
);