blob: b9d6c028f6703646589f3a77468efd8854b27d0c [file] [log] [blame]
// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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
//
// http://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.
#ifndef MEDIA_BASE_ENDIAN_UTIL_H_
#define MEDIA_BASE_ENDIAN_UTIL_H_
#include "base/sys_byteorder.h"
namespace media {
namespace endian_util {
// The following functions must be able to support storing to/loading from
// non-aligned memory. Thus, casts like "*reinterpret_cast<uint16_t*>(p)"
// should be avoided as these can cause crashes due to alignment on some
// platforms.
// Load 2 little-endian bytes at |p| and return as a host-endian uint16_t.
inline uint16_t load_uint16_little_endian(const uint8_t* p) {
uint16_t aligned_p;
memcpy(&aligned_p, p, sizeof(aligned_p));
return base::ByteSwapToLE16(aligned_p);
}
// Load 4 little-endian bytes at |p| and return as a host-endian uint32_t.
inline uint32_t load_uint32_little_endian(const uint8_t* p) {
uint32_t aligned_p;
memcpy(&aligned_p, p, sizeof(aligned_p));
return base::ByteSwapToLE32(aligned_p);
}
// Load 8 little-endian bytes at |p| and return as a host-endian uint64_t.
inline uint64_t load_uint64_little_endian(const uint8_t* p) {
uint64_t aligned_p;
memcpy(&aligned_p, p, sizeof(aligned_p));
return base::ByteSwapToLE64(aligned_p);
}
// Load 2 big-endian bytes at |p| and return as a host-endian uint16_t.
inline uint16_t load_uint16_big_endian(const uint8_t* p) {
uint16_t aligned_p;
memcpy(&aligned_p, p, sizeof(aligned_p));
return base::NetToHost16(aligned_p);
}
// Load 4 big-endian bytes at |p| and return as a host-endian uint32_t.
inline uint32_t load_uint32_big_endian(const uint8_t* p) {
uint32_t aligned_p;
memcpy(&aligned_p, p, sizeof(aligned_p));
return base::NetToHost32(aligned_p);
}
// Load 8 big-endian bytes at |p| and return as a host-endian uint64_t.
inline uint64_t load_uint64_big_endian(const uint8_t* p) {
uint64_t aligned_p;
memcpy(&aligned_p, p, sizeof(aligned_p));
return base::NetToHost64(aligned_p);
}
// Load 2 big-endian bytes at |p| and return as an host-endian int16_t.
inline int16_t load_int16_big_endian(const uint8_t* p) {
return static_cast<int16_t>(load_uint16_big_endian(p));
}
// Load 4 big-endian bytes at |p| and return as an host-endian int32_t.
inline int32_t load_int32_big_endian(const uint8_t* p) {
return static_cast<int32_t>(load_uint32_big_endian(p));
}
// Load 8 big-endian bytes at |p| and return as an host-endian int64_t.
inline int64_t load_int64_big_endian(const uint8_t* p) {
return static_cast<int64_t>(load_uint64_big_endian(p));
}
// Load 2 little-endian bytes at |p| and return as a host-endian int16_t.
inline int16_t load_int16_little_endian(const uint8_t* p) {
return static_cast<int16_t>(load_uint16_little_endian(p));
}
// Load 4 little-endian bytes at |p| and return as a host-endian int32_t.
inline int32_t load_int32_little_endian(const uint8_t* p) {
return static_cast<int32_t>(load_uint32_little_endian(p));
}
// Load 8 little-endian bytes at |p| and return as a host-endian int64_t.
inline int64_t load_int64_little_endian(const uint8_t* p) {
return static_cast<int64_t>(load_uint64_little_endian(p));
}
// Store 2 host-endian bytes as big-endian at |p|.
inline void store_uint16_big_endian(uint16_t d, uint8_t* p) {
uint16_t big_d = base::HostToNet16(d);
memcpy(p, &big_d, sizeof(big_d));
}
// Store 4 host-endian bytes as big-endian at |p|.
inline void store_uint32_big_endian(uint32_t d, uint8_t* p) {
uint32_t big_d = base::HostToNet32(d);
memcpy(p, &big_d, sizeof(big_d));
}
// Store 8 host-endian bytes as big-endian at |p|.
inline void store_uint64_big_endian(uint64_t d, uint8_t* p) {
uint64_t big_d = base::HostToNet64(d);
memcpy(p, &big_d, sizeof(big_d));
}
// Store 2 host-endian bytes as little-endian at |p|.
inline void store_uint16_little_endian(uint16_t d, uint8_t* p) {
uint16_t little_d = base::ByteSwapToLE16(d);
memcpy(p, &little_d, sizeof(little_d));
}
// Store 4 host-endian bytes as little-endian at |p|.
inline void store_uint32_little_endian(uint32_t d, uint8_t* p) {
uint32_t little_d = base::ByteSwapToLE32(d);
memcpy(p, &little_d, sizeof(little_d));
}
// Store 8 host-endian bytes as little-endian at |p|.
inline void store_uint64_little_endian(uint64_t d, uint8_t* p) {
uint64_t little_d = base::ByteSwapToLE64(d);
memcpy(p, &little_d, sizeof(little_d));
}
} // namespace endian_util
} // namespace media
#endif // MEDIA_BASE_ENDIAN_UTIL_H_