| Index: native_client_sdk/src/libraries/nacl_io/googledrivefs/googledrivefs.cc
|
| diff --git a/native_client_sdk/src/libraries/nacl_io/googledrivefs/googledrivefs.cc b/native_client_sdk/src/libraries/nacl_io/googledrivefs/googledrivefs.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b5bfbc009d4ed634a5d8aa4beac82832e6b59c7e
|
| --- /dev/null
|
| +++ b/native_client_sdk/src/libraries/nacl_io/googledrivefs/googledrivefs.cc
|
| @@ -0,0 +1,230 @@
|
| +// 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.h"
|
| +
|
| +#include "nacl_io/filesystem.h"
|
| +#include "nacl_io/statuscode.h"
|
| +#include "nacl_io/googledrivefs/googledrivefs_node.h"
|
| +#include "nacl_io/googledrivefs/googledrivefs_util.h"
|
| +
|
| +namespace nacl_io {
|
| +
|
| +GoogleDriveFs::GoogleDriveFs() {}
|
| +
|
| +Error GoogleDriveFs::Init(const FsInitArgs& args) {
|
| + Error error = Filesystem::Init(args);
|
| + if (error) {
|
| + return error;
|
| + }
|
| +
|
| + if (!ppapi()) {
|
| + return ENOSYS;
|
| + }
|
| +
|
| + StringMap_t::const_iterator token_it = args.string_map.find("token");
|
| +
|
| + if (token_it == args.string_map.end()) {
|
| + return EINVAL;
|
| + }
|
| +
|
| + token_ = token_it->second;
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +Error GoogleDriveFs::OpenWithMode(const Path& path,
|
| + int open_flags,
|
| + mode_t mode,
|
| + ScopedNode* out_node) {
|
| + ScopedNode node(new GoogleDriveFsNode(this, path));
|
| + Error error = node->Init(open_flags);
|
| + if (error) {
|
| + return error;
|
| + }
|
| +
|
| + *out_node = node;
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +Error GoogleDriveFs::Mkdir(const Path& path, int permissions) {
|
| + if (path.IsRoot()) {
|
| + return EEXIST;
|
| + }
|
| +
|
| + std::string parent_dir_id;
|
| + Error error = RequestParentDirId(path, this, &parent_dir_id);
|
| + if (error) {
|
| + return error;
|
| + }
|
| +
|
| + std::string item_id;
|
| + bool is_dir_type;
|
| + error = RequestItemIdAndItemType(parent_dir_id, path.Basename(), this,
|
| + &item_id, &is_dir_type);
|
| +
|
| + // mkdir does not create a directory when a directory or a file with
|
| + // path.Basename() already exists.
|
| + if (!error) {
|
| + return EEXIST;
|
| + } else if (error != ENOENT) {
|
| + return error;
|
| + }
|
| +
|
| + RequestUrlParams p;
|
| +
|
| + p.url = DRIVE_URL;
|
| + p.method = "POST";
|
| +
|
| + AddHeaders("Content-type", "application/json", &p.headers);
|
| + AddHeaders("Authorization", "Bearer " + token_, &p.headers);
|
| +
|
| + AddBody("{", &p.body);
|
| + AddBody(" \"name\": \"" + path.Basename() + "\",", &p.body);
|
| + AddBody(
|
| + std::string(" \"mimeType\": \"") + FOLDER_MIME_TYPE + std::string("\","),
|
| + &p.body);
|
| + AddBody(" \"parents\": [", &p.body);
|
| + AddBody(" \"" + parent_dir_id + "\"", &p.body);
|
| + AddBody(" ]", &p.body);
|
| + AddBody("}", &p.body);
|
| +
|
| + ScopedResource url_response_info_resource(ppapi());
|
| + error = LoadUrl(ppapi(), p, &url_response_info_resource);
|
| + if (error) {
|
| + return error;
|
| + }
|
| +
|
| + if (ReadStatusCode(ppapi(), url_response_info_resource.pp_resource()) !=
|
| + STATUSCODE_OK) {
|
| + return EPERM;
|
| + }
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +Error GoogleDriveFs::Rmdir(const Path& path) {
|
| + if (path.IsRoot()) {
|
| + return EEXIST;
|
| + }
|
| +
|
| + std::string parent_dir_id;
|
| + Error error = RequestParentDirId(path, this, &parent_dir_id);
|
| + if (error) {
|
| + return error;
|
| + }
|
| +
|
| + std::string item_id;
|
| + bool is_dir_type;
|
| + error = RequestItemIdAndItemType(parent_dir_id, path.Basename(), this,
|
| + &item_id, &is_dir_type);
|
| + if (error) {
|
| + return error;
|
| + }
|
| +
|
| + if (!is_dir_type) {
|
| + return ENOTDIR;
|
| + }
|
| +
|
| + bool is_empty_dir;
|
| + error = IsEmptyDir(item_id, &is_empty_dir);
|
| + if (error) {
|
| + return error;
|
| + }
|
| +
|
| + if (!is_empty_dir) {
|
| + return ENOTEMPTY;
|
| + }
|
| +
|
| + RequestUrlParams p;
|
| +
|
| + p.url = DRIVE_URL;
|
| + AddUrlPath(item_id, &p.url);
|
| +
|
| + p.method = "DELETE";
|
| +
|
| + AddHeaders("Content-type", "application/json", &p.headers);
|
| + AddHeaders("Authorization", "Bearer " + token_, &p.headers);
|
| +
|
| + ScopedResource url_response_info_resource(ppapi());
|
| + error = LoadUrl(ppapi(), p, &url_response_info_resource);
|
| + if (error) {
|
| + return error;
|
| + }
|
| +
|
| + if (ReadStatusCode(ppapi(), url_response_info_resource.pp_resource()) !=
|
| + STATUSCODE_NO_CONTENT) {
|
| + return EPERM;
|
| + }
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +Error GoogleDriveFs::Rename(const Path& path, const Path& newPath) {
|
| + // TODO: support rename
|
| + LOG_ERROR("rename not supported.");
|
| + return EPERM;
|
| +}
|
| +
|
| +Error GoogleDriveFs::Unlink(const Path& path) {
|
| + // TODO: support unlink
|
| + LOG_ERROR("unlink not supported.");
|
| + return EPERM;
|
| +}
|
| +
|
| +Error GoogleDriveFs::Remove(const Path& path) {
|
| + // TODO: support remove
|
| + LOG_ERROR("remove not supported.");
|
| + return EPERM;
|
| +}
|
| +
|
| +Error GoogleDriveFs::IsEmptyDir(const std::string& dir_id,
|
| + bool* out_is_empty_dir) {
|
| + RequestUrlParams p;
|
| +
|
| + p.url = DRIVE_URL;
|
| + AddUrlFirstQueryParameter("q", ParentEqualClause(dir_id), &p.url);
|
| +
|
| + p.method = "GET";
|
| +
|
| + AddHeaders("Content-type", "application/json", &p.headers);
|
| + AddHeaders("Authorization", "Bearer " + token_, &p.headers);
|
| +
|
| + ScopedResource url_response_info_resource(ppapi());
|
| + Error error = LoadUrl(ppapi(), p, &url_response_info_resource);
|
| + if (error) {
|
| + return error;
|
| + }
|
| +
|
| + if (ReadStatusCode(ppapi(), url_response_info_resource.pp_resource()) !=
|
| + STATUSCODE_OK) {
|
| + return EPERM;
|
| + }
|
| +
|
| + std::string output;
|
| + error = ReadResponseBody(ppapi(), url_response_info_resource.pp_resource(),
|
| + UINT_MAX, &output);
|
| + if (error) {
|
| + return error;
|
| + }
|
| +
|
| + std::string name_value;
|
| + size_t name_index;
|
| + error =
|
| + GetValueStringAndValuePos(output, "name", 0, &name_value, &name_index);
|
| + if (error && error != EINVAL) {
|
| + return error;
|
| + }
|
| +
|
| + *out_is_empty_dir = (error == EINVAL);
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +std::string GoogleDriveFs::token() {
|
| + return token_;
|
| +}
|
| +
|
| +} // namespace nacl_io
|
|
|