Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(313)

Side by Side Diff: native_client_sdk/src/libraries/nacl_io/googledrivefs/googledrivefs_node.cc

Issue 2156503002: [NaCl SDK] Expose Google Drive to nacl_io. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "nacl_io/googledrivefs/googledrivefs_node.h"
6
7 #include <stdio.h>
8 #include <time.h>
9
10 #include <algorithm>
11
12 #include "ppapi/c/pp_completion_callback.h"
13
14 #include "nacl_io/error.h"
15 #include "nacl_io/filesystem.h"
16 #include "nacl_io/getdents_helper.h"
17 #include "nacl_io/hash.h"
18 #include "nacl_io/kernel_handle.h"
19 #include "nacl_io/pepper_interface.h"
20 #include "nacl_io/statuscode.h"
21 #include "nacl_io/googledrivefs/googledrivefs.h"
22 #include "nacl_io/googledrivefs/googledrivefs_util.h"
23
24 namespace nacl_io {
25
26 GoogleDriveFsNode::GoogleDriveFsNode(Filesystem* filesystem, Path path)
27 : Node(filesystem), path_(path) {}
28
29 Error GoogleDriveFsNode::GetDents(size_t offs,
30 struct dirent* pdir,
31 size_t size,
32 int* out_bytes) {
33 *out_bytes = 0;
34
35 if (!IsaDir()) {
36 return ENOTDIR;
37 }
38
39 const ino_t kCurDirIno = -1;
40 const ino_t kParentDirIno = -2;
41 GetDentsHelper helper(kCurDirIno, kParentDirIno);
42
43 std::vector<std::string> dirent_names;
44 Error error = RequestDirent(&dirent_names);
45 if (error) {
46 return error;
47 }
48
49 for (size_t i = 0; i < dirent_names.size(); ++i) {
50 Path child_path(path_);
51 child_path = child_path.Append("/" + dirent_names[i]);
52 ino_t child_ino = HashPath(child_path);
53
54 helper.AddDirent(child_ino, dirent_names[i].c_str(),
55 dirent_names[i].size());
56 }
57
58 return helper.GetDents(offs, pdir, size, out_bytes);
59 }
60
61 Error GoogleDriveFsNode::GetStat(struct stat* pstat) {
62 Error error = GetSize(&pstat->st_size);
63 if (error) {
64 return error;
65 }
66
67 error = GetModifiedTime(&pstat->st_mtime);
68 if (error) {
69 return error;
70 }
71
72 pstat->st_atime = 0;
73 pstat->st_ctime = 0;
74
75 pstat->st_mode = stat_.st_mode;
76
77 return 0;
78 }
79
80 Error GoogleDriveFsNode::Write(const HandleAttr& attr,
81 const void* buf,
82 size_t count,
83 int* out_bytes) {
84 *out_bytes = 0;
85
86 if (IsaDir()) {
87 return EISDIR;
88 }
89 if ((GetMode() & S_IWRITE) == 0) {
90 return EACCES;
91 }
92
93 off_t file_size = 0;
94 Error error = GetSize(&file_size);
95 if (error) {
96 return error;
97 }
98
99 off_t file_buffer_size = std::max((unsigned long long int)file_size,
binji 2016/08/22 19:21:53 use std::max<off_t> instead of casting the argumen
chanpatorikku 2016/08/29 17:14:03 Done. std::max< 'C++ variable type' > is used in v
100 (unsigned long long int)attr.offs + count);
101
102 // use std::string for storing data in the heap, as the size of stack
103 // is measured in megabytes, disallowing files larger than that.
104 std::string file_buffer(file_buffer_size, '\0');
105
106 if (file_size > 0) {
107 int read_helper_out_bytes = 0;
108 error = ReadHelper(0, file_size - 1, &file_buffer, &read_helper_out_bytes);
109
110 if (error) {
111 return error;
112 }
113 }
114
115 char* pChar = (char*)buf;
116 for (size_t i = 0; i < count; ++i) {
117 file_buffer[attr.offs + i] = pChar[i];
118 }
119
120 error = WriteHelper(file_buffer.c_str(), file_buffer_size);
binji 2016/08/22 19:21:53 Is there no better way than reading the entire fil
chanpatorikku 2016/08/29 17:14:03 No. Google Drive API v3 supports only file overwr
121 if (error) {
122 return error;
123 }
124
125 *out_bytes = count;
126
127 return 0;
128 }
129
130 Error GoogleDriveFsNode::FTruncate(off_t length) {
131 if (IsaDir()) {
132 return EISDIR;
133 }
134
135 off_t file_size = 0;
136 Error error = GetSize(&file_size);
137 if (error) {
138 return error;
139 }
140
141 std::string file_buffer(length, '\0');
142
143 if (file_size > 0) {
144 int read_helper_out_bytes = 0;
145 off_t read_end = std::min(length, file_size);
146 error = ReadHelper(0, read_end - 1, &file_buffer, &read_helper_out_bytes);
147
148 if (error) {
149 return error;
150 }
151 }
152
153 error = WriteHelper(file_buffer.c_str(), length);
154 if (error) {
155 return error;
156 }
157
158 return 0;
159 }
160
161 Error GoogleDriveFsNode::Read(const HandleAttr& attr,
162 void* buf,
163 size_t count,
164 int* out_bytes) {
165 *out_bytes = 0;
166
167 if (IsaDir()) {
168 return EISDIR;
169 }
170 if ((GetMode() & S_IREAD) == 0) {
171 return EACCES;
172 }
173
174 std::string file_buffer(count, '\0');
175
176 Error error =
177 ReadHelper(attr.offs, attr.offs + count - 1, &file_buffer, out_bytes);
178 if (error) {
179 return error;
180 }
181
182 char* pChar = (char*)buf;
183 for (size_t i = 0; i < count; ++i) {
184 pChar[i] = file_buffer[i];
binji 2016/08/22 19:21:53 why not read directly into buf?
chanpatorikku 2016/08/29 17:14:03 buf has to be copied from a std::string object at
185 }
186
187 return 0;
188 }
189
190 Error GoogleDriveFsNode::GetSize(off_t* out_size) {
191 *out_size = 0;
192
193 GoogleDriveFs* googledrivefs = static_cast<GoogleDriveFs*>(filesystem_);
194
195 URLLoaderInterface* url_loader_iface =
196 googledrivefs->ppapi()->GetURLLoaderInterface();
197 PP_Resource url_loader_object =
198 url_loader_iface->Create(googledrivefs->instance());
199 URLRequestInfoInterface* url_request_info_iface =
200 googledrivefs->ppapi()->GetURLRequestInfoInterface();
201 PP_Resource url_request_info_object =
202 url_request_info_iface->Create(googledrivefs->instance());
203 PP_Resource url_response_info_object = 0;
204 Error error(0);
205 static const char base_url[] = "https://www.googleapis.com/drive/v3/files";
206 RequestUrlParams p;
207 std::string output;
208 std::string size_value;
209 int size_index;
210
211 if (IsaDir()) {
212 goto done;
213 }
214
215 p.url = base_url;
216 AddUrlPath(item_id_, &p.url);
217 AddUrlFirstQueryParameter("fields", "size", &p.url);
218
219 p.method = "GET";
220
221 p.headers = "";
222
223 AddHeaders("Content-type", "application/json", &p.headers);
224 AddHeaders("Authorization", "Bearer " + googledrivefs->token(), &p.headers);
225
226 error = MakeRequest(googledrivefs->ppapi(), url_loader_object,
227 url_request_info_object, p);
228
229 if (error) {
230 goto done;
231 }
232
233 error = FinishPreparingResponse(googledrivefs->ppapi(), url_loader_object,
234 &url_response_info_object);
235
236 if (error) {
237 goto done;
238 }
239
240 if (ReadStatusCode(googledrivefs->ppapi(), url_response_info_object) !=
241 STATUSCODE_OK) {
242 error = EPERM;
243 goto done;
244 }
245
246 error = ReadResponseBody(googledrivefs->ppapi(), googledrivefs->instance(),
247 url_response_info_object, INT_MAX, &output);
248 if (error) {
249 goto done;
250 }
251
252 GetValue(output, "size", 0, &size_value, &size_index);
253 if (size_index == -1) {
254 // in a STATUSCODE_OK response, size of a directory is not written.
255 size_value = "0";
256 }
257
258 *out_size = (off_t)atoi(size_value.c_str());
259
260 done:
261 if (url_loader_object) {
262 googledrivefs->ppapi()->ReleaseResource(url_loader_object);
263 }
264 if (url_request_info_object) {
265 googledrivefs->ppapi()->ReleaseResource(url_request_info_object);
266 }
267 if (url_response_info_object) {
268 googledrivefs->ppapi()->ReleaseResource(url_response_info_object);
269 }
270
271 return error;
272 }
273
274 Error GoogleDriveFsNode::Init(int open_flags) {
275 Error error = Node::Init(open_flags);
276
277 if (error) {
278 return error;
279 }
280
281 if (path_.Size() == 1) {
282 parent_dir_id_ = "";
283 item_id_ = "root";
284 SetType(S_IFDIR);
285 SetMode(S_IREAD);
286 return 0;
287 }
288
289 error = RequestParentDirId(path_, filesystem_, &parent_dir_id_);
290 if (error) {
291 return error;
292 }
293
294 // Request the ID of an item, which is a file or a directory
295 error =
296 RequestItemId(parent_dir_id_, path_.Basename(), filesystem_, &item_id_);
297
298 if (error == ENOENT) {
299 // Only files are open as mode O_CREAT
300 if ((open_flags & O_CREAT) != 0) {
301 error = CreateEmptyFile();
302 if (error) {
303 return error;
304 }
305 error = RequestItemId(parent_dir_id_, path_.Basename(), filesystem_,
306 &item_id_);
307 if (error) {
308 return error;
309 }
310 SetType(S_IFREG);
311 if ((open_flags & O_RDWR) != 0) {
312 SetMode(S_IREAD | S_IWRITE);
313 } else if ((open_flags & O_WRONLY) != 0) {
314 SetMode(S_IWRITE);
315 } else {
316 SetMode(S_IREAD);
317 }
318 } else {
319 return ENOENT;
320 }
321 } else if (error) {
322 return error;
323 } else {
324 std::string dir_id = "";
325 error =
326 RequestDirId(parent_dir_id_, path_.Basename(), filesystem_, &dir_id);
327 if (error == ENOENT) {
328 SetType(S_IFREG);
329 if ((open_flags & O_RDWR) != 0) {
330 SetMode(S_IREAD | S_IWRITE);
331 } else if ((open_flags & O_WRONLY) != 0) {
332 SetMode(S_IWRITE);
333 } else {
334 SetMode(S_IREAD);
335 }
336 } else if (error) {
337 return error;
338 } else {
339 SetType(S_IFDIR);
340 SetMode(S_IREAD);
341 }
342
343 if (open_flags == 0) {
344 // open_flags == 0 for file opened on fopen with mode r and
345 // directory opened on opendir
346 return 0;
347 } else if (IsaDir()) {
348 return EPERM;
349 } else if ((open_flags & O_TRUNC) != 0) {
350 error = WriteHelper(NULL, 0);
351 if (error) {
352 return error;
353 }
354 }
355 }
356
357 return 0;
358 }
359
360 void GoogleDriveFsNode::Destroy() {
361 Node::Destroy();
362 }
363
364 Error GoogleDriveFsNode::ReadHelper(off_t start,
365 off_t end,
366 std::string* out_string_buffer,
367 int* out_bytes) {
368 (*out_string_buffer)[0] = '\0';
369 *out_bytes = 0;
370
371 GoogleDriveFs* googledrivefs = static_cast<GoogleDriveFs*>(filesystem_);
372
373 URLLoaderInterface* url_loader_iface =
374 googledrivefs->ppapi()->GetURLLoaderInterface();
375 PP_Resource url_loader_object =
376 url_loader_iface->Create(googledrivefs->instance());
377 URLRequestInfoInterface* url_request_info_iface =
378 googledrivefs->ppapi()->GetURLRequestInfoInterface();
379 PP_Resource url_request_info_object =
380 url_request_info_iface->Create(googledrivefs->instance());
381 PP_Resource url_response_info_object = 0;
382 Error error(EPERM);
383 static const char base_url[] =
384 "https://www.googleapis.com/download/drive/v3/files";
385 RequestUrlParams p;
386 char range_value_buffer[1024];
387 int char_written = 0;
388 int status_code = 0;
389 std::string output;
390
391 p.url = base_url;
392 AddUrlPath(item_id_, &p.url);
393 AddUrlFirstQueryParameter("alt", "media", &p.url);
394
395 p.method = "GET";
396
397 p.headers = "";
398
399 AddHeaders("Content-type", "application/json", &p.headers);
400 AddHeaders("Authorization", "Bearer " + googledrivefs->token(), &p.headers);
401
402 char_written = sprintf(range_value_buffer, "bytes=%lli-%lli",
binji 2016/08/22 19:21:53 Use snprintf instead of sprintf
chanpatorikku 2016/08/29 17:14:03 Done.
403 (long long int)start, (long long int)end);
404 if (char_written < 0) {
405 error = EPERM;
406 goto done;
407 }
408
409 AddHeaders("Range", std::string(range_value_buffer), &p.headers);
binji 2016/08/22 19:21:53 Remove std::string constructor, it will be automat
chanpatorikku 2016/08/29 17:14:03 Done.
410
411 error = MakeRequest(googledrivefs->ppapi(), url_loader_object,
412 url_request_info_object, p);
413
414 if (error) {
415 goto done;
416 }
417
418 error = FinishPreparingResponse(googledrivefs->ppapi(), url_loader_object,
419 &url_response_info_object);
420
421 if (error) {
422 goto done;
423 }
424
425 status_code =
426 ReadStatusCode(googledrivefs->ppapi(), url_response_info_object);
427
428 if (status_code == STATUSCODE_OK ||
429 status_code == STATUSCODE_PARTIAL_CONTENT) {
430 error =
431 ReadResponseBody(googledrivefs->ppapi(), googledrivefs->instance(),
432 url_response_info_object, end - start + 1, &output);
433
434 if (error) {
435 goto done;
436 }
437
438 for (size_t i = 0; i < output.size(); ++i) {
439 (*out_string_buffer)[i] = output[i];
binji 2016/08/22 19:21:53 looks like you are assuming that out_string_buffer
chanpatorikku 2016/08/29 17:14:03 Not adding assert here, but adding assert in vario
440 }
441
442 *out_bytes = output.size();
443
444 error = 0;
445 goto done;
446 } else if (status_code == STATUSCODE_REQUESTED_RANGE_NOT_SATISFIABLE) {
447 error = 0;
binji 2016/08/22 19:21:53 why isn't this an error?
chanpatorikku 2016/08/29 17:14:03 Google Drive API v3, HttpFs, and Html5Fs do not sh
448 goto done;
449 }
450
451 done:
452 if (url_loader_object) {
453 googledrivefs->ppapi()->ReleaseResource(url_loader_object);
454 }
455 if (url_request_info_object) {
456 googledrivefs->ppapi()->ReleaseResource(url_request_info_object);
457 }
458 if (url_response_info_object) {
459 googledrivefs->ppapi()->ReleaseResource(url_response_info_object);
460 }
461
462 return error;
463 }
464
465 Error GoogleDriveFsNode::WriteHelper(const char* body_data,
466 uint32_t body_size) {
467 GoogleDriveFs* googledrivefs = static_cast<GoogleDriveFs*>(filesystem_);
468
469 URLLoaderInterface* url_loader_iface =
470 googledrivefs->ppapi()->GetURLLoaderInterface();
471 PP_Resource url_loader_object =
472 url_loader_iface->Create(googledrivefs->instance());
473 URLRequestInfoInterface* url_request_info_iface =
474 googledrivefs->ppapi()->GetURLRequestInfoInterface();
475 PP_Resource url_request_info_object =
476 url_request_info_iface->Create(googledrivefs->instance());
477 PP_Resource url_response_info_object = 0;
478 Error error(0);
479 static const char base_url[] =
480 "https://www.googleapis.com/upload/drive/v3/files";
481 RequestUrlParams p;
482
483 p.url = base_url;
484 AddUrlPath(item_id_, &p.url);
485 AddUrlFirstQueryParameter("uploadType", "media", &p.url);
486
487 p.method = "PATCH";
488
489 p.headers = "";
490
491 AddHeaders("Content-type", "application/json", &p.headers);
492 AddHeaders("Authorization", "Bearer " + googledrivefs->token(), &p.headers);
493
494 p.body = std::string(body_data, body_size);
495
496 error = MakeRequest(googledrivefs->ppapi(), url_loader_object,
497 url_request_info_object, p);
498
499 if (error) {
500 goto done;
501 }
502
503 error = FinishPreparingResponse(googledrivefs->ppapi(), url_loader_object,
504 &url_response_info_object);
505
506 if (error) {
507 goto done;
508 }
509
510 if (ReadStatusCode(googledrivefs->ppapi(), url_response_info_object) !=
511 STATUSCODE_OK) {
512 error = EPERM;
513 goto done;
514 }
515
516 done:
517 if (url_loader_object) {
518 googledrivefs->ppapi()->ReleaseResource(url_loader_object);
519 }
520 if (url_request_info_object) {
521 googledrivefs->ppapi()->ReleaseResource(url_request_info_object);
522 }
523 if (url_response_info_object) {
524 googledrivefs->ppapi()->ReleaseResource(url_response_info_object);
525 }
526
527 return error;
528 }
529
530 Error GoogleDriveFsNode::GetModifiedTime(time_t* out_mtime) {
531 GoogleDriveFs* googledrivefs = static_cast<GoogleDriveFs*>(filesystem_);
532
533 URLLoaderInterface* url_loader_iface =
534 googledrivefs->ppapi()->GetURLLoaderInterface();
535 PP_Resource url_loader_object =
536 url_loader_iface->Create(googledrivefs->instance());
537 URLRequestInfoInterface* url_request_info_iface =
538 googledrivefs->ppapi()->GetURLRequestInfoInterface();
539 PP_Resource url_request_info_object =
540 url_request_info_iface->Create(googledrivefs->instance());
541 PP_Resource url_response_info_object = 0;
542 Error error(0);
543 static const char base_url[] = "https://www.googleapis.com/drive/v3/files";
544 RequestUrlParams p;
545 std::string output;
546 std::string modified_time_value = "";
547 int modified_time_index = 0;
548 struct tm timeinfo;
549
550 p.url = base_url;
551 AddUrlPath(item_id_, &p.url);
552 AddUrlFirstQueryParameter("fields", "modifiedTime", &p.url);
553
554 p.method = "GET";
555
556 p.headers = "";
557
558 AddHeaders("Content-type", "application/json", &p.headers);
559 AddHeaders("Authorization", "Bearer " + googledrivefs->token(), &p.headers);
560
561 error = MakeRequest(googledrivefs->ppapi(), url_loader_object,
562 url_request_info_object, p);
563
564 if (error) {
565 goto done;
566 }
567
568 error = FinishPreparingResponse(googledrivefs->ppapi(), url_loader_object,
569 &url_response_info_object);
570
571 if (error) {
572 goto done;
573 }
574
575 if (ReadStatusCode(googledrivefs->ppapi(), url_response_info_object) !=
576 STATUSCODE_OK) {
577 error = EPERM;
578 goto done;
579 }
580
581 error = ReadResponseBody(googledrivefs->ppapi(), googledrivefs->instance(),
582 url_response_info_object, INT_MAX, &output);
583 if (error) {
584 goto done;
585 }
586
587 // the value of modifiedTime is assumed to be always in the STATUSCODE_OK
588 // response.
589 GetValue(output, "modifiedTime", 0, &modified_time_value,
chanpatorikku 2016/08/07 02:41:03 I don't know about how practical my implementation
binji 2016/08/22 19:21:53 You may want to specify the expected format below,
chanpatorikku 2016/08/29 17:14:03 The comment becomes not applicable now. GetValue(
590 &modified_time_index);
591
592 timeinfo.tm_year = atoi(modified_time_value.substr(0, 4).c_str());
593 timeinfo.tm_mon = atoi(modified_time_value.substr(5, 2).c_str());
594 timeinfo.tm_mday = atoi(modified_time_value.substr(8, 2).c_str());
595 timeinfo.tm_hour = atoi(modified_time_value.substr(11, 2).c_str());
596 timeinfo.tm_min = atoi(modified_time_value.substr(14, 2).c_str());
597 timeinfo.tm_sec = atoi(modified_time_value.substr(17, 2).c_str());
598 timeinfo.tm_isdst = 0;
599
600 *out_mtime = mktime(&timeinfo);
601
602 done:
603 if (url_loader_object) {
604 googledrivefs->ppapi()->ReleaseResource(url_loader_object);
605 }
606 if (url_request_info_object) {
607 googledrivefs->ppapi()->ReleaseResource(url_request_info_object);
608 }
609 if (url_response_info_object) {
610 googledrivefs->ppapi()->ReleaseResource(url_response_info_object);
611 }
612
613 return error;
614 }
615
616 Error GoogleDriveFsNode::CreateEmptyFile() {
617 GoogleDriveFs* googledrivefs = static_cast<GoogleDriveFs*>(filesystem_);
618
619 URLLoaderInterface* url_loader_iface =
620 googledrivefs->ppapi()->GetURLLoaderInterface();
621 PP_Resource url_loader_object =
622 url_loader_iface->Create(googledrivefs->instance());
623 URLRequestInfoInterface* url_request_info_iface =
624 googledrivefs->ppapi()->GetURLRequestInfoInterface();
625 PP_Resource url_request_info_object =
626 url_request_info_iface->Create(googledrivefs->instance());
627 PP_Resource url_response_info_object = 0;
628 Error error(0);
629 static const char base_url[] =
630 "https://www.googleapis.com/upload/drive/v3/files";
631 RequestUrlParams p;
632 std::string BOUNDARY_VALUE = "foo_bar_baz";
633
634 p.url = base_url;
635 AddUrlFirstQueryParameter("uploadType", "multipart", &p.url);
636
637 p.method = "POST";
638
639 p.headers = "";
640
641 AddHeaders("Content-type", "multipart/related; boundary=" + BOUNDARY_VALUE,
642 &p.headers);
643 AddHeaders("Authorization", "Bearer " + googledrivefs->token(), &p.headers);
644
645 p.body = "";
646 AddBody("--" + BOUNDARY_VALUE, &p.body);
647 AddBody("Content-Type: application/json; charset=UTF-8", &p.body);
648 AddBody("", &p.body);
649 AddBody("{", &p.body);
650 AddBody(std::string(" \"name\": \"") + path_.Basename() + std::string("\","),
651 &p.body);
652 AddBody(" \"parents\": [", &p.body);
653 AddBody(" \"" + parent_dir_id_ + "\"", &p.body);
654 AddBody(" ]", &p.body);
655 AddBody("}", &p.body);
656 AddBody("", &p.body);
657 AddBody("--" + BOUNDARY_VALUE, &p.body);
658 AddBody("Content-Type: text/plain", &p.body);
659 AddBody("", &p.body);
660 AddBody("", &p.body);
661 AddBody("--" + BOUNDARY_VALUE + "--", &p.body);
662
663 error = MakeRequest(googledrivefs->ppapi(), url_loader_object,
664 url_request_info_object, p);
665
666 if (error) {
667 goto done;
668 }
669
670 error = FinishPreparingResponse(googledrivefs->ppapi(), url_loader_object,
671 &url_response_info_object);
672
673 if (error) {
674 goto done;
675 }
676
677 if (ReadStatusCode(googledrivefs->ppapi(), url_response_info_object) !=
678 STATUSCODE_OK) {
679 error = EPERM;
680 goto done;
681 }
682
683 done:
684 if (url_loader_object) {
685 googledrivefs->ppapi()->ReleaseResource(url_loader_object);
686 }
687 if (url_request_info_object) {
688 googledrivefs->ppapi()->ReleaseResource(url_request_info_object);
689 }
690 if (url_response_info_object) {
691 googledrivefs->ppapi()->ReleaseResource(url_response_info_object);
692 }
693
694 return error;
695 }
696
697 Error GoogleDriveFsNode::RequestDirentHelper(
698 const std::string& url,
699 std::vector<std::string>* out_dirent_names) {
700 std::string response_body;
701 Error error = GetListFileResponseBody(url, filesystem_, &response_body);
702 if (error) {
703 return error;
704 }
705
706 std::string name_value = "";
707 int name_index = 0;
708
709 GetValue(response_body, "name", name_index, &name_value, &name_index);
710
711 while (name_index != -1) {
712 out_dirent_names->push_back(name_value);
713
714 GetValue(response_body, "name", name_index, &name_value, &name_index);
715 }
716
717 std::string next_page_token_value = "";
718 int next_page_token_index = 0;
719 GetValue(response_body, "nextPageToken", 0, &next_page_token_value,
720 &next_page_token_index);
721 if (next_page_token_index != -1) {
722 return RequestDirentWithNextPageToken(next_page_token_value,
723 out_dirent_names);
724 }
725
726 return 0;
727 }
728
729 Error GoogleDriveFsNode::RequestDirentWithNextPageToken(
730 const std::string& next_page_token,
731 std::vector<std::string>* out_dirent_names) {
732 static const char base_url[] = "https://www.googleapis.com/drive/v3/files";
733
734 std::string url = base_url;
735 AddUrlFirstQueryParameter("pageToken", next_page_token, &url);
736 AddUrlNextQueryParameter("q", "%27" + item_id_ + "%27+in+parents", &url);
737
738 return RequestDirentHelper(url, out_dirent_names);
739 }
740
741 Error GoogleDriveFsNode::RequestDirent(
742 std::vector<std::string>* out_dirent_names) {
743 static const char base_url[] = "https://www.googleapis.com/drive/v3/files";
744
745 std::string url = base_url;
746 AddUrlFirstQueryParameter("q", "%27" + item_id_ + "%27+in+parents", &url);
binji 2016/08/22 19:21:53 this expression ("%27" + ...) is very common, prob
chanpatorikku 2016/08/29 17:14:03 Done.
747
748 return RequestDirentHelper(url, out_dirent_names);
749 }
750
751 } // namespace nacl_io
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698