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