serialized_flash_menu.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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#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 11namespace ppapi { 12namespace proxy { 13 14namespace { 15// Maximum depth of submenus allowed (e.g., 1 indicates that submenus are 16// allowed, but not sub-submenus). 17const int kMaxMenuDepth = 2; 18 19bool CheckMenu(int depth, const PP_Flash_Menu* menu); 20void FreeMenu(const PP_Flash_Menu* menu); 21void WriteMenu(IPC::Message* m, const PP_Flash_Menu* menu); 22PP_Flash_Menu* ReadMenu(int depth, const IPC::Message* m, PickleIterator* iter); 23 24bool CheckMenuItem(int depth, const PP_Flash_MenuItem* item) { 25 if (item->type == PP_FLASH_MENUITEM_TYPE_SUBMENU) 26 return CheckMenu(depth, item->submenu); 27 return true; 28} 29 30bool CheckMenu(int depth, const PP_Flash_Menu* menu) { 31 if (depth > kMaxMenuDepth || !menu) 32 return false; 33 ++depth; 34 35 if (menu->count && !menu->items) 36 return false; 37 38 for (uint32_t i = 0; i < menu->count; ++i) { 39 if (!CheckMenuItem(depth, menu->items + i)) 40 return false; 41 } 42 return true; 43} 44 45void WriteMenuItem(IPC::Message* m, const PP_Flash_MenuItem* menu_item) { 46 PP_Flash_MenuItem_Type type = menu_item->type; 47 m->WriteUInt32(type); 48 m->WriteString(menu_item->name ? menu_item->name : ""); 49 m->WriteInt(menu_item->id); 50 IPC::ParamTraits<PP_Bool>::Write(m, menu_item->enabled); 51 IPC::ParamTraits<PP_Bool>::Write(m, menu_item->checked); 52 if (type == PP_FLASH_MENUITEM_TYPE_SUBMENU) 53 WriteMenu(m, menu_item->submenu); 54} 55 56void WriteMenu(IPC::Message* m, const PP_Flash_Menu* menu) { 57 m->WriteUInt32(menu->count); 58 for (uint32_t i = 0; i < menu->count; ++i) 59 WriteMenuItem(m, menu->items + i); 60} 61 62void FreeMenuItem(const PP_Flash_MenuItem* menu_item) { 63 if (menu_item->name) 64 delete [] menu_item->name; 65 if (menu_item->submenu) 66 FreeMenu(menu_item->submenu); 67} 68 69void FreeMenu(const PP_Flash_Menu* menu) { 70 if (menu->items) { 71 for (uint32_t i = 0; i < menu->count; ++i) 72 FreeMenuItem(menu->items + i); 73 delete [] menu->items; 74 } 75 delete menu; 76} 77 78bool ReadMenuItem(int depth, 79 const IPC::Message* m, 80 PickleIterator* iter, 81 PP_Flash_MenuItem* menu_item) { 82 uint32_t type; 83 if (!m->ReadUInt32(iter, &type)) 84 return false; 85 if (type > PP_FLASH_MENUITEM_TYPE_SUBMENU) 86 return false; 87 menu_item->type = static_cast<PP_Flash_MenuItem_Type>(type); 88 std::string name; 89 if (!m->ReadString(iter, &name)) 90 return false; 91 menu_item->name = new char[name.size() + 1]; 92 std::copy(name.begin(), name.end(), menu_item->name); 93 menu_item->name[name.size()] = 0; 94 if (!m->ReadInt(iter, &menu_item->id)) 95 return false; 96 if (!IPC::ParamTraits<PP_Bool>::Read(m, iter, &menu_item->enabled)) 97 return false; 98 if (!IPC::ParamTraits<PP_Bool>::Read(m, iter, &menu_item->checked)) 99 return false; 100 if (type == PP_FLASH_MENUITEM_TYPE_SUBMENU) { 101 menu_item->submenu = ReadMenu(depth, m, iter); 102 if (!menu_item->submenu) 103 return false; 104 } 105 return true; 106} 107 108PP_Flash_Menu* ReadMenu(int depth, 109 const IPC::Message* m, 110 PickleIterator* iter) { 111 if (depth > kMaxMenuDepth) 112 return NULL; 113 ++depth; 114 115 PP_Flash_Menu* menu = new PP_Flash_Menu; 116 menu->items = NULL; 117 118 if (!m->ReadUInt32(iter, &menu->count)) { 119 FreeMenu(menu); 120 return NULL; 121 } 122 123 if (menu->count == 0) 124 return menu; 125 126 menu->items = new PP_Flash_MenuItem[menu->count]; 127 memset(menu->items, 0, sizeof(PP_Flash_MenuItem) * menu->count); 128 for (uint32_t i = 0; i < menu->count; ++i) { 129 if (!ReadMenuItem(depth, m, iter, menu->items + i)) { 130 FreeMenu(menu); 131 return NULL; 132 } 133 } 134 return menu; 135} 136 137} // anonymous namespace 138 139SerializedFlashMenu::SerializedFlashMenu() 140 : pp_menu_(NULL), 141 own_menu_(false) { 142} 143 144SerializedFlashMenu::~SerializedFlashMenu() { 145 if (own_menu_) 146 FreeMenu(pp_menu_); 147} 148 149bool SerializedFlashMenu::SetPPMenu(const PP_Flash_Menu* menu) { 150 DCHECK(!pp_menu_); 151 if (!CheckMenu(0, menu)) 152 return false; 153 pp_menu_ = menu; 154 own_menu_ = false; 155 return true; 156} 157 158 159void SerializedFlashMenu::WriteToMessage(IPC::Message* m) const { 160 WriteMenu(m, pp_menu_); 161} 162 163bool SerializedFlashMenu::ReadFromMessage(const IPC::Message* m, 164 PickleIterator* iter) { 165 DCHECK(!pp_menu_); 166 pp_menu_ = ReadMenu(0, m, iter); 167 if (!pp_menu_) 168 return false; 169 170 own_menu_ = true; 171 return true; 172} 173 174} // namespace proxy 175} // namespace ppapi 176