Home | History | Annotate | Download | only in base
      1 #include "image_io/base/data_segment.h"
      2 
      3 #include <cstring>
      4 
      5 namespace photos_editing_formats {
      6 namespace image_io {
      7 
      8 using std::default_delete;
      9 using std::shared_ptr;
     10 
     11 shared_ptr<DataSegment> DataSegment::Create(
     12     const DataRange& data_range, const Byte* buffer,
     13     DataSegment::BufferDispositionPolicy buffer_policy) {
     14   return shared_ptr<DataSegment>(
     15       new DataSegment(data_range, buffer, buffer_policy),
     16       default_delete<DataSegment>());
     17 }
     18 
     19 size_t DataSegment::Find(size_t start_location, Byte value) const {
     20   if (!Contains(start_location)) {
     21     return GetEnd();
     22   }
     23   const Byte* location = reinterpret_cast<const Byte*>(
     24       memchr((buffer_ + start_location) - GetBegin(), value,
     25              GetEnd() - start_location));
     26   return location ? (location - buffer_) + GetBegin() : GetEnd();
     27 }
     28 
     29 size_t DataSegment::Find(size_t location, const char* str,
     30                          size_t str_length) const {
     31   char char0 = *str;
     32   while (Contains(location)) {
     33     size_t memchr_count = GetEnd() - location;
     34     const void* void0_ptr = memchr(GetBuffer(location), char0, memchr_count);
     35     if (void0_ptr) {
     36       const Byte* byte0_ptr = reinterpret_cast<const Byte*>(void0_ptr);
     37       size_t byte0_location = (byte0_ptr - buffer_) + GetBegin();
     38       if (byte0_location + str_length <= GetEnd()) {
     39         const char* char0_ptr = reinterpret_cast<const char*>(void0_ptr);
     40         if (strncmp(char0_ptr, str, str_length) == 0) {
     41           return byte0_location;
     42         }
     43       }
     44     }
     45     ++location;
     46   }
     47   return GetEnd();
     48 }
     49 
     50 ValidatedByte DataSegment::GetValidatedByte(size_t location,
     51                                             const DataSegment* segment1,
     52                                             const DataSegment* segment2) {
     53   for (const DataSegment* segment : {segment1, segment2}) {
     54     if (segment && segment->Contains(location)) {
     55       return segment->GetValidatedByte(location);
     56     }
     57   }
     58   return InvalidByte();
     59 }
     60 
     61 size_t DataSegment::Find(size_t start_location, Byte value,
     62                          const DataSegment* segment1,
     63                          const DataSegment* segment2) {
     64   if (segment1 && segment2 && segment1->GetEnd() == segment2->GetBegin()) {
     65     size_t value_location = segment2->GetEnd();
     66     if (segment1->Contains(start_location)) {
     67       value_location = segment1->Find(start_location, value);
     68       if (value_location == segment1->GetEnd()) {
     69         value_location = segment2->Find(segment2->GetBegin(), value);
     70       }
     71     } else {
     72       value_location = segment2->Find(start_location, value);
     73     }
     74     return value_location;
     75   }
     76   size_t segment1_end = segment1 ? segment1->GetEnd() : 0;
     77   return segment2 ? std::max(segment1_end, segment2->GetEnd()) : segment1_end;
     78 }
     79 
     80 }  // namespace image_io
     81 }  // namespace photos_editing_formats
     82