mirror of
				https://github.com/ton-blockchain/ton
				synced 2025-03-09 15:40:10 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			96 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			96 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|     This file is part of TON Blockchain Library.
 | |
| 
 | |
|     TON Blockchain Library is free software: you can redistribute it and/or modify
 | |
|     it under the terms of the GNU Lesser General Public License as published by
 | |
|     the Free Software Foundation, either version 2 of the License, or
 | |
|     (at your option) any later version.
 | |
| 
 | |
|     TON Blockchain Library is distributed in the hope that it will be useful,
 | |
|     but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|     GNU Lesser General Public License for more details.
 | |
| 
 | |
|     You should have received a copy of the GNU Lesser General Public License
 | |
|     along with TON Blockchain Library.  If not, see <http://www.gnu.org/licenses/>.
 | |
| 
 | |
|     Copyright 2017-2019 Telegram Systems LLP
 | |
| */
 | |
| #include "BinlogReaderHelper.h"
 | |
| #include "BinlogReaderInterface.h"
 | |
| 
 | |
| #include "td/utils/misc.h"
 | |
| 
 | |
| namespace td {
 | |
| td::Status BinlogReaderHelper::parse(BinlogReaderInterface& reader, td::Slice data) {
 | |
|   SCOPE_EXIT {
 | |
|     reader.flush();
 | |
|   };
 | |
|   while (true) {
 | |
|     if (expected_prefix_size_ > 0 && expected_prefix_size_ == prefix_size_) {
 | |
|       TRY_RESULT(size, reader.parse(MutableSlice(buf_.data(), prefix_size_)));
 | |
|       if (size < 0) {
 | |
|         if (expected_prefix_size_ > td::narrow_cast<size_t>(-size)) {
 | |
|           return td::Status::Error("BinlogReader decreased logevent size estimation (1)");
 | |
|         }
 | |
|         expected_prefix_size_ = static_cast<size_t>(-size);
 | |
|       } else {
 | |
|         if (expected_prefix_size_ != td::narrow_cast<size_t>(size)) {
 | |
|           return td::Status::Error("BinlogReader changed logevent");
 | |
|         }
 | |
|         prefix_size_ = 0;
 | |
|         expected_prefix_size_ = 0;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if (data.empty()) {
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     if (expected_prefix_size_ > 0) {
 | |
|       CHECK(expected_prefix_size_ < buf_.size());
 | |
|       CHECK(prefix_size_ < expected_prefix_size_);
 | |
|       auto got = data.copy().truncate(expected_prefix_size_ - prefix_size_);
 | |
|       reader.flush();
 | |
|       auto dest = td::MutableSlice(buf_.data(), buf_.size()).substr(prefix_size_);
 | |
|       if (dest.size() < got.size()) {
 | |
|         return td::Status::Error("Too big logevent");
 | |
|       }
 | |
|       dest.copy_from(got);
 | |
|       prefix_size_ += got.size();
 | |
|       data = data.substr(got.size());
 | |
|       continue;
 | |
|     }
 | |
| 
 | |
|     CHECK(!data.empty());
 | |
| 
 | |
|     TRY_RESULT(size, reader.parse(data));
 | |
|     if (size < 0) {
 | |
|       expected_prefix_size_ = td::narrow_cast<size_t>(-size);
 | |
|       prefix_size_ = data.size();
 | |
|       if (expected_prefix_size_ < prefix_size_) {
 | |
|         return td::Status::Error("BinlogReader waits for less data than it already has");
 | |
|       }
 | |
|       if (expected_prefix_size_ > buf_.size()) {
 | |
|         return td::Status::Error("BinlogReader waits for too big logevent");
 | |
|       }
 | |
|       reader.flush();
 | |
|       td::MutableSlice(buf_.data(), prefix_size_).copy_from(data);
 | |
|       break;
 | |
|     }
 | |
|     if (size == 0) {
 | |
|       return td::Status::Error("BinlogReader parseed nothing and asked for nothing");
 | |
|     }
 | |
|     if (td::narrow_cast<size_t>(size) > data.size()) {
 | |
|       return td::Status::Error("BinlogReader parseed more than was given");
 | |
|     }
 | |
|     data = data.substr(static_cast<size_t>(size));
 | |
|   }
 | |
|   return td::Status::OK();
 | |
| }
 | |
| 
 | |
| size_t BinlogReaderHelper::unparsed_size() const {
 | |
|   return prefix_size_;
 | |
| }
 | |
| 
 | |
| }  // namespace td
 |