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/writable_font_data.h"
     18 
     19 #include <algorithm>
     20 #include <limits>
     21 
     22 #include "sfntly/data/memory_byte_array.h"
     23 #include "sfntly/data/growable_memory_byte_array.h"
     24 
     25 namespace sfntly {
     26 
     27 WritableFontData::WritableFontData(ByteArray* ba) : ReadableFontData(ba) {
     28 }
     29 
     30 WritableFontData::~WritableFontData() {}
     31 
     32 // static
     33 CALLER_ATTACH
     34 WritableFontData* WritableFontData::CreateWritableFontData(int32_t length) {
     35   ByteArrayPtr ba;
     36   if (length > 0) {
     37     ba = new MemoryByteArray(length);
     38     ba->SetFilledLength(length);
     39   } else {
     40     ba = new GrowableMemoryByteArray();
     41   }
     42   WritableFontDataPtr wfd = new WritableFontData(ba);
     43   return wfd.Detach();
     44 }
     45 
     46 // TODO(arthurhsu): re-investigate the memory model of this function.  It's
     47 //                  not too useful without copying, but it's not performance
     48 //                  savvy to do copying.
     49 CALLER_ATTACH
     50 WritableFontData* WritableFontData::CreateWritableFontData(ByteVector* b) {
     51   ByteArrayPtr ba = new GrowableMemoryByteArray();
     52   ba->Put(0, b);
     53   WritableFontDataPtr wfd = new WritableFontData(ba);
     54   return wfd.Detach();
     55 }
     56 
     57 int32_t WritableFontData::WriteByte(int32_t index, byte_t b) {
     58   array_->Put(BoundOffset(index), b);
     59   return 1;
     60 }
     61 
     62 int32_t WritableFontData::WriteBytes(int32_t index,
     63                                      byte_t* b,
     64                                      int32_t offset,
     65                                      int32_t length) {
     66   return array_->Put(BoundOffset(index),
     67                      b,
     68                      offset,
     69                      BoundLength(index, length));
     70 }
     71 
     72 int32_t WritableFontData::WriteBytes(int32_t index, ByteVector* b) {
     73   assert(b);
     74   return WriteBytes(index, &((*b)[0]), 0, b->size());
     75 }
     76 
     77 int32_t WritableFontData::WriteBytesPad(int32_t index,
     78                                         ByteVector* b,
     79                                         int32_t offset,
     80                                         int32_t length,
     81                                         byte_t pad) {
     82   int32_t written =
     83       array_->Put(BoundOffset(index),
     84                   &((*b)[0]),
     85                   offset,
     86                   BoundLength(index,
     87                               std::min<int32_t>(length, b->size() - offset)));
     88   written += WritePadding(written + index, length - written, pad);
     89   return written;
     90 }
     91 
     92 int32_t WritableFontData::WritePadding(int32_t index, int32_t count) {
     93   return WritePadding(index, count, (byte_t)0);
     94 }
     95 
     96 int32_t WritableFontData::WritePadding(int32_t index, int32_t count,
     97                                        byte_t pad) {
     98   for (int32_t i = 0; i < count; ++i) {
     99     array_->Put(index + i, pad);
    100   }
    101   return count;
    102 }
    103 
    104 int32_t WritableFontData::WriteChar(int32_t index, byte_t c) {
    105   return WriteByte(index, c);
    106 }
    107 
    108 int32_t WritableFontData::WriteUShort(int32_t index, int32_t us) {
    109   WriteByte(index, (byte_t)((us >> 8) & 0xff));
    110   WriteByte(index + 1, (byte_t)(us & 0xff));
    111   return 2;
    112 }
    113 
    114 int32_t WritableFontData::WriteUShortLE(int32_t index, int32_t us) {
    115   WriteByte(index, (byte_t)(us & 0xff));
    116   WriteByte(index + 1, (byte_t)((us >> 8) & 0xff));
    117   return 2;
    118 }
    119 
    120 int32_t WritableFontData::WriteShort(int32_t index, int32_t s) {
    121   return WriteUShort(index, s);
    122 }
    123 
    124 int32_t WritableFontData::WriteUInt24(int32_t index, int32_t ui) {
    125   WriteByte(index, (byte_t)((ui >> 16) & 0xff));
    126   WriteByte(index + 1, (byte_t)((ui >> 8) & 0xff));
    127   WriteByte(index + 2, (byte_t)(ui & 0xff));
    128   return 3;
    129 }
    130 
    131 int32_t WritableFontData::WriteULong(int32_t index, int64_t ul) {
    132   WriteByte(index, (byte_t)((ul >> 24) & 0xff));
    133   WriteByte(index + 1, (byte_t)((ul >> 16) & 0xff));
    134   WriteByte(index + 2, (byte_t)((ul >> 8) & 0xff));
    135   WriteByte(index + 3, (byte_t)(ul & 0xff));
    136   return 4;
    137 }
    138 
    139 int32_t WritableFontData::WriteULongLE(int32_t index, int64_t ul) {
    140   WriteByte(index, (byte_t)(ul & 0xff));
    141   WriteByte(index + 1, (byte_t)((ul >> 8) & 0xff));
    142   WriteByte(index + 2, (byte_t)((ul >> 16) & 0xff));
    143   WriteByte(index + 3, (byte_t)((ul >> 24) & 0xff));
    144   return 4;
    145 }
    146 
    147 int32_t WritableFontData::WriteLong(int32_t index, int64_t l) {
    148   return WriteULong(index, l);
    149 }
    150 
    151 int32_t WritableFontData::WriteFixed(int32_t index, int32_t f) {
    152   return WriteLong(index, f);
    153 }
    154 
    155 int32_t WritableFontData::WriteDateTime(int32_t index, int64_t date) {
    156   WriteULong(index, (date >> 32) & 0xffffffff);
    157   WriteULong(index + 4, date & 0xffffffff);
    158   return 8;
    159 }
    160 
    161 void WritableFontData::CopyFrom(InputStream* is, int32_t length) {
    162   array_->CopyFrom(is, length);
    163 }
    164 
    165 void WritableFontData::CopyFrom(InputStream* is) {
    166   array_->CopyFrom(is);
    167 }
    168 
    169 CALLER_ATTACH FontData* WritableFontData::Slice(int32_t offset,
    170                                                 int32_t length) {
    171   if (offset < 0 || length < 0 ||
    172       offset > std::numeric_limits<int32_t>::max() - length ||
    173       offset + length > Size()) {
    174 #if !defined (SFNTLY_NO_EXCEPTION)
    175     throw IndexOutOfBoundsException(
    176         "Attempt to bind data outside of its limits");
    177 #endif
    178     return NULL;
    179   }
    180   FontDataPtr slice = new WritableFontData(this, offset, length);
    181   return slice.Detach();
    182 }
    183 
    184 CALLER_ATTACH FontData* WritableFontData::Slice(int32_t offset) {
    185   if (offset < 0 || offset > Size()) {
    186 #if !defined (SFNTLY_NO_EXCEPTION)
    187     throw IndexOutOfBoundsException(
    188         "Attempt to bind data outside of its limits");
    189 #endif
    190     return NULL;
    191   }
    192   FontDataPtr slice = new WritableFontData(this, offset);
    193   return slice.Detach();
    194 }
    195 
    196 WritableFontData::WritableFontData(WritableFontData* data, int32_t offset)
    197     : ReadableFontData(data, offset) {
    198 }
    199 
    200 WritableFontData::WritableFontData(WritableFontData* data,
    201                                    int32_t offset,
    202                                    int32_t length)
    203     : ReadableFontData(data, offset, length) {
    204 }
    205 
    206 }  // namespace sfntly
    207