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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: native_client_sdk/src/libraries/nacl_io/googledrivefs/googledrivefs_node.cc
diff --git a/native_client_sdk/src/libraries/nacl_io/googledrivefs/googledrivefs_node.cc b/native_client_sdk/src/libraries/nacl_io/googledrivefs/googledrivefs_node.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ea87e144b8ffc29132b37d1d13a4e8eeead7e649
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/googledrivefs/googledrivefs_node.cc
@@ -0,0 +1,751 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "nacl_io/googledrivefs/googledrivefs_node.h"
+
+#include <stdio.h>
+#include <time.h>
+
+#include <algorithm>
+
+#include "ppapi/c/pp_completion_callback.h"
+
+#include "nacl_io/error.h"
+#include "nacl_io/filesystem.h"
+#include "nacl_io/getdents_helper.h"
+#include "nacl_io/hash.h"
+#include "nacl_io/kernel_handle.h"
+#include "nacl_io/pepper_interface.h"
+#include "nacl_io/statuscode.h"
+#include "nacl_io/googledrivefs/googledrivefs.h"
+#include "nacl_io/googledrivefs/googledrivefs_util.h"
+
+namespace nacl_io {
+
+GoogleDriveFsNode::GoogleDriveFsNode(Filesystem* filesystem, Path path)
+ : Node(filesystem), path_(path) {}
+
+Error GoogleDriveFsNode::GetDents(size_t offs,
+ struct dirent* pdir,
+ size_t size,
+ int* out_bytes) {
+ *out_bytes = 0;
+
+ if (!IsaDir()) {
+ return ENOTDIR;
+ }
+
+ const ino_t kCurDirIno = -1;
+ const ino_t kParentDirIno = -2;
+ GetDentsHelper helper(kCurDirIno, kParentDirIno);
+
+ std::vector<std::string> dirent_names;
+ Error error = RequestDirent(&dirent_names);
+ if (error) {
+ return error;
+ }
+
+ for (size_t i = 0; i < dirent_names.size(); ++i) {
+ Path child_path(path_);
+ child_path = child_path.Append("/" + dirent_names[i]);
+ ino_t child_ino = HashPath(child_path);
+
+ helper.AddDirent(child_ino, dirent_names[i].c_str(),
+ dirent_names[i].size());
+ }
+
+ return helper.GetDents(offs, pdir, size, out_bytes);
+}
+
+Error GoogleDriveFsNode::GetStat(struct stat* pstat) {
+ Error error = GetSize(&pstat->st_size);
+ if (error) {
+ return error;
+ }
+
+ error = GetModifiedTime(&pstat->st_mtime);
+ if (error) {
+ return error;
+ }
+
+ pstat->st_atime = 0;
+ pstat->st_ctime = 0;
+
+ pstat->st_mode = stat_.st_mode;
+
+ return 0;
+}
+
+Error GoogleDriveFsNode::Write(const HandleAttr& attr,
+ const void* buf,
+ size_t count,
+ int* out_bytes) {
+ *out_bytes = 0;
+
+ if (IsaDir()) {
+ return EISDIR;
+ }
+ if ((GetMode() & S_IWRITE) == 0) {
+ return EACCES;
+ }
+
+ off_t file_size = 0;
+ Error error = GetSize(&file_size);
+ if (error) {
+ return error;
+ }
+
+ 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
+ (unsigned long long int)attr.offs + count);
+
+ // use std::string for storing data in the heap, as the size of stack
+ // is measured in megabytes, disallowing files larger than that.
+ std::string file_buffer(file_buffer_size, '\0');
+
+ if (file_size > 0) {
+ int read_helper_out_bytes = 0;
+ error = ReadHelper(0, file_size - 1, &file_buffer, &read_helper_out_bytes);
+
+ if (error) {
+ return error;
+ }
+ }
+
+ char* pChar = (char*)buf;
+ for (size_t i = 0; i < count; ++i) {
+ file_buffer[attr.offs + i] = pChar[i];
+ }
+
+ 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
+ if (error) {
+ return error;
+ }
+
+ *out_bytes = count;
+
+ return 0;
+}
+
+Error GoogleDriveFsNode::FTruncate(off_t length) {
+ if (IsaDir()) {
+ return EISDIR;
+ }
+
+ off_t file_size = 0;
+ Error error = GetSize(&file_size);
+ if (error) {
+ return error;
+ }
+
+ std::string file_buffer(length, '\0');
+
+ if (file_size > 0) {
+ int read_helper_out_bytes = 0;
+ off_t read_end = std::min(length, file_size);
+ error = ReadHelper(0, read_end - 1, &file_buffer, &read_helper_out_bytes);
+
+ if (error) {
+ return error;
+ }
+ }
+
+ error = WriteHelper(file_buffer.c_str(), length);
+ if (error) {
+ return error;
+ }
+
+ return 0;
+}
+
+Error GoogleDriveFsNode::Read(const HandleAttr& attr,
+ void* buf,
+ size_t count,
+ int* out_bytes) {
+ *out_bytes = 0;
+
+ if (IsaDir()) {
+ return EISDIR;
+ }
+ if ((GetMode() & S_IREAD) == 0) {
+ return EACCES;
+ }
+
+ std::string file_buffer(count, '\0');
+
+ Error error =
+ ReadHelper(attr.offs, attr.offs + count - 1, &file_buffer, out_bytes);
+ if (error) {
+ return error;
+ }
+
+ char* pChar = (char*)buf;
+ for (size_t i = 0; i < count; ++i) {
+ 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
+ }
+
+ return 0;
+}
+
+Error GoogleDriveFsNode::GetSize(off_t* out_size) {
+ *out_size = 0;
+
+ GoogleDriveFs* googledrivefs = static_cast<GoogleDriveFs*>(filesystem_);
+
+ URLLoaderInterface* url_loader_iface =
+ googledrivefs->ppapi()->GetURLLoaderInterface();
+ PP_Resource url_loader_object =
+ url_loader_iface->Create(googledrivefs->instance());
+ URLRequestInfoInterface* url_request_info_iface =
+ googledrivefs->ppapi()->GetURLRequestInfoInterface();
+ PP_Resource url_request_info_object =
+ url_request_info_iface->Create(googledrivefs->instance());
+ PP_Resource url_response_info_object = 0;
+ Error error(0);
+ static const char base_url[] = "https://www.googleapis.com/drive/v3/files";
+ RequestUrlParams p;
+ std::string output;
+ std::string size_value;
+ int size_index;
+
+ if (IsaDir()) {
+ goto done;
+ }
+
+ p.url = base_url;
+ AddUrlPath(item_id_, &p.url);
+ AddUrlFirstQueryParameter("fields", "size", &p.url);
+
+ p.method = "GET";
+
+ p.headers = "";
+
+ AddHeaders("Content-type", "application/json", &p.headers);
+ AddHeaders("Authorization", "Bearer " + googledrivefs->token(), &p.headers);
+
+ error = MakeRequest(googledrivefs->ppapi(), url_loader_object,
+ url_request_info_object, p);
+
+ if (error) {
+ goto done;
+ }
+
+ error = FinishPreparingResponse(googledrivefs->ppapi(), url_loader_object,
+ &url_response_info_object);
+
+ if (error) {
+ goto done;
+ }
+
+ if (ReadStatusCode(googledrivefs->ppapi(), url_response_info_object) !=
+ STATUSCODE_OK) {
+ error = EPERM;
+ goto done;
+ }
+
+ error = ReadResponseBody(googledrivefs->ppapi(), googledrivefs->instance(),
+ url_response_info_object, INT_MAX, &output);
+ if (error) {
+ goto done;
+ }
+
+ GetValue(output, "size", 0, &size_value, &size_index);
+ if (size_index == -1) {
+ // in a STATUSCODE_OK response, size of a directory is not written.
+ size_value = "0";
+ }
+
+ *out_size = (off_t)atoi(size_value.c_str());
+
+done:
+ if (url_loader_object) {
+ googledrivefs->ppapi()->ReleaseResource(url_loader_object);
+ }
+ if (url_request_info_object) {
+ googledrivefs->ppapi()->ReleaseResource(url_request_info_object);
+ }
+ if (url_response_info_object) {
+ googledrivefs->ppapi()->ReleaseResource(url_response_info_object);
+ }
+
+ return error;
+}
+
+Error GoogleDriveFsNode::Init(int open_flags) {
+ Error error = Node::Init(open_flags);
+
+ if (error) {
+ return error;
+ }
+
+ if (path_.Size() == 1) {
+ parent_dir_id_ = "";
+ item_id_ = "root";
+ SetType(S_IFDIR);
+ SetMode(S_IREAD);
+ return 0;
+ }
+
+ error = RequestParentDirId(path_, filesystem_, &parent_dir_id_);
+ if (error) {
+ return error;
+ }
+
+ // Request the ID of an item, which is a file or a directory
+ error =
+ RequestItemId(parent_dir_id_, path_.Basename(), filesystem_, &item_id_);
+
+ if (error == ENOENT) {
+ // Only files are open as mode O_CREAT
+ if ((open_flags & O_CREAT) != 0) {
+ error = CreateEmptyFile();
+ if (error) {
+ return error;
+ }
+ error = RequestItemId(parent_dir_id_, path_.Basename(), filesystem_,
+ &item_id_);
+ if (error) {
+ return error;
+ }
+ SetType(S_IFREG);
+ if ((open_flags & O_RDWR) != 0) {
+ SetMode(S_IREAD | S_IWRITE);
+ } else if ((open_flags & O_WRONLY) != 0) {
+ SetMode(S_IWRITE);
+ } else {
+ SetMode(S_IREAD);
+ }
+ } else {
+ return ENOENT;
+ }
+ } else if (error) {
+ return error;
+ } else {
+ std::string dir_id = "";
+ error =
+ RequestDirId(parent_dir_id_, path_.Basename(), filesystem_, &dir_id);
+ if (error == ENOENT) {
+ SetType(S_IFREG);
+ if ((open_flags & O_RDWR) != 0) {
+ SetMode(S_IREAD | S_IWRITE);
+ } else if ((open_flags & O_WRONLY) != 0) {
+ SetMode(S_IWRITE);
+ } else {
+ SetMode(S_IREAD);
+ }
+ } else if (error) {
+ return error;
+ } else {
+ SetType(S_IFDIR);
+ SetMode(S_IREAD);
+ }
+
+ if (open_flags == 0) {
+ // open_flags == 0 for file opened on fopen with mode r and
+ // directory opened on opendir
+ return 0;
+ } else if (IsaDir()) {
+ return EPERM;
+ } else if ((open_flags & O_TRUNC) != 0) {
+ error = WriteHelper(NULL, 0);
+ if (error) {
+ return error;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void GoogleDriveFsNode::Destroy() {
+ Node::Destroy();
+}
+
+Error GoogleDriveFsNode::ReadHelper(off_t start,
+ off_t end,
+ std::string* out_string_buffer,
+ int* out_bytes) {
+ (*out_string_buffer)[0] = '\0';
+ *out_bytes = 0;
+
+ GoogleDriveFs* googledrivefs = static_cast<GoogleDriveFs*>(filesystem_);
+
+ URLLoaderInterface* url_loader_iface =
+ googledrivefs->ppapi()->GetURLLoaderInterface();
+ PP_Resource url_loader_object =
+ url_loader_iface->Create(googledrivefs->instance());
+ URLRequestInfoInterface* url_request_info_iface =
+ googledrivefs->ppapi()->GetURLRequestInfoInterface();
+ PP_Resource url_request_info_object =
+ url_request_info_iface->Create(googledrivefs->instance());
+ PP_Resource url_response_info_object = 0;
+ Error error(EPERM);
+ static const char base_url[] =
+ "https://www.googleapis.com/download/drive/v3/files";
+ RequestUrlParams p;
+ char range_value_buffer[1024];
+ int char_written = 0;
+ int status_code = 0;
+ std::string output;
+
+ p.url = base_url;
+ AddUrlPath(item_id_, &p.url);
+ AddUrlFirstQueryParameter("alt", "media", &p.url);
+
+ p.method = "GET";
+
+ p.headers = "";
+
+ AddHeaders("Content-type", "application/json", &p.headers);
+ AddHeaders("Authorization", "Bearer " + googledrivefs->token(), &p.headers);
+
+ 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.
+ (long long int)start, (long long int)end);
+ if (char_written < 0) {
+ error = EPERM;
+ goto done;
+ }
+
+ 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.
+
+ error = MakeRequest(googledrivefs->ppapi(), url_loader_object,
+ url_request_info_object, p);
+
+ if (error) {
+ goto done;
+ }
+
+ error = FinishPreparingResponse(googledrivefs->ppapi(), url_loader_object,
+ &url_response_info_object);
+
+ if (error) {
+ goto done;
+ }
+
+ status_code =
+ ReadStatusCode(googledrivefs->ppapi(), url_response_info_object);
+
+ if (status_code == STATUSCODE_OK ||
+ status_code == STATUSCODE_PARTIAL_CONTENT) {
+ error =
+ ReadResponseBody(googledrivefs->ppapi(), googledrivefs->instance(),
+ url_response_info_object, end - start + 1, &output);
+
+ if (error) {
+ goto done;
+ }
+
+ for (size_t i = 0; i < output.size(); ++i) {
+ (*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
+ }
+
+ *out_bytes = output.size();
+
+ error = 0;
+ goto done;
+ } else if (status_code == STATUSCODE_REQUESTED_RANGE_NOT_SATISFIABLE) {
+ 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
+ goto done;
+ }
+
+done:
+ if (url_loader_object) {
+ googledrivefs->ppapi()->ReleaseResource(url_loader_object);
+ }
+ if (url_request_info_object) {
+ googledrivefs->ppapi()->ReleaseResource(url_request_info_object);
+ }
+ if (url_response_info_object) {
+ googledrivefs->ppapi()->ReleaseResource(url_response_info_object);
+ }
+
+ return error;
+}
+
+Error GoogleDriveFsNode::WriteHelper(const char* body_data,
+ uint32_t body_size) {
+ GoogleDriveFs* googledrivefs = static_cast<GoogleDriveFs*>(filesystem_);
+
+ URLLoaderInterface* url_loader_iface =
+ googledrivefs->ppapi()->GetURLLoaderInterface();
+ PP_Resource url_loader_object =
+ url_loader_iface->Create(googledrivefs->instance());
+ URLRequestInfoInterface* url_request_info_iface =
+ googledrivefs->ppapi()->GetURLRequestInfoInterface();
+ PP_Resource url_request_info_object =
+ url_request_info_iface->Create(googledrivefs->instance());
+ PP_Resource url_response_info_object = 0;
+ Error error(0);
+ static const char base_url[] =
+ "https://www.googleapis.com/upload/drive/v3/files";
+ RequestUrlParams p;
+
+ p.url = base_url;
+ AddUrlPath(item_id_, &p.url);
+ AddUrlFirstQueryParameter("uploadType", "media", &p.url);
+
+ p.method = "PATCH";
+
+ p.headers = "";
+
+ AddHeaders("Content-type", "application/json", &p.headers);
+ AddHeaders("Authorization", "Bearer " + googledrivefs->token(), &p.headers);
+
+ p.body = std::string(body_data, body_size);
+
+ error = MakeRequest(googledrivefs->ppapi(), url_loader_object,
+ url_request_info_object, p);
+
+ if (error) {
+ goto done;
+ }
+
+ error = FinishPreparingResponse(googledrivefs->ppapi(), url_loader_object,
+ &url_response_info_object);
+
+ if (error) {
+ goto done;
+ }
+
+ if (ReadStatusCode(googledrivefs->ppapi(), url_response_info_object) !=
+ STATUSCODE_OK) {
+ error = EPERM;
+ goto done;
+ }
+
+done:
+ if (url_loader_object) {
+ googledrivefs->ppapi()->ReleaseResource(url_loader_object);
+ }
+ if (url_request_info_object) {
+ googledrivefs->ppapi()->ReleaseResource(url_request_info_object);
+ }
+ if (url_response_info_object) {
+ googledrivefs->ppapi()->ReleaseResource(url_response_info_object);
+ }
+
+ return error;
+}
+
+Error GoogleDriveFsNode::GetModifiedTime(time_t* out_mtime) {
+ GoogleDriveFs* googledrivefs = static_cast<GoogleDriveFs*>(filesystem_);
+
+ URLLoaderInterface* url_loader_iface =
+ googledrivefs->ppapi()->GetURLLoaderInterface();
+ PP_Resource url_loader_object =
+ url_loader_iface->Create(googledrivefs->instance());
+ URLRequestInfoInterface* url_request_info_iface =
+ googledrivefs->ppapi()->GetURLRequestInfoInterface();
+ PP_Resource url_request_info_object =
+ url_request_info_iface->Create(googledrivefs->instance());
+ PP_Resource url_response_info_object = 0;
+ Error error(0);
+ static const char base_url[] = "https://www.googleapis.com/drive/v3/files";
+ RequestUrlParams p;
+ std::string output;
+ std::string modified_time_value = "";
+ int modified_time_index = 0;
+ struct tm timeinfo;
+
+ p.url = base_url;
+ AddUrlPath(item_id_, &p.url);
+ AddUrlFirstQueryParameter("fields", "modifiedTime", &p.url);
+
+ p.method = "GET";
+
+ p.headers = "";
+
+ AddHeaders("Content-type", "application/json", &p.headers);
+ AddHeaders("Authorization", "Bearer " + googledrivefs->token(), &p.headers);
+
+ error = MakeRequest(googledrivefs->ppapi(), url_loader_object,
+ url_request_info_object, p);
+
+ if (error) {
+ goto done;
+ }
+
+ error = FinishPreparingResponse(googledrivefs->ppapi(), url_loader_object,
+ &url_response_info_object);
+
+ if (error) {
+ goto done;
+ }
+
+ if (ReadStatusCode(googledrivefs->ppapi(), url_response_info_object) !=
+ STATUSCODE_OK) {
+ error = EPERM;
+ goto done;
+ }
+
+ error = ReadResponseBody(googledrivefs->ppapi(), googledrivefs->instance(),
+ url_response_info_object, INT_MAX, &output);
+ if (error) {
+ goto done;
+ }
+
+ // the value of modifiedTime is assumed to be always in the STATUSCODE_OK
+ // response.
+ 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(
+ &modified_time_index);
+
+ timeinfo.tm_year = atoi(modified_time_value.substr(0, 4).c_str());
+ timeinfo.tm_mon = atoi(modified_time_value.substr(5, 2).c_str());
+ timeinfo.tm_mday = atoi(modified_time_value.substr(8, 2).c_str());
+ timeinfo.tm_hour = atoi(modified_time_value.substr(11, 2).c_str());
+ timeinfo.tm_min = atoi(modified_time_value.substr(14, 2).c_str());
+ timeinfo.tm_sec = atoi(modified_time_value.substr(17, 2).c_str());
+ timeinfo.tm_isdst = 0;
+
+ *out_mtime = mktime(&timeinfo);
+
+done:
+ if (url_loader_object) {
+ googledrivefs->ppapi()->ReleaseResource(url_loader_object);
+ }
+ if (url_request_info_object) {
+ googledrivefs->ppapi()->ReleaseResource(url_request_info_object);
+ }
+ if (url_response_info_object) {
+ googledrivefs->ppapi()->ReleaseResource(url_response_info_object);
+ }
+
+ return error;
+}
+
+Error GoogleDriveFsNode::CreateEmptyFile() {
+ GoogleDriveFs* googledrivefs = static_cast<GoogleDriveFs*>(filesystem_);
+
+ URLLoaderInterface* url_loader_iface =
+ googledrivefs->ppapi()->GetURLLoaderInterface();
+ PP_Resource url_loader_object =
+ url_loader_iface->Create(googledrivefs->instance());
+ URLRequestInfoInterface* url_request_info_iface =
+ googledrivefs->ppapi()->GetURLRequestInfoInterface();
+ PP_Resource url_request_info_object =
+ url_request_info_iface->Create(googledrivefs->instance());
+ PP_Resource url_response_info_object = 0;
+ Error error(0);
+ static const char base_url[] =
+ "https://www.googleapis.com/upload/drive/v3/files";
+ RequestUrlParams p;
+ std::string BOUNDARY_VALUE = "foo_bar_baz";
+
+ p.url = base_url;
+ AddUrlFirstQueryParameter("uploadType", "multipart", &p.url);
+
+ p.method = "POST";
+
+ p.headers = "";
+
+ AddHeaders("Content-type", "multipart/related; boundary=" + BOUNDARY_VALUE,
+ &p.headers);
+ AddHeaders("Authorization", "Bearer " + googledrivefs->token(), &p.headers);
+
+ p.body = "";
+ AddBody("--" + BOUNDARY_VALUE, &p.body);
+ AddBody("Content-Type: application/json; charset=UTF-8", &p.body);
+ AddBody("", &p.body);
+ AddBody("{", &p.body);
+ AddBody(std::string(" \"name\": \"") + path_.Basename() + std::string("\","),
+ &p.body);
+ AddBody(" \"parents\": [", &p.body);
+ AddBody(" \"" + parent_dir_id_ + "\"", &p.body);
+ AddBody(" ]", &p.body);
+ AddBody("}", &p.body);
+ AddBody("", &p.body);
+ AddBody("--" + BOUNDARY_VALUE, &p.body);
+ AddBody("Content-Type: text/plain", &p.body);
+ AddBody("", &p.body);
+ AddBody("", &p.body);
+ AddBody("--" + BOUNDARY_VALUE + "--", &p.body);
+
+ error = MakeRequest(googledrivefs->ppapi(), url_loader_object,
+ url_request_info_object, p);
+
+ if (error) {
+ goto done;
+ }
+
+ error = FinishPreparingResponse(googledrivefs->ppapi(), url_loader_object,
+ &url_response_info_object);
+
+ if (error) {
+ goto done;
+ }
+
+ if (ReadStatusCode(googledrivefs->ppapi(), url_response_info_object) !=
+ STATUSCODE_OK) {
+ error = EPERM;
+ goto done;
+ }
+
+done:
+ if (url_loader_object) {
+ googledrivefs->ppapi()->ReleaseResource(url_loader_object);
+ }
+ if (url_request_info_object) {
+ googledrivefs->ppapi()->ReleaseResource(url_request_info_object);
+ }
+ if (url_response_info_object) {
+ googledrivefs->ppapi()->ReleaseResource(url_response_info_object);
+ }
+
+ return error;
+}
+
+Error GoogleDriveFsNode::RequestDirentHelper(
+ const std::string& url,
+ std::vector<std::string>* out_dirent_names) {
+ std::string response_body;
+ Error error = GetListFileResponseBody(url, filesystem_, &response_body);
+ if (error) {
+ return error;
+ }
+
+ std::string name_value = "";
+ int name_index = 0;
+
+ GetValue(response_body, "name", name_index, &name_value, &name_index);
+
+ while (name_index != -1) {
+ out_dirent_names->push_back(name_value);
+
+ GetValue(response_body, "name", name_index, &name_value, &name_index);
+ }
+
+ std::string next_page_token_value = "";
+ int next_page_token_index = 0;
+ GetValue(response_body, "nextPageToken", 0, &next_page_token_value,
+ &next_page_token_index);
+ if (next_page_token_index != -1) {
+ return RequestDirentWithNextPageToken(next_page_token_value,
+ out_dirent_names);
+ }
+
+ return 0;
+}
+
+Error GoogleDriveFsNode::RequestDirentWithNextPageToken(
+ const std::string& next_page_token,
+ std::vector<std::string>* out_dirent_names) {
+ static const char base_url[] = "https://www.googleapis.com/drive/v3/files";
+
+ std::string url = base_url;
+ AddUrlFirstQueryParameter("pageToken", next_page_token, &url);
+ AddUrlNextQueryParameter("q", "%27" + item_id_ + "%27+in+parents", &url);
+
+ return RequestDirentHelper(url, out_dirent_names);
+}
+
+Error GoogleDriveFsNode::RequestDirent(
+ std::vector<std::string>* out_dirent_names) {
+ static const char base_url[] = "https://www.googleapis.com/drive/v3/files";
+
+ std::string url = base_url;
+ 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.
+
+ return RequestDirentHelper(url, out_dirent_names);
+}
+
+} // namespace nacl_io

Powered by Google App Engine
This is Rietveld 408576698