• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2011 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "shill/net/byte_string.h"
18 
19 #include <netinet/in.h>
20 #include <string.h>
21 
22 #include <algorithm>
23 
24 #include <base/strings/string_number_conversions.h>
25 
26 using std::min;
27 using std::string;
28 using std::vector;
29 
30 namespace shill {
31 
ByteString(const ByteString & b)32 ByteString::ByteString(const ByteString& b) {
33   data_ = b.data_;
34 }
35 
operator =(const ByteString & b)36 ByteString& ByteString::operator=(const ByteString& b) {
37   data_ = b.data_;
38   return *this;
39 }
40 
GetData()41 unsigned char* ByteString::GetData() {
42   return (GetLength() == 0) ? nullptr : &data_.front();
43 }
44 
GetConstData() const45 const unsigned char* ByteString::GetConstData() const {
46   return (GetLength() == 0) ? nullptr : &data_.front();
47 }
48 
GetLength() const49 size_t ByteString::GetLength() const {
50   return data_.size();
51 }
52 
GetSubstring(size_t offset,size_t length) const53 ByteString ByteString::GetSubstring(size_t offset, size_t length) const {
54   if (offset > GetLength()) {
55     offset = GetLength();
56   }
57   if (length > GetLength() - offset) {
58     length = GetLength() - offset;
59   }
60   return ByteString(GetConstData() + offset, length);
61 }
62 
63 // static
CreateFromCPUUInt32(uint32_t val)64 ByteString ByteString::CreateFromCPUUInt32(uint32_t val) {
65   return ByteString(reinterpret_cast<unsigned char*>(&val), sizeof(val));
66 }
67 
68 // static
CreateFromNetUInt32(uint32_t val)69 ByteString ByteString::CreateFromNetUInt32(uint32_t val) {
70   return CreateFromCPUUInt32(ntohl(val));
71 }
72 
73 // static
CreateFromHexString(const string & hex_string)74 ByteString ByteString::CreateFromHexString(const string& hex_string) {
75   vector<uint8_t> bytes;
76   if (!base::HexStringToBytes(hex_string, &bytes)) {
77     return ByteString();
78   }
79   return ByteString(&bytes.front(), bytes.size());
80 }
81 
ConvertToCPUUInt32(uint32_t * val) const82 bool ByteString::ConvertToCPUUInt32(uint32_t* val) const {
83   if (val == nullptr || GetLength() != sizeof(*val)) {
84     return false;
85   }
86   memcpy(val, GetConstData(), sizeof(*val));
87 
88   return true;
89 }
90 
ConvertToNetUInt32(uint32_t * val) const91 bool ByteString::ConvertToNetUInt32(uint32_t* val) const {
92   if (!ConvertToCPUUInt32(val)) {
93     return false;
94   }
95   *val = ntohl(*val);
96   return true;
97 }
98 
99 template <typename T>
ConvertByteOrderAsUIntArray(T (* converter)(T))100 bool ByteString::ConvertByteOrderAsUIntArray(T (*converter)(T)) {
101   size_t length = GetLength();
102   if ((length % sizeof(T)) != 0) {
103     return false;
104   }
105   for (auto i = data_.begin(); i != data_.end(); i += sizeof(T)) {
106     // Take care of word alignment.
107     T val;
108     memcpy(&val, &(*i), sizeof(T));
109     val = converter(val);
110     memcpy(&(*i), &val, sizeof(T));
111   }
112   return true;
113 }
114 
ConvertFromNetToCPUUInt32Array()115 bool ByteString::ConvertFromNetToCPUUInt32Array() {
116   return ConvertByteOrderAsUIntArray(ntohl);
117 }
118 
ConvertFromCPUToNetUInt32Array()119 bool ByteString::ConvertFromCPUToNetUInt32Array() {
120   return ConvertByteOrderAsUIntArray(htonl);
121 }
122 
IsZero() const123 bool ByteString::IsZero() const {
124   for (const auto& i : data_) {
125     if (i != 0) {
126       return false;
127     }
128   }
129   return true;
130 }
131 
BitwiseAnd(const ByteString & b)132 bool ByteString::BitwiseAnd(const ByteString& b) {
133   if (GetLength() != b.GetLength()) {
134     return false;
135   }
136   auto lhs = data_.begin();
137   for (const auto& rhs : b.data_) {
138     *lhs++ &= rhs;
139   }
140   return true;
141 }
142 
BitwiseOr(const ByteString & b)143 bool ByteString::BitwiseOr(const ByteString& b) {
144   if (GetLength() != b.GetLength()) {
145     return false;
146   }
147   auto lhs = data_.begin();
148   for (const auto& rhs : b.data_) {
149     *lhs++ |= rhs;
150   }
151   return true;
152 }
153 
BitwiseInvert()154 void ByteString::BitwiseInvert() {
155   for (auto& i : data_) {
156     i = ~i;
157   }
158 }
159 
Equals(const ByteString & b) const160 bool ByteString::Equals(const ByteString& b) const {
161   if (GetLength() != b.GetLength()) {
162     return false;
163   }
164   auto lhs = data_.begin();
165   for (const auto& rhs : b.data_) {
166     if (*lhs++ != rhs) {
167       return false;
168     }
169   }
170   return true;
171 }
172 
Append(const ByteString & b)173 void ByteString::Append(const ByteString& b) {
174   data_.insert(data_.end(), b.data_.begin(), b.data_.end());
175 }
176 
Clear()177 void ByteString::Clear() {
178   data_.clear();
179 }
180 
Resize(int size)181 void ByteString::Resize(int size) {
182   data_.resize(size, 0);
183 }
184 
HexEncode() const185 string ByteString::HexEncode() const {
186   return base::HexEncode(GetConstData(), GetLength());
187 }
188 
CopyData(size_t size,void * output) const189 bool ByteString::CopyData(size_t size, void* output) const {
190   if (output == nullptr || GetLength() < size) {
191     return false;
192   }
193   memcpy(output, GetConstData(), size);
194   return true;
195 }
196 
197 // static
IsLessThan(const ByteString & lhs,const ByteString & rhs)198 bool ByteString::IsLessThan(const ByteString& lhs, const ByteString& rhs) {
199   size_t byte_count = min(lhs.GetLength(), rhs.GetLength());
200   int result = memcmp(lhs.GetConstData(), rhs.GetConstData(), byte_count);
201   if (result == 0) {
202     return lhs.GetLength() < rhs.GetLength();
203   }
204   return result < 0;
205 }
206 
207 }  // namespace shill
208