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
,
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
);
33 bool CheckMenu(int depth
, const PP_Flash_Menu
* menu
) {
34 if (depth
> kMaxMenuDepth
|| !menu
)
38 if (menu
->count
&& !menu
->items
)
41 for (uint32_t i
= 0; i
< menu
->count
; ++i
) {
42 if (!CheckMenuItem(depth
, menu
->items
+ i
))
48 void WriteMenuItem(IPC::Message
* m
, const PP_Flash_MenuItem
* menu_item
) {
49 PP_Flash_MenuItem_Type type
= menu_item
->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
) {
67 delete [] menu_item
->name
;
68 if (menu_item
->submenu
)
69 FreeMenu(menu_item
->submenu
);
72 void FreeMenu(const PP_Flash_Menu
* menu
) {
74 for (uint32_t i
= 0; i
< menu
->count
; ++i
)
75 FreeMenuItem(menu
->items
+ i
);
76 delete [] menu
->items
;
81 bool ReadMenuItem(int depth
,
82 const IPC::Message
* m
,
83 base::PickleIterator
* iter
,
84 PP_Flash_MenuItem
* menu_item
) {
86 if (!iter
->ReadUInt32(&type
))
88 if (type
> PP_FLASH_MENUITEM_TYPE_SUBMENU
)
90 menu_item
->type
= static_cast<PP_Flash_MenuItem_Type
>(type
);
92 if (!iter
->ReadString(&name
))
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
))
99 if (!IPC::ParamTraits
<PP_Bool
>::Read(m
, iter
, &menu_item
->enabled
))
101 if (!IPC::ParamTraits
<PP_Bool
>::Read(m
, iter
, &menu_item
->checked
))
103 if (type
== PP_FLASH_MENUITEM_TYPE_SUBMENU
) {
104 menu_item
->submenu
= ReadMenu(depth
, m
, iter
);
105 if (!menu_item
->submenu
)
111 PP_Flash_Menu
* ReadMenu(int depth
,
112 const IPC::Message
* m
,
113 base::PickleIterator
* iter
) {
114 if (depth
> kMaxMenuDepth
)
118 PP_Flash_Menu
* menu
= new PP_Flash_Menu
;
121 if (!iter
->ReadUInt32(&menu
->count
)) {
126 if (menu
->count
== 0)
129 if (menu
->count
> kMaxMenuEntries
) {
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
)) {
145 } // anonymous namespace
147 SerializedFlashMenu::SerializedFlashMenu()
152 SerializedFlashMenu::~SerializedFlashMenu() {
157 bool SerializedFlashMenu::SetPPMenu(const PP_Flash_Menu
* menu
) {
159 if (!CheckMenu(0, menu
))
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
) {
174 pp_menu_
= ReadMenu(0, m
, iter
);