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