Chromium Code Reviews| Index: chrome/browser/android/vr_shell/gltf_parser.cc |
| diff --git a/chrome/browser/android/vr_shell/gltf_parser.cc b/chrome/browser/android/vr_shell/gltf_parser.cc |
| index 17be0c8c098129ba39c62fd4acb0652695d2fa89..72737880c65d762083518839def9af6b5383918e 100644 |
| --- a/chrome/browser/android/vr_shell/gltf_parser.cc |
| +++ b/chrome/browser/android/vr_shell/gltf_parser.cc |
| @@ -4,36 +4,55 @@ |
| #include "chrome/browser/android/vr_shell/gltf_parser.h" |
| -#include "base/base64.h" |
| +#include "base/files/file_util.h" |
| +#include "base/json/json_file_value_serializer.h" |
| #include "base/logging.h" |
| #include "base/memory/ptr_util.h" |
| +#include "net/base/data_url.h" |
| +#include "net/base/filename_util.h" |
| +#include "url/gurl.h" |
| namespace vr_shell { |
| -constexpr char kBase64Header[] = "data:application/octet-stream;base64,"; |
| -constexpr size_t kBase64HeaderSize = 37; |
| - |
| GltfParser::GltfParser() {} |
| GltfParser::~GltfParser() = default; |
| std::unique_ptr<gltf::Asset> GltfParser::Parse( |
| - const base::DictionaryValue& dict) { |
| - std::string gltf_version; |
| - if (!dict.GetString("asset.version", &gltf_version) || gltf_version != "1.0") |
| - return nullptr; |
| - |
| + const base::DictionaryValue& dict, |
| + const base::FilePath& path) { |
| + path_ = path; |
| asset_ = base::MakeUnique<gltf::Asset>(); |
| if (!ParseInternal(dict)) { |
| - asset_.reset(); |
| + Clear(); |
|
cjgrant
2017/03/24 15:11:54
I don't think its warranted here, but if this code
acondor_
2017/03/24 18:00:55
I went for the first suggestion.
|
| return nullptr; |
| } |
| - return std::move(asset_); |
| + auto asset = std::move(asset_); |
| + Clear(); |
| + return asset; |
| +} |
| + |
| +std::unique_ptr<gltf::Asset> GltfParser::Parse( |
| + const base::FilePath& gltf_path) { |
| + JSONFileValueDeserializer json_deserializer(gltf_path); |
| + int error_code; |
| + std::string error_msg; |
| + auto asset_value = json_deserializer.Deserialize(&error_code, &error_msg); |
| + if (!asset_value) |
| + return nullptr; |
| + base::DictionaryValue* asset; |
| + if (!asset_value->GetAsDictionary(&asset)) |
| + return nullptr; |
| + return Parse(*asset, gltf_path); |
| } |
| bool GltfParser::ParseInternal(const base::DictionaryValue& dict) { |
| + std::string gltf_version; |
| + if (!dict.GetString("asset.version", &gltf_version) || gltf_version != "1.0") |
| + return false; |
| + |
| const base::DictionaryValue* sub_dict; |
| if (dict.GetDictionary("buffers", &sub_dict) && !SetBuffers(*sub_dict)) |
| return false; |
| @@ -66,14 +85,11 @@ bool GltfParser::SetBuffers(const base::DictionaryValue& dict) { |
| if (!it.value().GetAsDictionary(&buffer_dict)) |
| return false; |
| - std::string uri; |
| - // TODO(acondor): Support files. Only inline data is supported now. |
| - if (!buffer_dict->GetString("uri", &uri) || |
| - uri.substr(0, kBase64HeaderSize) != kBase64Header) |
| + std::string uri_str; |
| + if (!buffer_dict->GetString("uri", &uri_str)) |
| return false; |
| - |
| - auto buffer = base::MakeUnique<gltf::Buffer>(); |
| - if (!base::Base64Decode(uri.substr(kBase64HeaderSize), buffer.get())) |
| + auto buffer = ProcessUri(uri_str); |
| + if (!buffer) |
| return false; |
| int byte_length; |
| @@ -86,6 +102,30 @@ bool GltfParser::SetBuffers(const base::DictionaryValue& dict) { |
| return true; |
| } |
| +std::unique_ptr<gltf::Buffer> GltfParser::ProcessUri( |
| + const std::string& uri_str) { |
| + auto uri = path_.empty() ? GURL(uri_str) |
| + : net::FilePathToFileURL(path_).Resolve(uri_str); |
| + if (!uri.is_valid()) |
| + return nullptr; |
| + if (uri.SchemeIs(url::kDataScheme)) { |
| + std::string mime_type; |
| + std::string charset; |
| + auto data = base::MakeUnique<gltf::Buffer>(); |
| + if (!net::DataURL::Parse(uri, &mime_type, &charset, data.get())) |
| + return nullptr; |
| + return data; |
| + } |
| + if (uri.SchemeIsFile()) { |
| + auto data = base::MakeUnique<gltf::Buffer>(); |
| + if (!base::ReadFileToString(base::FilePath(uri.path()), data.get())) |
| + return nullptr; |
| + return data; |
| + } |
| + // No other schemes are supported yet. |
| + return nullptr; |
| +} |
| + |
| bool GltfParser::SetBufferViews(const base::DictionaryValue& dict) { |
| for (base::DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) { |
| const base::DictionaryValue* buffer_view_dict; |
| @@ -271,4 +311,15 @@ bool GltfParser::SetScenes(const base::DictionaryValue& dict) { |
| return true; |
| } |
| +void GltfParser::Clear() { |
| + asset_.reset(); |
| + path_.clear(); |
| + buffer_ids_.clear(); |
| + buffer_view_ids_.clear(); |
| + accessor_ids_.clear(); |
| + node_ids_.clear(); |
| + mesh_ids_.clear(); |
| + scene_ids_.clear(); |
| +} |
| + |
| } // namespace vr_shell |