1 : /*
2 : * Copyright (c) 2011 The Native Client 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 : // This file exports a single function used to setup the
8 : // file-io sub-system for use with sel_universal
9 :
10 : // NOTE: this is for experimentation and testing. We are not concerned
11 : // about descriptor and memory leaks
12 :
13 : #include <stdio.h>
14 : #include <string>
15 : #include <map>
16 :
17 : #include "ppapi/c/pp_errors.h"
18 : #include "ppapi/c/ppb_url_request_info.h"
19 : #include "ppapi/c/ppb_url_response_info.h"
20 :
21 : #include "native_client/src/shared/platform/nacl_check.h"
22 : #include "native_client/src/shared/platform/nacl_log.h"
23 : #include "native_client/src/shared/srpc/nacl_srpc.h"
24 :
25 : #include "native_client/src/trusted/sel_universal/pepper_emu_helper.h"
26 : #include "native_client/src/trusted/sel_universal/pepper_emu.h"
27 : #include "native_client/src/trusted/sel_universal/primitives.h"
28 : #include "native_client/src/trusted/sel_universal/rpc_universal.h"
29 : #include "native_client/src/trusted/sel_universal/srpc_helper.h"
30 : namespace {
31 :
32 : // This will be used to invoke the call backs
33 : IMultimedia* GlobalMultiMediaInterface = 0;
34 :
35 : using std::map;
36 : using std::string;
37 :
38 : struct DataLoader {
39 : int dummy;
40 : FILE* fp;
41 : int request_info;
42 : };
43 :
44 11000 : struct DataRequestInfo {
45 : string url;
46 : string method;
47 : int stream_to_file;
48 : };
49 :
50 : struct DataResponseInfo {
51 : int dummy;
52 : };
53 :
54 22 : Resource<DataLoader> GlobalLoaderResources(500, "loader");
55 22 : Resource<DataResponseInfo> GlobalResponseInfoResources(500, "response_info");
56 22 : Resource<DataRequestInfo> GlobalRequestInfoResources(500, "request_info");
57 :
58 :
59 22 : map<string, string> GlobalUrlToFilenameMap;
60 :
61 :
62 0 : static void PPB_URLRequestInfo_Create(SRPC_PARAMS) {
63 0 : int instance = ins[0]->u.ival;
64 0 : NaClLog(1, "PPB_URLRequestInfo_Create(%d)\n", instance);
65 :
66 0 : outs[0]->u.ival = GlobalRequestInfoResources.Alloc();
67 0 : if (outs[0]->u.ival < 0) {
68 0 : NaClLog(LOG_FATAL, "PPB_URLRequestInfo_Create: failed\n");
69 : }
70 0 : NaClLog(1, "PPB_URLRequestInfo_Create -> %d\n", outs[0]->u.ival);
71 0 : rpc->result = NACL_SRPC_RESULT_OK;
72 0 : done->Run(done);
73 0 : }
74 :
75 :
76 0 : static void PPB_URLLoader_Create(SRPC_PARAMS) {
77 0 : int instance = ins[0]->u.ival;
78 0 : NaClLog(1, "PPB_URLLoader_Create(%d)\n", instance);
79 :
80 0 : outs[0]->u.ival = GlobalLoaderResources.Alloc();
81 0 : if (outs[0]->u.ival < 0) {
82 0 : NaClLog(LOG_FATAL, "PPB_URLLoader_Create: failed\n");
83 : }
84 0 : NaClLog(1, "PPB_URLLoader_Create -> %d\n", outs[0]->u.ival);
85 0 : rpc->result = NACL_SRPC_RESULT_OK;
86 0 : done->Run(done);
87 0 : }
88 :
89 :
90 0 : static void PPB_URLLoader_GetResponseInfo(SRPC_PARAMS) {
91 0 : int handle = ins[0]->u.ival;
92 0 : NaClLog(1, "PPB_URLLoader_GetResponseInfo(%d)\n", handle);
93 :
94 0 : outs[0]->u.ival = GlobalResponseInfoResources.Alloc();
95 0 : if (outs[0]->u.ival < 0) {
96 0 : NaClLog(LOG_FATAL, "PPB_URLLoader_GetResponseInfo: failed\n");
97 : }
98 0 : NaClLog(1, "PPB_URLLoader_GetResponseInfo -> %d\n", outs[0]->u.ival);
99 0 : rpc->result = NACL_SRPC_RESULT_OK;
100 0 : done->Run(done);
101 0 : }
102 :
103 :
104 0 : static void PPB_URLRequestInfo_SetProperty(SRPC_PARAMS) {
105 0 : int handle = ins[0]->u.ival;
106 0 : int property = ins[1]->u.ival;
107 0 : NaClLog(1, "PPB_URLRequestInfo_SetProperty(%d, %d)\n", handle, property);
108 : DataRequestInfo* request_info =
109 0 : GlobalRequestInfoResources.GetDataForHandle(handle);
110 0 : if (request_info == NULL) {
111 0 : NaClLog(LOG_FATAL, "PPB_URLRequestInfo_SetProperty: unknown resource\n");
112 : }
113 0 : switch (property) {
114 : default:
115 0 : NaClLog(LOG_FATAL, "PPB_URLRequestInfo_SetProperty: unknown property\n");
116 0 : break;
117 : case PP_URLREQUESTPROPERTY_URL:
118 0 : request_info->url = GetMarshalledJSString(ins[2]);
119 0 : break;
120 : case PP_URLREQUESTPROPERTY_METHOD:
121 0 : request_info->method = GetMarshalledJSString(ins[2]);
122 0 : break;
123 : case PP_URLREQUESTPROPERTY_STREAMTOFILE:
124 0 : request_info->stream_to_file = GetMarshalledJSBool(ins[2]);
125 : break;
126 : }
127 :
128 0 : outs[0]->u.ival = 1;
129 0 : rpc->result = NACL_SRPC_RESULT_OK;
130 0 : done->Run(done);
131 0 : }
132 :
133 :
134 0 : static void PPB_URLLoader_Open(SRPC_PARAMS) {
135 0 : int handle_loader = ins[0]->u.ival;
136 0 : int request_info_handle = ins[1]->u.ival;
137 0 : int callback = ins[2]->u.ival;
138 : NaClLog(1, "PPB_URLLoader_Open(%d, %d, %d)\n",
139 0 : handle_loader, request_info_handle, callback);
140 : DataRequestInfo* request_info =
141 0 : GlobalRequestInfoResources.GetDataForHandle(request_info_handle);
142 0 : DataLoader* loader = GlobalLoaderResources.GetDataForHandle(handle_loader);
143 0 : loader->request_info = request_info_handle;
144 0 : string filename = request_info->url;
145 0 : NaClLog(1, "PPB_URLLoader_Open opening url: [%s]\n", filename.c_str());
146 0 : if (GlobalUrlToFilenameMap.find(filename) != GlobalUrlToFilenameMap.end()) {
147 0 : filename = GlobalUrlToFilenameMap[filename];
148 0 : NaClLog(1, "Using Alias: [%s]\n", filename.c_str());
149 : }
150 0 : loader->fp = fopen(filename.c_str(), "rb");
151 0 : if (loader->fp == NULL) {
152 0 : NaClLog(LOG_WARNING, "PPB_URLLoader_Open could not open file\n");
153 : }
154 0 : int result = (loader->fp == NULL) ? PP_ERROR_FAILED : PP_OK;
155 : UserEvent* event =
156 0 : MakeUserEvent(EVENT_TYPE_OPEN_CALLBACK, callback, result, 0, 0);
157 0 : GlobalMultiMediaInterface->PushUserEvent(event);
158 :
159 0 : outs[0]->u.ival = PP_OK_COMPLETIONPENDING;
160 0 : NaClLog(1, "PPB_URLLoader_Open -> %d\n", outs[0]->u.ival);
161 0 : rpc->result = NACL_SRPC_RESULT_OK;
162 0 : done->Run(done);
163 0 : }
164 :
165 :
166 0 : static void PPB_URLResponseInfo_GetProperty(SRPC_PARAMS) {
167 0 : int handle = ins[0]->u.ival;
168 0 : int property = ins[1]->u.ival;
169 0 : NaClLog(1, "PPB_URLResponseInfo_GetProperty(%d, %d)\n", handle, property);
170 :
171 0 : switch (property) {
172 : default:
173 0 : NaClLog(LOG_FATAL, "PPB_URLResponseInfo_GetProperty: unknown property\n");
174 0 : break;
175 : case PP_URLRESPONSEPROPERTY_STATUSCODE:
176 : // we are rather optimistic
177 0 : SetMarshalledJSInt(outs[0], 200);
178 : break;
179 : }
180 :
181 0 : rpc->result = NACL_SRPC_RESULT_OK;
182 0 : done->Run(done);
183 0 : }
184 :
185 : // PPB_URLLoader_ReadResponseBody:iii:Ci
186 0 : static void PPB_URLLoader_ReadResponseBody(SRPC_PARAMS) {
187 0 : int handle_loader = ins[0]->u.ival;
188 0 : int size = ins[1]->u.ival;
189 0 : int callback = ins[2]->u.ival;
190 0 : DataLoader* loader = GlobalLoaderResources.GetDataForHandle(handle_loader);
191 : DataRequestInfo* request_info = GlobalRequestInfoResources.
192 0 : GetDataForHandle(loader->request_info);
193 : NaClLog(1, "PPB_URLLoader_ReadResponseBody(%d (%s), %d, %d)\n",
194 0 : handle_loader, request_info->url.c_str(), size, callback);
195 0 : char* buffer = static_cast<char*>(malloc(size));
196 0 : const int n = (int) fread(buffer, 1, size, loader->fp);
197 : UserEvent* event =
198 0 : MakeUserEvent(EVENT_TYPE_READ_CALLBACK, callback, n, buffer, n);
199 0 : if (n < size) {
200 0 : NaClLog(1, "PPB_URLLoader_ReadResponseBody reached eof\n");
201 : }
202 0 : GlobalMultiMediaInterface->PushUserEvent(event);
203 0 : outs[0]->u.count = 0;
204 0 : outs[1]->u.ival = PP_OK_COMPLETIONPENDING;
205 0 : rpc->result = NACL_SRPC_RESULT_OK;
206 0 : done->Run(done);
207 0 : }
208 :
209 0 : UNIMPLEMENTED(PPB_URLLoader_IsURLLoader)
210 :
211 0 : UNIMPLEMENTED(PPB_URLLoader_FollowRedirect)
212 0 : UNIMPLEMENTED(PPB_URLLoader_GetUploadProgress)
213 0 : UNIMPLEMENTED(PPB_URLLoader_GetDownloadProgress)
214 0 : UNIMPLEMENTED(PPB_URLLoader_FinishStreamingToFile)
215 0 : UNIMPLEMENTED(PPB_URLLoader_Close)
216 :
217 0 : UNIMPLEMENTED(PPB_URLRequestInfo_IsURLRequestInfo)
218 0 : UNIMPLEMENTED(PPB_URLRequestInfo_AppendDataToBody)
219 0 : UNIMPLEMENTED(PPB_URLRequestInfo_AppendFileToBody)
220 :
221 0 : UNIMPLEMENTED(PPB_URLResponseInfo_IsURLResponseInfo)
222 0 : UNIMPLEMENTED(PPB_URLResponseInfo_GetBodyAsFileRef)
223 :
224 : } // end namespace
225 :
226 0 : void RegisterFileAliasForUrl(string url, string filename) {
227 0 : CHECK(GlobalUrlToFilenameMap.find(url) == GlobalUrlToFilenameMap.end());
228 0 : GlobalUrlToFilenameMap[url] = filename;
229 0 : }
230 :
231 :
232 : #define TUPLE(a, b) #a #b, a
233 0 : void PepperEmuInitFileIO(NaClCommandLoop* ncl, IMultimedia* im) {
234 0 : GlobalMultiMediaInterface = im;
235 :
236 0 : ncl->AddUpcallRpc(TUPLE(PPB_URLLoader_Create, :i:i));
237 0 : ncl->AddUpcallRpc(TUPLE(PPB_URLLoader_IsURLLoader, :i:i));
238 0 : ncl->AddUpcallRpc(TUPLE(PPB_URLLoader_Open, :iii:i));
239 0 : ncl->AddUpcallRpc(TUPLE(PPB_URLLoader_FollowRedirect, :ii:i));
240 0 : ncl->AddUpcallRpc(TUPLE(PPB_URLLoader_GetUploadProgress, :i:lli));
241 0 : ncl->AddUpcallRpc(TUPLE(PPB_URLLoader_GetDownloadProgress, :i:lli));
242 0 : ncl->AddUpcallRpc(TUPLE(PPB_URLLoader_GetResponseInfo, :i:i));
243 0 : ncl->AddUpcallRpc(TUPLE(PPB_URLLoader_ReadResponseBody, :iii:Ci));
244 0 : ncl->AddUpcallRpc(TUPLE(PPB_URLLoader_FinishStreamingToFile, :ii:i));
245 0 : ncl->AddUpcallRpc(TUPLE(PPB_URLLoader_Close, :i:));
246 0 : ncl->AddUpcallRpc(TUPLE(PPB_URLRequestInfo_Create, :i:i));
247 0 : ncl->AddUpcallRpc(TUPLE(PPB_URLRequestInfo_IsURLRequestInfo, :i:i));
248 0 : ncl->AddUpcallRpc(TUPLE(PPB_URLRequestInfo_SetProperty, :iiC:i));
249 0 : ncl->AddUpcallRpc(TUPLE(PPB_URLRequestInfo_AppendDataToBody, :iC:i));
250 0 : ncl->AddUpcallRpc(TUPLE(PPB_URLRequestInfo_AppendFileToBody, :iilld:i));
251 0 : ncl->AddUpcallRpc(TUPLE(PPB_URLResponseInfo_IsURLResponseInfo, :i:i));
252 0 : ncl->AddUpcallRpc(TUPLE(PPB_URLResponseInfo_GetProperty, :ii:C));
253 0 : ncl->AddUpcallRpc(TUPLE(PPB_URLResponseInfo_GetBodyAsFileRef, :i:i));
254 22 : }
|