protected override Yield WriteData_Helper(ExportItem item, Result result) { string file = GetFilePath(item); string filepath = Path.Combine(_packageDirectory, file); string path = Path.GetDirectoryName(filepath); if(!Directory.Exists(path)) { _log.DebugFormat("creating directory: {0}", path); Directory.CreateDirectory(path); } FileStream fileStream = File.Create(filepath); Result<long> copyResult; yield return copyResult = item.Data.CopyTo(fileStream, item.DataLength, new Result<long>()).Catch(); item.Data.Close(); fileStream.Close(); if(copyResult.HasException) { result.Throw(copyResult.Exception); yield break; } if(item.DataLength != copyResult.Value) { throw new IOException(string.Format("tried to write {0} bytes, but wrote {1} instead for {2}", item.DataLength, copyResult.Value, filepath)); } _log.DebugFormat("saved: {0}", filepath); AddFileMap(item.DataId, file); item.Data.Close(); result.Return(); yield break; }
protected virtual string GetFilePath(ExportItem item) { var path = item.ItemManifest["path"].AsText; var segments = new List<string>(); if(path.StartsWith("//")) { segments.Add("relative"); } else { segments.Add("absolute"); } segments.AddRange(path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries)); switch(item.ItemManifest.Name) { case "page": segments.Add("page.xml"); break; case "file": segments.Add(Encode(item.ItemManifest["filename"].AsText)); break; case "property": segments.Add(Encode(item.ItemManifest["name"].AsText) + ".dat"); break; default: segments.Add(item.ItemManifest.Name + ".dat"); break; } return string.Join("/", segments.Select(x => Encode(x)).ToArray()); }
public void Pack_and_unpack_manifest() { // Arrange string directory = Path.Combine(Path.GetTempPath(), StringUtil.CreateAlphaNumericKey(6)); Directory.CreateDirectory(directory); List<XDoc> docs = new List<XDoc>(); docs.Add(new XDoc("doc1").Attr("dataid", "a")); docs.Add(new XDoc("doc2").Attr("dataid", "b")); docs.Add(new XDoc("doc3").Attr("dataid", "c")); List<Tuplet<string, MemoryStream>> data = new List<Tuplet<string, MemoryStream>>(); foreach(XDoc doc in docs) { string id = doc["@dataid"].AsText; data.Add(new Tuplet<string, MemoryStream>(id, new MemoryStream(doc.ToBytes()))); } XDoc manifest = new XDoc("manifest") .Start("page").Attr("dataid", "a").End() .Start("page").Attr("dataid", "b").End() .Start("page").Attr("dataid", "c").End(); // Act using(FilePackageWriter packageWriter = new FilePackageWriter(directory)) { foreach(Tuplet<string, MemoryStream> tuple in data) { var item = new ExportItem(tuple.Item1, tuple.Item2, tuple.Item2.Length, new XDoc("item").Elem("path", "abc")); packageWriter.WriteDataAsync(item, new Result()).Wait(); } packageWriter.WriteManifest(manifest, new Result()).Wait(); } XDoc manifest2; List<XDoc> docs2 = new List<XDoc>(); using(FilePackageReader packageReader = new FilePackageReader(directory)) { manifest2 = packageReader.ReadManifest(new Result<XDoc>()).Wait(); foreach(XDoc id in manifest2["*/@dataid"]) { using(ImportItem item = packageReader.ReadData(new ImportItem(id.AsText, null, null), new Result<ImportItem>()).Wait()) { using(StreamReader reader = new StreamReader(item.Data)) { docs2.Add(XDocFactory.From(reader, MimeType.TEXT_XML)); } } } } // Assert Assert.IsTrue(File.Exists(Path.Combine(directory, "package.xml"))); Assert.AreEqual(ToCanonical(manifest), ToCanonical(manifest2)); Assert.AreEqual(docs.Count, docs2.Count); foreach(var doc in docs) { Assert.IsTrue(docs2.Select(x => x == doc).Any()); } }
//--- Methods --- protected override Yield WriteData_Helper(ExportItem item, Result result) { var tempfilename = Path.GetTempFileName(); var file = GetFilePath(item); using(var fileStream = File.Create(tempfilename)) { Result<long> copyResult; yield return copyResult = item.Data.CopyTo(fileStream, item.DataLength, new Result<long>()).Catch(); item.Data.Close(); if(copyResult.HasException) { result.Throw(copyResult.Exception); yield break; } if(item.DataLength != copyResult.Value) { throw new IOException(string.Format("tried to write {0} bytes, but wrote {1} instead for {2}", item.DataLength, copyResult.Value, tempfilename)); } fileStream.Seek(0, SeekOrigin.Begin); yield return WriteZipStream(file, fileStream, item.DataLength, new Result()); } File.Delete(tempfilename); _log.DebugFormat("saved: {0}", file); AddFileMap(item.DataId, file); item.Data.Close(); result.Return(); yield break; }
protected abstract Yield WriteData_Helper(ExportItem item, Result result);
public virtual Result WriteDataAsync(ExportItem item, Result result) { return Coroutine.Invoke(WriteData_Helper, item, result); }
public virtual Result WriteDataAsync(ExportItem item, Result result) { return(Coroutine.Invoke(WriteData_Helper, item, result)); }
protected override IEnumerator<IYield> WriteData_Helper(ExportItem item, Result result) { throw new NotImplementedException(); }
public string GetFilename(ExportItem item) { return GetFilePath(item); }
public void Generates_absolute_path_without_double_slash() { var packager = new MockPackager(); var item = new ExportItem(null, null, 0, new XDoc("page").Elem("path", "foo")); Assert.AreEqual("absolute/foo/page.xml", packager.GetFilename(item)); }
public void Generates_relative_path_for_double_slash() { var packager = new MockPackager(); var item = new ExportItem(null, null, 0, new XDoc("page").Elem("path", "//foo")); Assert.AreEqual("relative/foo/page.xml", packager.GetFilename(item)); }
public void Conflicting_unknown_types_get_numbered() { var packager = new MockPackager(); var item = new ExportItem(null, null, 0, new XDoc("widget").Elem("path", "//foo")); Assert.AreEqual("relative/foo/widget.dat", packager.GetFilename(item)); Assert.AreEqual("relative/foo/widget.dat", packager.GetFilename(item)); }
public void Conflicting_pages_get_numbered() { var packager = new MockPackager(); var item = new ExportItem(null, null, 0, new XDoc("page").Elem("path", "//foo")); Assert.AreEqual("relative/foo/page.xml", packager.GetFilename(item)); Assert.AreEqual("relative/foo/page.xml", packager.GetFilename(item)); }
private Yield GetItem_Helper(string dataId, Result<ExportItem> result) { XDoc request = _exportDocument[string.Format("requests/request[@dataid='{0}']", dataId)]; Plug itemPlug = Plug.New(request["@href"].AsUri) .WithHeaders(_dekiApi.Headers) .WithCredentials(_dekiApi.Credentials) .WithCookieJar(_dekiApi.CookieJar) .WithTimeout(TimeSpan.FromMinutes(30)); foreach(XDoc header in request["header"]) { itemPlug = itemPlug.WithHeader(header["@name"].AsText, header["@value"].AsText); } string verb = request["@method"].AsText; Result<DreamMessage> invokeResult; yield return invokeResult = itemPlug.InvokeEx(verb, DreamMessage.Ok(), new Result<DreamMessage>()); DreamMessage response = invokeResult.Value; if(!response.IsSuccessful) { throw new DreamResponseException(response, string.Format("Request failed with {0} for {1}", response.Status, itemPlug.Uri)); } XDoc manifestItem = _exportDocument[string.Format("manifest/*[@dataid='{0}']", dataId)].Clone(); ExportItem item = new ExportItem(dataId, response.ToStream(), response.ContentLength, manifestItem); result.Return(item); }