summaryrefslogtreecommitdiffstats
path: root/o3d/import
diff options
context:
space:
mode:
authorgman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-17 22:25:08 +0000
committergman@google.com <gman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-17 22:25:08 +0000
commit523b2523c1f2cb22f56be9cc52fb734370992387 (patch)
treeede3f93c4e118e840778e39b5633d6bfc7058ab3 /o3d/import
parent9521c61f5588480d8cd6134144db7137630f2529 (diff)
downloadchromium_src-523b2523c1f2cb22f56be9cc52fb734370992387.zip
chromium_src-523b2523c1f2cb22f56be9cc52fb734370992387.tar.gz
chromium_src-523b2523c1f2cb22f56be9cc52fb734370992387.tar.bz2
Add RawData request in preparation for manual loading of
Bitmaps and being able to flip them, scale them, etc... Basically this just makes it possible to download a RawData directly which you can then pass you'll be able to pass to pack->CreateBitmapFromRawData. Some design comments: I used SetFromFile instead of making a different constructor since it seemed wrong to do file IO in a constructor. Given that SetFromFile is private I don't think this is a problem since you can't call it directly. Also, I thought about loading the file first and then calling the original constructor but it seemed like a waste to load the file into memory, then copy it to a new buffer when I could just load it directly. Finally I made it take a String instead of a FilePath because it meant other places had to do less work. Review URL: http://codereview.chromium.org/149784 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21015 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/import')
-rw-r--r--o3d/import/cross/raw_data.cc81
-rw-r--r--o3d/import/cross/raw_data.h9
-rw-r--r--o3d/import/cross/raw_data_test.cc74
3 files changed, 158 insertions, 6 deletions
diff --git a/o3d/import/cross/raw_data.cc b/o3d/import/cross/raw_data.cc
index 53039c2..deabe37 100644
--- a/o3d/import/cross/raw_data.cc
+++ b/o3d/import/cross/raw_data.cc
@@ -35,6 +35,9 @@
#include "import/cross/raw_data.h"
#include "base/file_util.h"
+#include "utils/cross/file_path_utils.h"
+#include "base/file_path.h"
+#include "base/file_util.h"
#ifdef OS_MACOSX
#include <CoreFoundation/CoreFoundation.h>
@@ -44,6 +47,10 @@
#include <rpc.h>
#endif
+using file_util::OpenFile;
+using file_util::CloseFile;
+using file_util::GetFileSize;
+
namespace o3d {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -59,7 +66,7 @@ RawData::RawData(ServiceLocator* service_locator,
const String &uri,
const void *data,
size_t length)
- : ParamObject(service_locator), uri_(uri) {
+ : ParamObject(service_locator), uri_(uri), allow_string_value_(true) {
// make private copy of data
data_.reset(new uint8[length]);
length_ = length;
@@ -74,6 +81,17 @@ RawData::Ref RawData::Create(ServiceLocator* service_locator,
return RawData::Ref(new RawData(service_locator, uri, data, length));
}
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+RawData::Ref RawData::CreateFromFile(ServiceLocator* service_locator,
+ const String &uri,
+ const String& filename) {
+ RawData::Ref data(Create(service_locator, uri, NULL, 0));
+ if (!data->SetFromFile(filename)) {
+ data.Reset();
+ }
+
+ return data;
+}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RawData::~RawData() {
@@ -81,6 +99,46 @@ RawData::~RawData() {
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+bool RawData::SetFromFile(const String& filename) {
+ // We can't allow general string files to be downloaded from anywhere
+ // as that would override the security measures that have been added to
+ // XMLHttpRequest over the years. Images and other binary datas are okay.
+ // because RawData can only be passed to stuff that understands specific
+ // formats.
+ allow_string_value_ = false;
+ FilePath filepath = UTF8ToFilePath(filename);
+ FILE *file = OpenFile(filepath, "rb");
+ bool result = false;
+ if (!file) {
+ DLOG(ERROR) << "file not found \"" << filename << "\"";
+ } else {
+ // Determine the file's length
+ int64 file_size64;
+ if (!GetFileSize(filepath, &file_size64)) {
+ DLOG(ERROR) << "error getting file size \"" << filename << "\"";
+ } else {
+ if (file_size64 > 0xffffffffLL) {
+ DLOG(ERROR) << "file is too large \"" << filename << "\"";
+ } else {
+ size_t file_length = static_cast<size_t>(file_size64);
+
+ // Load the file data into memory
+ data_.reset(new uint8[file_length]);
+ length_ = file_length;
+ if (fread(data_.get(), file_length, 1, file) != 1) {
+ DLOG(ERROR) << "error reading file \"" << filename << "\"";
+ } else {
+ result = true;
+ }
+ }
+ }
+ CloseFile(file);
+ }
+
+ return result;
+}
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const uint8 *RawData::GetData() const {
// Return data immediately if we have it
if (data_.get()) {
@@ -195,12 +253,23 @@ String RawData::StringValue() const {
// .json, .xml, .ini, .csv, .php, .js, .html, .css .xsl, .dae, etc.) So,
// instead we validate the string is valid UTF-8 AND that there are no NULLs
// in the string.
- size_t length;
- const char* utf8 = GetValidUTF8(*this, &length);
- if (!utf8) {
- O3D_ERROR(service_locator()) << "RawData is not valid UTF-8 string";
+
+ // We can't allow general string files to be downloaded from anywhere
+ // as that would override the security measures that have been added to
+ // XMLHttpRequest over the years. Images and other binary datas are okay.
+ // because RawData can only be passed to stuff that understands specific
+ // formats.
+ if (!allow_string_value_) {
+ O3D_ERROR(service_locator())
+ << "You can only get a stringValue from RawDatas inside archives.";
} else {
- return String (utf8, length);
+ size_t length;
+ const char* utf8 = GetValidUTF8(*this, &length);
+ if (!utf8) {
+ O3D_ERROR(service_locator()) << "RawData is not valid UTF-8 string";
+ } else {
+ return String (utf8, length);
+ }
}
return String();
}
diff --git a/o3d/import/cross/raw_data.h b/o3d/import/cross/raw_data.h
index 8012efd..1929b1a 100644
--- a/o3d/import/cross/raw_data.h
+++ b/o3d/import/cross/raw_data.h
@@ -46,6 +46,8 @@
#include "core/cross/param.h"
#include "core/cross/types.h"
+class FilePath;
+
namespace o3d {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -58,6 +60,10 @@ class RawData : public ParamObject {
const void *data,
size_t length);
+ static RawData::Ref CreateFromFile(ServiceLocator* service_locator,
+ const String &uri,
+ const String& filename);
+
virtual ~RawData();
const uint8 *GetData() const;
@@ -94,6 +100,7 @@ class RawData : public ParamObject {
mutable scoped_array<uint8> data_;
size_t length_;
FilePath temp_filepath_;
+ bool allow_string_value_;
// Deletes temp file if it exists
void DeleteTempFile();
@@ -103,6 +110,8 @@ class RawData : public ParamObject {
const void *data,
size_t length);
+ bool SetFromFile(const String& filename);
+
friend class IClassManager;
friend class Pack;
diff --git a/o3d/import/cross/raw_data_test.cc b/o3d/import/cross/raw_data_test.cc
index b1ccc5dd..4ab0955 100644
--- a/o3d/import/cross/raw_data_test.cc
+++ b/o3d/import/cross/raw_data_test.cc
@@ -34,14 +34,42 @@
#include "core/cross/client.h"
#include "tests/common/win/testing_common.h"
+#include "utils/cross/file_path_utils.h"
+#include "base/file_path.h"
+#include "base/file_util.h"
#include "core/cross/error.h"
+#include "core/cross/error_status.h"
#include "import/cross/memory_buffer.h"
#include "import/cross/raw_data.h"
+using file_util::OpenFile;
+using file_util::CloseFile;
+using file_util::GetFileSize;
+
namespace o3d {
+namespace {
+
+// Checks if an error has occured on the client then clears the error.
+bool CheckErrorExists(IErrorStatus* error_status) {
+ bool have_error = !error_status->GetLastError().empty();
+ error_status->ClearLastError();
+ return have_error;
+}
+
+} // anonymous namespace
+
// Test fixture for RawData testing.
class RawDataTest : public testing::Test {
+ protected:
+ RawDataTest()
+ : error_status_(g_service_locator) {
+ }
+
+ IErrorStatus* error_status() { return &error_status_; }
+
+ private:
+ ErrorStatus error_status_;
};
// Test RawData
@@ -75,6 +103,52 @@ TEST_F(RawDataTest, Basic) {
ASSERT_EQ(raw_data->uri(), uri);
}
+TEST_F(RawDataTest, CreateFromFile) {
+ String uri("test_filename");
+ String filename = *g_program_path + "/bitmap_test/tga-256x256-24bit.tga";
+ RawData::Ref ref = RawData::CreateFromFile(g_service_locator,
+ uri,
+ filename);
+ ASSERT_FALSE(ref.IsNull());
+ FilePath filepath = UTF8ToFilePath(filename);
+ FILE *file = OpenFile(filepath, "rb");
+ ASSERT_TRUE(file != NULL);
+ int64 file_size64;
+ ASSERT_TRUE(GetFileSize(filepath, &file_size64));
+ size_t file_length = static_cast<size_t>(file_size64);
+ ASSERT_TRUE(file_length > 0);
+ scoped_array<uint8> data(new uint8[file_length]);
+ ASSERT_EQ(fread(data.get(), file_length, 1, file), 1);
+ CloseFile(file);
+
+ ASSERT_EQ(file_length, ref->GetLength());
+ ASSERT_EQ(0, memcmp(ref->GetData(), data.get(), file_length));
+}
+
+TEST_F(RawDataTest, CreateFromFileFail) {
+ String uri("test_filename");
+ String filename = *g_program_path + "/bitmap_test/non-existent-file.foo";
+ RawData::Ref ref = RawData::CreateFromFile(g_service_locator,
+ uri,
+ filename);
+ ASSERT_TRUE(ref.IsNull());
+}
+
+TEST_F(RawDataTest, CreateFromFileStringValue) {
+ String uri("test_filename");
+ String filename = *g_program_path + "/unittest_data/fur.fx";
+ RawData::Ref ref = RawData::CreateFromFile(g_service_locator,
+ uri,
+ filename);
+ ASSERT_FALSE(ref.IsNull());
+ EXPECT_TRUE(ref->GetLength() > 0);
+ EXPECT_FALSE(CheckErrorExists(error_status()));
+ // We should NOT be able to get a string value from an individually
+ // loaded RawData.
+ EXPECT_TRUE(ref->StringValue().empty());
+ EXPECT_TRUE(CheckErrorExists(error_status()));
+}
+
namespace {
struct TestData {