Function that imports files to application(kml/kmz)

This commit is contained in:
Kirill Zhdanovich 2013-01-08 12:00:58 +03:00 committed by Alex Zolotarev
parent 208a1580b0
commit c535a99995
7 changed files with 109 additions and 14 deletions

View file

@ -246,9 +246,8 @@ bool CopyFile(string const & fOld, string const & fNew)
if (ofs.fail())
{
// Well, specification says that exception is thrown for critical errors.
// So just log stream fail state and continue.
LOG(LWARNING, ("Bad or Fail bit is set while writing file:", fNew));
return false;
}
return true;

View file

@ -47,6 +47,7 @@ private:
bool GetFileSize(string const & fName, uint64_t & sz);
bool DeleteFileX(string const & fName);
bool RenameFileX(string const & fOld, string const & fNew);
/// @return false if copy fails. DO NOT THROWS exceptions
bool CopyFile(string const & fOld, string const & fNew);
}

View file

@ -433,7 +433,7 @@ namespace
}
}
string BookmarkCategory::GetValidFileName(string const & name)
string BookmarkCategory::RemoveInvalidSymbols(string const & name)
{
// Remove not allowed symbols
strings::UniString uniName = strings::MakeUniString(name);
@ -447,8 +447,14 @@ string BookmarkCategory::GetValidFileName(string const & name)
return (uniName.empty() ? "Bookmarks" : strings::ToUtf8(uniName));
}
string BookmarkCategory::GenerateUniqueFileName(const string & path, string const & name)
string BookmarkCategory::GenerateUniqueFileName(const string & path, string name)
{
string const kmlExt(".kml");
// check if file name already contains .kml extension
size_t const extPos = name.rfind(kmlExt);
if (extPos == name.size() - kmlExt.size())
name.resize(name.size() - kmlExt.size());
size_t counter = 1;
string suffix;
while (Platform::IsFileExistsByFullPath(path + name + suffix + ".kml"))
@ -461,18 +467,21 @@ bool BookmarkCategory::SaveToKMLFile()
string oldFile;
// Get valid file name from category name
string const name = GetValidFileName(m_name);
string const name = RemoveInvalidSymbols(m_name);
if (!m_file.empty())
{
size_t i2 = m_file.find_last_of('.');
if (i2 == string::npos) i2 = m_file.size();
if (i2 == string::npos)
i2 = m_file.size();
size_t i1 = m_file.find_last_of("\\/");
if (i1 == string::npos) i1 = 0;
else ++i1;
if (i1 == string::npos)
i1 = 0;
else
++i1;
// If m_file doesn't match name, assign new m_file for this category and save old file name.
if (m_file.substr(i1, i2-i1).find(name) != 0)
if (m_file.substr(i1, i2 - i1).find(name) != 0)
{
oldFile = GenerateUniqueFileName(GetPlatform().WritableDir(), name);
m_file.swap(oldFile);

View file

@ -103,9 +103,9 @@ public:
static BookmarkCategory * CreateFromKMLFile(string const & file);
/// Get valid file name from input (remove illegal symbols).
static string GetValidFileName(string const & name);
/// Get unique file name from path and valid file name.
static string GenerateUniqueFileName(const string & path, string const & name);
static string RemoveInvalidSymbols(string const & name);
/// Get unique bookmark file name from path and valid file name.
static string GenerateUniqueFileName(const string & path, string name);
//@}
};

View file

@ -27,11 +27,14 @@
#include "../coding/internal/file_data.hpp"
#include "../coding/zip_reader.hpp"
#include "../geometry/angles.hpp"
#include "../geometry/distance_on_sphere.hpp"
#include "../base/math.hpp"
#include "../base/timer.hpp"
#include "../base/scope_guard.hpp"
#include "../std/algorithm.hpp"
#include "../std/target_os.hpp"
@ -41,6 +44,9 @@
/// How many pixels around touch point are used to get bookmark or POI
#define TOUCH_PIXEL_RADIUS 20
#define KML_EXTENSION ".kml"
#define KMZ_EXTENSION ".kmz"
using namespace storage;
@ -349,7 +355,7 @@ void Framework::LoadBookmarks()
string const dir = GetPlatform().WritableDir();
Platform::FilesList files;
Platform::GetFilesByExt(dir, ".kml", files);
Platform::GetFilesByExt(dir, KML_EXTENSION, files);
for (size_t i = 0; i < files.size(); ++i)
{
BookmarkCategory * cat = BookmarkCategory::CreateFromKMLFile(dir + files[i]);
@ -525,6 +531,84 @@ void Framework::ClearBookmarks()
m_bookmarks.clear();
}
namespace
{
// @return extension with a dot (or empty string if no extension is present)
string const GetFileExt(string const & filePath)
{
size_t const pos = filePath.rfind('.');
if (pos == string::npos)
return string();
string lowerCaseExtension = string(filePath, pos, filePath.size() - pos);
transform(lowerCaseExtension.begin(), lowerCaseExtension.end(), lowerCaseExtension.begin(), ::tolower);
return lowerCaseExtension;
}
string const GetFileName(string const & filePath)
{
size_t pos = filePath.rfind('/');
if (pos == string::npos)
return filePath;
++pos;
return string(filePath, pos, filePath.size() - pos);
}
string const GenerateValidandUniqFilePathForKLM(string const & filename)
{
string filePath = BookmarkCategory::RemoveInvalidSymbols(filename);
filePath = BookmarkCategory::GenerateUniqueFileName(GetPlatform().WritableDir(), filePath);
return filePath;
}
}
bool Framework::AddBookmarksFile(string const & filePath)
{
string const fileExt = GetFileExt(filePath);
if (fileExt == KML_EXTENSION)
{
string savePath = GenerateValidandUniqFilePathForKLM( GetFileName(filePath) );
if (!my::CopyFile(filePath, savePath))
return false;
}
else if (fileExt == KMZ_EXTENSION)
{
try
{
string const filename = GetFileName(filePath);
vector<string> files;
ZipFileReader::FilesList(filePath, files);
string kmlFileName;
for (size_t i = 0; i < files.size();++i)
{
if (GetFileExt(files[i]) == KML_EXTENSION)
{
kmlFileName = files[i];
break;
}
}
if (kmlFileName.empty())
return false;
string const savePath = GenerateValidandUniqFilePathForKLM(kmlFileName);
ZipFileReader::UnzipFile(filePath, kmlFileName, savePath);
}
catch (RootException const & e)
{
LOG(LWARNING, ("Error unzipping file", filePath, e.Msg()));
return false;
}
}
else
{
LOG(LWARNING, ("Unknown file type", filePath));
return false;
}
// Update freshly added bookmarks
LoadBookmarks();
return true;
}
void Framework::GetLocalMaps(vector<string> & outMaps) const
{
Platform & pl = GetPlatform();

View file

@ -211,6 +211,8 @@ public:
void ClearBookmarks();
bool AddBookmarksFile(string const & filePath);
inline m2::PointD PtoG(m2::PointD const & p) const { return m_navigator.PtoG(p); }
inline m2::PointD GtoP(m2::PointD const & p) const { return m_navigator.GtoP(p); }

View file

@ -324,7 +324,7 @@ UNIT_TEST(Bookmarks_IllegalFileName)
for (size_t i = 0; i < ARRAY_SIZE(arrIllegal); ++i)
{
string const name = BookmarkCategory::GetValidFileName(arrIllegal[i]);
string const name = BookmarkCategory::RemoveInvalidSymbols(arrIllegal[i]);
if (strlen(arrLegal[i]) == 0)
{