직렬화 버퍼에서 가장 많이 사용하는 데이터 유형 중 하나가 문자열입니다.
오늘은 string을 <<, >>를 오버로딩을 통해 사용하는 방법에 대해 알아보겠습니다.
기본적으로 직렬화 버퍼의 <<, >>를 오버로딩 할 때 가장 중요한 점은, 짝을 맞추는 것이라고 생각합니다.
넣는 방법과 동일하게 빼야 합니다.
string에서 필요한 정보는 기본적으로 문자열 데이터 그 자체와, 그 문자열의 크기입니다.
크기를 알아야 이어지는 문자열을 직렬화 버퍼에서 정확하게 빼올 수 있습니다.
string과 wstring
string은 한글자를 1byte wstring은 wide_char를 사용하기 때문에 글자당 2byte를 먹습니다.
https://basaeng.tistory.com/31
[뇌를 자극하는 윈도우즈 시스템 프로그래밍] 2장. 아스키코드 vs 유니코드
https://basaeng.tistory.com/3 컴퓨터로 문자를 표현하는 법개요컴퓨터는 언제나 0과 1만 인식할 수 있다. 모든 문자는 이진수로 변환되어 저장되고 이진수가 다시 문자로 변환되어 우리에게 보이게 된
basaeng.tistory.com
operator<<
string에서 직렬화 버퍼로 데이터를 옮기는 operator입니다.
꺼낼 때 length, data순서로 꺼내야하기 때문에 넣을 때도 동일한 순서인 length, data로 넣어야합니다.
건실하게 read pointer, write pointer, data size 등 필요한 요소들을 변경해주면 됩니다.
MessageStream& MessageStream::operator<<(const std::string& value)
{
const int length = static_cast<int>(value.size());
if (writePos_ + static_cast<int>(sizeof(length)) + length > bufferSize_)
{
throw std::out_of_range("Buffer overflow in operator<<");
}
std::memcpy(buffer_.data() + writePos_, &length, sizeof(length));
writePos_ += static_cast<int>(sizeof(length));
std::memcpy(buffer_.data() + writePos_, value.data(), length);
writePos_ += length;
dataSize_ += static_cast<int>(sizeof(length)) + length;
return *this;
}
MessageStream& MessageStream::operator<<(const std::wstring& value)
{
const int length = static_cast<int>(value.size());
const int bytes = length * static_cast<int>(sizeof(wchar_t));
if (writePos_ + static_cast<int>(sizeof(length)) + bytes > bufferSize_)
{
throw std::out_of_range("Buffer overflow in operator<<");
}
std::memcpy(buffer_.data() + writePos_, &length, sizeof(length));
writePos_ += static_cast<int>(sizeof(length));
std::memcpy(buffer_.data() + writePos_, value.data(), bytes);
writePos_ += bytes;
dataSize_ += static_cast<int>(sizeof(length)) + bytes;
return *this;
}
operator>>
직렬화 버퍼에서 string으로 데이터를 꺼내는 operator입니다.
꺼낼 때 length, data순서로 꺼냅니다.
string자체의 세팅은 단순히 대입만으로 되지 않기 때문에 string의 assign을 사용할 것입니다.
MessageStream& MessageStream::operator>>(std::string& value)
{
int length = 0;
if (readPos_ + static_cast<int>(sizeof(length)) > writePos_)
{
throw std::out_of_range("Buffer underflow in operator>>");
}
std::memcpy(&length, buffer_.data() + readPos_, sizeof(length));
readPos_ += static_cast<int>(sizeof(length));
if (readPos_ + length > writePos_)
{
throw std::out_of_range("Buffer underflow in operator>>");
}
value.assign(buffer_.data() + readPos_, length);
readPos_ += length;
dataSize_ -= static_cast<int>(sizeof(length)) + length;
return *this;
}
MessageStream& MessageStream::operator>>(std::wstring& value)
{
int length = 0;
if (readPos_ + static_cast<int>(sizeof(length)) > writePos_)
{
throw std::out_of_range("Buffer underflow in operator>>");
}
std::memcpy(&length, buffer_.data() + readPos_, sizeof(length));
readPos_ += static_cast<int>(sizeof(length));
const int bytes = length * static_cast<int>(sizeof(wchar_t));
if (readPos_ + bytes > writePos_)
{
throw std::out_of_range("Buffer underflow in operator>>");
}
value.assign(reinterpret_cast<const wchar_t*>(buffer_.data() + readPos_), length);
readPos_ += bytes;
dataSize_ -= static_cast<int>(sizeof(length)) + bytes;
return *this;
}
'CS > 프밍 잡지식' 카테고리의 다른 글
| Overlapped I/O 알아보기 - 2 (0) | 2025.12.09 |
|---|---|
| Overlapped I/O 알아보기 - 1 (0) | 2025.12.04 |
| 컴퓨터의 시간측정 응용 - FixedUpdate (1) | 2025.07.03 |
| 함수 호출 시 일어나는 일 (0) | 2025.06.29 |
| switch case 그리고 점프 테이블 (1) | 2025.04.17 |