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/lib/core/coding.h"
17
18 #include "tensorflow/core/platform/cpu_info.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
EncodeVarint64(char * dst,uint64 v)110 char* EncodeVarint64(char* dst, uint64 v) {
111 static const int B = 128;
112 unsigned char* ptr = reinterpret_cast<unsigned char*>(dst);
113 while (v >= B) {
114 *(ptr++) = (v & (B - 1)) | B;
115 v >>= 7;
116 }
117 *(ptr++) = static_cast<unsigned char>(v);
118 return reinterpret_cast<char*>(ptr);
119 }
120
PutVarint64(string * dst,uint64 v)121 void PutVarint64(string* dst, uint64 v) {
122 char buf[10];
123 char* ptr = EncodeVarint64(buf, v);
124 dst->append(buf, ptr - buf);
125 }
126
VarintLength(uint64_t v)127 int VarintLength(uint64_t v) {
128 int len = 1;
129 while (v >= 128) {
130 v >>= 7;
131 len++;
132 }
133 return len;
134 }
135
GetVarint32PtrFallback(const char * p,const char * limit,uint32 * value)136 const char* GetVarint32PtrFallback(const char* p, const char* limit,
137 uint32* value) {
138 uint32 result = 0;
139 for (uint32 shift = 0; shift <= 28 && p < limit; shift += 7) {
140 uint32 byte = *(reinterpret_cast<const unsigned char*>(p));
141 p++;
142 if (byte & 128) {
143 // More bytes are present
144 result |= ((byte & 127) << shift);
145 } else {
146 result |= (byte << shift);
147 *value = result;
148 return reinterpret_cast<const char*>(p);
149 }
150 }
151 return nullptr;
152 }
153
GetVarint32(StringPiece * input,uint32 * value)154 bool GetVarint32(StringPiece* input, uint32* value) {
155 const char* p = input->data();
156 const char* limit = p + input->size();
157 const char* q = GetVarint32Ptr(p, limit, value);
158 if (q == nullptr) {
159 return false;
160 } else {
161 *input = StringPiece(q, limit - q);
162 return true;
163 }
164 }
165
GetVarint64Ptr(const char * p,const char * limit,uint64 * value)166 const char* GetVarint64Ptr(const char* p, const char* limit, uint64* value) {
167 uint64 result = 0;
168 for (uint32 shift = 0; shift <= 63 && p < limit; shift += 7) {
169 uint64 byte = *(reinterpret_cast<const unsigned char*>(p));
170 p++;
171 if (byte & 128) {
172 // More bytes are present
173 result |= ((byte & 127) << shift);
174 } else {
175 result |= (byte << shift);
176 *value = result;
177 return reinterpret_cast<const char*>(p);
178 }
179 }
180 return nullptr;
181 }
182
GetVarint64(StringPiece * input,uint64 * value)183 bool GetVarint64(StringPiece* input, uint64* value) {
184 const char* p = input->data();
185 const char* limit = p + input->size();
186 const char* q = GetVarint64Ptr(p, limit, value);
187 if (q == nullptr) {
188 return false;
189 } else {
190 *input = StringPiece(q, limit - q);
191 return true;
192 }
193 }
194
195 } // namespace core
196 } // namespace tensorflow
197