Improve NPRuntime marshalling by adding glue functions for serializing / deserializing a NPIdentifier.  Also kill some extraneous std::string copies in NPVariant_Param code.

If you like I could eliminate NPIdentifier_Param in place of using NPIdentifier directly.

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@442 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/common/plugin_messages.h b/chrome/common/plugin_messages.h
index a06439b..85463cb 100644
--- a/chrome/common/plugin_messages.h
+++ b/chrome/common/plugin_messages.h
@@ -44,6 +44,7 @@
 #include "chrome/common/ipc_message.h"
 #include "chrome/common/ipc_message_utils.h"
 #include "googleurl/src/gurl.h"
+#include "webkit/glue/npruntime_util.h"
 
 void PluginMessagesInit();
 
@@ -107,9 +108,7 @@
 };
 
 struct NPIdentifier_Param {
-  bool is_string;
-  std::string string;
-  int number;
+  NPIdentifier identifier;
 };
 
 enum NPVariant_ParamEnum {
@@ -380,12 +379,12 @@
     switch(p.event) {
      case WM_KEYDOWN:
       event = L"WM_KEYDOWN";
-      wparam = StringPrintf(L"%d", p.wParam);
-      lparam = StringPrintf(L"%d", p.lParam);
+      wparam = IntToString(p.wParam);
+      lparam = IntToString(p.lParam);
       break;
      case WM_KEYUP:
       event = L"WM_KEYDOWN";
-      wparam = StringPrintf(L"%d", p.wParam);
+      wparam = IntToString(p.wParam);
       lparam = StringPrintf(L"%x", p.lParam);
       break;
      case WM_MOUSEMOVE:
@@ -444,31 +443,18 @@
 struct ParamTraits<NPIdentifier_Param> {
   typedef NPIdentifier_Param param_type;
   static void Write(Message* m, const param_type& p) {
-    WriteParam(m, p.is_string);
-    if (p.is_string) {
-      WriteParam(m, p.string);
-    } else {
-      WriteParam(m, p.number);
-    }
+    webkit_glue::SerializeNPIdentifier(p.identifier, m);
   }
   static bool Read(const Message* m, void** iter, param_type* r) {
-    if (!ReadParam(m, iter, &r->is_string))
-      return false;
-
-    bool result;
-    if (r->is_string) {
-      result = ReadParam(m, iter, &r->string);
-    } else {
-      result = ReadParam(m, iter, &r->number);
-    }
-
-    return result;
+    return webkit_glue::DeserializeNPIdentifier(*m, iter, &r->identifier);
   }
   static void Log(const param_type& p, std::wstring* l) {
-    if (p.is_string) {
-      l->append(ASCIIToWide(p.string));
+    if (NPN_IdentifierIsString(p.identifier)) {
+      NPUTF8* str = NPN_UTF8FromIdentifier(p.identifier);
+      l->append(UTF8ToWide(str));
+      NPN_MemFree(str);
     } else {
-      l->append(StringPrintf(L"%d", p.number));
+      l->append(IntToString(NPN_IntFromIdentifier(p.identifier)));
     }
   }
 };
@@ -485,7 +471,7 @@
     } else if (p.type == NPVARIANT_PARAM_DOUBLE) {
       WriteParam(m, p.double_value);
     } else if (p.type == NPVARIANT_PARAM_STRING) {
-      WriteParam(m, std::string(p.string_value));
+      WriteParam(m, p.string_value);
     } else if (p.type == NPVARIANT_PARAM_OBJECT_ROUTING_ID) {
       // This is the routing id used to connect NPObjectProxy in the other
       // process with NPObjectStub in this process.
diff --git a/chrome/plugin/npobject_proxy.cc b/chrome/plugin/npobject_proxy.cc
index 2dc8819..edc5b1c9 100644
--- a/chrome/plugin/npobject_proxy.cc
+++ b/chrome/plugin/npobject_proxy.cc
@@ -176,7 +176,7 @@
   NPIdentifier_Param name_param;
   if (is_default) {
     // The data won't actually get used, but set it so we don't send random data.
-    name_param.is_string = true;
+    name_param.identifier = NULL;
   } else {
     CreateNPIdentifierParam(name, &name_param);
   }
diff --git a/chrome/plugin/npobject_util.cc b/chrome/plugin/npobject_util.cc
index fa6f68ef..1f4b67d 100644
--- a/chrome/plugin/npobject_util.cc
+++ b/chrome/plugin/npobject_util.cc
@@ -150,22 +150,11 @@
 }
 
 void CreateNPIdentifierParam(NPIdentifier id, NPIdentifier_Param* param) {
-  param->is_string = NPN_IdentifierIsString(id);
-  if (param->is_string) {
-    NPUTF8* utf8 = NPN_UTF8FromIdentifier(id);
-    param->string = utf8;
-    NPN_MemFree(utf8);
-  } else {
-    param->number = NPN_IntFromIdentifier(id);
-  }
+  param->identifier = id;
 }
 
-NPIdentifier CreateNPIdentifier(const  NPIdentifier_Param& param) {
-  if (param.is_string) {
-    return NPN_GetStringIdentifier(param.string.c_str());
-  } else {
-    return NPN_GetIntIdentifier(param.number);
-  }
+NPIdentifier CreateNPIdentifier(const NPIdentifier_Param& param) {
+  return param.identifier;
 }
 
 void CreateNPVariantParam(const NPVariant& variant,
@@ -194,8 +183,8 @@
     case NPVariantType_String:
       param->type = NPVARIANT_PARAM_STRING;
       if (variant.value.stringValue.UTF8Length) {
-        param->string_value = std::string(variant.value.stringValue.UTF8Characters,
-                                          variant.value.stringValue.UTF8Length);
+        param->string_value.assign(variant.value.stringValue.UTF8Characters,
+                                   variant.value.stringValue.UTF8Length);
       }
       break;
     case NPVariantType_Object:
diff --git a/webkit/glue/npruntime_util.cc b/webkit/glue/npruntime_util.cc
new file mode 100644
index 0000000..6f86e33
--- /dev/null
+++ b/webkit/glue/npruntime_util.cc
@@ -0,0 +1,90 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//    * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//    * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//    * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+
+#include "webkit/glue/npruntime_util.h"
+
+// Import the definition of PrivateIdentifier
+#if USE(V8_BINDING)
+#include "webkit/port/bindings/v8/np_v8object.h"
+#elif USE(JAVASCRIPTCORE_BINDINGS)
+#include "c_utility.h"
+#endif
+
+#include "base/pickle.h"
+
+namespace webkit_glue {
+
+bool SerializeNPIdentifier(NPIdentifier identifier, Pickle* pickle) {
+  PrivateIdentifier* priv = static_cast<PrivateIdentifier*>(identifier);
+
+  // If the identifier was null, then we just send a numeric 0.  This is to
+  // support cases where the other end doesn't care about the NPIdentifier
+  // being serialized, so the bogus value of 0 is really inconsequential.
+  PrivateIdentifier null_id;
+  if (!priv) {
+    priv = &null_id;
+    priv->isString = false;
+    priv->value.number = 0;
+  }
+
+  if (!pickle->WriteBool(priv->isString))
+    return false;
+  if (priv->isString) {
+    // Write the null byte for efficiency on the other end.
+    return pickle->WriteData(
+        priv->value.string, strlen(priv->value.string) + 1);
+  }
+  return pickle->WriteInt(priv->value.number);
+}
+
+bool DeserializeNPIdentifier(const Pickle& pickle, void** pickle_iter,
+                             NPIdentifier* identifier) {
+  bool is_string;
+  if (!pickle.ReadBool(pickle_iter, &is_string))
+    return false;
+
+  if (is_string) {
+    const char* data;
+    int data_len;
+    if (!pickle.ReadData(pickle_iter, &data, &data_len))
+      return false;
+    DCHECK_EQ(data_len, strlen(data) + 1);
+    *identifier = NPN_GetStringIdentifier(data);
+  } else {
+    int number;
+    if (!pickle.ReadInt(pickle_iter, &number))
+      return false;
+    *identifier = NPN_GetIntIdentifier(number);
+  }
+  return true;
+}
+
+}  // namespace webkit_glue
diff --git a/webkit/glue/npruntime_util.h b/webkit/glue/npruntime_util.h
new file mode 100644
index 0000000..9ff9e2c8
--- /dev/null
+++ b/webkit/glue/npruntime_util.h
@@ -0,0 +1,46 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//    * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//    * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//    * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef WEBKIT_GLUE_NPRUNTIME_UTIL_H_
+#define WEBKIT_GLUE_NPRUNTIME_UTIL_H_
+
+#include "third_party/npapi/bindings/npruntime.h"
+
+class Pickle;
+
+namespace webkit_glue {
+
+// Efficiently serialize/deserialize a NPIdentifier
+bool SerializeNPIdentifier(NPIdentifier identifier, Pickle* pickle);
+bool DeserializeNPIdentifier(const Pickle& pickle, void** pickle_iter,
+                             NPIdentifier* identifier);
+
+}  // namespace webkit_glue
+
+#endif  // WEBKIT_GLUE_NPRUNTIME_UTIL_H_