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/tsl/platform/coding.h" |
17 | |
18 | #include "tensorflow/tsl/platform/byte_order.h" |
19 | |
20 | namespace tsl { |
21 | namespace core { |
22 | |
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 | |
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 | |
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 | |
58 | void PutFixed16(string* dst, uint16 value) { |
59 | char buf[sizeof(value)]; |
60 | EncodeFixed16(buf, value); |
61 | dst->append(buf, sizeof(buf)); |
62 | } |
63 | |
64 | void PutFixed32(string* dst, uint32 value) { |
65 | char buf[sizeof(value)]; |
66 | EncodeFixed32(buf, value); |
67 | dst->append(buf, sizeof(buf)); |
68 | } |
69 | |
70 | void PutFixed64(string* dst, uint64 value) { |
71 | char buf[sizeof(value)]; |
72 | EncodeFixed64(buf, value); |
73 | dst->append(buf, sizeof(buf)); |
74 | } |
75 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 tsl |
220 | |