Ton

Форк
0
/
BinlogReaderHelper.cpp 
96 строк · 3.2 Кб
1
/*
2
    This file is part of TON Blockchain Library.
3

4
    TON Blockchain Library is free software: you can redistribute it and/or modify
5
    it under the terms of the GNU Lesser General Public License as published by
6
    the Free Software Foundation, either version 2 of the License, or
7
    (at your option) any later version.
8

9
    TON Blockchain Library is distributed in the hope that it will be useful,
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
    GNU Lesser General Public License for more details.
13

14
    You should have received a copy of the GNU Lesser General Public License
15
    along with TON Blockchain Library.  If not, see <http://www.gnu.org/licenses/>.
16

17
    Copyright 2017-2020 Telegram Systems LLP
18
*/
19
#include "BinlogReaderHelper.h"
20
#include "BinlogReaderInterface.h"
21

22
#include "td/utils/misc.h"
23

24
namespace td {
25
td::Status BinlogReaderHelper::parse(BinlogReaderInterface& reader, td::Slice data) {
26
  SCOPE_EXIT {
27
    reader.flush();
28
  };
29
  while (true) {
30
    if (expected_prefix_size_ > 0 && expected_prefix_size_ == prefix_size_) {
31
      TRY_RESULT(size, reader.parse(MutableSlice(buf_.data(), prefix_size_)));
32
      if (size < 0) {
33
        if (expected_prefix_size_ > td::narrow_cast<size_t>(-size)) {
34
          return td::Status::Error("BinlogReader decreased logevent size estimation (1)");
35
        }
36
        expected_prefix_size_ = static_cast<size_t>(-size);
37
      } else {
38
        if (expected_prefix_size_ != td::narrow_cast<size_t>(size)) {
39
          return td::Status::Error("BinlogReader changed logevent");
40
        }
41
        prefix_size_ = 0;
42
        expected_prefix_size_ = 0;
43
      }
44
    }
45

46
    if (data.empty()) {
47
      break;
48
    }
49

50
    if (expected_prefix_size_ > 0) {
51
      CHECK(expected_prefix_size_ < buf_.size());
52
      CHECK(prefix_size_ < expected_prefix_size_);
53
      auto got = data.copy().truncate(expected_prefix_size_ - prefix_size_);
54
      reader.flush();
55
      auto dest = td::MutableSlice(buf_.data(), buf_.size()).substr(prefix_size_);
56
      if (dest.size() < got.size()) {
57
        return td::Status::Error("Too big logevent");
58
      }
59
      dest.copy_from(got);
60
      prefix_size_ += got.size();
61
      data = data.substr(got.size());
62
      continue;
63
    }
64

65
    CHECK(!data.empty());
66

67
    TRY_RESULT(size, reader.parse(data));
68
    if (size < 0) {
69
      expected_prefix_size_ = td::narrow_cast<size_t>(-size);
70
      prefix_size_ = data.size();
71
      if (expected_prefix_size_ < prefix_size_) {
72
        return td::Status::Error("BinlogReader waits for less data than it already has");
73
      }
74
      if (expected_prefix_size_ > buf_.size()) {
75
        return td::Status::Error("BinlogReader waits for too big logevent");
76
      }
77
      reader.flush();
78
      td::MutableSlice(buf_.data(), prefix_size_).copy_from(data);
79
      break;
80
    }
81
    if (size == 0) {
82
      return td::Status::Error("BinlogReader parseed nothing and asked for nothing");
83
    }
84
    if (td::narrow_cast<size_t>(size) > data.size()) {
85
      return td::Status::Error("BinlogReader parseed more than was given");
86
    }
87
    data = data.substr(static_cast<size_t>(size));
88
  }
89
  return td::Status::OK();
90
}
91

92
size_t BinlogReaderHelper::unparsed_size() const {
93
  return prefix_size_;
94
}
95

96
}  // namespace td
97

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.