1 /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15
16 #include "tensorflow/core/platform/coding.h"
17
18 #include "tensorflow/core/platform/byte_order.h"
19
20 namespace tensorflow {
21 namespace core {
22
EncodeFixed16(char * buf,uint16 value)23 void EncodeFixed16(char* buf, uint16 value) {
24 if (port::kLittleEndian) {
25 memcpy(buf, &value, sizeof(value));
26 } else {
27 buf[0] = value & 0xff;
28 buf[1] = (value >> 8) & 0xff;
29 }
30 }
31
EncodeFixed32(char * buf,uint32 value)32 void EncodeFixed32(char* buf, uint32 value) {
33 if (port::kLittleEndian) {
34 memcpy(buf, &value, sizeof(value));
35 } else {
36 buf[0] = value & 0xff;
37 buf[1] = (value >> 8) & 0xff;
38 buf[2] = (value >> 16) & 0xff;
39 buf[3] = (value >> 24) & 0xff;
40 }
41 }
42
EncodeFixed64(char * buf,uint64 value)43 void EncodeFixed64(char* buf, uint64 value) {
44 if (port::kLittleEndian) {
45 memcpy(buf, &value, sizeof(value));
46 } else {
47 buf[0] = value & 0xff;
48 buf[1] = (value >> 8) & 0xff;
49 buf[2] = (value >> 16) & 0xff;
50 buf[3] = (value >> 24) & 0xff;
51 buf[4] = (value >> 32) & 0xff;
52 buf[5] = (value >> 40) & 0xff;
53 buf[6] = (value >> 48) & 0xff;
54 buf[7] = (value >> 56) & 0xff;
55 }
56 }
57
PutFixed16(string * dst,uint16 value)58 void PutFixed16(string* dst, uint16 value) {
59 char buf[sizeof(value)];
60 EncodeFixed16(buf, value);
61 dst->append(buf, sizeof(buf));
62 }
63
PutFixed32(string * dst,uint32 value)64 void PutFixed32(string* dst, uint32 value) {
65 char buf[sizeof(value)];
66 EncodeFixed32(buf, value);
67 dst->append(buf, sizeof(buf));
68 }
69
PutFixed64(string * dst,uint64 value)70 void PutFixed64(string* dst, uint64 value) {
71 char buf[sizeof(value)];
72 EncodeFixed64(buf, value);
73 dst->append(buf, sizeof(buf));
74 }
75
EncodeVarint32(char * dst,uint32 v)76 char* EncodeVarint32(char* dst, uint32 v) {
77 // Operate on characters as unsigneds
78 unsigned char* ptr = reinterpret_cast<unsigned char*>(dst);
79 static const int B = 128;
80 if (v < (1 << 7)) {
81 *(ptr++) = v;
82 } else if (v < (1 << 14)) {
83 *(ptr++) = v | B;
84 *(ptr++) = v >> 7;
85 } else if (v < (1 << 21)) {
86 *(ptr++) = v | B;
87 *(ptr++) = (v >> 7) | B;
88 *(ptr++) = v >> 14;
89 } else if (v < (1 << 28)) {
90 *(ptr++) = v | B;
91 *(ptr++) = (v >> 7) | B;
92 *(ptr++) = (v >> 14) | B;
93 *(ptr++) = v >> 21;
94 } else {
95 *(ptr++) = v | B;
96 *(ptr++) = (v >> 7) | B;
97 *(ptr++) = (v >> 14) | B;
98 *(ptr++) = (v >> 21) | B;
99 *(ptr++) = v >> 28;
100 }
101 return reinterpret_cast<char*>(ptr);
102 }
103
PutVarint32(string * dst,uint32 v)104 void PutVarint32(string* dst, uint32 v) {
105 char buf[5];
106 char* ptr = EncodeVarint32(buf, v);
107 dst->append(buf, ptr - buf);
108 }
109
PutVarint32(tstring * dst,uint32 v)110 void PutVarint32(tstring* dst, uint32 v) {
111 char buf[5];
112 char* ptr = EncodeVarint32(buf, v);
113 dst->append(buf, ptr - buf);
114 }
115
EncodeVarint64(char * dst,uint64 v)116 char* EncodeVarint64(char* dst, uint64 v) {
117 static const int B = 128;
118 unsigned char* ptr = reinterpret_cast<unsigned char*>(dst);
119 while (v >= B) {
120 *(ptr++) = (v & (B - 1)) | B;
121 v >>= 7;
122 }
123 *(ptr++) = static_cast<unsigned char>(v);
124 return reinterpret_cast<char*>(ptr);
125 }
126
PutVarint64(string * dst,uint64 v)127 void PutVarint64(string* dst, uint64 v) {
128 char buf[10];
129 char* ptr = EncodeVarint64(buf, v);
130 dst->append(buf, ptr - buf);
131 }
132
PutVarint64(tstring * dst,uint64 v)133 void PutVarint64(tstring* dst, uint64 v) {
134 char buf[10];
135 char* ptr = EncodeVarint64(buf, v);
136 dst->append(buf, ptr - buf);
137 }
138
VarintLength(uint64_t v)139 int VarintLength(uint64_t v) {
140 int len = 1;
141 while (v >= 128) {
142 v >>= 7;
143 len++;
144 }
145 return len;
146 }
147
GetVarint32Ptr(const char * p,const char * limit,uint32 * value)148 const char* GetVarint32Ptr(const char* p, const char* limit, uint32* value) {
149 if (p < limit) {
150 uint32 result = *(reinterpret_cast<const unsigned char*>(p));
151 if ((result & 128) == 0) {
152 *value = result;
153 return p + 1;
154 }
155 }
156 return GetVarint32PtrFallback(p, limit, value);
157 }
158
GetVarint32PtrFallback(const char * p,const char * limit,uint32 * value)159 const char* GetVarint32PtrFallback(const char* p, const char* limit,
160 uint32* value) {
161 uint32 result = 0;
162 for (uint32 shift = 0; shift <= 28 && p < limit; shift += 7) {
163 uint32 byte = *(reinterpret_cast<const unsigned char*>(p));
164 p++;
165 if (byte & 128) {
166 // More bytes are present
167 result |= ((byte & 127) << shift);
168 } else {
169 result |= (byte << shift);
170 *value = result;
171 return reinterpret_cast<const char*>(p);
172 }
173 }
174 return nullptr;
175 }
176
GetVarint32(StringPiece * input,uint32 * value)177 bool GetVarint32(StringPiece* input, uint32* value) {
178 const char* p = input->data();
179 const char* limit = p + input->size();
180 const char* q = GetVarint32Ptr(p, limit, value);
181 if (q == nullptr) {
182 return false;
183 } else {
184 *input = StringPiece(q, limit - q);
185 return true;
186 }
187 }
188
GetVarint64Ptr(const char * p,const char * limit,uint64 * value)189 const char* GetVarint64Ptr(const char* p, const char* limit, uint64* value) {
190 uint64 result = 0;
191 for (uint32 shift = 0; shift <= 63 && p < limit; shift += 7) {
192 uint64 byte = *(reinterpret_cast<const unsigned char*>(p));
193 p++;
194 if (byte & 128) {
195 // More bytes are present
196 result |= ((byte & 127) << shift);
197 } else {
198 result |= (byte << shift);
199 *value = result;
200 return reinterpret_cast<const char*>(p);
201 }
202 }
203 return nullptr;
204 }
205
GetVarint64(StringPiece * input,uint64 * value)206 bool GetVarint64(StringPiece* input, uint64* value) {
207 const char* p = input->data();
208 const char* limit = p + input->size();
209 const char* q = GetVarint64Ptr(p, limit, value);
210 if (q == nullptr) {
211 return false;
212 } else {
213 *input = StringPiece(q, limit - q);
214 return true;
215 }
216 }
217
218 } // namespace core
219 } // namespace tensorflow
220