static RawObject packObject()

in runtime/memoryview-builtins.cpp [131:285]


static RawObject packObject(Thread* thread, uword address, char format,
                            word index, RawObject value) {
  byte* dst = reinterpret_cast<byte*>(address + index);
  if (isIntFormat(format)) {
    if (!value.isInt()) return Unbound::object();
    switch (format) {
      case 'b': {
        OptInt<char> opt_val = RawInt::cast(value).asInt<char>();
        if (opt_val.error != CastError::None) {
          return raiseInvalidValueError(thread, format);
        }
        std::memcpy(dst, &opt_val.value, sizeof(opt_val.value));
        break;
      }
      case 'h': {
        OptInt<short> opt_val = RawInt::cast(value).asInt<short>();
        if (opt_val.error != CastError::None) {
          return raiseInvalidValueError(thread, format);
        }
        std::memcpy(dst, &opt_val.value, sizeof(opt_val.value));
        break;
      }
      case 'i': {
        OptInt<int> opt_val = RawInt::cast(value).asInt<int>();
        if (opt_val.error != CastError::None) {
          return raiseInvalidValueError(thread, format);
        }
        std::memcpy(dst, &opt_val.value, sizeof(opt_val.value));
        break;
      }
      case 'l': {
        OptInt<long> opt_val = RawInt::cast(value).asInt<long>();
        if (opt_val.error != CastError::None) {
          return raiseInvalidValueError(thread, format);
        }
        std::memcpy(dst, &opt_val.value, sizeof(opt_val.value));
        break;
      }
      case 'B': {
        OptInt<unsigned char> opt_val =
            RawInt::cast(value).asInt<unsigned char>();
        if (opt_val.error != CastError::None) {
          return raiseInvalidValueError(thread, format);
        }
        std::memcpy(dst, &opt_val.value, sizeof(opt_val.value));
        break;
      }
      case 'H': {
        OptInt<unsigned short> opt_val =
            RawInt::cast(value).asInt<unsigned short>();
        if (opt_val.error != CastError::None) {
          return raiseInvalidValueError(thread, format);
        }
        std::memcpy(dst, &opt_val.value, sizeof(opt_val.value));
        break;
      }
      case 'I': {
        OptInt<unsigned int> opt_val =
            RawInt::cast(value).asInt<unsigned int>();
        if (opt_val.error != CastError::None) {
          return raiseInvalidValueError(thread, format);
        }
        std::memcpy(dst, &opt_val.value, sizeof(opt_val.value));
        break;
      }
      case 'L': {
        OptInt<unsigned long> opt_val =
            RawInt::cast(value).asInt<unsigned long>();
        if (opt_val.error != CastError::None) {
          return raiseInvalidValueError(thread, format);
        }
        std::memcpy(dst, &opt_val.value, sizeof(opt_val.value));
        break;
      }
      case 'q': {
        OptInt<long long> opt_val = RawInt::cast(value).asInt<long long>();
        if (opt_val.error != CastError::None) {
          return raiseInvalidValueError(thread, format);
        }
        std::memcpy(dst, &opt_val.value, sizeof(opt_val.value));
        break;
      }
      case 'Q': {
        OptInt<unsigned long long> opt_val =
            RawInt::cast(value).asInt<unsigned long long>();
        if (opt_val.error != CastError::None) {
          return raiseInvalidValueError(thread, format);
        }
        std::memcpy(dst, &opt_val.value, sizeof(opt_val.value));
        break;
      }
      case 'n': {
        OptInt<ssize_t> opt_val = RawInt::cast(value).asInt<ssize_t>();
        if (opt_val.error != CastError::None) {
          return raiseInvalidValueError(thread, format);
        }
        std::memcpy(dst, &opt_val.value, sizeof(opt_val.value));
        break;
      }
      case 'N': {
        OptInt<size_t> opt_val = RawInt::cast(value).asInt<size_t>();
        if (opt_val.error != CastError::None) {
          return raiseInvalidValueError(thread, format);
        }
        std::memcpy(dst, &opt_val.value, sizeof(opt_val.value));
        break;
      }
      case 'P': {
        OptInt<uintptr_t> opt_val = RawInt::cast(value).asInt<uintptr_t>();
        if (opt_val.error != CastError::None) {
          return raiseInvalidValueError(thread, format);
        }
        std::memcpy(dst, &opt_val.value, sizeof(opt_val.value));
        break;
      }
    }
    return NoneType::object();
  }

  switch (format) {
    case 'f': {
      if (!value.isFloat()) return Unbound::object();
      float value_float = Float::cast(floatUnderlying(value)).value();
      std::memcpy(dst, &value_float, sizeof(value_float));
      return NoneType::object();
    }

    case 'd': {
      if (!value.isFloat()) return Unbound::object();
      double value_double = Float::cast(floatUnderlying(value)).value();
      std::memcpy(dst, &value_double, sizeof(value_double));
      return NoneType::object();
    }

    case 'c': {
      if (!value.isBytes()) return raiseInvalidTypeError(thread, format);
      RawBytes value_bytes = bytesUnderlying(value);
      if (value_bytes.length() != 1) {
        return raiseInvalidValueError(thread, format);
      }
      *dst = value_bytes.byteAt(0);
      return NoneType::object();
    }

    case '?': {
      if (!value.isBool()) return Unbound::object();
      bool value_bool = Bool::cast(value).value();
      std::memcpy(dst, &value_bool, sizeof(value_bool));
      return NoneType::object();
    }
    default:
      UNREACHABLE("invalid format");
  }
  return NoneType::object();
}