1/*
2 * Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
7
8#include "ppapi/native_client/src/trusted/plugin/srpc_params.h"
9
10#include <stdlib.h>
11
12#include "native_client/src/shared/srpc/nacl_srpc.h"
13
14
15namespace plugin {
16
17namespace {
18
19bool FillVec(NaClSrpcArg* vec[], const char* types) {
20  const size_t kLength = strlen(types);
21  if (kLength > NACL_SRPC_MAX_ARGS) {
22    return false;
23  }
24  // We use malloc/new here rather than new/delete, because the SRPC layer
25  // is written in C and hence will use malloc/free.
26  // This array will get deallocated by FreeArguments().
27  if (kLength > 0) {
28    NaClSrpcArg* args =
29      reinterpret_cast<NaClSrpcArg*>(malloc(kLength * sizeof(*args)));
30    if (NULL == args) {
31      return false;
32    }
33
34    memset(static_cast<void*>(args), 0, kLength * sizeof(*args));
35    for (size_t i = 0; i < kLength; ++i) {
36      vec[i] = &args[i];
37      args[i].tag = static_cast<NaClSrpcArgType>(types[i]);
38    }
39  }
40  vec[kLength] = NULL;
41  return true;
42}
43
44void FreeSrpcArg(NaClSrpcArg* arg) {
45  switch (arg->tag) {
46    case NACL_SRPC_ARG_TYPE_CHAR_ARRAY:
47      free(arg->arrays.carr);
48      break;
49    case NACL_SRPC_ARG_TYPE_DOUBLE_ARRAY:
50      free(arg->arrays.darr);
51      break;
52    case NACL_SRPC_ARG_TYPE_HANDLE:
53      break;
54    case NACL_SRPC_ARG_TYPE_INT_ARRAY:
55      free(arg->arrays.iarr);
56      break;
57    case NACL_SRPC_ARG_TYPE_LONG_ARRAY:
58      free(arg->arrays.larr);
59      break;
60    case NACL_SRPC_ARG_TYPE_STRING:
61      // All strings that are passed in SrpcArg must be allocated using
62      // malloc! We cannot use browser's allocation API
63      // since some of SRPC arguments is handled outside of the plugin code.
64      free(arg->arrays.str);
65      break;
66    case NACL_SRPC_ARG_TYPE_VARIANT_ARRAY:
67      if (arg->arrays.varr) {
68        for (uint32_t i = 0; i < arg->u.count; i++) {
69          FreeSrpcArg(&arg->arrays.varr[i]);
70        }
71      }
72      break;
73    case NACL_SRPC_ARG_TYPE_OBJECT:
74      // This is a pointer to a scriptable object and should be released
75      // by the browser
76      break;
77    case NACL_SRPC_ARG_TYPE_BOOL:
78    case NACL_SRPC_ARG_TYPE_DOUBLE:
79    case NACL_SRPC_ARG_TYPE_INT:
80    case NACL_SRPC_ARG_TYPE_LONG:
81    case NACL_SRPC_ARG_TYPE_INVALID:
82    default:
83      break;
84  }
85}
86
87void FreeArguments(NaClSrpcArg* vec[]) {
88  if (NULL == vec[0]) {
89    return;
90  }
91  for (NaClSrpcArg** argp = vec; *argp; ++argp) {
92    FreeSrpcArg(*argp);
93  }
94  // Free the vector containing the arguments themselves that was
95  // allocated with FillVec().
96  free(vec[0]);
97}
98
99}  // namespace
100
101bool SrpcParams::Init(const char* in_types, const char* out_types) {
102  if (!FillVec(ins_, in_types)) {
103    return false;
104  }
105  if (!FillVec(outs_, out_types)) {
106    FreeArguments(ins_);
107    return false;
108  }
109  return true;
110}
111
112void SrpcParams::FreeAll() {
113  FreeArguments(ins_);
114  FreeArguments(outs_);
115  memset(ins_, 0, sizeof(ins_));
116  memset(outs_, 0, sizeof(outs_));
117}
118
119}  // namespace plugin
120