Home | History | Annotate | Download | only in core
      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 
     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* 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 
    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 
    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 
    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