TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / src / anbox / common / binary_writer.cpp
1 /*
2  * Copyright (C) 2016 Thomas Voss <thomas.voss.bochum@gmail.com>
3  *                    Simon Fels <morphis@gravedo.de>
4  *
5  * This program is free software: you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 3, as published
7  * by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranties of
11  * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12  * PURPOSE.  See the GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  */
18
19 #include "anbox/common/binary_writer.h"
20
21 #include <cstring>
22 #include <stdexcept>
23
24 #include <boost/endian/buffers.hpp>
25 #include <boost/endian/conversion.hpp>
26
27 namespace {
28 bool is_little_endian() {
29   static const std::uint32_t v = 1;
30   return (*reinterpret_cast<const std::uint8_t*>(&v) ==  1);
31 }
32 }
33
34 namespace anbox {
35 namespace common {
36
37 BinaryWriter::BinaryWriter(std::vector<std::uint8_t>::iterator begin,
38                            std::vector<std::uint8_t>::iterator end) :
39   begin_{begin}, current_{begin}, end_{end},
40   byte_order_{is_little_endian() ? Order::Little : Order::Big} {}
41
42 void BinaryWriter::set_byte_order(Order order) {
43   byte_order_ = order;
44 }
45
46 void BinaryWriter::write_uint16(std::uint16_t value) {
47   if (current_ + sizeof(value) > end_)
48     throw std::out_of_range{"Write buffer exhausted"};
49
50   std::uint16_t v = value;
51   switch (byte_order_) {
52   case Order::Big:
53     v = boost::endian::native_to_big(value);
54     break;
55   case Order::Little:
56     v = boost::endian::native_to_little(value);
57     break;
58   default:
59     break;
60   }
61
62   memcpy(&(*current_), &v, sizeof(std::uint16_t));
63   current_ += sizeof(v);
64 }
65
66 void BinaryWriter::write_uint32(std::uint32_t value) {
67   if (current_ + sizeof(value) > end_)
68     throw std::out_of_range{"Write buffer exhausted"};
69
70   std::uint32_t v = value;
71   switch (byte_order_) {
72   case Order::Big:
73     v = boost::endian::native_to_big(value);
74     break;
75   case Order::Little:
76     v = boost::endian::native_to_little(value);
77     break;
78   default:
79     break;
80   }
81   memcpy(&(*current_), &v, sizeof(std::uint32_t));
82   current_ += sizeof(v);
83 }
84
85 void BinaryWriter::write_string(const char *s, std::size_t size) {
86   if (current_ + size > end_)
87     throw std::out_of_range{"Write buffer exhausted"};
88
89   memcpy(&(*current_), s, size);
90   current_ += size;
91 }
92
93 void BinaryWriter::write_string_with_size(const std::string &str) {
94   write_string_with_size(str.c_str(), str.length());
95 }
96
97 void BinaryWriter::write_string_with_size(const char *s, std::size_t size) {
98   write_uint16(size);
99   write_string(s, size);
100 }
101
102 std::size_t BinaryWriter::bytes_written() const {
103   return current_ - begin_;
104 }
105 } // namespace common
106 } // namespace anbox