<commit_before>#include <jni.h>

#include "../../../../../defines.hpp"

#include "../../../../../coding/url_encode.hpp"
#include "../../../../../coding/reader_streambuf.hpp"
#include "../../../../../coding/internal/file_data.hpp"

#include "../../../../../platform/platform.hpp"
#include "../../../../../platform/http_request.hpp"
#include "../../../../../platform/servers_list.hpp"

#include "../../../../../base/logging.hpp"
#include "../../../../../base/string_utils.hpp"

#include "../../../../../std/vector.hpp"
#include "../../../../../std/string.hpp"
#include "../../../../../std/bind.hpp"
#include "../../../../../std/shared_ptr.hpp"

#include "../core/jni_helper.hpp"

#include "Framework.hpp"


/// Special error codes to notify GUI about free space
//@{
#define ERR_DOWNLOAD_SUCCESS         0
#define ERR_NOT_ENOUGH_MEMORY       -1
#define ERR_NOT_ENOUGH_FREE_SPACE   -2
#define ERR_STORAGE_DISCONNECTED    -3
#define ERR_DOWNLOAD_ERROR          -4
#define ERR_NO_MORE_FILES           -5
#define ERR_FILE_IN_PROGRESS        -6
//@}

struct FileToDownload
{
  vector<string> m_urls;
  string m_fileName;
  string m_pathOnSdcard;
  uint64_t m_fileSize;
};

//static string g_apkPath;
//static string g_sdcardPath;
static vector<FileToDownload> g_filesToDownload;
static int g_totalDownloadedBytes;
static int g_totalBytesToDownload;
static shared_ptr<downloader::HttpRequest> g_currentRequest;

