summaryrefslogtreecommitdiff
path: root/src/base/data_segment.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/data_segment.cc')
-rw-r--r--src/base/data_segment.cc81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/base/data_segment.cc b/src/base/data_segment.cc
new file mode 100644
index 0000000..95b4cc7
--- /dev/null
+++ b/src/base/data_segment.cc
@@ -0,0 +1,81 @@
+#include "image_io/base/data_segment.h"
+
+#include <cstring>
+
+namespace photos_editing_formats {
+namespace image_io {
+
+using std::default_delete;
+using std::shared_ptr;
+
+shared_ptr<DataSegment> DataSegment::Create(
+ const DataRange& data_range, const Byte* buffer,
+ DataSegment::BufferDispositionPolicy buffer_policy) {
+ return shared_ptr<DataSegment>(
+ new DataSegment(data_range, buffer, buffer_policy),
+ default_delete<DataSegment>());
+}
+
+size_t DataSegment::Find(size_t start_location, Byte value) const {
+ if (!Contains(start_location)) {
+ return GetEnd();
+ }
+ const Byte* location = reinterpret_cast<const Byte*>(
+ memchr((buffer_ + start_location) - GetBegin(), value,
+ GetEnd() - start_location));
+ return location ? (location - buffer_) + GetBegin() : GetEnd();
+}
+
+size_t DataSegment::Find(size_t location, const char* str,
+ size_t str_length) const {
+ char char0 = *str;
+ while (Contains(location)) {
+ size_t memchr_count = GetEnd() - location;
+ const void* void0_ptr = memchr(GetBuffer(location), char0, memchr_count);
+ if (void0_ptr) {
+ const Byte* byte0_ptr = reinterpret_cast<const Byte*>(void0_ptr);
+ size_t byte0_location = (byte0_ptr - buffer_) + GetBegin();
+ if (byte0_location + str_length <= GetEnd()) {
+ const char* char0_ptr = reinterpret_cast<const char*>(void0_ptr);
+ if (strncmp(char0_ptr, str, str_length) == 0) {
+ return byte0_location;
+ }
+ }
+ }
+ ++location;
+ }
+ return GetEnd();
+}
+
+ValidatedByte DataSegment::GetValidatedByte(size_t location,
+ const DataSegment* segment1,
+ const DataSegment* segment2) {
+ for (const DataSegment* segment : {segment1, segment2}) {
+ if (segment && segment->Contains(location)) {
+ return segment->GetValidatedByte(location);
+ }
+ }
+ return InvalidByte();
+}
+
+size_t DataSegment::Find(size_t start_location, Byte value,
+ const DataSegment* segment1,
+ const DataSegment* segment2) {
+ if (segment1 && segment2 && segment1->GetEnd() == segment2->GetBegin()) {
+ size_t value_location = segment2->GetEnd();
+ if (segment1->Contains(start_location)) {
+ value_location = segment1->Find(start_location, value);
+ if (value_location == segment1->GetEnd()) {
+ value_location = segment2->Find(segment2->GetBegin(), value);
+ }
+ } else {
+ value_location = segment2->Find(start_location, value);
+ }
+ return value_location;
+ }
+ size_t segment1_end = segment1 ? segment1->GetEnd() : 0;
+ return segment2 ? std::max(segment1_end, segment2->GetEnd()) : segment1_end;
+}
+
+} // namespace image_io
+} // namespace photos_editing_formats