mirror of
				https://github.com/facebook/zstd.git
				synced 2025-10-30 10:25:39 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			100 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /**
 | |
|  * Copyright (c) 2016-present, Facebook, Inc.
 | |
|  * All rights reserved.
 | |
|  *
 | |
|  * This source code is licensed under the BSD-style license found in the
 | |
|  * LICENSE file in the root directory of this source tree. An additional grant
 | |
|  * of patent rights can be found in the PATENTS file in the same directory.
 | |
|  */
 | |
| #pragma once
 | |
| 
 | |
| #include "utils/Range.h"
 | |
| 
 | |
| #include <array>
 | |
| #include <cstddef>
 | |
| #include <memory>
 | |
| 
 | |
| namespace pzstd {
 | |
| 
 | |
| /**
 | |
|  * A `Buffer` has a pointer to a shared buffer, and a range of the buffer that
 | |
|  * it owns.
 | |
|  * The idea is that you can allocate one buffer, and write chunks into it
 | |
|  * and break off those chunks.
 | |
|  * The underlying buffer is reference counted, and will be destroyed when all
 | |
|  * `Buffer`s that reference it are destroyed.
 | |
|  */
 | |
| class Buffer {
 | |
|   std::shared_ptr<unsigned char> buffer_;
 | |
|   MutableByteRange range_;
 | |
| 
 | |
|   static void delete_buffer(unsigned char* buffer) {
 | |
|     delete[] buffer;
 | |
|   }
 | |
| 
 | |
|  public:
 | |
|   /// Construct an empty buffer that owns no data.
 | |
|   explicit Buffer() {}
 | |
| 
 | |
|   /// Construct a `Buffer` that owns a new underlying buffer of size `size`.
 | |
|   explicit Buffer(std::size_t size)
 | |
|       : buffer_(new unsigned char[size], delete_buffer),
 | |
|         range_(buffer_.get(), buffer_.get() + size) {}
 | |
| 
 | |
|   explicit Buffer(std::shared_ptr<unsigned char> buffer, MutableByteRange data)
 | |
|       : buffer_(buffer), range_(data) {}
 | |
| 
 | |
|   Buffer(Buffer&&) = default;
 | |
|   Buffer& operator=(Buffer&&) & = default;
 | |
| 
 | |
|   /**
 | |
|    * Splits the data into two pieces: [begin, begin + n), [begin + n, end).
 | |
|    * Their data both points into the same underlying buffer.
 | |
|    * Modifies the original `Buffer` to point to only [begin + n, end).
 | |
|    *
 | |
|    * @param n  The offset to split at.
 | |
|    * @returns  A buffer that owns the data [begin, begin + n).
 | |
|    */
 | |
|   Buffer splitAt(std::size_t n) {
 | |
|     auto firstPiece = range_.subpiece(0, n);
 | |
|     range_.advance(n);
 | |
|     return Buffer(buffer_, firstPiece);
 | |
|   }
 | |
| 
 | |
|   /// Modifies the buffer to point to the range [begin + n, end).
 | |
|   void advance(std::size_t n) {
 | |
|     range_.advance(n);
 | |
|   }
 | |
| 
 | |
|   /// Modifies the buffer to point to the range [begin, end - n).
 | |
|   void subtract(std::size_t n) {
 | |
|     range_.subtract(n);
 | |
|   }
 | |
| 
 | |
|   /// Returns a read only `Range` pointing to the `Buffer`s data.
 | |
|   ByteRange range() const {
 | |
|     return range_;
 | |
|   }
 | |
|   /// Returns a mutable `Range` pointing to the `Buffer`s data.
 | |
|   MutableByteRange range() {
 | |
|     return range_;
 | |
|   }
 | |
| 
 | |
|   const unsigned char* data() const {
 | |
|     return range_.data();
 | |
|   }
 | |
| 
 | |
|   unsigned char* data() {
 | |
|     return range_.data();
 | |
|   }
 | |
| 
 | |
|   std::size_t size() const {
 | |
|     return range_.size();
 | |
|   }
 | |
| 
 | |
|   bool empty() const {
 | |
|     return range_.empty();
 | |
|   }
 | |
| };
 | |
| }
 |