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 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 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 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 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 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 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 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 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 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