blob: 91a1de7396bbf87dfa9b81a46e612ab14727dcac [file] [log] [blame]
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// -----------------------------------------------------------------------------
//
// Data and Metadata
//
// Author: Skal (pascal.massimino@gmail.com)
#include <algorithm> // for std::min
#include <cstdint>
#include <cstring> // for memcpy()
#include "src/utils/utils.h"
#include "src/wp2/base.h"
namespace WP2 {
//------------------------------------------------------------------------------
Data::Data(Data&& other) noexcept { TrivialMoveCtor(this, &other); }
Data& Data::operator=(Data&& other) noexcept {
this->Clear();
TrivialMoveCtor(this, &other);
return *this;
}
void Data::Clear() {
WP2Free(bytes);
bytes = nullptr;
size = 0;
}
WP2Status Data::Resize(size_t data_size, bool keep_bytes) {
if (size == data_size) return WP2_STATUS_OK;
if (data_size == 0) {
Clear();
} else {
if (!keep_bytes) Clear();
uint8_t* const new_bytes = (uint8_t*)WP2Malloc(1ull, data_size);
WP2_CHECK_ALLOC_OK(new_bytes != nullptr);
if (keep_bytes) {
const size_t to_copy = std::min(size, data_size);
memcpy(new_bytes, bytes, to_copy);
Clear();
}
bytes = new_bytes;
size = data_size;
}
return WP2_STATUS_OK;
}
WP2Status Data::CopyFrom(const uint8_t* data, size_t data_size) {
if (data_size == 0) {
Clear();
} else {
WP2_CHECK_OK(data != nullptr, WP2_STATUS_INVALID_PARAMETER);
WP2_CHECK_STATUS(Resize(data_size, /*keep_bytes=*/false));
std::memcpy(bytes, data, size);
}
return WP2_STATUS_OK;
}
WP2Status Data::Append(const uint8_t* data, size_t data_size) {
if (data_size > 0) {
WP2_CHECK_OK(data != nullptr, WP2_STATUS_INVALID_PARAMETER);
WP2_CHECK_STATUS(Resize(size + data_size, /*keep_bytes=*/true));
std::memcpy(bytes + size - data_size, data, data_size);
}
return WP2_STATUS_OK;
}
void swap(Data& a, Data& b) {
std::swap(a.bytes, b.bytes);
std::swap(a.size, b.size);
}
//------------------------------------------------------------------------------
bool Metadata::IsEmpty() const {
if (iccp.size > 0 || xmp.size > 0 || exif.size > 0) {
return false;
}
return true;
}
void Metadata::Clear() {
iccp.Clear();
xmp.Clear();
exif.Clear();
}
WP2Status Metadata::CopyFrom(const Metadata& src) {
WP2_CHECK_STATUS(iccp.CopyFrom(src.iccp.bytes, src.iccp.size));
WP2_CHECK_STATUS(xmp.CopyFrom(src.xmp.bytes, src.xmp.size));
WP2_CHECK_STATUS(exif.CopyFrom(src.exif.bytes, src.exif.size));
return WP2_STATUS_OK;
}
void swap(Metadata& a, Metadata& b) {
swap(a.iccp, b.iccp);
swap(a.xmp, b.xmp);
swap(a.exif, b.exif);
}
//------------------------------------------------------------------------------
} // namespace WP2