• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/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 
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 
GetVarint32Ptr(const char * p,const char * limit,uint32 * value)136 const char* GetVarint32Ptr(const char* p, const char* limit, uint32* value) {
137   if (p < limit) {
138     uint32 result = *(reinterpret_cast<const unsigned char*>(p));
139     if ((result & 128) == 0) {
140       *value = result;
141       return p + 1;
142     }
143   }
144   return GetVarint32PtrFallback(p, limit, value);
145 }
146 
GetVarint32PtrFallback(const char * p,const char * limit,uint32 * value)147 const char* GetVarint32PtrFallback(const char* p, const char* limit,
148                                    uint32* value) {
149   uint32 result = 0;
150   for (uint32 shift = 0; shift <= 28 && p < limit; shift += 7) {
151     uint32 byte = *(reinterpret_cast<const unsigned char*>(p));
152     p++;
153     if (byte & 128) {
154       // More bytes are present
155       result |= ((byte & 127) << shift);
156     } else {
157       result |= (byte << shift);
158       *value = result;
159       return reinterpret_cast<const char*>(p);
160     }
161   }
162   return nullptr;
163 }
164 
GetVarint32(StringPiece * input,uint32 * value)165 bool GetVarint32(StringPiece* input, uint32* value) {
166   const char* p = input->data();
167   const char* limit = p + input->size();
168   const char* q = GetVarint32Ptr(p, limit, value);
169   if (q == nullptr) {
170     return false;
171   } else {
172     *input = StringPiece(q, limit - q);
173     return true;
174   }
175 }
176 
GetVarint64Ptr(const char * p,const char * limit,uint64 * value)177 const char* GetVarint64Ptr(const char* p, const char* limit, uint64* value) {
178   uint64 result = 0;
179   for (uint32 shift = 0; shift <= 63 && p < limit; shift += 7) {
180     uint64 byte = *(reinterpret_cast<const unsigned char*>(p));
181     p++;
182     if (byte & 128) {
183       // More bytes are present
184       result |= ((byte & 127) << shift);
185     } else {
186       result |= (byte << shift);
187       *value = result;
188       return reinterpret_cast<const char*>(p);
189     }
190   }
191   return nullptr;
192 }
193 
GetVarint64(StringPiece * input,uint64 * value)194 bool GetVarint64(StringPiece* input, uint64* value) {
195   const char* p = input->data();
196   const char* limit = p + input->size();
197   const char* q = GetVarint64Ptr(p, limit, value);
198   if (q == nullptr) {
199     return false;
200   } else {
201     *input = StringPiece(q, limit - q);
202     return true;
203   }
204 }
205 
206 }  // namespace core
207 }  // namespace tensorflow
208