Continue fixing strict aliasing warnings

This commit is contained in:
Nekotekina 2021-03-13 18:02:37 +03:00
parent aff63028d4
commit c22e1e71f0
12 changed files with 65 additions and 45 deletions

View File

@ -16,6 +16,7 @@
#include "Utilities/StrUtil.h" #include "Utilities/StrUtil.h"
#include "Utilities/span.h" #include "Utilities/span.h"
#include "util/init_mutex.hpp" #include "util/init_mutex.hpp"
#include "util/asm.hpp"
#include <thread> #include <thread>
@ -1343,7 +1344,7 @@ error_code cellDiscGameGetBootDiscInfo(vm::ptr<CellDiscGameSystemFileParam> getP
} }
// Always sets 0 at first dword // Always sets 0 at first dword
reinterpret_cast<nse_t<u32, 1>*>(getParam->titleId)[0] = 0; *utils::bless<nse_t<u32, 1>>(getParam->titleId + 0) = 0;
// This is also called by non-disc games, see NPUB90029 // This is also called by non-disc games, see NPUB90029
static const std::string dir = "/dev_bdvd/PS3_GAME"s; static const std::string dir = "/dev_bdvd/PS3_GAME"s;

View File

@ -9,6 +9,8 @@
#include "Emu/Cell/lv2/sys_fs.h" #include "Emu/Cell/lv2/sys_fs.h"
#include "cellGifDec.h" #include "cellGifDec.h"
#include "util/asm.hpp"
LOG_CHANNEL(cellGifDec); LOG_CHANNEL(cellGifDec);
// Temporarily // Temporarily
@ -131,8 +133,8 @@ error_code cellGifDecReadHeader(PMainHandle mainHandle, PSubHandle subHandle, PI
} }
} }
if (*reinterpret_cast<be_t<u32>*>(buffer) != 0x47494638u || if (*utils::bless<be_t<u32>>(buffer + 0) != 0x47494638u ||
(*reinterpret_cast<le_t<u16>*>(buffer + 4) != 0x6139u && *reinterpret_cast<le_t<u16>*>(buffer + 4) != 0x6137u)) // Error: The first 6 bytes are not a valid GIF signature (*utils::bless<le_t<u16>>(buffer + 4) != 0x6139u && *utils::bless<le_t<u16>>(buffer + 4) != 0x6137u)) // Error: The first 6 bytes are not a valid GIF signature
{ {
return CELL_GIFDEC_ERROR_STREAM_FORMAT; // Surprisingly there is no error code related with headerss return CELL_GIFDEC_ERROR_STREAM_FORMAT; // Surprisingly there is no error code related with headerss
} }

View File

@ -9,6 +9,8 @@
#include "Emu/Cell/lv2/sys_fs.h" #include "Emu/Cell/lv2/sys_fs.h"
#include "cellJpgDec.h" #include "cellJpgDec.h"
#include "util/asm.hpp"
LOG_CHANNEL(cellJpgDec); LOG_CHANNEL(cellJpgDec);
// Temporarily // Temporarily
@ -146,8 +148,8 @@ error_code cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr<CellJpgDe
} }
} }
if (*reinterpret_cast<le_t<u32>*>(buffer.get()) != 0xE0FFD8FF || // Error: Not a valid SOI header if (*utils::bless<le_t<u32>>(buffer.get() + 0) != 0xE0FFD8FF || // Error: Not a valid SOI header
*reinterpret_cast<u32*>(buffer.get() + 6) != "JFIF"_u32) // Error: Not a valid JFIF string *utils::bless<u32>(buffer.get() + 6) != "JFIF"_u32) // Error: Not a valid JFIF string
{ {
return CELL_JPGDEC_ERROR_HEADER; return CELL_JPGDEC_ERROR_HEADER;
} }

View File

