/*
 * Copyright 2024 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
 *
 *     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.
 */

#pragma once

#include <stdint.h>

// When compiling test, the host OS might have conflicting defines for this:
#undef ntohs
#undef htons
#undef ntohl
#undef htonl
#undef ltohs
#undef ltohl

static inline uint16_t ntohs(uint16_t v) {
  // return ((v & 0x00ff) << 8) | ((v & 0xff00) >> 8);
  return __builtin_bswap16(v);
}

static inline uint16_t htons(uint16_t v) {
  return ntohs(v);
}

static inline uint32_t ntohl(uint32_t v) {
  // return ((v & 0x000000ff) << 24) |
  //        ((v & 0x0000ff00) << 8) |
  //        ((v & 0x00ff0000) >> 8) |
  //        ((v & 0xff000000) >> 24);
  return __builtin_bswap32(v);
}

static inline uint32_t htonl(uint32_t v) {
  return ntohl(v);
}

#define ltohs(v) (v)
#define ltohl(v) (v)

// Types for values in network byte-order. They are wrapped in structs so that
// the compiler will disallow implicit casting of these types to or from
// integral types. This way it is a compile error to try using variables of
// these types without first performing a byte-order conversion.
// There is no overhead for wrapping the values in structs.
typedef struct net16 {
  uint16_t v;
} net16;

typedef struct net32 {
  uint32_t v;
} net32;

static inline uint16_t ntoh16(net16 net) {
  return ntohs(net.v);
}

static inline net16 hton16(uint16_t v) {
  return (net16){ htons(v) };
}

static inline uint32_t ntoh32(net32 net) {
  return ntohl(net.v);
}

static inline net32 hton32(uint32_t v) {
  return (net32){ htonl(v) };
}
