Home | History | Annotate | Download | only in test
      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 <vector>
     18 #include <algorithm>
     19 
     20 #include "gtest/gtest.h"
     21 #include "sfntly/port/type.h"
     22 #include "sfntly/data/writable_font_data.h"
     23 #include "sfntly/data/memory_byte_array.h"
     24 
     25 namespace sfntly {
     26 
     27 const int32_t BYTE_ARRAY_SIZES[] =
     28   {1, 7, 127, 128, 129, 255, 256, 257, 666, 1023, 0x10000};
     29 
     30 // array data for searching
     31 const int32_t LOWER_BYTE_ARRAY_FOR_SEARCHING[] = {2, 4, 7, 13, 127};
     32 const int32_t UPPER_BYTE_ARRAY_FOR_SEARCHING[] = {2, 5, 12, 16, 256};
     33 const int32_t kLowerByteArrayForSearchingLength = 5;
     34 const int32_t kUpperByteArrayForSearchingLength = 5;
     35 
     36 // search test result pairs - number to search for; index found at
     37 const int32_t SEARCH_TEST_PAIRS[][2] = {
     38   {0, -1}, {1, -1}, {2, 0}, {3, -1}, {4, 1}, {5, 1}, {6, -1}, {12, 2},
     39   {13, 3}, {17, -1}, {126, -1}, {127, 4}, {256, 4}, {257, -1}, {0x1000, -1}
     40 };
     41 const int32_t kSearchTestPairsLength = 15;
     42 
     43 // offset and start index data for searching data
     44 // array data size, lower_start_index, lower_offset, upper_start_index,
     45 // upper_offset
     46 const int32_t SEARCH_TEST_OFFSETS[][5] = {
     47   // lower[], upper[]
     48   { (kLowerByteArrayForSearchingLength + kUpperByteArrayForSearchingLength)
     49     * DataSize::kUSHORT,
     50     0,
     51     DataSize::kUSHORT,
     52     kLowerByteArrayForSearchingLength * DataSize::kUSHORT,
     53     DataSize::kUSHORT },
     54 
     55   // {lower, upper} []
     56   { (kLowerByteArrayForSearchingLength + kUpperByteArrayForSearchingLength)
     57     * DataSize::kUSHORT,
     58     0,
     59     2 * DataSize::kUSHORT,
     60     DataSize::kUSHORT,
     61     2 * DataSize::kUSHORT },
     62 
     63   // upper[], lower[]
     64   { (kLowerByteArrayForSearchingLength + kUpperByteArrayForSearchingLength)
     65     * DataSize::kUSHORT,
     66     kLowerByteArrayForSearchingLength * DataSize::kUSHORT,
     67     DataSize::kUSHORT,
     68     0,
     69     DataSize::kUSHORT },
     70 
     71   // {upper, lower} []
     72   { (kLowerByteArrayForSearchingLength + kUpperByteArrayForSearchingLength)
     73     * DataSize::kUSHORT,
     74     DataSize::kUSHORT,
     75     2 * DataSize::kUSHORT,
     76     0,
     77     2 * DataSize::kUSHORT }
     78 };
     79 const int32_t kSearchTestOffsetLength = 4;
     80 
     81 ReadableFontData*
     82 FillTestFontDataWithShortsForSearching(WritableFontData* wfd,
     83                                        const int32_t* lower_data,
     84                                        int32_t lower_start_index,
     85                                        int32_t lower_offset,
     86                                        const int32_t* upper_data,
     87                                        int32_t upper_start_index,
     88                                        int32_t upper_offset) {
     89   // lower data
     90   int offset = lower_start_index;
     91   for (int32_t i = 0; i < kLowerByteArrayForSearchingLength; ++i) {
     92     wfd->WriteUShort(offset, lower_data[i]);
     93     offset += lower_offset;
     94   }
     95 
     96   // upper data
     97   offset = upper_start_index;
     98   for (int32_t i = 0; i < kUpperByteArrayForSearchingLength; ++i) {
     99     wfd->WriteUShort(offset, upper_data[i]);
    100     offset += upper_offset;
    101   }
    102 
    103   return wfd;
    104 }
    105 
    106 bool TestReadableFontDataSearching() {
    107   for (int32_t i = 0; i < kSearchTestOffsetLength; ++i) {
    108     const int32_t* array_setup_offset = SEARCH_TEST_OFFSETS[i];
    109     WritableFontDataPtr wfd;
    110     wfd.Attach(WritableFontData::CreateWritableFontData(array_setup_offset[0]));
    111     FillTestFontDataWithShortsForSearching(wfd,
    112                                            LOWER_BYTE_ARRAY_FOR_SEARCHING,
    113                                            array_setup_offset[1],
    114                                            array_setup_offset[2],
    115                                            UPPER_BYTE_ARRAY_FOR_SEARCHING,
    116                                            array_setup_offset[3],
    117                                            array_setup_offset[4]);
    118     for (int32_t j = 0; j < kSearchTestPairsLength; ++j) {
    119       const int32_t* test_case = SEARCH_TEST_PAIRS[j];
    120       int32_t found = wfd->SearchUShort(array_setup_offset[1],
    121                                         array_setup_offset[2],
    122                                         array_setup_offset[3],
    123                                         array_setup_offset[4],
    124                                         kLowerByteArrayForSearchingLength,
    125                                         test_case[0]);
    126 #if defined (SFNTLY_DEBUG_FONTDATA)
    127       fprintf(stderr, "Searching for %d; Got %d; Expected %d; "
    128               "[test %d][offset %d]\n",
    129               test_case[0], found, test_case[1], j, i);
    130 #endif
    131       EXPECT_EQ(test_case[1], found);
    132     }
    133   }
    134   return true;
    135 }
    136 
    137 void FillTestByteArray(ByteArray* ba, int32_t size) {
    138   for (int32_t i = 0; i < size; ++i) {
    139     ba->Put(i, (byte_t)(i % 256));
    140   }
    141 }
    142 
    143 void ReadFontDataWithSingleByte(ReadableFontData* rfd, ByteVector* buffer) {
    144   buffer->resize(rfd->Length());
    145   for (int32_t index = 0; index < rfd->Length(); ++index) {
    146     (*buffer)[index] = (byte_t)(rfd->ReadByte(index));
    147   }
    148 }
    149 
    150 void ReadFontDataWithBuffer(ReadableFontData* rfd,
    151                             int32_t buffer_size,
    152                             ByteVector* b) {
    153   ByteVector buffer(buffer_size);
    154   b->resize(rfd->Length());
    155 
    156   int32_t index = 0;
    157   while (index < rfd->Length()) {
    158     int32_t bytes_read = rfd->ReadBytes(index, &(buffer[0]), 0, buffer.size());
    159     EXPECT_GE(bytes_read, 0);
    160     std::copy(buffer.begin(), buffer.begin() + bytes_read, b->begin() + index);
    161     index += bytes_read;
    162   }
    163 }
    164 
    165 void ReadFontDataWithSlidingWindow(ReadableFontData* rfd, int32_t window_size,
    166                                    ByteVector* b) {
    167   b->resize(rfd->Length());
    168   int32_t index = 0;
    169   while (index < rfd->Length()) {
    170     int32_t actual_window_size =
    171         std::min<int32_t>(window_size, b->size() - index);
    172     int32_t bytes_read =
    173         rfd->ReadBytes(index, &((*b)[0]), index, actual_window_size);
    174     EXPECT_GE(bytes_read, 0);
    175     index += bytes_read;
    176   }
    177 }
    178 
    179 void WriteFontDataWithSingleByte(ReadableFontData* rfd, WritableFontData* wfd) {
    180   for (int32_t index = 0; index < rfd->Length(); ++index) {
    181     byte_t b = (byte_t)(rfd->ReadByte(index));
    182     wfd->WriteByte(index, b);
    183   }
    184 }
    185 
    186 void WriteFontDataWithBuffer(ReadableFontData* rfd,
    187                              WritableFontData* wfd,
    188                              int32_t buffer_size) {
    189   ByteVector buffer(buffer_size);
    190   int32_t index = 0;
    191   while (index < rfd->Length()) {
    192     int32_t bytesRead = rfd->ReadBytes(index, &(buffer[0]), 0, buffer.size());
    193     wfd->WriteBytes(index, &(buffer[0]), 0, buffer.size());
    194     index += bytesRead;
    195   }
    196 }
    197 
    198 void WriteFontDataWithSlidingWindow(ReadableFontData* rfd,
    199                                     WritableFontData* wfd,
    200                                     int32_t window_size) {
    201   ByteVector b(rfd->Length());
    202   int32_t index = 0;
    203   while (index < rfd->Length()) {
    204     int32_t sliding_size = std::min<int32_t>(window_size, b.size() - index);
    205     int32_t bytes_read = rfd->ReadBytes(index, &(b[0]), index, sliding_size);
    206     wfd->WriteBytes(index, &(b[0]), index, sliding_size);
    207     index += bytes_read;
    208   }
    209 }
    210 
    211 bool ReadComparison(int32_t offset,
    212                     int32_t length,
    213                     ReadableFontData* rfd1,
    214                     ReadableFontData* rfd2) {
    215   EXPECT_TRUE(length == rfd2->Length());
    216   ByteVector b1, b2;
    217   b1.resize(length);
    218   b2.resize(length);
    219 
    220   // single byte reads
    221   ReadFontDataWithSingleByte(rfd1, &b1);
    222   ReadFontDataWithSingleByte(rfd2, &b2);
    223   EXPECT_EQ(memcmp(&(b1[offset]), &(b2[0]), length), 0);
    224 
    225   // buffer reads
    226   int32_t increments = std::max<int32_t>(length / 11, 1);
    227   for (int32_t buffer_size = 1; buffer_size <= length;
    228        buffer_size += increments) {
    229     b1.clear();
    230     b2.clear();
    231     b1.resize(length);
    232     b2.resize(length);
    233     ReadFontDataWithBuffer(rfd1, buffer_size, &b1);
    234     ReadFontDataWithBuffer(rfd2, buffer_size, &b2);
    235     int result = memcmp(&(b1[offset]), &(b2[0]), length);
    236     EXPECT_EQ(result, 0);
    237   }
    238 
    239   // sliding window reads
    240   for (int32_t window_size = 1; window_size <= length;
    241        window_size += increments) {
    242     b1.clear();
    243     b2.clear();
    244     b1.resize(length);
    245     b2.resize(length);
    246     ReadFontDataWithSlidingWindow(rfd1, window_size, &b1);
    247     ReadFontDataWithSlidingWindow(rfd2, window_size, &b2);
    248     int result = memcmp(&(b1[offset]), &(b2[0]), length);
    249     EXPECT_EQ(result, 0);
    250   }
    251   return true;
    252 }
    253 
    254 void SlicingReadTest(ReadableFontData* rfd) {
    255   fprintf(stderr, "read - trim = ");
    256   for (int32_t trim = 0; trim < (rfd->Length() / 2) + 1;
    257        trim += (rfd->Length() / 21) + 1) {
    258     fprintf(stderr, "%d ", trim);
    259     int32_t length = rfd->Length() - 2 * trim;
    260     ReadableFontDataPtr slice;
    261     slice.Attach(down_cast<ReadableFontData*>(rfd->Slice(trim, length)));
    262     EXPECT_TRUE(ReadComparison(trim, length, rfd, slice));
    263   }
    264   fprintf(stderr, "\n");
    265 }
    266 
    267 void SlicingWriteTest(ReadableFontData* rfd, WritableFontData* wfd) {
    268   fprintf(stderr, "write - trim = ");
    269   for (int32_t trim = 0; trim < (rfd->Length() / 2) + 1;
    270        trim += (rfd->Length() / 21) + 1) {
    271     fprintf(stderr, "%d ", trim);
    272     int32_t length = rfd->Length() - 2 * trim;
    273     WritableFontDataPtr w_slice;
    274     ReadableFontDataPtr r_slice;
    275 
    276     // single byte writes
    277     w_slice.Attach(down_cast<WritableFontData*>(wfd->Slice(trim, length)));
    278     r_slice.Attach(down_cast<ReadableFontData*>(rfd->Slice(trim, length)));
    279     WriteFontDataWithSingleByte(r_slice, w_slice);
    280     EXPECT_TRUE(ReadComparison(trim, length, rfd, w_slice));
    281 
    282     // buffer writes
    283     int32_t increments = std::max<int32_t>(length / 11, 1);
    284     for (int32_t buffer_size = 1; buffer_size < length;
    285          buffer_size += increments) {
    286       w_slice.Attach(down_cast<WritableFontData*>(wfd->Slice(trim, length)));
    287       r_slice.Attach(down_cast<ReadableFontData*>(rfd->Slice(trim, length)));
    288       WriteFontDataWithBuffer(r_slice, w_slice, buffer_size);
    289       EXPECT_TRUE(ReadComparison(trim, length, rfd, w_slice));
    290     }
    291 
    292     // sliding window writes
    293     for (int window_size = 1; window_size < length; window_size += increments) {
    294       w_slice.Attach(down_cast<WritableFontData*>(wfd->Slice(trim, length)));
    295       r_slice.Attach(down_cast<ReadableFontData*>(rfd->Slice(trim, length)));
    296       WriteFontDataWithSlidingWindow(r_slice, w_slice, window_size);
    297       EXPECT_TRUE(ReadComparison(trim, length, rfd, w_slice));
    298     }
    299   }
    300   fprintf(stderr, "\n");
    301 }
    302 
    303 bool TestReadableFontData() {
    304   for (size_t i = 0; i < sizeof(BYTE_ARRAY_SIZES) / sizeof(int32_t); ++i) {
    305     int32_t size = BYTE_ARRAY_SIZES[i];
    306     ByteArrayPtr ba = new MemoryByteArray(size);
    307     FillTestByteArray(ba, size);
    308     ReadableFontDataPtr rfd = new ReadableFontData(ba);
    309     SlicingReadTest(rfd);
    310   }
    311   return true;
    312 }
    313 
    314 bool TestWritableFontData() {
    315   for (size_t i = 0; i < sizeof(BYTE_ARRAY_SIZES) / sizeof(int32_t); ++i) {
    316     int32_t size = BYTE_ARRAY_SIZES[i];
    317     ByteArrayPtr ba = new MemoryByteArray(size);
    318     FillTestByteArray(ba, size);
    319     WritableFontDataPtr wfd = new WritableFontData(ba);
    320     SlicingReadTest(wfd);
    321     ByteArrayPtr temp = new MemoryByteArray(size);
    322     WritableFontDataPtr wfd_copy = new WritableFontData(temp);
    323     SlicingWriteTest(wfd, wfd_copy);
    324   }
    325   return true;
    326 }
    327 
    328 }  // namespace sfntly
    329 
    330 TEST(FontData, ReadableFontDataSearching) {
    331   ASSERT_TRUE(sfntly::TestReadableFontDataSearching());
    332 }
    333 
    334 TEST(FontData, All) {
    335   ASSERT_TRUE(sfntly::TestReadableFontData());
    336   ASSERT_TRUE(sfntly::TestWritableFontData());
    337 }
    338