diff options
Diffstat (limited to 'webkit/glue/plugins/pepper_file_ref.cc')
-rw-r--r-- | webkit/glue/plugins/pepper_file_ref.cc | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/webkit/glue/plugins/pepper_file_ref.cc b/webkit/glue/plugins/pepper_file_ref.cc new file mode 100644 index 0000000..9b42cff --- /dev/null +++ b/webkit/glue/plugins/pepper_file_ref.cc @@ -0,0 +1,169 @@ +// Copyright (c) 2010 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 "webkit/glue/plugins/pepper_file_ref.h" + +#include "base/string_util.h" +#include "webkit/glue/plugins/pepper_plugin_instance.h" +#include "webkit/glue/plugins/pepper_var.h" +#include "webkit/glue/plugins/pepper_resource_tracker.h" + +namespace pepper { + +namespace { + +bool IsValidLocalPath(const std::string& path) { + // The path must start with '/' + if (path.empty() || path[0] != '/') + return false; + + // The path must contain valid UTF-8 characters. + if (!IsStringUTF8(path)) + return false; + + return true; +} + +void TrimTrailingSlash(std::string* path) { + // If this path ends with a slash, then normalize it away unless path is the + // root path. + if (path->size() > 1 && path->at(path->size() - 1) == '/') + path->erase(path->size() - 1, 1); +} + +PP_Resource CreateFileRef(PP_Instance instance_id, + PP_FileSystemType fs_type, + const char* path) { + PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + if (!instance) + return 0; + + std::string origin; // TODO(darin): Extract from PluginInstance. + + std::string validated_path(path); + if (!IsValidLocalPath(validated_path)) + return 0; + TrimTrailingSlash(&validated_path); + + FileRef* file_ref = new FileRef(instance->module(), + fs_type, + validated_path, + origin); + return file_ref->GetReference(); +} + +PP_Resource CreatePersistentFileRef(PP_Instance instance_id, const char* path) { + return CreateFileRef(instance_id, PP_FILESYSTEMTYPE_LOCALPERSISTENT, path); +} + +PP_Resource CreateTemporaryFileRef(PP_Instance instance_id, const char* path) { + return CreateFileRef(instance_id, PP_FILESYSTEMTYPE_LOCALTEMPORARY, path); +} + +bool IsFileRef(PP_Resource resource) { + return !!Resource::GetAs<FileRef>(resource); +} + +PP_FileSystemType GetFileSystemType(PP_Resource file_ref_id) { + scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); + if (!file_ref) + return PP_FILESYSTEMTYPE_EXTERNAL; + + return file_ref->file_system_type(); +} + +PP_Var GetName(PP_Resource file_ref_id) { + scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); + if (!file_ref) + return PP_MakeVoid(); + + return StringToPPVar(file_ref->GetName()); +} + +PP_Var GetPath(PP_Resource file_ref_id) { + scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); + if (!file_ref) + return PP_MakeVoid(); + + if (file_ref->file_system_type() == PP_FILESYSTEMTYPE_EXTERNAL) + return PP_MakeVoid(); + + return StringToPPVar(file_ref->path()); +} + +PP_Resource GetParent(PP_Resource file_ref_id) { + scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); + if (!file_ref) + return 0; + + if (file_ref->file_system_type() == PP_FILESYSTEMTYPE_EXTERNAL) + return 0; + + scoped_refptr<FileRef> parent_ref(file_ref->GetParent()); + if (!parent_ref) + return 0; + + return parent_ref->GetReference(); +} + +const PPB_FileRef ppb_fileref = { + &CreatePersistentFileRef, + &CreateTemporaryFileRef, + &IsFileRef, + &GetFileSystemType, + &GetName, + &GetPath, + &GetParent +}; + +} // namespace + +FileRef::FileRef(PluginModule* module, + PP_FileSystemType file_system_type, + const std::string& validated_path, + const std::string& origin) + : Resource(module), + fs_type_(file_system_type), + path_(validated_path), + origin_(origin) { + // TODO(darin): Need to initialize system_path_. +} + +FileRef::~FileRef() { +} + +// static +const PPB_FileRef* FileRef::GetInterface() { + return &ppb_fileref; +} + +std::string FileRef::GetName() const { + if (path_.size() == 1 && path_[0] == '/') + return path_; + + // There should always be a leading slash at least! + size_t pos = path_.rfind('/'); + DCHECK(pos != std::string::npos); + + return path_.substr(pos + 1); +} + +scoped_refptr<FileRef> FileRef::GetParent() { + if (path_.size() == 1 && path_[0] == '/') + return this; + + // There should always be a leading slash at least! + size_t pos = path_.rfind('/'); + DCHECK(pos != std::string::npos); + + // If the path is "/foo", then we want to include the slash. + if (pos == 0) + pos++; + std::string parent_path = path_.substr(0, pos); + + FileRef* parent_ref = new FileRef(module(), fs_type_, parent_path, origin_); + return parent_ref; +} + +} // namespace pepper |