summaryrefslogtreecommitdiffstats
path: root/o3d
diff options
context:
space:
mode:
authorkbr@chromium.org <kbr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-16 23:12:10 +0000
committerkbr@chromium.org <kbr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-16 23:12:10 +0000
commit07537bff7d75b6315b295ff84842f5a4bd95e2c8 (patch)
tree563ffd624e01fefc669ae80c8c7c8d1cf7a14f91 /o3d
parent6caa7aa367c2a2416c7d231531cd997130cd5214 (diff)
downloadchromium_src-07537bff7d75b6315b295ff84842f5a4bd95e2c8.zip
chromium_src-07537bff7d75b6315b295ff84842f5a4bd95e2c8.tar.gz
chromium_src-07537bff7d75b6315b295ff84842f5a4bd95e2c8.tar.bz2
Changed --json-only argument to converter to --no-archive and
implemented it. Verified that normal operation is unchanged and that --no-archive produces desired results. Also tested with --no-binary. BUG=none TEST=none Review URL: http://codereview.chromium.org/1646012 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@44850 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d')
-rw-r--r--o3d/converter/cross/converter.cc221
-rw-r--r--o3d/converter/cross/converter.h7
-rw-r--r--o3d/converter/cross/converter_main.cc8
3 files changed, 210 insertions, 26 deletions
diff --git a/o3d/converter/cross/converter.cc b/o3d/converter/cross/converter.cc
index e258780..cda3143 100644
--- a/o3d/converter/cross/converter.cc
+++ b/o3d/converter/cross/converter.cc
@@ -53,6 +53,7 @@
#include "import/cross/collada.h"
#include "import/cross/collada_conditioner.h"
#include "import/cross/file_output_stream_processor.h"
+#include "import/cross/iarchive_generator.h"
#include "import/cross/targz_generator.h"
#include "import/cross/archive_request.h"
#include "serializer/cross/serializer.h"
@@ -64,8 +65,182 @@
namespace o3d {
namespace {
+// Writes either to an archive file or to multiple flat files.
+class MultiFileWriter : public IArchiveGenerator {
+ public:
+ virtual ~MultiFileWriter() {}
+
+ // Takes the path of an archive file. If writing multiple flat
+ // files, then for archive named archive.o3dtgz, creates directory
+ // "archive/" and writes all files within.
+ virtual bool OpenTopLevelFile(const FilePath& file_name,
+ const char* mode) = 0;
+
+ // Closes the top-level file and any currently open sub-file.
+ virtual void CloseTopLevelFile(bool success) = 0;
+
+ int AddFileBytes(const uint8* data, size_t n);
+
+ //----------------------------------------------------------------------
+ // IArchiveGenerator
+ // It seems these virtual functions need to be re-declared here.
+ // (Compiler bugs on Mac OS X?)
+
+ // AddFile either adds a file to the archive, or opens a new flat
+ // file. If a sub-file is currently open, implicitly closes it.
+ virtual bool AddFile(const String& file_name,
+ size_t file_size) = 0;
+
+ // Writes data to the current sub-file.
+ virtual int AddFileBytes(MemoryReadStream* stream, size_t n) = 0;
+
+ // Closes the current sub-file.
+ virtual void Close(bool success) = 0;
+
+ protected:
+ MultiFileWriter() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MultiFileWriter);
+};
+
+int MultiFileWriter::AddFileBytes(const uint8* data, size_t n) {
+ MemoryReadStream stream(data, n);
+ return AddFileBytes(&stream, n);
+}
+
+class TarGzWriter : public MultiFileWriter {
+ public:
+ TarGzWriter() {}
+ virtual ~TarGzWriter();
+
+ virtual bool OpenTopLevelFile(const FilePath& file_name,
+ const char* mode);
+ virtual bool AddFile(const String& file_name,
+ size_t file_size);
+ virtual int AddFileBytes(MemoryReadStream* stream,
+ size_t n);
+ virtual void Close(bool success);
+ virtual void CloseTopLevelFile(bool success);
+
+ private:
+ scoped_ptr<FileOutputStreamProcessor> stream_processor_;
+ scoped_ptr<TarGzGenerator> archive_generator_;
+ DISALLOW_COPY_AND_ASSIGN(TarGzWriter);
+};
+
+TarGzWriter::~TarGzWriter() {
+ // Need to reset these in the right order.
+ archive_generator_.reset();
+ stream_processor_.reset();
+}
+
+bool TarGzWriter::OpenTopLevelFile(const FilePath& file_name,
+ const char* mode) {
+ FILE* out_file = file_util::OpenFile(file_name, mode);
+ if (out_file == NULL) {
+ return false;
+ }
+ stream_processor_.reset(new FileOutputStreamProcessor(out_file));
+ archive_generator_.reset(new TarGzGenerator(stream_processor_.get()));
+ return true;
+}
+
+bool TarGzWriter::AddFile(const String& file_name,
+ size_t file_size) {
+ archive_generator_->AddFile(file_name, file_size);
+ return true;
+}
+
+int TarGzWriter::AddFileBytes(MemoryReadStream* stream,
+ size_t n) {
+ return archive_generator_->AddFileBytes(stream, n);
+}
+
+void TarGzWriter::Close(bool success) {
+}
+
+void TarGzWriter::CloseTopLevelFile(bool success) {
+ archive_generator_->Close(success);
+}
+
+class FlatFileWriter : public MultiFileWriter {
+ public:
+ FlatFileWriter() {}
+ virtual ~FlatFileWriter();
+
+ virtual bool OpenTopLevelFile(const FilePath& file_name,
+ const char* mode);
+ virtual bool AddFile(const String& file_name,
+ size_t file_size);
+ virtual int AddFileBytes(MemoryReadStream* stream,
+ size_t n);
+ virtual void Close(bool success);
+ virtual void CloseTopLevelFile(bool success);
+
+ private:
+ FilePath destination_directory_;
+ String mode_;
+ scoped_ptr<FileOutputStreamProcessor> stream_processor_;
+ DISALLOW_COPY_AND_ASSIGN(FlatFileWriter);
+};
+
+FlatFileWriter::~FlatFileWriter() {
+}
+
+bool FlatFileWriter::OpenTopLevelFile(const FilePath& file_name,
+ const char* mode) {
+ destination_directory_ = file_name.RemoveExtension();
+ if (!file_util::CreateDirectory(destination_directory_)) {
+ return false;
+ }
+ mode_ = String(mode);
+ return true;
+}
+
+bool FlatFileWriter::AddFile(const String& file_name,
+ size_t file_size) {
+ Close(true);
+ FilePath path = destination_directory_.Append(UTF8ToFilePath(file_name));
+ // We may need to make parent directories.
+ FilePath parent_dir = path.DirName();
+ if (!file_util::CreateDirectory(parent_dir)) {
+ return false;
+ }
+ FILE* out_file = file_util::OpenFile(path, mode_.c_str());
+ // We expect to be able to write the desired file.
+ DCHECK_NE(out_file, static_cast<FILE*>(NULL));
+ if (out_file == NULL) {
+ return false;
+ }
+ stream_processor_.reset(new FileOutputStreamProcessor(out_file));
+ return true;
+}
+
+int FlatFileWriter::AddFileBytes(MemoryReadStream* stream,
+ size_t n) {
+ if (!stream_processor_.get())
+ return 0;
+ StreamProcessor::Status status =
+ stream_processor_->ProcessBytes(stream, n);
+ if (status == StreamProcessor::FAILURE)
+ return 0;
+ return n;
+}
+
+void FlatFileWriter::Close(bool success) {
+ if (stream_processor_.get()) {
+ stream_processor_->Close(success);
+ stream_processor_.reset();
+ }
+}
+
+void FlatFileWriter::CloseTopLevelFile(bool success) {
+ Close(success);
+}
+
void AddBinaryElements(const Collada& collada,
- TarGzGenerator* archive_generator) {
+ MultiFileWriter* file_writer) {
const ColladaDataMap& data_map(collada.original_data_map());
std::vector<FilePath> paths = data_map.GetOriginalDataFilenames();
for (std::vector<FilePath>::const_iterator iter = paths.begin();
@@ -73,8 +248,8 @@ void AddBinaryElements(const Collada& collada,
++iter) {
const std::string& data = data_map.GetOriginalData(*iter);
- archive_generator->AddFile(FilePathToUTF8(*iter), data.size());
- archive_generator->AddFileBytes(
+ file_writer->AddFile(FilePathToUTF8(*iter), data.size());
+ file_writer->AddFileBytes(
reinterpret_cast<const uint8*>(data.c_str()),
data.length());
}
@@ -211,8 +386,16 @@ bool Convert(const FilePath& in_filename,
}
// Attempt to open the output file.
- FILE* out_file = file_util::OpenFile(out_filename, "wb");
- if (out_file == NULL) {
+ scoped_ptr<MultiFileWriter> file_writer;
+ if (options.archive) {
+ file_writer.reset(new TarGzWriter);
+ } else {
+ file_writer.reset(new FlatFileWriter);
+ }
+
+ // Create an archive file or individual flat files and serialize the
+ // JSON scene graph and assets to it / them.
+ if (!file_writer->OpenTopLevelFile(out_filename, "wb")) {
O3D_ERROR(&service_locator) << "Could not open output file \""
<< FilePathToUTF8(out_filename).c_str()
<< "\"";
@@ -222,15 +405,13 @@ bool Convert(const FilePath& in_filename,
return false;
}
- // Create an archive file and serialize the JSON scene graph and assets to it.
- FileOutputStreamProcessor stream_processor(out_file);
- TarGzGenerator archive_generator(&stream_processor);
-
- archive_generator.AddFile(ArchiveRequest::kO3DMarker,
- ArchiveRequest::kO3DMarkerContentLength);
- archive_generator.AddFileBytes(
- reinterpret_cast<const uint8*>(ArchiveRequest::kO3DMarkerContent),
- ArchiveRequest::kO3DMarkerContentLength);
+ if (options.archive) {
+ file_writer->AddFile(ArchiveRequest::kO3DMarker,
+ ArchiveRequest::kO3DMarkerContentLength);
+ file_writer->AddFileBytes(
+ reinterpret_cast<const uint8*>(ArchiveRequest::kO3DMarkerContent),
+ ArchiveRequest::kO3DMarkerContentLength);
+ }
// Serialize the created O3D scene graph to JSON.
StringWriter out_writer(StringWriter::LF);
@@ -242,7 +423,7 @@ bool Convert(const FilePath& in_filename,
options.binary ? Serializer::Options::kBinaryOutputOn :
Serializer::Options::kBinaryOutputOff);
Serializer serializer(
- &service_locator, &json_writer, &archive_generator, serializer_options);
+ &service_locator, &json_writer, file_writer.get(), serializer_options);
serializer.SerializePack(pack.Get());
json_writer.Close();
out_writer.Close();
@@ -252,15 +433,15 @@ bool Convert(const FilePath& in_filename,
String json = out_writer.ToString();
- archive_generator.AddFile("scene.json", json.length());
- archive_generator.AddFileBytes(reinterpret_cast<const uint8*>(json.c_str()),
- json.length());
+ file_writer->AddFile("scene.json", json.length());
+ file_writer->AddFileBytes(reinterpret_cast<const uint8*>(json.c_str()),
+ json.length());
// Now add original data (e.g. compressed textures) collected during
// the loading process.
- AddBinaryElements(collada, &archive_generator);
+ AddBinaryElements(collada, file_writer.get());
- archive_generator.Close(true);
+ file_writer->CloseTopLevelFile(true);
pack->Destroy();
if (error_messages) {
diff --git a/o3d/converter/cross/converter.h b/o3d/converter/cross/converter.h
index 48f652c..47dde59 100644
--- a/o3d/converter/cross/converter.h
+++ b/o3d/converter/cross/converter.h
@@ -54,7 +54,8 @@ struct Options {
up_axis(0, 0, 0),
pretty_print(false),
keep_filters(false),
- keep_materials(false) {
+ keep_materials(false),
+ archive(true) {
}
// A list of paths to search for assets..
@@ -87,8 +88,8 @@ struct Options {
// Use binary formats for buffers, skin, curve.
bool binary;
- // Don't make a gzipped tar file. Just make json.
- bool json_only;
+ // True means make a gzipped tar file. False means write individual files.
+ bool archive;
};
// Converts the given file for use in O3D. This is done by
diff --git a/o3d/converter/cross/converter_main.cc b/o3d/converter/cross/converter_main.cc
index bb1dc7d..90d7774 100644
--- a/o3d/converter/cross/converter_main.cc
+++ b/o3d/converter/cross/converter_main.cc
@@ -103,8 +103,10 @@ int CrossMain(int argc, char**argv) {
<< " they are used by a mesh that has no normals.\n"
<< "--no-binary\n"
<< " Use JSON for buffers, skins, curves instead of binary\n"
- << "--json-only\n"
- << " Don't make a gzipped tar file, just JSON.\n";
+ << "--no-archive\n"
+ << " Don't make a gzipped tar file, just flat files. Still takes\n"
+ << " the name of an archive file; for archive.o3dtgz, creates\n"
+ << " directory named archive/ and writes files inside.\n";
return EXIT_FAILURE;
}
@@ -112,7 +114,7 @@ int CrossMain(int argc, char**argv) {
options.condition = !command_line->HasSwitch("no-condition");
options.pretty_print = command_line->HasSwitch("pretty-print");
options.binary = !command_line->HasSwitch("no-binary");
- options.json_only = !command_line->HasSwitch("json-only");
+ options.archive = !command_line->HasSwitch("no-archive");
if (command_line->HasSwitch("base-path")) {
options.base_path = o3d::WideToFilePath(
command_line->GetSwitchValue("base-path"));