Home | History | Annotate | Download | only in data
      1 /*
      2  * Copyright 2011 Google Inc. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "sfntly/data/byte_array.h"
     18 
     19 #include <algorithm>
     20 
     21 #include "sfntly/port/exception_type.h"
     22 
     23 namespace sfntly {
     24 
     25 const int32_t ByteArray::COPY_BUFFER_SIZE = 8192;
     26 
     27 ByteArray::~ByteArray() {}
     28 
     29 int32_t ByteArray::Length() { return filled_length_; }
     30 int32_t ByteArray::Size() { return storage_length_; }
     31 
     32 int32_t ByteArray::SetFilledLength(int32_t filled_length) {
     33   filled_length_ = std::min<int32_t>(filled_length, storage_length_);
     34   return filled_length_;
     35 }
     36 
     37 int32_t ByteArray::Get(int32_t index) {
     38   if (index < 0 || index >= Length())
     39     return -1;
     40   return InternalGet(index) & 0xff;
     41 }
     42 
     43 int32_t ByteArray::Get(int32_t index, ByteVector* b) {
     44   assert(b);
     45   return Get(index, &((*b)[0]), 0, b->size());
     46 }
     47 
     48 int32_t ByteArray::Get(int32_t index,
     49                        byte_t* b,
     50                        int32_t offset,
     51                        int32_t length) {
     52   assert(b);
     53   if (index < 0 || index >= filled_length_) {
     54     return 0;
     55   }
     56   int32_t actual_length = std::min<int32_t>(length, filled_length_ - index);
     57   return InternalGet(index, b, offset, actual_length);
     58 }
     59 
     60 void ByteArray::Put(int32_t index, byte_t b) {
     61   if (index < 0 || index >= Size()) {
     62 #if defined (SFNTLY_NO_EXCEPTION)
     63     return;
     64 #else
     65     throw IndexOutOfBoundException(
     66         "Attempt to write outside the bounds of the data");
     67 #endif
     68   }
     69   InternalPut(index, b);
     70   filled_length_ = std::max<int32_t>(filled_length_, index + 1);
     71 }
     72 
     73 int32_t ByteArray::Put(int index, ByteVector* b) {
     74   assert(b);
     75   return Put(index, &((*b)[0]), 0, b->size());
     76 }
     77 
     78 int32_t ByteArray::Put(int32_t index,
     79                        byte_t* b,
     80                        int32_t offset,
     81                        int32_t length) {
     82   assert(b);
     83   if (index < 0 || index >= Size()) {
     84 #if defined (SFNTLY_NO_EXCEPTION)
     85     return 0;
     86 #else
     87     throw IndexOutOfBoundException(
     88         "Attempt to write outside the bounds of the data");
     89 #endif
     90   }
     91   int32_t actual_length = std::min<int32_t>(length, Size() - index);
     92   int32_t bytes_written = InternalPut(index, b, offset, actual_length);
     93   filled_length_ = std::max<int32_t>(filled_length_, index + bytes_written);
     94   return bytes_written;
     95 }
     96 
     97 int32_t ByteArray::CopyTo(ByteArray* array) {
     98   return CopyTo(array, 0, Length());
     99 }
    100 
    101 int32_t ByteArray::CopyTo(ByteArray* array, int32_t offset, int32_t length) {
    102   return CopyTo(0, array, offset, length);
    103 }
    104 
    105 int32_t ByteArray::CopyTo(int32_t dst_offset, ByteArray* array,
    106                           int32_t src_offset, int32_t length) {
    107   assert(array);
    108   if (array->Size() < dst_offset + length) {  // insufficient space
    109     return -1;
    110   }
    111 
    112   ByteVector b(COPY_BUFFER_SIZE);
    113   int32_t bytes_read = 0;
    114   int32_t index = 0;
    115   int32_t remaining_length = length;
    116   int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
    117   while ((bytes_read =
    118               Get(index + src_offset, &(b[0]), 0, buffer_length)) > 0) {
    119     int bytes_written = array->Put(index + dst_offset, &(b[0]), 0, bytes_read);
    120     UNREFERENCED_PARAMETER(bytes_written);
    121     index += bytes_read;
    122     remaining_length -= bytes_read;
    123     buffer_length = std::min<int32_t>(b.size(), remaining_length);
    124   }
    125   return index;
    126 }
    127 
    128 int32_t ByteArray::CopyTo(OutputStream* os) {
    129     return CopyTo(os, 0, Length());
    130 }
    131 
    132 int32_t ByteArray::CopyTo(OutputStream* os, int32_t offset, int32_t length) {
    133   ByteVector b(COPY_BUFFER_SIZE);
    134   int32_t bytes_read = 0;
    135   int32_t index = 0;
    136   int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
    137   while ((bytes_read = Get(index + offset, &(b[0]), 0, buffer_length)) > 0) {
    138     os->Write(&b, 0, bytes_read);
    139     index += bytes_read;
    140     buffer_length = std::min<int32_t>(b.size(), length - index);
    141   }
    142   return index;
    143 }
    144 
    145 bool ByteArray::CopyFrom(InputStream* is, int32_t length) {
    146   ByteVector b(COPY_BUFFER_SIZE);
    147   int32_t bytes_read = 0;
    148   int32_t index = 0;
    149   int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
    150   while ((bytes_read = is->Read(&b, 0, buffer_length)) > 0) {
    151     if (Put(index, &(b[0]), 0, bytes_read) != bytes_read) {
    152 #if defined (SFNTLY_NO_EXCEPTION)
    153       return 0;
    154 #else
    155       throw IOException("Error writing bytes.");
    156 #endif
    157     }
    158     index += bytes_read;
    159     length -= bytes_read;
    160     buffer_length = std::min<int32_t>(b.size(), length);
    161   }
    162   return true;
    163 }
    164 
    165 bool ByteArray::CopyFrom(InputStream* is) {
    166   ByteVector b(COPY_BUFFER_SIZE);
    167   int32_t bytes_read = 0;
    168   int32_t index = 0;
    169   int32_t buffer_length = COPY_BUFFER_SIZE;
    170   while ((bytes_read = is->Read(&b, 0, buffer_length)) > 0) {
    171     if (Put(index, &b[0], 0, bytes_read) != bytes_read) {
    172 #if defined (SFNTLY_NO_EXCEPTION)
    173       return 0;
    174 #else
    175       throw IOException("Error writing bytes.");
    176 #endif
    177     }
    178     index += bytes_read;
    179   }
    180   return true;
    181 }
    182 
    183 ByteArray::ByteArray(int32_t filled_length,
    184                      int32_t storage_length,
    185                      bool growable) {
    186   Init(filled_length, storage_length, growable);
    187 }
    188 
    189 ByteArray::ByteArray(int32_t filled_length, int32_t storage_length) {
    190   Init(filled_length, storage_length, false);
    191 }
    192 
    193 void ByteArray::Init(int32_t filled_length,
    194                      int32_t storage_length,
    195                      bool growable) {
    196   storage_length_ = storage_length;
    197   growable_ = growable;
    198   SetFilledLength(filled_length);
    199 }
    200 
    201 }  // namespace sfntly
    202