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