Welcome to mirror list, hosted at ThFree Co, Russian Federation.

file_reader.cpp « coding - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 500d0e9fbdc1c12199d8e2c98e9b03a6833ce6ce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include "coding/file_reader.hpp"
#include "coding/reader_cache.hpp"
#include "coding/internal/file_data.hpp"

#ifndef LOG_FILE_READER_STATS
#define LOG_FILE_READER_STATS 0
#endif // LOG_FILE_READER_STATS

#if LOG_FILE_READER_STATS && !defined(LOG_FILE_READER_EVERY_N_READS_MASK)
#define LOG_FILE_READER_EVERY_N_READS_MASK 0xFFFFFFFF
#endif

namespace
{
  class FileDataWithCachedSize : public my::FileData
  {
      typedef my::FileData base_t;

  public:
    explicit FileDataWithCachedSize(string const & fileName)
      : base_t(fileName, FileData::OP_READ), m_Size(FileData::Size()) {}

    uint64_t Size() const { return m_Size; }

  private:
    uint64_t m_Size;
  };
}

class FileReader::FileReaderData
{
public:
  FileReaderData(string const & fileName, uint32_t logPageSize, uint32_t logPageCount)
    : m_FileData(fileName), m_ReaderCache(logPageSize, logPageCount)
  {
#if LOG_FILE_READER_STATS
    m_ReadCallCount = 0;
#endif
  }

  ~FileReaderData()
  {
#if LOG_FILE_READER_STATS
    LOG(LINFO, ("FileReader", GetName(), m_ReaderCache.GetStatsStr()));
#endif
  }

  uint64_t Size() const { return m_FileData.Size(); }

  void Read(uint64_t pos, void * p, size_t size)
  {
#if LOG_FILE_READER_STATS
    if (((++m_ReadCallCount) & LOG_FILE_READER_EVERY_N_READS_MASK) == 0)
    {
      LOG(LINFO, ("FileReader", GetName(), m_ReaderCache.GetStatsStr()));
    }
#endif

    return m_ReaderCache.Read(m_FileData, pos, p, size);
  }

private:
  FileDataWithCachedSize m_FileData;
  ReaderCache<FileDataWithCachedSize, LOG_FILE_READER_STATS> m_ReaderCache;

#if LOG_FILE_READER_STATS
  uint32_t m_ReadCallCount;
#endif
};

FileReader::FileReader(string const & fileName, bool withExceptions,
                       uint32_t logPageSize, uint32_t logPageCount)
  : BaseType(fileName)
  , m_fileData(new FileReaderData(fileName, logPageSize, logPageCount))
  , m_offset(0)
  , m_size(m_fileData->Size())
  , m_withExceptions(withExceptions)
{}

FileReader::FileReader(FileReader const & reader, uint64_t offset, uint64_t size)
  : BaseType(reader.GetName())
  , m_fileData(reader.m_fileData)
  , m_offset(offset)
  , m_size(size)
  , m_withExceptions(reader.m_withExceptions)
{}

uint64_t FileReader::Size() const
{
  return m_size;
}

void FileReader::Read(uint64_t pos, void * p, size_t size) const
{
  CheckPosAndSize(pos, size);
  m_fileData->Read(m_offset + pos, p, size);
}

FileReader FileReader::SubReader(uint64_t pos, uint64_t size) const
{
  CheckPosAndSize(pos, size);
  return FileReader(*this, m_offset + pos, size);
}

unique_ptr<Reader> FileReader::CreateSubReader(uint64_t pos, uint64_t size) const
{
  CheckPosAndSize(pos, size);
  // Can't use make_unique with private constructor.
  return unique_ptr<Reader>(new FileReader(*this, m_offset + pos, size));
}

bool FileReader::AssertPosAndSize(uint64_t pos, uint64_t size) const
{
  uint64_t const allSize1 = Size();
  bool const ret1 = (pos + size <= allSize1);
  if (!m_withExceptions)
    ASSERT(ret1, (pos, size, allSize1));

  uint64_t const allSize2 = m_fileData->Size();
  bool const ret2 = (m_offset + pos + size <= allSize2);
  if (!m_withExceptions)
    ASSERT(ret2, (m_offset, pos, size, allSize2));

  return (ret1 && ret2);
}

void FileReader::CheckPosAndSize(uint64_t pos, uint64_t size) const
{
  if (m_withExceptions && !AssertPosAndSize(pos, size))
    MYTHROW(Reader::SizeException, (pos, size));
  else
    ASSERT(AssertPosAndSize(pos, size), ());
}

void FileReader::SetOffsetAndSize(uint64_t offset, uint64_t size)
{
  CheckPosAndSize(offset, size);
  m_offset = offset;
  m_size = size;
}