15beee10b17e676380727da0b16b98ba7568669ecPeng Xu/* 25beee10b17e676380727da0b16b98ba7568669ecPeng Xu * Copyright (C) 2017 The Android Open Source Project 35beee10b17e676380727da0b16b98ba7568669ecPeng Xu * 45beee10b17e676380727da0b16b98ba7568669ecPeng Xu * Licensed under the Apache License, Version 2.0 (the "License"); 55beee10b17e676380727da0b16b98ba7568669ecPeng Xu * you may not use this file except in compliance with the License. 65beee10b17e676380727da0b16b98ba7568669ecPeng Xu * You may obtain a copy of the License at 75beee10b17e676380727da0b16b98ba7568669ecPeng Xu * 85beee10b17e676380727da0b16b98ba7568669ecPeng Xu * http://www.apache.org/licenses/LICENSE-2.0 95beee10b17e676380727da0b16b98ba7568669ecPeng Xu * 105beee10b17e676380727da0b16b98ba7568669ecPeng Xu * Unless required by applicable law or agreed to in writing, software 115beee10b17e676380727da0b16b98ba7568669ecPeng Xu * distributed under the License is distributed on an "AS IS" BASIS, 125beee10b17e676380727da0b16b98ba7568669ecPeng Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135beee10b17e676380727da0b16b98ba7568669ecPeng Xu * See the License for the specific language governing permissions and 145beee10b17e676380727da0b16b98ba7568669ecPeng Xu * limitations under the License. 155beee10b17e676380727da0b16b98ba7568669ecPeng Xu */ 165beee10b17e676380727da0b16b98ba7568669ecPeng Xu#ifndef HIDUTIL_STREAM_IO_UTIL_H_ 175beee10b17e676380727da0b16b98ba7568669ecPeng Xu#define HIDUTIL_STREAM_IO_UTIL_H_ 185beee10b17e676380727da0b16b98ba7568669ecPeng Xu 195beee10b17e676380727da0b16b98ba7568669ecPeng Xu#include "HidLog.h" 205beee10b17e676380727da0b16b98ba7568669ecPeng Xu#include <istream> 215beee10b17e676380727da0b16b98ba7568669ecPeng Xu#include <iomanip> 225beee10b17e676380727da0b16b98ba7568669ecPeng Xu#include <sstream> 235beee10b17e676380727da0b16b98ba7568669ecPeng Xu#include <vector> 245beee10b17e676380727da0b16b98ba7568669ecPeng Xu#include <cassert> 255beee10b17e676380727da0b16b98ba7568669ecPeng Xu 265beee10b17e676380727da0b16b98ba7568669ecPeng Xunamespace HidUtil { 275beee10b17e676380727da0b16b98ba7568669ecPeng Xu 285beee10b17e676380727da0b16b98ba7568669ecPeng Xutemplate<typename CharT> 295beee10b17e676380727da0b16b98ba7568669ecPeng Xuclass charvectorbuf : public std::streambuf { // class name is consistent with std lib 305beee10b17e676380727da0b16b98ba7568669ecPeng Xu static_assert(std::is_const<CharT>::value == false, "cannot use const type"); 315beee10b17e676380727da0b16b98ba7568669ecPeng Xupublic: 325beee10b17e676380727da0b16b98ba7568669ecPeng Xu // r/w buffer constructors 335beee10b17e676380727da0b16b98ba7568669ecPeng Xu charvectorbuf(std::vector<CharT> &vec) { 345beee10b17e676380727da0b16b98ba7568669ecPeng Xu init(vec.data(), vec.size()); 355beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 365beee10b17e676380727da0b16b98ba7568669ecPeng Xu 375beee10b17e676380727da0b16b98ba7568669ecPeng Xu charvectorbuf(CharT *begin, CharT *end) { 385beee10b17e676380727da0b16b98ba7568669ecPeng Xu assert(end >= begin); 395beee10b17e676380727da0b16b98ba7568669ecPeng Xu init(begin, end - begin); 405beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 415beee10b17e676380727da0b16b98ba7568669ecPeng Xu 425beee10b17e676380727da0b16b98ba7568669ecPeng Xu charvectorbuf(CharT *begin, size_t size) { 435beee10b17e676380727da0b16b98ba7568669ecPeng Xu init(begin, size); 445beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 455beee10b17e676380727da0b16b98ba7568669ecPeng Xu 465beee10b17e676380727da0b16b98ba7568669ecPeng Xu // r/o buffer constructor 475beee10b17e676380727da0b16b98ba7568669ecPeng Xu charvectorbuf(const std::vector<CharT> &vec) { 485beee10b17e676380727da0b16b98ba7568669ecPeng Xu init(vec.data(), vec.size()); 495beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 505beee10b17e676380727da0b16b98ba7568669ecPeng Xu 515beee10b17e676380727da0b16b98ba7568669ecPeng Xu charvectorbuf(const CharT *begin, const CharT *end) { 525beee10b17e676380727da0b16b98ba7568669ecPeng Xu assert(end >= begin); 535beee10b17e676380727da0b16b98ba7568669ecPeng Xu init(begin, end - begin); 545beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 555beee10b17e676380727da0b16b98ba7568669ecPeng Xu 565beee10b17e676380727da0b16b98ba7568669ecPeng Xu charvectorbuf(const CharT *begin, size_t size) { 575beee10b17e676380727da0b16b98ba7568669ecPeng Xu init(begin, size); 585beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 595beee10b17e676380727da0b16b98ba7568669ecPeng Xu protected: 605beee10b17e676380727da0b16b98ba7568669ecPeng Xu virtual std::streampos seekpos( 615beee10b17e676380727da0b16b98ba7568669ecPeng Xu std::streampos sp, std::ios_base::openmode which = 625beee10b17e676380727da0b16b98ba7568669ecPeng Xu std::ios_base::in | std::ios_base::out) override { 635beee10b17e676380727da0b16b98ba7568669ecPeng Xu return seekoff(std::streamoff(sp), std::ios_base::beg, which); 645beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 655beee10b17e676380727da0b16b98ba7568669ecPeng Xu 665beee10b17e676380727da0b16b98ba7568669ecPeng Xu // this is needed to use ftell() on stream 675beee10b17e676380727da0b16b98ba7568669ecPeng Xu virtual std::streampos seekoff( 685beee10b17e676380727da0b16b98ba7568669ecPeng Xu std::streamoff off, std::ios_base::seekdir way, 695beee10b17e676380727da0b16b98ba7568669ecPeng Xu std::ios_base::openmode which = 705beee10b17e676380727da0b16b98ba7568669ecPeng Xu std::ios_base::in | std::ios_base::out) override { 715beee10b17e676380727da0b16b98ba7568669ecPeng Xu 725beee10b17e676380727da0b16b98ba7568669ecPeng Xu // pptr() == nullptr: read-only 735beee10b17e676380727da0b16b98ba7568669ecPeng Xu assert(pptr() == nullptr || egptr() - eback() == epptr() - pbase()); 745beee10b17e676380727da0b16b98ba7568669ecPeng Xu bool in = which & std::ios_base::in; 755beee10b17e676380727da0b16b98ba7568669ecPeng Xu bool out = which & std::ios_base::out; 765beee10b17e676380727da0b16b98ba7568669ecPeng Xu pos_type end = egptr() - eback(); 775beee10b17e676380727da0b16b98ba7568669ecPeng Xu 785beee10b17e676380727da0b16b98ba7568669ecPeng Xu if (!in && !out) { 795beee10b17e676380727da0b16b98ba7568669ecPeng Xu return pos_type(-1); 805beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 815beee10b17e676380727da0b16b98ba7568669ecPeng Xu 825beee10b17e676380727da0b16b98ba7568669ecPeng Xu if (in && out && way == std::ios_base::cur) { 835beee10b17e676380727da0b16b98ba7568669ecPeng Xu return pos_type(-1); 845beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 855beee10b17e676380727da0b16b98ba7568669ecPeng Xu 865beee10b17e676380727da0b16b98ba7568669ecPeng Xu off_type noff; 875beee10b17e676380727da0b16b98ba7568669ecPeng Xu switch (way) { 885beee10b17e676380727da0b16b98ba7568669ecPeng Xu case std::ios_base::beg: 895beee10b17e676380727da0b16b98ba7568669ecPeng Xu noff = 0; 905beee10b17e676380727da0b16b98ba7568669ecPeng Xu break; 915beee10b17e676380727da0b16b98ba7568669ecPeng Xu case std::ios_base::cur: 925beee10b17e676380727da0b16b98ba7568669ecPeng Xu if (in) { 935beee10b17e676380727da0b16b98ba7568669ecPeng Xu noff = gptr() - eback(); 945beee10b17e676380727da0b16b98ba7568669ecPeng Xu } else { 955beee10b17e676380727da0b16b98ba7568669ecPeng Xu noff = pptr() - pbase(); 965beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 975beee10b17e676380727da0b16b98ba7568669ecPeng Xu break; 985beee10b17e676380727da0b16b98ba7568669ecPeng Xu case std::ios_base::end: 995beee10b17e676380727da0b16b98ba7568669ecPeng Xu noff = end; 1005beee10b17e676380727da0b16b98ba7568669ecPeng Xu break; 1015beee10b17e676380727da0b16b98ba7568669ecPeng Xu default: 1025beee10b17e676380727da0b16b98ba7568669ecPeng Xu return pos_type(-1); 1035beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 1045beee10b17e676380727da0b16b98ba7568669ecPeng Xu noff += off; 1055beee10b17e676380727da0b16b98ba7568669ecPeng Xu if (noff < 0 || noff > end) { 1065beee10b17e676380727da0b16b98ba7568669ecPeng Xu return pos_type(-1); 1075beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 1085beee10b17e676380727da0b16b98ba7568669ecPeng Xu 1095beee10b17e676380727da0b16b98ba7568669ecPeng Xu if (noff != 0 && ((in && gptr() == nullptr) || (out && pptr() == nullptr))) { 1105beee10b17e676380727da0b16b98ba7568669ecPeng Xu return pos_type(-1); 1115beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 1125beee10b17e676380727da0b16b98ba7568669ecPeng Xu 1135beee10b17e676380727da0b16b98ba7568669ecPeng Xu if (in) { 1145beee10b17e676380727da0b16b98ba7568669ecPeng Xu setg(eback(), eback() + noff, egptr()); 1155beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 1165beee10b17e676380727da0b16b98ba7568669ecPeng Xu 1175beee10b17e676380727da0b16b98ba7568669ecPeng Xu if (out) { 1185beee10b17e676380727da0b16b98ba7568669ecPeng Xu setp(pbase(), epptr()); 1195beee10b17e676380727da0b16b98ba7568669ecPeng Xu pbump(noff); 1205beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 1215beee10b17e676380727da0b16b98ba7568669ecPeng Xu 1225beee10b17e676380727da0b16b98ba7568669ecPeng Xu return pos_type(noff); 1235beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 1245beee10b17e676380727da0b16b98ba7568669ecPeng Xuprivate: 1255beee10b17e676380727da0b16b98ba7568669ecPeng Xu // read only buffer init 1265beee10b17e676380727da0b16b98ba7568669ecPeng Xu void init(const CharT *base, size_t size) { 1275beee10b17e676380727da0b16b98ba7568669ecPeng Xu setg((char*)base, (char*)base, (char*)(base + size)); 1285beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 1295beee10b17e676380727da0b16b98ba7568669ecPeng Xu 1305beee10b17e676380727da0b16b98ba7568669ecPeng Xu // read write buffer init 1315beee10b17e676380727da0b16b98ba7568669ecPeng Xu void init(CharT *base, size_t size) { 1325beee10b17e676380727da0b16b98ba7568669ecPeng Xu setg((char*)base, (char*)base, (char*)(base + size)); 1335beee10b17e676380727da0b16b98ba7568669ecPeng Xu setp((char*)base, (char*)(base + size)); 1345beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 1355beee10b17e676380727da0b16b98ba7568669ecPeng Xu}; 1365beee10b17e676380727da0b16b98ba7568669ecPeng Xu 1375beee10b17e676380727da0b16b98ba7568669ecPeng Xu// dump binary values 1385beee10b17e676380727da0b16b98ba7568669ecPeng Xutemplate <class ForwardIterator> 1395beee10b17e676380727da0b16b98ba7568669ecPeng Xuvoid hexdumpToStream(std::ostream &os, const ForwardIterator &first, const ForwardIterator &last) { 1405beee10b17e676380727da0b16b98ba7568669ecPeng Xu static_assert( 1415beee10b17e676380727da0b16b98ba7568669ecPeng Xu std::is_convertible< 1425beee10b17e676380727da0b16b98ba7568669ecPeng Xu typename std::iterator_traits<ForwardIterator>::iterator_category, 1435beee10b17e676380727da0b16b98ba7568669ecPeng Xu std::forward_iterator_tag>::value 1445beee10b17e676380727da0b16b98ba7568669ecPeng Xu && std::is_convertible< 1455beee10b17e676380727da0b16b98ba7568669ecPeng Xu typename std::iterator_traits<ForwardIterator>::value_type, 1465beee10b17e676380727da0b16b98ba7568669ecPeng Xu unsigned char>::value 1475beee10b17e676380727da0b16b98ba7568669ecPeng Xu && sizeof(typename std::iterator_traits<ForwardIterator>::value_type) 1485beee10b17e676380727da0b16b98ba7568669ecPeng Xu == sizeof(unsigned char), 1495beee10b17e676380727da0b16b98ba7568669ecPeng Xu "Only accepts forward iterator of a type of size 1 " 1505beee10b17e676380727da0b16b98ba7568669ecPeng Xu "that can be convert to unsigned char.\n"); 1515beee10b17e676380727da0b16b98ba7568669ecPeng Xu size_t c = 0; 1525beee10b17e676380727da0b16b98ba7568669ecPeng Xu std::ostringstream ss; 1535beee10b17e676380727da0b16b98ba7568669ecPeng Xu for (ForwardIterator i = first; i != last; ++i, ++c) { 1545beee10b17e676380727da0b16b98ba7568669ecPeng Xu unsigned char v = *i; 1555beee10b17e676380727da0b16b98ba7568669ecPeng Xu // formatting 1565beee10b17e676380727da0b16b98ba7568669ecPeng Xu switch (c & 0xf) { 1575beee10b17e676380727da0b16b98ba7568669ecPeng Xu case 0: 1585beee10b17e676380727da0b16b98ba7568669ecPeng Xu // address 1595beee10b17e676380727da0b16b98ba7568669ecPeng Xu os << ss.str() << LOG_ENDL; 1605beee10b17e676380727da0b16b98ba7568669ecPeng Xu ss.str(""); 1615beee10b17e676380727da0b16b98ba7568669ecPeng Xu ss << std::hex; 1625beee10b17e676380727da0b16b98ba7568669ecPeng Xu ss << std::setfill('0') << std::setw(4) << c << ": "; 1635beee10b17e676380727da0b16b98ba7568669ecPeng Xu break; 1645beee10b17e676380727da0b16b98ba7568669ecPeng Xu case 8: 1655beee10b17e676380727da0b16b98ba7568669ecPeng Xu // space 1665beee10b17e676380727da0b16b98ba7568669ecPeng Xu ss << " "; 1675beee10b17e676380727da0b16b98ba7568669ecPeng Xu break; 1685beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 1695beee10b17e676380727da0b16b98ba7568669ecPeng Xu ss << std::setfill('0') << std::setw(2) 1705beee10b17e676380727da0b16b98ba7568669ecPeng Xu << static_cast<unsigned>(static_cast<unsigned char>(v)) << " "; 1715beee10b17e676380727da0b16b98ba7568669ecPeng Xu } 1725beee10b17e676380727da0b16b98ba7568669ecPeng Xu os << ss.str() << LOG_ENDL; 1735beee10b17e676380727da0b16b98ba7568669ecPeng Xu} 1745beee10b17e676380727da0b16b98ba7568669ecPeng Xu} //namespace HidUtil 1755beee10b17e676380727da0b16b98ba7568669ecPeng Xu 1765beee10b17e676380727da0b16b98ba7568669ecPeng Xu#endif // HIDUTIL_STREAM_IO_UTIL_H_ 1775beee10b17e676380727da0b16b98ba7568669ecPeng Xu 178