+ ObjectList objects;
+ bool raw = detect_raw(in);
+ if(raw)
+ transfer_raw(in, *tmp_file);
+ else
+ {
+ transfer_datafile(in, fn, *tmp_buf, objects);
+ tmp_buf->flush();
+ }
+
+ unsigned length = tmp_file->tell()-offset;
+
+ DataFile::Statement st("file");
+ st.append(FS::basename(fn));
+ st.sub.push_back((DataFile::Statement("slice"), offset, length));
+ for(list<Object>::const_iterator i=objects.begin(); i!=objects.end(); ++i)
+ st.sub.push_back((DataFile::Statement("object"), i->name, i->keyword));
+ directory.push_back(st);
+ dir_alloc += 100+objects.size()*100;
+}
+
+bool Packer::detect_raw(IO::Seekable &in)
+{
+ IO::SeekOffset offset = in.tell();
+ bool raw = false;
+ DataFile::Parser parser(in, "-");
+ while(!raw && parser && in.tell()<10240)
+ {
+ try
+ {
+ parser.parse();
+ }
+ catch(...)
+ {
+ raw = true;
+ }
+ }
+ in.seek(offset, IO::S_BEG);
+ return raw;
+}
+
+void Packer::transfer_datafile(IO::Base &in, const string &fn, IO::Base &out, ObjectList &objects)
+{