OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 static void Log(const char* event); | 72 static void Log(const char* event); |
73 }; | 73 }; |
74 | 74 |
75 /** | 75 /** |
76 * An http request processor that is scriptable using JavaScript. | 76 * An http request processor that is scriptable using JavaScript. |
77 */ | 77 */ |
78 class JsHttpRequestProcessor : public HttpRequestProcessor { | 78 class JsHttpRequestProcessor : public HttpRequestProcessor { |
79 public: | 79 public: |
80 // Creates a new processor that processes requests by invoking the | 80 // Creates a new processor that processes requests by invoking the |
81 // Process function of the JavaScript script given as an argument. | 81 // Process function of the JavaScript script given as an argument. |
82 explicit JsHttpRequestProcessor(Handle<String> script) : script_(script) { } | 82 JsHttpRequestProcessor(Isolate* isolate, Handle<String> script) |
| 83 : isolate_(isolate), script_(script) { } |
83 virtual ~JsHttpRequestProcessor(); | 84 virtual ~JsHttpRequestProcessor(); |
84 | 85 |
85 virtual bool Initialize(map<string, string>* opts, | 86 virtual bool Initialize(map<string, string>* opts, |
86 map<string, string>* output); | 87 map<string, string>* output); |
87 virtual bool Process(HttpRequest* req); | 88 virtual bool Process(HttpRequest* req); |
88 | 89 |
89 private: | 90 private: |
90 // Execute the script associated with this processor and extract the | 91 // Execute the script associated with this processor and extract the |
91 // Process function. Returns true if this succeeded, otherwise false. | 92 // Process function. Returns true if this succeeded, otherwise false. |
92 bool ExecuteScript(Handle<String> script); | 93 bool ExecuteScript(Handle<String> script); |
93 | 94 |
94 // Wrap the options and output map in a JavaScript objects and | 95 // Wrap the options and output map in a JavaScript objects and |
95 // install it in the global namespace as 'options' and 'output'. | 96 // install it in the global namespace as 'options' and 'output'. |
96 bool InstallMaps(map<string, string>* opts, map<string, string>* output); | 97 bool InstallMaps(map<string, string>* opts, map<string, string>* output); |
97 | 98 |
98 // Constructs the template that describes the JavaScript wrapper | 99 // Constructs the template that describes the JavaScript wrapper |
99 // type for requests. | 100 // type for requests. |
100 static Handle<ObjectTemplate> MakeRequestTemplate(); | 101 static Handle<ObjectTemplate> MakeRequestTemplate(Isolate* isolate); |
101 static Handle<ObjectTemplate> MakeMapTemplate(); | 102 static Handle<ObjectTemplate> MakeMapTemplate(Isolate* isolate); |
102 | 103 |
103 // Callbacks that access the individual fields of request objects. | 104 // Callbacks that access the individual fields of request objects. |
104 static Handle<Value> GetPath(Local<String> name, const AccessorInfo& info); | 105 static Handle<Value> GetPath(Local<String> name, const AccessorInfo& info); |
105 static Handle<Value> GetReferrer(Local<String> name, | 106 static Handle<Value> GetReferrer(Local<String> name, |
106 const AccessorInfo& info); | 107 const AccessorInfo& info); |
107 static Handle<Value> GetHost(Local<String> name, const AccessorInfo& info); | 108 static Handle<Value> GetHost(Local<String> name, const AccessorInfo& info); |
108 static Handle<Value> GetUserAgent(Local<String> name, | 109 static Handle<Value> GetUserAgent(Local<String> name, |
109 const AccessorInfo& info); | 110 const AccessorInfo& info); |
110 | 111 |
111 // Callbacks that access maps | 112 // Callbacks that access maps |
112 static Handle<Value> MapGet(Local<String> name, const AccessorInfo& info); | 113 static Handle<Value> MapGet(Local<String> name, const AccessorInfo& info); |
113 static Handle<Value> MapSet(Local<String> name, | 114 static Handle<Value> MapSet(Local<String> name, |
114 Local<Value> value, | 115 Local<Value> value, |
115 const AccessorInfo& info); | 116 const AccessorInfo& info); |
116 | 117 |
117 // Utility methods for wrapping C++ objects as JavaScript objects, | 118 // Utility methods for wrapping C++ objects as JavaScript objects, |
118 // and going back again. | 119 // and going back again. |
119 Handle<Object> WrapMap(map<string, string>* obj); | 120 Handle<Object> WrapMap(map<string, string>* obj); |
120 static map<string, string>* UnwrapMap(Handle<Object> obj); | 121 static map<string, string>* UnwrapMap(Handle<Object> obj); |
121 Handle<Object> WrapRequest(HttpRequest* obj); | 122 Handle<Object> WrapRequest(HttpRequest* obj); |
122 static HttpRequest* UnwrapRequest(Handle<Object> obj); | 123 static HttpRequest* UnwrapRequest(Handle<Object> obj); |
123 | 124 |
124 Isolate* GetIsolate() { return context_->GetIsolate(); } | 125 Isolate* GetIsolate() { return isolate_; } |
125 | 126 |
| 127 Isolate* isolate_; |
126 Handle<String> script_; | 128 Handle<String> script_; |
127 Persistent<Context> context_; | 129 Persistent<Context> context_; |
128 Persistent<Function> process_; | 130 Persistent<Function> process_; |
129 static Persistent<ObjectTemplate> request_template_; | 131 static Persistent<ObjectTemplate> request_template_; |
130 static Persistent<ObjectTemplate> map_template_; | 132 static Persistent<ObjectTemplate> map_template_; |
131 }; | 133 }; |
132 | 134 |
133 // ------------------------- | 135 // ------------------------- |
134 // --- P r o c e s s o r --- | 136 // --- P r o c e s s o r --- |
135 // ------------------------- | 137 // ------------------------- |
136 | 138 |
137 | 139 |
138 static Handle<Value> LogCallback(const Arguments& args) { | 140 static Handle<Value> LogCallback(const Arguments& args) { |
139 if (args.Length() < 1) return v8::Undefined(); | 141 if (args.Length() < 1) return Undefined(); |
140 HandleScope scope; | 142 HandleScope scope(args.GetIsolate()); |
141 Handle<Value> arg = args[0]; | 143 Handle<Value> arg = args[0]; |
142 String::Utf8Value value(arg); | 144 String::Utf8Value value(arg); |
143 HttpRequestProcessor::Log(*value); | 145 HttpRequestProcessor::Log(*value); |
144 return v8::Undefined(); | 146 return Undefined(); |
145 } | 147 } |
146 | 148 |
147 | 149 |
148 // Execute the script and fetch the Process method. | 150 // Execute the script and fetch the Process method. |
149 bool JsHttpRequestProcessor::Initialize(map<string, string>* opts, | 151 bool JsHttpRequestProcessor::Initialize(map<string, string>* opts, |
150 map<string, string>* output) { | 152 map<string, string>* output) { |
151 // Create a handle scope to hold the temporary references. | 153 // Create a handle scope to hold the temporary references. |
152 HandleScope handle_scope; | 154 HandleScope handle_scope(GetIsolate()); |
153 | 155 |
154 // Create a template for the global object where we set the | 156 // Create a template for the global object where we set the |
155 // built-in global functions. | 157 // built-in global functions. |
156 Handle<ObjectTemplate> global = ObjectTemplate::New(); | 158 Handle<ObjectTemplate> global = ObjectTemplate::New(); |
157 global->Set(String::New("log"), FunctionTemplate::New(LogCallback)); | 159 global->Set(String::New("log"), FunctionTemplate::New(LogCallback)); |
158 | 160 |
159 // Each processor gets its own context so different processors don't | 161 // Each processor gets its own context so different processors don't |
160 // affect each other. Context::New returns a persistent handle which | 162 // affect each other. Context::New returns a persistent handle which |
161 // is what we need for the reference to remain after we return from | 163 // is what we need for the reference to remain after we return from |
162 // this method. That persistent handle has to be disposed in the | 164 // this method. That persistent handle has to be disposed in the |
(...skipping 27 matching lines...) Expand all Loading... |
190 // Store the function in a Persistent handle, since we also want | 192 // Store the function in a Persistent handle, since we also want |
191 // that to remain after this call returns | 193 // that to remain after this call returns |
192 process_ = Persistent<Function>::New(GetIsolate(), process_fun); | 194 process_ = Persistent<Function>::New(GetIsolate(), process_fun); |
193 | 195 |
194 // All done; all went well | 196 // All done; all went well |
195 return true; | 197 return true; |
196 } | 198 } |
197 | 199 |
198 | 200 |
199 bool JsHttpRequestProcessor::ExecuteScript(Handle<String> script) { | 201 bool JsHttpRequestProcessor::ExecuteScript(Handle<String> script) { |
200 HandleScope handle_scope; | 202 HandleScope handle_scope(GetIsolate()); |
201 | 203 |
202 // We're just about to compile the script; set up an error handler to | 204 // We're just about to compile the script; set up an error handler to |
203 // catch any exceptions the script might throw. | 205 // catch any exceptions the script might throw. |
204 TryCatch try_catch; | 206 TryCatch try_catch; |
205 | 207 |
206 // Compile the script and check for errors. | 208 // Compile the script and check for errors. |
207 Handle<Script> compiled_script = Script::Compile(script); | 209 Handle<Script> compiled_script = Script::Compile(script); |
208 if (compiled_script.IsEmpty()) { | 210 if (compiled_script.IsEmpty()) { |
209 String::Utf8Value error(try_catch.Exception()); | 211 String::Utf8Value error(try_catch.Exception()); |
210 Log(*error); | 212 Log(*error); |
211 // The script failed to compile; bail out. | 213 // The script failed to compile; bail out. |
212 return false; | 214 return false; |
213 } | 215 } |
214 | 216 |
215 // Run the script! | 217 // Run the script! |
216 Handle<Value> result = compiled_script->Run(); | 218 Handle<Value> result = compiled_script->Run(); |
217 if (result.IsEmpty()) { | 219 if (result.IsEmpty()) { |
218 // The TryCatch above is still in effect and will have caught the error. | 220 // The TryCatch above is still in effect and will have caught the error. |
219 String::Utf8Value error(try_catch.Exception()); | 221 String::Utf8Value error(try_catch.Exception()); |
220 Log(*error); | 222 Log(*error); |
221 // Running the script failed; bail out. | 223 // Running the script failed; bail out. |
222 return false; | 224 return false; |
223 } | 225 } |
224 return true; | 226 return true; |
225 } | 227 } |
226 | 228 |
227 | 229 |
228 bool JsHttpRequestProcessor::InstallMaps(map<string, string>* opts, | 230 bool JsHttpRequestProcessor::InstallMaps(map<string, string>* opts, |
229 map<string, string>* output) { | 231 map<string, string>* output) { |
230 HandleScope handle_scope; | 232 HandleScope handle_scope(GetIsolate()); |
231 | 233 |
232 // Wrap the map object in a JavaScript wrapper | 234 // Wrap the map object in a JavaScript wrapper |
233 Handle<Object> opts_obj = WrapMap(opts); | 235 Handle<Object> opts_obj = WrapMap(opts); |
234 | 236 |
235 // Set the options object as a property on the global object. | 237 // Set the options object as a property on the global object. |
236 context_->Global()->Set(String::New("options"), opts_obj); | 238 context_->Global()->Set(String::New("options"), opts_obj); |
237 | 239 |
238 Handle<Object> output_obj = WrapMap(output); | 240 Handle<Object> output_obj = WrapMap(output); |
239 context_->Global()->Set(String::New("output"), output_obj); | 241 context_->Global()->Set(String::New("output"), output_obj); |
240 | 242 |
241 return true; | 243 return true; |
242 } | 244 } |
243 | 245 |
244 | 246 |
245 bool JsHttpRequestProcessor::Process(HttpRequest* request) { | 247 bool JsHttpRequestProcessor::Process(HttpRequest* request) { |
246 // Create a handle scope to keep the temporary object references. | 248 // Create a handle scope to keep the temporary object references. |
247 HandleScope handle_scope; | 249 HandleScope handle_scope(GetIsolate()); |
248 | 250 |
249 // Enter this processor's context so all the remaining operations | 251 // Enter this processor's context so all the remaining operations |
250 // take place there | 252 // take place there |
251 Context::Scope context_scope(context_); | 253 Context::Scope context_scope(context_); |
252 | 254 |
253 // Wrap the C++ request object in a JavaScript wrapper | 255 // Wrap the C++ request object in a JavaScript wrapper |
254 Handle<Object> request_obj = WrapRequest(request); | 256 Handle<Object> request_obj = WrapRequest(request); |
255 | 257 |
256 // Set up an exception handler before calling the Process function | 258 // Set up an exception handler before calling the Process function |
257 TryCatch try_catch; | 259 TryCatch try_catch; |
(...skipping 10 matching lines...) Expand all Loading... |
268 } else { | 270 } else { |
269 return true; | 271 return true; |
270 } | 272 } |
271 } | 273 } |
272 | 274 |
273 | 275 |
274 JsHttpRequestProcessor::~JsHttpRequestProcessor() { | 276 JsHttpRequestProcessor::~JsHttpRequestProcessor() { |
275 // Dispose the persistent handles. When noone else has any | 277 // Dispose the persistent handles. When noone else has any |
276 // references to the objects stored in the handles they will be | 278 // references to the objects stored in the handles they will be |
277 // automatically reclaimed. | 279 // automatically reclaimed. |
278 v8::Isolate* isolate = GetIsolate(); | 280 Isolate* isolate = GetIsolate(); |
279 context_.Dispose(isolate); | 281 context_.Dispose(isolate); |
280 process_.Dispose(isolate); | 282 process_.Dispose(isolate); |
281 } | 283 } |
282 | 284 |
283 | 285 |
284 Persistent<ObjectTemplate> JsHttpRequestProcessor::request_template_; | 286 Persistent<ObjectTemplate> JsHttpRequestProcessor::request_template_; |
285 Persistent<ObjectTemplate> JsHttpRequestProcessor::map_template_; | 287 Persistent<ObjectTemplate> JsHttpRequestProcessor::map_template_; |
286 | 288 |
287 | 289 |
288 // ----------------------------------- | 290 // ----------------------------------- |
289 // --- A c c e s s i n g M a p s --- | 291 // --- A c c e s s i n g M a p s --- |
290 // ----------------------------------- | 292 // ----------------------------------- |
291 | 293 |
292 // Utility function that wraps a C++ http request object in a | 294 // Utility function that wraps a C++ http request object in a |
293 // JavaScript object. | 295 // JavaScript object. |
294 Handle<Object> JsHttpRequestProcessor::WrapMap(map<string, string>* obj) { | 296 Handle<Object> JsHttpRequestProcessor::WrapMap(map<string, string>* obj) { |
295 // Handle scope for temporary handles. | 297 // Handle scope for temporary handles. |
296 HandleScope handle_scope; | 298 HandleScope handle_scope(GetIsolate()); |
297 | 299 |
298 // Fetch the template for creating JavaScript map wrappers. | 300 // Fetch the template for creating JavaScript map wrappers. |
299 // It only has to be created once, which we do on demand. | 301 // It only has to be created once, which we do on demand. |
300 if (map_template_.IsEmpty()) { | 302 if (map_template_.IsEmpty()) { |
301 Handle<ObjectTemplate> raw_template = MakeMapTemplate(); | 303 Handle<ObjectTemplate> raw_template = MakeMapTemplate(GetIsolate()); |
302 map_template_ = Persistent<ObjectTemplate>::New(GetIsolate(), raw_template); | 304 map_template_ = Persistent<ObjectTemplate>::New(GetIsolate(), raw_template); |
303 } | 305 } |
304 Handle<ObjectTemplate> templ = map_template_; | 306 Handle<ObjectTemplate> templ = map_template_; |
305 | 307 |
306 // Create an empty map wrapper. | 308 // Create an empty map wrapper. |
307 Handle<Object> result = templ->NewInstance(); | 309 Handle<Object> result = templ->NewInstance(); |
308 | 310 |
309 // Wrap the raw C++ pointer in an External so it can be referenced | 311 // Wrap the raw C++ pointer in an External so it can be referenced |
310 // from within JavaScript. | 312 // from within JavaScript. |
311 Handle<External> map_ptr = External::New(obj); | 313 Handle<External> map_ptr = External::New(obj); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 string value = ObjectToString(value_obj); | 371 string value = ObjectToString(value_obj); |
370 | 372 |
371 // Update the map. | 373 // Update the map. |
372 (*obj)[key] = value; | 374 (*obj)[key] = value; |
373 | 375 |
374 // Return the value; any non-empty handle will work. | 376 // Return the value; any non-empty handle will work. |
375 return value_obj; | 377 return value_obj; |
376 } | 378 } |
377 | 379 |
378 | 380 |
379 Handle<ObjectTemplate> JsHttpRequestProcessor::MakeMapTemplate() { | 381 Handle<ObjectTemplate> JsHttpRequestProcessor::MakeMapTemplate( |
380 HandleScope handle_scope; | 382 Isolate* isolate) { |
| 383 HandleScope handle_scope(isolate); |
381 | 384 |
382 Handle<ObjectTemplate> result = ObjectTemplate::New(); | 385 Handle<ObjectTemplate> result = ObjectTemplate::New(); |
383 result->SetInternalFieldCount(1); | 386 result->SetInternalFieldCount(1); |
384 result->SetNamedPropertyHandler(MapGet, MapSet); | 387 result->SetNamedPropertyHandler(MapGet, MapSet); |
385 | 388 |
386 // Again, return the result through the current handle scope. | 389 // Again, return the result through the current handle scope. |
387 return handle_scope.Close(result); | 390 return handle_scope.Close(result); |
388 } | 391 } |
389 | 392 |
390 | 393 |
391 // ------------------------------------------- | 394 // ------------------------------------------- |
392 // --- A c c e s s i n g R e q u e s t s --- | 395 // --- A c c e s s i n g R e q u e s t s --- |
393 // ------------------------------------------- | 396 // ------------------------------------------- |
394 | 397 |
395 /** | 398 /** |
396 * Utility function that wraps a C++ http request object in a | 399 * Utility function that wraps a C++ http request object in a |
397 * JavaScript object. | 400 * JavaScript object. |
398 */ | 401 */ |
399 Handle<Object> JsHttpRequestProcessor::WrapRequest(HttpRequest* request) { | 402 Handle<Object> JsHttpRequestProcessor::WrapRequest(HttpRequest* request) { |
400 // Handle scope for temporary handles. | 403 // Handle scope for temporary handles. |
401 HandleScope handle_scope; | 404 HandleScope handle_scope(GetIsolate()); |
402 | 405 |
403 // Fetch the template for creating JavaScript http request wrappers. | 406 // Fetch the template for creating JavaScript http request wrappers. |
404 // It only has to be created once, which we do on demand. | 407 // It only has to be created once, which we do on demand. |
405 if (request_template_.IsEmpty()) { | 408 if (request_template_.IsEmpty()) { |
406 Handle<ObjectTemplate> raw_template = MakeRequestTemplate(); | 409 Handle<ObjectTemplate> raw_template = MakeRequestTemplate(GetIsolate()); |
407 request_template_ = | 410 request_template_ = |
408 Persistent<ObjectTemplate>::New(GetIsolate(), raw_template); | 411 Persistent<ObjectTemplate>::New(GetIsolate(), raw_template); |
409 } | 412 } |
410 Handle<ObjectTemplate> templ = request_template_; | 413 Handle<ObjectTemplate> templ = request_template_; |
411 | 414 |
412 // Create an empty http request wrapper. | 415 // Create an empty http request wrapper. |
413 Handle<Object> result = templ->NewInstance(); | 416 Handle<Object> result = templ->NewInstance(); |
414 | 417 |
415 // Wrap the raw C++ pointer in an External so it can be referenced | 418 // Wrap the raw C++ pointer in an External so it can be referenced |
416 // from within JavaScript. | 419 // from within JavaScript. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 | 471 |
469 | 472 |
470 Handle<Value> JsHttpRequestProcessor::GetUserAgent(Local<String> name, | 473 Handle<Value> JsHttpRequestProcessor::GetUserAgent(Local<String> name, |
471 const AccessorInfo& info) { | 474 const AccessorInfo& info) { |
472 HttpRequest* request = UnwrapRequest(info.Holder()); | 475 HttpRequest* request = UnwrapRequest(info.Holder()); |
473 const string& path = request->UserAgent(); | 476 const string& path = request->UserAgent(); |
474 return String::New(path.c_str(), static_cast<int>(path.length())); | 477 return String::New(path.c_str(), static_cast<int>(path.length())); |
475 } | 478 } |
476 | 479 |
477 | 480 |
478 Handle<ObjectTemplate> JsHttpRequestProcessor::MakeRequestTemplate() { | 481 Handle<ObjectTemplate> JsHttpRequestProcessor::MakeRequestTemplate( |
479 HandleScope handle_scope; | 482 Isolate* isolate) { |
| 483 HandleScope handle_scope(isolate); |
480 | 484 |
481 Handle<ObjectTemplate> result = ObjectTemplate::New(); | 485 Handle<ObjectTemplate> result = ObjectTemplate::New(); |
482 result->SetInternalFieldCount(1); | 486 result->SetInternalFieldCount(1); |
483 | 487 |
484 // Add accessors for each of the fields of the request. | 488 // Add accessors for each of the fields of the request. |
485 result->SetAccessor(String::NewSymbol("path"), GetPath); | 489 result->SetAccessor(String::NewSymbol("path"), GetPath); |
486 result->SetAccessor(String::NewSymbol("referrer"), GetReferrer); | 490 result->SetAccessor(String::NewSymbol("referrer"), GetReferrer); |
487 result->SetAccessor(String::NewSymbol("host"), GetHost); | 491 result->SetAccessor(String::NewSymbol("host"), GetHost); |
488 result->SetAccessor(String::NewSymbol("userAgent"), GetUserAgent); | 492 result->SetAccessor(String::NewSymbol("userAgent"), GetUserAgent); |
489 | 493 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 | 605 |
602 | 606 |
603 int main(int argc, char* argv[]) { | 607 int main(int argc, char* argv[]) { |
604 map<string, string> options; | 608 map<string, string> options; |
605 string file; | 609 string file; |
606 ParseOptions(argc, argv, options, &file); | 610 ParseOptions(argc, argv, options, &file); |
607 if (file.empty()) { | 611 if (file.empty()) { |
608 fprintf(stderr, "No script was specified.\n"); | 612 fprintf(stderr, "No script was specified.\n"); |
609 return 1; | 613 return 1; |
610 } | 614 } |
611 HandleScope scope; | 615 Isolate* isolate = Isolate::GetCurrent(); |
| 616 HandleScope scope(isolate); |
612 Handle<String> source = ReadFile(file); | 617 Handle<String> source = ReadFile(file); |
613 if (source.IsEmpty()) { | 618 if (source.IsEmpty()) { |
614 fprintf(stderr, "Error reading '%s'.\n", file.c_str()); | 619 fprintf(stderr, "Error reading '%s'.\n", file.c_str()); |
615 return 1; | 620 return 1; |
616 } | 621 } |
617 JsHttpRequestProcessor processor(source); | 622 JsHttpRequestProcessor processor(isolate, source); |
618 map<string, string> output; | 623 map<string, string> output; |
619 if (!processor.Initialize(&options, &output)) { | 624 if (!processor.Initialize(&options, &output)) { |
620 fprintf(stderr, "Error initializing processor.\n"); | 625 fprintf(stderr, "Error initializing processor.\n"); |
621 return 1; | 626 return 1; |
622 } | 627 } |
623 if (!ProcessEntries(&processor, kSampleSize, kSampleRequests)) | 628 if (!ProcessEntries(&processor, kSampleSize, kSampleRequests)) |
624 return 1; | 629 return 1; |
625 PrintMap(&output); | 630 PrintMap(&output); |
626 } | 631 } |
OLD | NEW |