extern "C"
{
  int HasSpaceForFiles(string const & sdcardPath, size_t fileSize)
  {
    switch (GetPlatform().GetWritableStorageStatus(fileSize))
    {
    case Platform::STORAGE_DISCONNECTED: return ERR_STORAGE_DISCONNECTED;
    case Platform::NOT_ENOUGH_SPACE: return ERR_NOT_ENOUGH_FREE_SPACE;
    default: return fileSize;
    }
  }

  JNIEXPORT jint JNICALL
  Java_com_mapswithme_maps_DownloadResourcesActivity_getBytesToDownload(
      JNIEnv * env, jobject thiz, jstring apkPath, jstring sdcardPath)
  {
    // clear all
    g_filesToDownload.clear();
    g_totalBytesToDownload = 0;
    g_totalDownloadedBytes = 0;

    //g_apkPath = jni::ToNativeString(env, apkPath);
    string const path = jni::ToNativeString(env, sdcardPath);

    Platform & pl = GetPlatform();
    ReaderStreamBuf buffer(pl.GetReader("external_resources.txt"));

    istream in(&buffer);

    string name;
    int size;

    while (true)
    {
      in >> name;

      if (!in.good())
        break;

      in >> size;

      if (!in.good())
        break;

      uint64_t originSize = 0;
      if (!pl.GetFileSizeByName(name, originSize) || size != originSize)
      {
        LOG(LDEBUG, ("Should download", name, "sized", size, "bytes"));

        FileToDownload f;
        f.m_pathOnSdcard = path + name;
        f.m_fileName = name;
        f.m_fileSize = size;

        g_filesToDownload.push_back(f);
        g_totalBytesToDownload += size;
      }
    }

    int const res = HasSpaceForFiles(path, g_totalBytesToDownload);
    switch (res)
    {
    case ERR_STORAGE_DISCONNECTED:
      LOG(LWARNING, ("External file system is not available"));
      break;
    case ERR_NOT_ENOUGH_FREE_SPACE:
      LOG(LWARNING, ("Not enough space to extract files"));
      break;
    };<commit_msg>[android] Skip downloading World and WorldCosts if they are compatible with current version.<commit_after>#include <jni.h>

#include "../../../../../defines.hpp"

#include "../../../../../coding/url_encode.hpp"
#include "../../../../../coding/reader_streambuf.hpp"
#include "../../../../../coding/internal/file_data.hpp"

#include "../../../../../platform/platform.hpp"
#include "../../../../../platform/http_request.hpp"
#include "../../../../../platform/servers_list.hpp"

#include "../../../../../base/logging.hpp"
#include "../../../../../base/string_utils.hpp"

#include "../../../../../std/vector.hpp"
#include "../../../../../std/string.hpp"
#include "../../../../../std/bind.hpp"
#include "../../../../../std/shared_ptr.hpp"

#include "../core/jni_helper.hpp"

#include "Framework.hpp"


/// Special error codes to notify GUI about free space
//@{
#define ERR_DOWNLOAD_SUCCESS         0
#define ERR_NOT_ENOUGH_MEMORY       -1
#define ERR_NOT_ENOUGH_FREE_SPACE   -2
#define ERR_STORAGE_DISCONNECTED    -3
#define ERR_DOWNLOAD_ERROR          -4
#define ERR_NO_MORE_FILES           -5
#define ERR_FILE_IN_PROGRESS        -6
//@}

struct FileToDownload
{
  vector<string> m_urls;
  string m_fileName;
  string m_pathOnSdcard;
  uint64_t m_fileSize;
};

//static string g_apkPath;
//static string g_sdcardPath;
static vector<FileToDownload> g_filesToDownload;
static int g_totalDownloadedBytes;
static int g_totalBytesToDownload;
static shared_ptr<downloader::HttpRequest> g_currentRequest;

extern "C"
{
  int HasSpaceForFiles(string const & sdcardPath, size_t fileSize)
  {
    switch (GetPlatform().GetWritableStorageStatus(fileSize))
    {
    case Platform::STORAGE_DISCONNECTED: return ERR_STORAGE_DISCONNECTED;
    case Platform::NOT_ENOUGH_SPACE: return ERR_NOT_ENOUGH_FREE_SPACE;
    default: return fileSize;
    }
  }

  // Check if we need to download mandatory resource file.
  bool NeedToDownload(string const & name, int size)
  {
    uint64_t originSize = 0;
    if (!GetPlatform().GetFileSizeByName(name, originSize))
    {
      // no such file
      return true;
    }

    if (size == originSize)
    {
      // file is up-to-date
      return false;
    }

    if (name == WORLD_FILE_NAME DATA_FILE_EXTENSION)
    {
      FilesContainerR cont(name);
      if (cont.IsReaderExist(SEARCH_INDEX_FILE_TAG))
      {
        // World.mwm file has search index - can skip new version
        return false;
      }
    }
    else if (name == WORLD_COASTS_FILE_NAME DATA_FILE_EXTENSION)
    {
      // Skip WorldCoasts.mwm
      return false;
    }

    // Do download otherwise.
    return true;
  }

  JNIEXPORT jint JNICALL
  Java_com_mapswithme_maps_DownloadResourcesActivity_getBytesToDownload(
      JNIEnv * env, jobject thiz, jstring apkPath, jstring sdcardPath)
  {
    // clear all
    g_filesToDownload.clear();
    g_totalBytesToDownload = 0;
    g_totalDownloadedBytes = 0;

    //g_apkPath = jni::ToNativeString(env, apkPath);
    string const path = jni::ToNativeString(env, sdcardPath);

    Platform & pl = GetPlatform();
    ReaderStreamBuf buffer(pl.GetReader("external_resources.txt"));

    istream in(&buffer);

    string name;
    int size;

    while (true)
    {
      in >> name;

      if (!in.good())
        break;

      in >> size;

      if (!in.good())
        break;

      if (NeedToDownload(name, size))
      {
        LOG(LDEBUG, ("Should download", name, "sized", size, "bytes"));

        FileToDownload f;
        f.m_pathOnSdcard = path + name;
        f.m_fileName = name;
        f.m_fileSize = size;

        g_filesToDownload.push_back(f);
        g_totalBytesToDownload += size;
      }
    }

    int const res = HasSpaceForFiles(path, g_totalBytesToDownload);
    switch (res)
    {
    case ERR_STORAGE_DISCONNECTED:
      LOG(LWARNING, ("External file system is not available"));
      break;
    case ERR_NOT_ENOUGH_FREE_SPACE:
      LOG(LWARNING, ("Not enough space to extract files"));
      break;
    };
{'fraction_non_alphanumeric': 0.15238361526632183, 'fraction_numerical': 0.003914441493079826, 'mean_word_length': 2.633316404266125, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 37, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6438429', 'n_tokens_mistral': 2366, 'n_tokens_neox': 2339, 'n_words': 504}