• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/big_endian.h"
6 
7 #include <string.h>
8 
9 #include "base/numerics/checked_math.h"
10 #include "base/strings/string_piece.h"
11 
12 namespace base {
13 
FromStringPiece(base::StringPiece string_piece)14 BigEndianReader BigEndianReader::FromStringPiece(
15     base::StringPiece string_piece) {
16   return BigEndianReader(base::as_bytes(base::make_span(string_piece)));
17 }
18 
BigEndianReader(const uint8_t * buf,size_t len)19 BigEndianReader::BigEndianReader(const uint8_t* buf, size_t len)
20     : ptr_(buf), end_(ptr_ + len) {
21   // Ensure `len` does not cause `end_` to wrap around.
22   CHECK_GE(end_, ptr_);
23 }
24 
BigEndianReader(base::span<const uint8_t> buf)25 BigEndianReader::BigEndianReader(base::span<const uint8_t> buf)
26     : ptr_(buf.data()), end_(buf.data() + buf.size()) {}
27 
Skip(size_t len)28 bool BigEndianReader::Skip(size_t len) {
29   if (len > remaining())
30     return false;
31   ptr_ += len;
32   return true;
33 }
34 
ReadBytes(void * out,size_t len)35 bool BigEndianReader::ReadBytes(void* out, size_t len) {
36   if (len > remaining())
37     return false;
38   memcpy(out, ptr_, len);
39   ptr_ += len;
40   return true;
41 }
42 
ReadPiece(base::StringPiece * out,size_t len)43 bool BigEndianReader::ReadPiece(base::StringPiece* out, size_t len) {
44   if (len > remaining())
45     return false;
46   *out = base::StringPiece(reinterpret_cast<const char*>(ptr_), len);
47   ptr_ += len;
48   return true;
49 }
50 
ReadSpan(base::span<const uint8_t> * out,size_t len)51 bool BigEndianReader::ReadSpan(base::span<const uint8_t>* out, size_t len) {
52   if (len > remaining())
53     return false;
54   *out = base::make_span(ptr_, len);
55   ptr_ += len;
56   return true;
57 }
58 
59 template<typename T>
Read(T * value)60 bool BigEndianReader::Read(T* value) {
61   if (sizeof(T) > remaining())
62     return false;
63   ReadBigEndian<T>(ptr_, value);
64   ptr_ += sizeof(T);
65   return true;
66 }
67 
ReadU8(uint8_t * value)68 bool BigEndianReader::ReadU8(uint8_t* value) {
69   return Read(value);
70 }
71 
ReadU16(uint16_t * value)72 bool BigEndianReader::ReadU16(uint16_t* value) {
73   return Read(value);
74 }
75 
ReadU32(uint32_t * value)76 bool BigEndianReader::ReadU32(uint32_t* value) {
77   return Read(value);
78 }
79 
ReadU64(uint64_t * value)80 bool BigEndianReader::ReadU64(uint64_t* value) {
81   return Read(value);
82 }
83 
84 template <typename T>
ReadLengthPrefixed(base::StringPiece * out)85 bool BigEndianReader::ReadLengthPrefixed(base::StringPiece* out) {
86   T t_len;
87   if (!Read(&t_len))
88     return false;
89   size_t len = strict_cast<size_t>(t_len);
90   const uint8_t* original_ptr = ptr_;
91   if (!Skip(len)) {
92     ptr_ -= sizeof(T);
93     return false;
94   }
95   *out = base::StringPiece(reinterpret_cast<const char*>(original_ptr), len);
96   return true;
97 }
98 
ReadU8LengthPrefixed(base::StringPiece * out)99 bool BigEndianReader::ReadU8LengthPrefixed(base::StringPiece* out) {
100   return ReadLengthPrefixed<uint8_t>(out);
101 }
102 
ReadU16LengthPrefixed(base::StringPiece * out)103 bool BigEndianReader::ReadU16LengthPrefixed(base::StringPiece* out) {
104   return ReadLengthPrefixed<uint16_t>(out);
105 }
106 
BigEndianWriter(char * buf,size_t len)107 BigEndianWriter::BigEndianWriter(char* buf, size_t len)
108     : ptr_(buf), end_(ptr_ + len) {
109   // Ensure `len` does not cause `end_` to wrap around.
110   CHECK_GE(end_, ptr_);
111 }
112 
Skip(size_t len)113 bool BigEndianWriter::Skip(size_t len) {
114   if (len > remaining())
115     return false;
116   ptr_ += len;
117   return true;
118 }
119 
WriteBytes(const void * buf,size_t len)120 bool BigEndianWriter::WriteBytes(const void* buf, size_t len) {
121   if (len > remaining())
122     return false;
123   memcpy(ptr_, buf, len);
124   ptr_ += len;
125   return true;
126 }
127 
128 template<typename T>
Write(T value)129 bool BigEndianWriter::Write(T value) {
130   if (sizeof(T) > remaining())
131     return false;
132   WriteBigEndian<T>(ptr_, value);
133   ptr_ += sizeof(T);
134   return true;
135 }
136 
WriteU8(uint8_t value)137 bool BigEndianWriter::WriteU8(uint8_t value) {
138   return Write(value);
139 }
140 
WriteU16(uint16_t value)141 bool BigEndianWriter::WriteU16(uint16_t value) {
142   return Write(value);
143 }
144 
WriteU32(uint32_t value)145 bool BigEndianWriter::WriteU32(uint32_t value) {
146   return Write(value);
147 }
148 
WriteU64(uint64_t value)149 bool BigEndianWriter::WriteU64(uint64_t value) {
150   return Write(value);
151 }
152 
153 }  // namespace base
154