private string CopyFileToEpub(string srcPath)
{
string existingFile;
if (_mapSrcPathToDestFileName.TryGetValue(srcPath, out existingFile))
return existingFile; // File already present, must be used more than once.
string originalFileName;
if (srcPath.StartsWith(Storage.FolderPath))
originalFileName = srcPath.Substring(Storage.FolderPath.Length + 1).Replace("\\", "/"); // allows keeping folder structure
else
originalFileName = Path.GetFileName(srcPath); // probably can't happen, but in case, put at root.
// Validator warns against spaces in filenames. + and % and &<> are problematic because to get the real
// file name it is necessary to use just the right decoding process. Some clients may do this
// right but if we substitute them we can be sure things are fine.
// I'm deliberately not using UrlPathString here because it doesn't correctly encode a lot of Ascii characters like =$&<>
// which are technically not valid in hrefs
var encoded =
HttpUtility.UrlEncode(
originalFileName.Replace("+", "_").Replace(" ", "_").Replace("&", "_").Replace("<", "_").Replace(">", "_"));
var fileName = encoded.Replace("%", "_");
var dstPath = Path.Combine(_contentFolder, fileName);
// We deleted the root directory at the start, so if the file is already
// there it is a clash, either multiple sources for files with the same name,
// or produced by replacing spaces, or something. Come up with a similar unique name.
for (int fix = 1; RobustFile.Exists(dstPath); fix++)
{
var fileNameWithoutExtension = Path.Combine(Path.GetDirectoryName(fileName),
Path.GetFileNameWithoutExtension(fileName));
fileName = Path.ChangeExtension(fileNameWithoutExtension + fix, Path.GetExtension(fileName));
dstPath = Path.Combine(_contentFolder, fileName);
}
if (originalFileName != fileName)
_mapChangedFileNames[originalFileName] = fileName;
Directory.CreateDirectory(Path.GetDirectoryName(dstPath));
CopyFile(srcPath, dstPath);
_manifestItems.Add(fileName);
_mapSrcPathToDestFileName[srcPath] = fileName;
return dstPath;
}