| Index: ppapi/proxy/serialized_flash_menu.cc
|
| diff --git a/ppapi/proxy/serialized_flash_menu.cc b/ppapi/proxy/serialized_flash_menu.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c7ef5ab80ca2c07def24f100d8c4878ba2e25f53
|
| --- /dev/null
|
| +++ b/ppapi/proxy/serialized_flash_menu.cc
|
| @@ -0,0 +1,172 @@
|
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "ppapi/proxy/serialized_flash_menu.h"
|
| +
|
| +#include "ipc/ipc_message.h"
|
| +#include "ppapi/c/private/ppb_flash_menu.h"
|
| +#include "ppapi/proxy/ppapi_param_traits.h"
|
| +
|
| +namespace pp {
|
| +namespace proxy {
|
| +
|
| +namespace {
|
| +// Maximum depth of submenus allowed (e.g., 1 indicates that submenus are
|
| +// allowed, but not sub-submenus).
|
| +const int kMaxMenuDepth = 2;
|
| +
|
| +bool CheckMenu(int depth, const PP_Flash_Menu* menu);
|
| +void FreeMenu(const PP_Flash_Menu* menu);
|
| +void WriteMenu(IPC::Message* m, const PP_Flash_Menu* menu);
|
| +PP_Flash_Menu* ReadMenu(int depth, const IPC::Message* m, void** iter);
|
| +
|
| +bool CheckMenuItem(int depth, const PP_Flash_MenuItem* item) {
|
| + if (item->type == PP_FLASH_MENUITEM_TYPE_SUBMENU)
|
| + return CheckMenu(depth, item->submenu);
|
| + return true;
|
| +}
|
| +
|
| +bool CheckMenu(int depth, const PP_Flash_Menu* menu) {
|
| + if (depth > kMaxMenuDepth || !menu)
|
| + return false;
|
| + ++depth;
|
| +
|
| + if (menu->count && !menu->items)
|
| + return false;
|
| +
|
| + for (uint32_t i = 0; i < menu->count; ++i) {
|
| + if (!CheckMenuItem(depth, menu->items + i))
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +void WriteMenuItem(IPC::Message* m, const PP_Flash_MenuItem* menu_item) {
|
| + PP_Flash_MenuItem_Type type = menu_item->type;
|
| + m->WriteUInt32(type);
|
| + m->WriteString(menu_item->name ? menu_item->name : "");
|
| + m->WriteInt(menu_item->id);
|
| + IPC::ParamTraits<PP_Bool>::Write(m, menu_item->enabled);
|
| + IPC::ParamTraits<PP_Bool>::Write(m, menu_item->checked);
|
| + if (type == PP_FLASH_MENUITEM_TYPE_SUBMENU)
|
| + WriteMenu(m, menu_item->submenu);
|
| +}
|
| +
|
| +void WriteMenu(IPC::Message* m, const PP_Flash_Menu* menu) {
|
| + m->WriteUInt32(menu->count);
|
| + for (uint32_t i = 0; i < menu->count; ++i)
|
| + WriteMenuItem(m, menu->items + i);
|
| +}
|
| +
|
| +void FreeMenuItem(const PP_Flash_MenuItem* menu_item) {
|
| + if (menu_item->name)
|
| + delete [] menu_item->name;
|
| + if (menu_item->submenu)
|
| + FreeMenu(menu_item->submenu);
|
| +}
|
| +
|
| +void FreeMenu(const PP_Flash_Menu* menu) {
|
| + if (menu->items) {
|
| + for (uint32_t i = 0; i < menu->count; ++i)
|
| + FreeMenuItem(menu->items + i);
|
| + delete [] menu->items;
|
| + }
|
| + delete menu;
|
| +}
|
| +
|
| +bool ReadMenuItem(int depth,
|
| + const IPC::Message* m,
|
| + void** iter,
|
| + PP_Flash_MenuItem* menu_item) {
|
| + uint32_t type;
|
| + if (!m->ReadUInt32(iter, &type))
|
| + return false;
|
| + if (type > PP_FLASH_MENUITEM_TYPE_SUBMENU)
|
| + return false;
|
| + menu_item->type = static_cast<PP_Flash_MenuItem_Type>(type);
|
| + std::string name;
|
| + if (!m->ReadString(iter, &name))
|
| + return false;
|
| + menu_item->name = new char[name.size() + 1];
|
| + std::copy(name.begin(), name.end(), menu_item->name);
|
| + menu_item->name[name.size()] = 0;
|
| + if (!m->ReadInt(iter, &menu_item->id))
|
| + return false;
|
| + if (!IPC::ParamTraits<PP_Bool>::Read(m, iter, &menu_item->enabled))
|
| + return false;
|
| + if (!IPC::ParamTraits<PP_Bool>::Read(m, iter, &menu_item->checked))
|
| + return false;
|
| + if (type == PP_FLASH_MENUITEM_TYPE_SUBMENU) {
|
| + menu_item->submenu = ReadMenu(depth, m, iter);
|
| + if (!menu_item->submenu)
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +PP_Flash_Menu* ReadMenu(int depth, const IPC::Message* m, void** iter) {
|
| + if (depth > kMaxMenuDepth)
|
| + return NULL;
|
| + ++depth;
|
| +
|
| + PP_Flash_Menu* menu = new PP_Flash_Menu;
|
| + menu->items = NULL;
|
| +
|
| + if (!m->ReadUInt32(iter, &menu->count)) {
|
| + FreeMenu(menu);
|
| + return NULL;
|
| + }
|
| +
|
| + if (menu->count == 0)
|
| + return menu;
|
| +
|
| + menu->items = new PP_Flash_MenuItem[menu->count];
|
| + memset(menu->items, 0, sizeof(PP_Flash_MenuItem) * menu->count);
|
| + for (uint32_t i = 0; i < menu->count; ++i) {
|
| + if (!ReadMenuItem(depth, m, iter, menu->items + i)) {
|
| + FreeMenu(menu);
|
| + return NULL;
|
| + }
|
| + }
|
| + return menu;
|
| +}
|
| +
|
| +} // anonymous namespace
|
| +
|
| +SerializedFlashMenu::SerializedFlashMenu()
|
| + : pp_menu_(NULL),
|
| + own_menu_(false) {
|
| +}
|
| +
|
| +SerializedFlashMenu::~SerializedFlashMenu() {
|
| + if (own_menu_)
|
| + FreeMenu(pp_menu_);
|
| +}
|
| +
|
| +bool SerializedFlashMenu::SetPPMenu(const PP_Flash_Menu* menu) {
|
| + DCHECK(!pp_menu_);
|
| + if (!CheckMenu(0, menu))
|
| + return false;
|
| + pp_menu_ = menu;
|
| + own_menu_ = false;
|
| + return true;
|
| +}
|
| +
|
| +
|
| +void SerializedFlashMenu::WriteToMessage(IPC::Message* m) const {
|
| + WriteMenu(m, pp_menu_);
|
| +}
|
| +
|
| +bool SerializedFlashMenu::ReadFromMessage(const IPC::Message* m, void** iter) {
|
| + DCHECK(!pp_menu_);
|
| + pp_menu_ = ReadMenu(0, m, iter);
|
| + if (!pp_menu_)
|
| + return false;
|
| +
|
| + own_menu_ = true;
|
| + return true;
|
| +}
|
| +
|
| +} // namespace proxy
|
| +} // namespace pp
|
|
|