1 /****
2 DIAMOND protein aligner
3 Copyright (C) 2013-2017 Benjamin Buchfink <buchfink@gmail.com>
4 
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 ****/
18 
19 #ifndef BINARY_BUFFER_H_
20 #define BINARY_BUFFER_H_
21 
22 #include <vector>
23 #include <stdexcept>
24 #include <stdint.h>
25 #include <string.h>
26 #include "intrin.h"
27 #include "algo/varint.h"
28 
29 using std::vector;
30 using std::string;
31 
32 struct BinaryBuffer : public vector<char>
33 {
34 
35 	struct Iterator
36 	{
IteratorBinaryBuffer::Iterator37 		Iterator(vector<char>::const_iterator begin, vector<char>::const_iterator end):
38 			ptr_ (begin),
39 			end_ (end)
40 		{ }
41 		Iterator& operator>>(uint32_t &x)
42 		{ read(x); return *this; }
43 		Iterator& operator>>(uint8_t &x)
44 		{ read(x); return *this; }
45 		template<typename _t>
readBinaryBuffer::Iterator46 		void read(_t &x)
47 		{
48 			check(sizeof(_t));
49 			x = *(_t*)(&*ptr_);
50 			ptr_ += sizeof(_t);
51 		}
52 		template<typename _t>
readBinaryBuffer::Iterator53 		void read(vector<_t> &v, size_t count)
54 		{
55 			const size_t l = sizeof(_t) * count;
56 			check(l);
57 			v.resize(count);
58 			memcpy(v.data(), &*ptr_, l);
59 			ptr_ += l;
60 		}
read_packedBinaryBuffer::Iterator61 		void read_packed(uint8_t length, uint32_t &dst)
62 		{
63 			switch(length) {
64 			case 0: uint8_t x; read(x); dst = x; break;
65 			case 1: uint16_t y; read(y); dst = y; break;
66 			case 2: read(dst);
67 			}
68 		}
read_packedBinaryBuffer::Iterator69 		void read_packed(uint8_t length, int32_t& dst)
70 		{
71 			switch (length) {
72 			case 0: uint8_t x; read(x); dst = (int32_t)x; break;
73 			case 1: uint16_t y; read(y); dst = (int32_t)y; break;
74 			case 2: read(dst);
75 			}
76 		}
read_varintBinaryBuffer::Iterator77 		void read_varint(uint32_t &dst)
78 		{
79 			::read_varint(*this, dst);
80 		}
81 		Iterator& operator>>(string &dst)
82 		{
83 			dst.clear();
84 			char c;
85 			while(read(c), c != '\0')
86 				dst.push_back(c);
87 			return *this;
88 		}
goodBinaryBuffer::Iterator89 		bool good() const
90 		{ return ptr_ < end_; }
91 	private:
checkBinaryBuffer::Iterator92 		void check(size_t size) const
93 		{ if(ptr_+size > end_) throw std::runtime_error("Unexpected end of file."); }
94 		vector<char>::const_iterator ptr_, end_;
95 	};
96 
beginBinaryBuffer97 	Iterator begin() const
98 	{ return Iterator (vector<char>::begin(), vector<char>::end()); }
99 
100 };
101 
102 #endif /* BINARY_BUFFER_H_ */
103