1/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9Unless required by applicable law or agreed to in writing, software
10distributed under the License is distributed on an "AS IS" BASIS,
11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12See the License for the specific language governing permissions and
13limitations under the License.
14==============================================================================*/
15
16#include "tensorflow/tsl/platform/coding.h"
17
18#include "tensorflow/tsl/platform/byte_order.h"
19
20namespace tsl {
21namespace core {
22
23void 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
32void 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
43void 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
58void PutFixed16(string* dst, uint16 value) {
59 char buf[sizeof(value)];
60 EncodeFixed16(buf, value);
61 dst->append(buf, sizeof(buf));
62}
63
64void PutFixed32(string* dst, uint32 value) {
65 char buf[sizeof(value)];
66 EncodeFixed32(buf, value);
67 dst->append(buf, sizeof(buf));
68}
69
70void PutFixed64(string* dst, uint64 value) {
71 char buf[sizeof(value)];
72 EncodeFixed64(buf, value);
73 dst->append(buf, sizeof(buf));
74}
75
76char* 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
104void PutVarint32(string* dst, uint32 v) {
105 char buf[5];
106 char* ptr = EncodeVarint32(buf, v);
107 dst->append(buf, ptr - buf);
108}
109
110void PutVarint32(tstring* dst, uint32 v) {
111 char buf[5];
112 char* ptr = EncodeVarint32(buf, v);
113 dst->append(buf, ptr - buf);
114}
115
116char* 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
127void PutVarint64(string* dst, uint64 v) {
128 char buf[10];
129 char* ptr = EncodeVarint64(buf, v);
130 dst->append(buf, ptr - buf);
131}
132
133void PutVarint64(tstring* dst, uint64 v) {
134 char buf[10];
135 char* ptr = EncodeVarint64(buf, v);
136 dst->append(buf, ptr - buf);
137}
138
139int VarintLength(uint64_t v) {
140 int len = 1;
141 while (v >= 128) {
142 v >>= 7;
143 len++;
144 }
145 return len;
146}
147
148const 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
159const 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
177bool 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
189const 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
206bool 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 tsl
220