@ -16,6 +16,8 @@ typedef const char *HostCode;
#include "cellL10n.h" #include "cellL10n.h"
#include "util/asm.hpp"
LOG_CHANNEL(cellL10n); LOG_CHANNEL(cellL10n);
// Translate code id to code name. some codepage may has another name. // Translate code id to code name. some codepage may has another name.
@ -235,7 +237,7 @@ s32 _ConvertStr(s32 src_code, const void *src, s32 src_len, s32 dst_code, void *
if (dst != NULL) if (dst != NULL)
{ {
usz dstLen = *dst_len; usz dstLen = *dst_len;
usz ictd = iconv(ict, const_cast<char**>(reinterpret_cast<const char**>(&src)), &srcLen, reinterpret_cast<char**>(&dst), &dstLen); usz ictd = iconv(ict, utils::bless<char*>(&src), &srcLen, utils::bless<char*>(&dst), &dstLen);
*dst_len -= dstLen; *dst_len -= dstLen;
if (ictd == umax) if (ictd == umax)
{ {
@ -260,7 +262,7 @@ s32 _ConvertStr(s32 src_code, const void *src, s32 src_len, s32 dst_code, void *
{ {
//char *bufPtr = buf; //char *bufPtr = buf;
usz bufLeft = sizeof(buf); usz bufLeft = sizeof(buf);
usz ictd = iconv(ict, const_cast<char**>(reinterpret_cast<const char**>(&src)), &srcLen, reinterpret_cast<char**>(&dst), &bufLeft); usz ictd = iconv(ict, utils::bless<char*>(&src), &srcLen, utils::bless<char*>(&dst), &bufLeft);
*dst_len += sizeof(buf) - bufLeft; *dst_len += sizeof(buf) - bufLeft;
if (ictd == umax && errno != E2BIG) if (ictd == umax && errno != E2BIG)
{ {

View File

@ -548,7 +548,7 @@ struct nt_p2p_port
auto* hdr_ptr = reinterpret_cast<lv2_socket::p2ps_i::encapsulated_tcp *>(packet_data+sizeof(u16)); auto* hdr_ptr = reinterpret_cast<lv2_socket::p2ps_i::encapsulated_tcp *>(packet_data+sizeof(u16));
hdr_ptr->checksum = 0; hdr_ptr->checksum = 0;
hdr_ptr->checksum = tcp_checksum(reinterpret_cast<u16 *>(hdr_ptr), sizeof(lv2_socket::p2ps_i::encapsulated_tcp) + datasize); hdr_ptr->checksum = tcp_checksum(utils::bless<u16>(hdr_ptr), sizeof(lv2_socket::p2ps_i::encapsulated_tcp) + datasize);
return packet; return packet;
} }

View File

@ -2,6 +2,8 @@
#include "Skylander.h" #include "Skylander.h"
#include "Emu/Cell/lv2/sys_usbd.h" #include "Emu/Cell/lv2/sys_usbd.h"
#include "util/asm.hpp"
LOG_CHANNEL(skylander_log, "skylander"); LOG_CHANNEL(skylander_log, "skylander");
sky_portal g_skyportal; sky_portal g_skyportal;
@ -89,9 +91,9 @@ void sky_portal::get_status(u8* reply_buf)
status |= s.status; status |= s.status;
} }
memset(reply_buf, 0, 0x20); std::memset(reply_buf, 0, 0x20);
reply_buf[0] = 0x53; reply_buf[0] = 0x53;
reinterpret_cast<le_t<u16>&>(reply_buf[1]) = status; *utils::bless<le_t<u16>>(reply_buf + 1) = status;
reply_buf[5] = interrupt_counter++; reply_buf[5] = interrupt_counter++;
reply_buf[6] = 0x01; reply_buf[6] = 0x01;
} }
@ -157,7 +159,7 @@ u8 sky_portal::load_skylander(u8* buf, fs::file in_file)
{ {
std::lock_guard lock(sky_mutex); std::lock_guard lock(sky_mutex);
u32 sky_serial = reinterpret_cast<le_t<u32>&>(buf[0]); u32 sky_serial = *utils::bless<le_t<u32>>(buf);
u8 found_slot = 0xFF; u8 found_slot = 0xFF;
// mimics spot retaining on the portal // mimics spot retaining on the portal

View File

@ -11,6 +11,8 @@
#include "Emu/IdManager.h" #include "Emu/IdManager.h"
#include "Emu/System.h" #include "Emu/System.h"
#include "util/asm.hpp"
#include "generated/np2_structs_generated.h" #include "generated/np2_structs_generated.h"
#ifdef _WIN32 #ifdef _WIN32
@ -421,8 +423,8 @@ bool rpcn_client::manage_connection()
{ {
if (msg.size() == 6) if (msg.size() == 6)
{ {
addr_sig = reinterpret_cast<const le_t<u32>&>(msg[0]); addr_sig = *utils::bless<le_t<u32>>(&msg[0]);
port_sig = reinterpret_cast<const be_t<u16>&>(msg[4]); port_sig = *utils::bless<be_t<u16>>(&msg[4]);
[[maybe_unused]] in_addr orig{}; [[maybe_unused]] in_addr orig{};
orig.s_addr = addr_sig; orig.s_addr = addr_sig;
@ -440,7 +442,7 @@ bool rpcn_client::manage_connection()
{ {
std::vector<u8> ping(9); std::vector<u8> ping(9);
ping[0] = 1; ping[0] = 1;
*reinterpret_cast<le_t<s64>*>(&ping[1]) = user_id; *utils::bless<le_t<s64, 1>>(&ping[1]) = user_id;
if (send_packet_from_p2p_port(ping, addr_rpcn_udp) == -1) if (send_packet_from_p2p_port(ping, addr_rpcn_udp) == -1)
{ {
rpcn_log.error("Failed to send ping to rpcn!"); rpcn_log.error("Failed to send ping to rpcn!");
@ -462,9 +464,9 @@ bool rpcn_client::manage_connection()
} }
const u8 packet_type = header[0]; const u8 packet_type = header[0];
const u16 command = reinterpret_cast<le_t<u16>&>(header[1]); const u16 command = *utils::bless<le_t<u16>>(&header[1]);
const u16 packet_size = reinterpret_cast<le_t<u16>&>(header[3]); const u16 packet_size = *utils::bless<le_t<u16>>(&header[3]);
const u32 packet_id = reinterpret_cast<le_t<u32>&>(header[5]); const u32 packet_id = *utils::bless<le_t<u32>>(&header[5]);
if (packet_size < RPCN_HEADER_SIZE) if (packet_size < RPCN_HEADER_SIZE)
return error_and_disconnect("Invalid packet size"); return error_and_disconnect("Invalid packet size");
@ -844,7 +846,7 @@ bool rpcn_client::search_room(u32 req_id, const SceNpCommunicationId& communicat
} }
flatbuffers::Offset<flatbuffers::Vector<u16>> attrid_vec; flatbuffers::Offset<flatbuffers::Vector<u16>> attrid_vec;
if (req->attrIdNum) if (req->attrIdNum)
attrid_vec = builder.CreateVector(reinterpret_cast<const u16*>(req->attrId.get_ptr()), req->attrIdNum); attrid_vec = builder.CreateVector(utils::bless<const u16>(req->attrId.get_ptr()), req->attrIdNum);
SearchRoomRequestBuilder s_req(builder); SearchRoomRequestBuilder s_req(builder);
s_req.add_option(req->option); s_req.add_option(req->option);
@ -940,7 +942,7 @@ bool rpcn_client::get_roomdata_internal(u32 req_id, const SceNpCommunicationId&
flatbuffers::Offset<flatbuffers::Vector<u16>> final_attr_ids_vec; flatbuffers::Offset<flatbuffers::Vector<u16>> final_attr_ids_vec;
if (req->attrIdNum) if (req->attrIdNum)
final_attr_ids_vec = builder.CreateVector(reinterpret_cast<const u16*>(req->attrId.get_ptr()), req->attrIdNum); final_attr_ids_vec = builder.CreateVector(utils::bless<const u16>(req->attrId.get_ptr()), req->attrIdNum);
auto req_finished = CreateGetRoomDataInternalRequest(builder, req->roomId, final_attr_ids_vec); auto req_finished = CreateGetRoomDataInternalRequest(builder, req->roomId, final_attr_ids_vec);
@ -994,7 +996,7 @@ bool rpcn_client::set_roomdata_internal(u32 req_id, const SceNpCommunicationId&
flatbuffers::Offset<flatbuffers::Vector<u16>> final_ownerprivilege_vec; flatbuffers::Offset<flatbuffers::Vector<u16>> final_ownerprivilege_vec;
if (req->ownerPrivilegeRankNum) if (req->ownerPrivilegeRankNum)
final_ownerprivilege_vec = builder.CreateVector(reinterpret_cast<const u16*>(req->ownerPrivilegeRank.get_ptr()), req->ownerPrivilegeRankNum); final_ownerprivilege_vec = builder.CreateVector(utils::bless<const u16>(req->ownerPrivilegeRank.get_ptr()), req->ownerPrivilegeRankNum);
auto req_finished = auto req_finished =
CreateSetRoomDataInternalRequest(builder, req->roomId, req->flagFilter, req->flagAttr, final_binattrinternal_vec, final_grouppasswordconfig_vec, final_passwordSlotMask, final_ownerprivilege_vec); CreateSetRoomDataInternalRequest(builder, req->roomId, req->flagFilter, req->flagAttr, final_binattrinternal_vec, final_grouppasswordconfig_vec, final_passwordSlotMask, final_ownerprivilege_vec);
@ -1021,7 +1023,7 @@ bool rpcn_client::ping_room_owner(u32 req_id, const SceNpCommunicationId& commun
data.resize(COMMUNICATION_ID_SIZE + sizeof(u64)); data.resize(COMMUNICATION_ID_SIZE + sizeof(u64));
memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE); memcpy(data.data(), communication_id.data, COMMUNICATION_ID_SIZE);
reinterpret_cast<le_t<u64>&>(data[COMMUNICATION_ID_SIZE]) = room_id; *utils::bless<le_t<u64>>(&data[COMMUNICATION_ID_SIZE]) = room_id;
if (!forge_send(CommandType::PingRoomOwner, req_id, data)) if (!forge_send(CommandType::PingRoomOwner, req_id, data))
return false; return false;

View File

@ -5,6 +5,8 @@
#include <chrono> #include <chrono>
#include "Utilities/mutex.h" #include "Utilities/mutex.h"
#include "util/asm.hpp"
#ifdef _WIN32 #ifdef _WIN32
#include <winsock2.h> #include <winsock2.h>
#include <WS2tcpip.h> #include <WS2tcpip.h>
@ -45,7 +47,7 @@ public:
error = true; error = true;
return 0; return 0;
} }
T res = reinterpret_cast<le_t<T>&>(vec[i]); T res = *utils::bless<le_t<T, 1>>(&vec[i]);
i += sizeof(T); i += sizeof(T);
return res; return res;
} }
@ -84,7 +86,7 @@ public:
template <typename T> template <typename T>
void insert(T value) void insert(T value)
{ {
value = reinterpret_cast<le_t<T>>(value); value = std::bit_cast<le_t<T>, T>(value);
// resize + memcpy instead? // resize + memcpy instead?
for (usz index = 0; index < sizeof(T); index++) for (usz index = 0; index < sizeof(T); index++)
{ {

View File

@ -5,6 +5,7 @@
#include "util/to_endian.hpp" #include "util/to_endian.hpp"
#include "util/sysinfo.hpp" #include "util/sysinfo.hpp"
#include "util/asm.hpp"
#include "emmintrin.h" #include "emmintrin.h"
#include "immintrin.h" #include "immintrin.h"
@ -142,8 +143,8 @@ namespace
if (remaining) if (remaining)
{ {
const auto src_ptr2 = reinterpret_cast<const se_t<u32, true, 1>*>(src_ptr); const auto src_ptr2 = utils::bless<const se_t<u32, true, 1>>(src_ptr);
const auto dst_ptr2 = reinterpret_cast<nse_t<u32, 1>*>(dst_ptr); const auto dst_ptr2 = utils::bless<nse_t<u32, 1>>(dst_ptr);
for (u32 i = 0; i < remaining; ++i) for (u32 i = 0; i < remaining; ++i)
dst_ptr2[i] = src_ptr2[i]; dst_ptr2[i] = src_ptr2[i];
@ -220,8 +221,8 @@ namespace
if (remaining) if (remaining)
{ {
const auto src_ptr2 = reinterpret_cast<const se_t<u32, true, 1>*>(src_ptr); const auto src_ptr2 = utils::bless<const se_t<u32, true, 1>>(src_ptr);
const auto dst_ptr2 = reinterpret_cast<nse_t<u32, 1>*>(dst_ptr); const auto dst_ptr2 = utils::bless<nse_t<u32, 1>>(dst_ptr);
for (u32 i = 0; i < remaining; ++i) for (u32 i = 0; i < remaining; ++i)
{ {
@ -285,8 +286,8 @@ namespace
if (remaining) if (remaining)
{ {
auto src_ptr2 = reinterpret_cast<const se_t<u16, true, 1>*>(src_ptr); auto src_ptr2 = utils::bless<const se_t<u16, true, 1>>(src_ptr);
auto dst_ptr2 = reinterpret_cast<nse_t<u16, 1>*>(dst_ptr); auto dst_ptr2 = utils::bless<nse_t<u16, 1>>(dst_ptr);
for (u32 i = 0; i < remaining; ++i) for (u32 i = 0; i < remaining; ++i)
dst_ptr2[i] = src_ptr2[i]; dst_ptr2[i] = src_ptr2[i];
@ -349,8 +350,8 @@ namespace
const u8 attribute_sz = min_block_size >> 2; const u8 attribute_sz = min_block_size >> 2;
for (u32 n = 0; n < remainder; ++n) for (u32 n = 0; n < remainder; ++n)
{ {
auto src_ptr2 = reinterpret_cast<const be_t<u32>*>(src_ptr); auto src_ptr2 = utils::bless<const be_t<u32>>(src_ptr);
auto dst_ptr2 = reinterpret_cast<u32*>(dst_ptr); auto dst_ptr2 = utils::bless<u32>(dst_ptr);
for (u32 v = 0; v < attribute_sz; ++v) for (u32 v = 0; v < attribute_sz; ++v)
dst_ptr2[v] = src_ptr2[v]; dst_ptr2[v] = src_ptr2[v];
@ -415,8 +416,8 @@ namespace
const u8 attribute_sz = min_block_size >> 1; const u8 attribute_sz = min_block_size >> 1;
for (u32 n = 0; n < remainder; ++n) for (u32 n = 0; n < remainder; ++n)
{ {
auto src_ptr2 = reinterpret_cast<const be_t<u16>*>(src_ptr); auto src_ptr2 = utils::bless<const be_t<u16>>(src_ptr);
auto dst_ptr2 = reinterpret_cast<u16*>(dst_ptr); auto dst_ptr2 = utils::bless<u16>(dst_ptr);
for (u32 v = 0; v < attribute_sz; ++v) for (u32 v = 0; v < attribute_sz; ++v)
dst_ptr2[v] = src_ptr2[v]; dst_ptr2[v] = src_ptr2[v];

View File

@ -2,6 +2,8 @@
#include "ds3_pad_handler.h" #include "ds3_pad_handler.h"
#include "Emu/Io/pad_config.h" #include "Emu/Io/pad_config.h"
#include "util/asm.hpp"
LOG_CHANNEL(ds3_log, "DS3"); LOG_CHANNEL(ds3_log, "DS3");
struct ds3_rumble struct ds3_rumble
@ -444,14 +446,14 @@ void ds3_pad_handler::get_extended_info(const std::shared_ptr<PadDevice>& device
#ifdef _WIN32 #ifdef _WIN32
// Official Sony Windows DS3 driver seems to do the same modification of this value as the ps3 // Official Sony Windows DS3 driver seems to do the same modification of this value as the ps3
pad->m_sensors[0].m_value = *reinterpret_cast<le_t<u16, 1>*>(&ds3dev->padData[41 + DS3_HID_OFFSET]); pad->m_sensors[0].m_value = *utils::bless<le_t<u16, 1>>(&ds3dev->padData[41 + DS3_HID_OFFSET]);
#else #else
// When getting raw values from the device this adjustement is needed // When getting raw values from the device this adjustement is needed
pad->m_sensors[0].m_value = 512 - (*reinterpret_cast<le_t<u16, 1>*>(&ds3dev->padData[41]) - 512); pad->m_sensors[0].m_value = 512 - (*utils::bless<le_t<u16, 1>>(&ds3dev->padData[41]) - 512);
#endif #endif
pad->m_sensors[1].m_value = *reinterpret_cast<le_t<u16, 1>*>(&ds3dev->padData[45 + DS3_HID_OFFSET]); pad->m_sensors[1].m_value = *utils::bless<le_t<u16, 1>>(&ds3dev->padData[45 + DS3_HID_OFFSET]);
pad->m_sensors[2].m_value = *reinterpret_cast<le_t<u16, 1>*>(&ds3dev->padData[43 + DS3_HID_OFFSET]); pad->m_sensors[2].m_value = *utils::bless<le_t<u16, 1>>(&ds3dev->padData[43 + DS3_HID_OFFSET]);
pad->m_sensors[3].m_value = *reinterpret_cast<le_t<u16, 1>*>(&ds3dev->padData[47 + DS3_HID_OFFSET]); pad->m_sensors[3].m_value = *utils::bless<le_t<u16, 1>>(&ds3dev->padData[47 + DS3_HID_OFFSET]);
// Those are formulas used to adjust sensor values in sys_hid code but I couldn't find all the vars. // Those are formulas used to adjust sensor values in sys_hid code but I couldn't find all the vars.
//auto polish_value = [](s32 value, s32 dword_0x0, s32 dword_0x4, s32 dword_0x8, s32 dword_0xC, s32 dword_0x18, s32 dword_0x1C) -> u16 //auto polish_value = [](s32 value, s32 dword_0x0, s32 dword_0x4, s32 dword_0x8, s32 dword_0xC, s32 dword_0x18, s32 dword_0x1C) -> u16

View File

@ -2,6 +2,8 @@
#include "custom_dialog.h" #include "custom_dialog.h"
#include "Emu/Cell/Modules/cellMsgDialog.h" #include "Emu/Cell/Modules/cellMsgDialog.h"
#include "util/asm.hpp"
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QLabel> #include <QLabel>
#include <QLineEdit> #include <QLineEdit>
@ -173,7 +175,7 @@ void osk_dialog_frame::Create(const std::string& title, const std::u16string& me
void osk_dialog_frame::SetOskText(const QString& text) void osk_dialog_frame::SetOskText(const QString& text)
{ {
std::memcpy(osk_text, reinterpret_cast<const char16_t*>(text.constData()), (text.size() + 1u) * sizeof(char16_t)); std::memcpy(osk_text, utils::bless<char16_t>(text.constData()), (text.size() + 1u) * sizeof(char16_t));
} }
void osk_dialog_frame::Close(bool accepted) void osk_dialog_frame::Close(bool accepted)

View File

@ -6,6 +6,8 @@
#include "skylander_dialog.h" #include "skylander_dialog.h"
#include "Emu/Io/Skylander.h" #include "Emu/Io/Skylander.h"
#include "util/asm.hpp"
#include <QLabel> #include <QLabel>
#include <QGroupBox> #include <QGroupBox>
#include <QFileDialog> #include <QFileDialog>
@ -643,17 +645,17 @@ skylander_creator_dialog::skylander_creator_dialog(QWidget* parent)
std::array<u8, 0x40 * 0x10> buf{}; std::array<u8, 0x40 * 0x10> buf{};
auto data = buf.data(); auto data = buf.data();
// Set the block permissions // Set the block permissions
reinterpret_cast<le_t<u32>&>(data[0x36]) = 0x690F0F0F; *utils::bless<le_t<u32>>(&data[0x36]) = 0x690F0F0F;
for (u32 index = 1; index < 0x10; index++) for (u32 index = 1; index < 0x10; index++)
{ {
reinterpret_cast<le_t<u32>&>(data[(index * 0x40) + 0x36]) = 0x69080F7F; *utils::bless<le_t<u32>>(&data[(index * 0x40) + 0x36]) = 0x69080F7F;
} }
// Set the skylander infos // Set the skylander infos
reinterpret_cast<le_t<u16>&>(data[0]) = (sky_id | sky_var) + 1; *utils::bless<le_t<u16>>(&data[0]) = (sky_id | sky_var) + 1;
reinterpret_cast<le_t<u16>&>(data[0x10]) = sky_id; *utils::bless<le_t<u16>>(&data[0x10]) = sky_id;
reinterpret_cast<le_t<u16>&>(data[0x1C]) = sky_var; *utils::bless<le_t<u16>>(&data[0x1C]) = sky_var;
// Set checksum // Set checksum
reinterpret_cast<le_t<u16>&>(data[0x1E]) = skylander_crc16(0xFFFF, data, 0x1E); *utils::bless<le_t<u16>>(&data[0x1E]) = skylander_crc16(0xFFFF, data, 0x1E);
sky_file.write(buf.data(), buf.size()); sky_file.write(buf.data(), buf.size());
sky_file.close(); sky_file.close();