• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Create(const DataRange & data_range,const Byte * buffer,DataSegment::BufferDispositionPolicy buffer_policy)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 
Find(size_t start_location,Byte value) const19 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 
Find(size_t location,const char * str,size_t str_length) const29 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 
GetValidatedByte(size_t location,const DataSegment * segment1,const DataSegment * segment2)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 
Find(size_t start_location,Byte value,const DataSegment * segment1,const DataSegment * segment2)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