LCOV - code coverage report
Current view: top level - gfx/sfntly/cpp/src/sfntly/data - readable_font_data.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 214 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 37 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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/readable_font_data.h"
      18             : 
      19             : #include <stdio.h>
      20             : 
      21             : #include <limits>
      22             : 
      23             : #include "sfntly/data/memory_byte_array.h"
      24             : #include "sfntly/data/writable_font_data.h"
      25             : #include "sfntly/port/exception_type.h"
      26             : 
      27             : namespace sfntly {
      28             : 
      29           0 : ReadableFontData::ReadableFontData(ByteArray* array)
      30             :     : FontData(array),
      31             :       checksum_set_(false),
      32           0 :       checksum_(0) {
      33           0 : }
      34             : 
      35           0 : ReadableFontData::~ReadableFontData() {}
      36             : 
      37             : // TODO(arthurhsu): re-investigate the memory model of this function.  It's
      38             : //                  not too useful without copying, but it's not performance
      39             : //                  savvy to do copying.
      40             : CALLER_ATTACH
      41           0 : ReadableFontData* ReadableFontData::CreateReadableFontData(ByteVector* b) {
      42           0 :   assert(b);
      43           0 :   ByteArrayPtr ba = new MemoryByteArray(b->size());
      44           0 :   ba->Put(0, b);
      45           0 :   ReadableFontDataPtr wfd = new ReadableFontData(ba);
      46           0 :   return wfd.Detach();
      47             : }
      48             : 
      49           0 : int64_t ReadableFontData::Checksum() {
      50           0 :   AutoLock lock(checksum_lock_);
      51           0 :   if (!checksum_set_) {
      52           0 :     ComputeChecksum();
      53             :   }
      54           0 :   return checksum_;
      55             : }
      56             : 
      57           0 : void ReadableFontData::SetCheckSumRanges(const IntegerList& ranges) {
      58           0 :   checksum_range_ = ranges;
      59           0 :   checksum_set_ = false;  // UNIMPLEMENTED: atomicity
      60           0 : }
      61             : 
      62           0 : int32_t ReadableFontData::ReadUByte(int32_t index) {
      63           0 :   int32_t b = array_->Get(BoundOffset(index));
      64           0 :   if (b < 0) {
      65             : #if !defined (SFNTLY_NO_EXCEPTION)
      66             :     throw IndexOutOfBoundException(
      67             :         "Index attempted to be read from is out of bounds", index);
      68             : #endif
      69           0 :     return kInvalidUnsigned;
      70             :   }
      71           0 :   return b;
      72             : }
      73             : 
      74           0 : int32_t ReadableFontData::ReadByte(int32_t index) {
      75           0 :   int32_t b = array_->Get(BoundOffset(index));
      76           0 :   if (b < 0) {
      77             : #if !defined (SFNTLY_NO_EXCEPTION)
      78             :     throw IndexOutOfBoundException(
      79             :         "Index attempted to be read from is out of bounds", index);
      80             : #endif
      81           0 :     return kInvalidByte;
      82             :   }
      83           0 :   return (b << 24) >> 24;
      84             : }
      85             : 
      86           0 : int32_t ReadableFontData::ReadBytes(int32_t index,
      87             :                                     byte_t* b,
      88             :                                     int32_t offset,
      89             :                                     int32_t length) {
      90           0 :   return array_->Get(BoundOffset(index), b, offset, BoundLength(index, length));
      91             : }
      92             : 
      93           0 : int32_t ReadableFontData::ReadChar(int32_t index) {
      94           0 :   return ReadUByte(index);
      95             : }
      96             : 
      97           0 : int32_t ReadableFontData::ReadUShort(int32_t index) {
      98           0 :   int32_t b1 = ReadUByte(index);
      99           0 :   if (b1 < 0)
     100           0 :     return kInvalidUnsigned;
     101           0 :   int32_t b2 = ReadUByte(index + 1);
     102           0 :   if (b2 < 0)
     103           0 :     return kInvalidUnsigned;
     104           0 :   return 0xffff & (b1 << 8 | b2);
     105             : }
     106             : 
     107           0 : int32_t ReadableFontData::ReadShort(int32_t index) {
     108           0 :   int32_t b1 = ReadByte(index);
     109           0 :   if (b1 == kInvalidByte)
     110           0 :     return kInvalidShort;
     111           0 :   int32_t b2 = ReadUByte(index + 1);
     112           0 :   if (b2 < 0)
     113           0 :     return kInvalidShort;
     114             : 
     115           0 :   uint32_t result = static_cast<uint32_t>(b1) << 8 | b2;
     116           0 :   return static_cast<int32_t>(result << 16) >> 16;
     117             : }
     118             : 
     119           0 : int32_t ReadableFontData::ReadUInt24(int32_t index) {
     120           0 :   int32_t b1 = ReadUByte(index);
     121           0 :   if (b1 < 0)
     122           0 :     return kInvalidUnsigned;
     123           0 :   int32_t b2 = ReadUByte(index + 1);
     124           0 :   if (b2 < 0)
     125           0 :     return kInvalidUnsigned;
     126           0 :   int32_t b3 = ReadUByte(index + 2);
     127           0 :   if (b3 < 0)
     128           0 :     return kInvalidUnsigned;
     129           0 :   return 0xffffff & (b1 << 16 | b2 << 8 | b3);
     130             : }
     131             : 
     132           0 : int64_t ReadableFontData::ReadULong(int32_t index) {
     133           0 :   int32_t b1 = ReadUByte(index);
     134           0 :   if (b1 < 0)
     135           0 :     return kInvalidUnsigned;
     136           0 :   int32_t b2 = ReadUByte(index + 1);
     137           0 :   if (b2 < 0)
     138           0 :     return kInvalidUnsigned;
     139           0 :   int32_t b3 = ReadUByte(index + 2);
     140           0 :   if (b3 < 0)
     141           0 :     return kInvalidUnsigned;
     142           0 :   int32_t b4 = ReadUByte(index + 3);
     143           0 :   if (b4 < 0)
     144           0 :     return kInvalidUnsigned;
     145           0 :   return 0xffffffffL & (b1 << 24 | b2 << 16 | b3 << 8 | b4);
     146             : }
     147             : 
     148           0 : int32_t ReadableFontData::ReadULongAsInt(int32_t index) {
     149           0 :   int64_t ulong = ReadULong(index);
     150             : #if !defined (SFNTLY_NO_EXCEPTION)
     151             :   if ((ulong & 0x80000000) == 0x80000000) {
     152             :     throw ArithmeticException("Long value too large to fit into an integer.");
     153             :   }
     154             : #endif
     155           0 :   return static_cast<int32_t>(ulong);
     156             : }
     157             : 
     158           0 : int64_t ReadableFontData::ReadULongLE(int32_t index) {
     159           0 :   int32_t b1 = ReadUByte(index);
     160           0 :   if (b1 < 0)
     161           0 :     return kInvalidUnsigned;
     162           0 :   int32_t b2 = ReadUByte(index + 1);
     163           0 :   if (b2 < 0)
     164           0 :     return kInvalidUnsigned;
     165           0 :   int32_t b3 = ReadUByte(index + 2);
     166           0 :   if (b3 < 0)
     167           0 :     return kInvalidUnsigned;
     168           0 :   int32_t b4 = ReadUByte(index + 3);
     169           0 :   if (b4 < 0)
     170           0 :     return kInvalidUnsigned;
     171           0 :   return 0xffffffffL & (b1 | b2 << 8 | b3 << 16 | b4 << 24);
     172             : }
     173             : 
     174           0 : int32_t ReadableFontData::ReadLong(int32_t index) {
     175           0 :   int32_t b1 = ReadByte(index);
     176           0 :   if (b1 == kInvalidByte)
     177           0 :     return kInvalidLong;
     178           0 :   int32_t b2 = ReadUByte(index + 1);
     179           0 :   if (b2 < 0)
     180           0 :     return kInvalidLong;
     181           0 :   int32_t b3 = ReadUByte(index + 2);
     182           0 :   if (b3 < 0)
     183           0 :     return kInvalidLong;
     184           0 :   int32_t b4 = ReadUByte(index + 3);
     185           0 :   if (b4 < 0)
     186           0 :     return kInvalidLong;
     187           0 :   return static_cast<uint32_t>(b1) << 24 | b2 << 16 | b3 << 8 | b4;
     188             : }
     189             : 
     190           0 : int32_t ReadableFontData::ReadFixed(int32_t index) {
     191           0 :   return ReadLong(index);
     192             : }
     193             : 
     194           0 : int64_t ReadableFontData::ReadDateTimeAsLong(int32_t index) {
     195           0 :   int32_t high = ReadULong(index);
     196           0 :   if (high == kInvalidUnsigned)
     197           0 :     return kInvalidLongDateTime;
     198           0 :   int32_t low = ReadULong(index + 4);
     199           0 :   if (low == kInvalidUnsigned)
     200           0 :     return kInvalidLongDateTime;
     201           0 :   return (int64_t)high << 32 | low;
     202             : }
     203             : 
     204           0 : int32_t ReadableFontData::ReadFWord(int32_t index) {
     205           0 :   return ReadShort(index);
     206             : }
     207             : 
     208           0 : int32_t ReadableFontData::ReadFUFWord(int32_t index) {
     209           0 :   return ReadUShort(index);
     210             : }
     211             : 
     212           0 : int32_t ReadableFontData::CopyTo(OutputStream* os) {
     213           0 :   return array_->CopyTo(os, BoundOffset(0), Length());
     214             : }
     215             : 
     216           0 : int32_t ReadableFontData::CopyTo(WritableFontData* wfd) {
     217           0 :   return array_->CopyTo(wfd->BoundOffset(0),
     218             :                         wfd->array_,
     219             :                         BoundOffset(0),
     220           0 :                         Length());
     221             : }
     222             : 
     223           0 : int32_t ReadableFontData::CopyTo(ByteArray* ba) {
     224           0 :   return array_->CopyTo(ba, BoundOffset(0), Length());
     225             : }
     226             : 
     227           0 : int32_t ReadableFontData::SearchUShort(int32_t start_index,
     228             :                                        int32_t start_offset,
     229             :                                        int32_t end_index,
     230             :                                        int32_t end_offset,
     231             :                                        int32_t length,
     232             :                                        int32_t key) {
     233           0 :   int32_t location = 0;
     234           0 :   int32_t bottom = 0;
     235           0 :   int32_t top = length;
     236           0 :   while (top != bottom) {
     237           0 :     location = (top + bottom) / 2;
     238           0 :     int32_t location_start = ReadUShort(start_index + location * start_offset);
     239           0 :     if (key < location_start) {
     240             :       // location is below current location
     241           0 :       top = location;
     242             :     } else {
     243             :       // is key below the upper bound?
     244           0 :       int32_t location_end = ReadUShort(end_index + location * end_offset);
     245             : #if defined (SFNTLY_DEBUG_FONTDATA)
     246             :       fprintf(stderr, "**start: %d; end: %d\n", location_start, location_end);
     247             : #endif
     248           0 :       if (key <= location_end)
     249           0 :         return location;
     250             : 
     251             :       // location is above the current location
     252           0 :       bottom = location + 1;
     253             :     }
     254             :   }
     255           0 :   return -1;
     256             : }
     257             : 
     258           0 : int32_t ReadableFontData::SearchUShort(int32_t start_index,
     259             :                                        int32_t start_offset,
     260             :                                        int32_t length,
     261             :                                        int32_t key) {
     262           0 :   int32_t location = 0;
     263           0 :   int32_t bottom = 0;
     264           0 :   int32_t top = length;
     265           0 :   while (top != bottom) {
     266           0 :     location = (top + bottom) / 2;
     267           0 :     int32_t location_start = ReadUShort(start_index + location * start_offset);
     268           0 :     if (key == location_start)
     269           0 :       return location;
     270             : 
     271           0 :     if (key < location_start) {
     272             :       // location is below current location
     273           0 :       top = location;
     274             :     } else {
     275             :       // location is above current location
     276           0 :       bottom = location + 1;
     277             :     }
     278             :   }
     279           0 :   return -1;
     280             : }
     281             : 
     282           0 : int32_t ReadableFontData::SearchULong(int32_t start_index,
     283             :                                       int32_t start_offset,
     284             :                                       int32_t end_index,
     285             :                                       int32_t end_offset,
     286             :                                       int32_t length,
     287             :                                       int32_t key) {
     288           0 :   int32_t location = 0;
     289           0 :   int32_t bottom = 0;
     290           0 :   int32_t top = length;
     291           0 :   while (top != bottom) {
     292           0 :     location = (top + bottom) / 2;
     293           0 :     int32_t location_start = ReadULongAsInt(start_index
     294           0 :                                             + location * start_offset);
     295           0 :     if (key < location_start) {
     296             :       // location is below current location
     297           0 :       top = location;
     298             :     } else {
     299             :       // is key below the upper bound?
     300           0 :       int32_t location_end = ReadULongAsInt(end_index + location * end_offset);
     301             : #if defined (SFNTLY_DEBUG_FONTDATA)
     302             :       fprintf(stderr, "**start: %d; end: %d\n", location_start, location_end);
     303             : #endif
     304           0 :       if (key <= location_end)
     305           0 :         return location;
     306             : 
     307             :       // location is above the current location
     308           0 :       bottom = location + 1;
     309             :     }
     310             :   }
     311           0 :   return -1;
     312             : }
     313             : 
     314           0 : CALLER_ATTACH FontData* ReadableFontData::Slice(int32_t offset,
     315             :                                                 int32_t length) {
     316           0 :   if (offset < 0 || length < 0 ||
     317           0 :       offset > std::numeric_limits<int32_t>::max() - length ||
     318           0 :       offset + length > Size()) {
     319             : #if !defined (SFNTLY_NO_EXCEPTION)
     320             :     throw IndexOutOfBoundsException(
     321             :         "Attempt to bind data outside of its limits");
     322             : #endif
     323           0 :     return NULL;
     324             :   }
     325           0 :   FontDataPtr slice = new ReadableFontData(this, offset, length);
     326           0 :   return slice.Detach();
     327             : }
     328             : 
     329           0 : CALLER_ATTACH FontData* ReadableFontData::Slice(int32_t offset) {
     330           0 :   if (offset < 0 || offset > Size()) {
     331             : #if !defined (SFNTLY_NO_EXCEPTION)
     332             :     throw IndexOutOfBoundsException(
     333             :         "Attempt to bind data outside of its limits");
     334             : #endif
     335           0 :     return NULL;
     336             :   }
     337           0 :   FontDataPtr slice = new ReadableFontData(this, offset);
     338           0 :   return slice.Detach();
     339             : }
     340             : 
     341           0 : ReadableFontData::ReadableFontData(ReadableFontData* data, int32_t offset)
     342             :     : FontData(data, offset),
     343             :       checksum_set_(false),
     344           0 :       checksum_(0) {
     345           0 : }
     346             : 
     347           0 : ReadableFontData::ReadableFontData(ReadableFontData* data,
     348             :                                    int32_t offset,
     349           0 :                                    int32_t length)
     350             :     : FontData(data, offset, length),
     351             :       checksum_set_(false),
     352           0 :       checksum_(0) {
     353           0 : }
     354             : 
     355           0 : void ReadableFontData::ComputeChecksum() {
     356             :   // TODO(arthurhsu): IMPLEMENT: synchronization/atomicity
     357           0 :   int64_t sum = 0;
     358           0 :   if (checksum_range_.empty()) {
     359           0 :     sum = ComputeCheckSum(0, Length());
     360             :   } else {
     361           0 :     for (uint32_t low_bound_index = 0; low_bound_index < checksum_range_.size();
     362           0 :          low_bound_index += 2) {
     363           0 :       int32_t low_bound = checksum_range_[low_bound_index];
     364           0 :       int32_t high_bound = (low_bound_index == checksum_range_.size() - 1) ?
     365           0 :                                 Length() :
     366           0 :                                 checksum_range_[low_bound_index + 1];
     367           0 :       sum += ComputeCheckSum(low_bound, high_bound);
     368             :     }
     369             :   }
     370             : 
     371           0 :   checksum_ = sum & 0xffffffffL;
     372           0 :   checksum_set_ = true;
     373           0 : }
     374             : 
     375           0 : int64_t ReadableFontData::ComputeCheckSum(int32_t low_bound,
     376             :                                           int32_t high_bound) {
     377           0 :   int64_t sum = 0;
     378             :   // Checksum all whole 4-byte chunks.
     379           0 :   for (int32_t i = low_bound; i <= high_bound - 4; i += 4) {
     380           0 :     sum += ReadULong(i);
     381             :   }
     382             : 
     383             :   // Add last fragment if not 4-byte multiple
     384           0 :   int32_t off = high_bound & -4;
     385           0 :   if (off < high_bound) {
     386           0 :     int32_t b3 = ReadUByte(off);
     387           0 :     int32_t b2 = (off + 1 < high_bound) ? ReadUByte(off + 1) : 0;
     388           0 :     int32_t b1 = (off + 2 < high_bound) ? ReadUByte(off + 2) : 0;
     389           0 :     int32_t b0 = 0;
     390           0 :     sum += (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
     391             :   }
     392           0 :   return sum;
     393             : }
     394             : 
     395             : }  // namespace sfntly

Generated by: LCOV version 1.13