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