📄 stream.cc
字号:
#include <sys/types.h>#include <sys/stat.h>#include <errno.h>#include <string>#include "basictypes.h"#include "common.h"#include "stream.h"#include "stringencode.h"#ifdef WIN32#include "win32.h"#define fileno _fileno#endifnamespace utils_base {///////////////////////////////////////////////////////////////////////////////StreamResult StreamInterface::WriteAll(const void* data, size_t data_len, size_t* written, int* error) { StreamResult result = SR_SUCCESS; size_t total_written = 0, current_written; while (total_written < data_len) { result = Write(static_cast<const char*>(data) + total_written, data_len - total_written, ¤t_written, error); if (result != SR_SUCCESS) break; total_written += current_written; } if (written) *written = total_written; return result;}StreamResult StreamInterface::ReadAll(void* buffer, size_t buffer_len, size_t* read, int* error) { StreamResult result = SR_SUCCESS; size_t total_read = 0, current_read; while (total_read < buffer_len) { result = Read(static_cast<char*>(buffer) + total_read, buffer_len - total_read, ¤t_read, error); if (result != SR_SUCCESS) break; total_read += current_read; } if (read) *read = total_read; return result;}StreamResult StreamInterface::ReadLine(std::string* line) { StreamResult result = SR_SUCCESS; while (true) { char ch; result = Read(&ch, sizeof(ch), NULL, NULL); if (result != SR_SUCCESS) { break; } if (ch == '\n') { break; } line->push_back(ch); } if (!line->empty()) { // give back the line we've collected so far with result = SR_SUCCESS; // a success code. Otherwise return the last code } return result;}///////////////////////////////////////////////////////////////////////////////// StreamTap///////////////////////////////////////////////////////////////////////////////StreamTap::StreamTap(StreamInterface* stream, StreamInterface* tap): StreamAdapterInterface(stream), tap_(NULL), tap_result_(SR_SUCCESS), tap_error_(0){ AttachTap(tap);}void StreamTap::AttachTap(StreamInterface* tap) { tap_.reset(tap);}StreamInterface* StreamTap::DetachTap() { return tap_.release();}StreamResult StreamTap::GetTapResult(int* error) { if (error) { *error = tap_error_; } return tap_result_;}StreamResult StreamTap::Read(void* buffer, size_t buffer_len, size_t* read, int* error) { size_t backup_read; if (!read) { read = &backup_read; } StreamResult res = StreamAdapterInterface::Read(buffer, buffer_len, read, error); if ((res == SR_SUCCESS) && (tap_result_ == SR_SUCCESS)) { tap_result_ = tap_->WriteAll(buffer, *read, NULL, &tap_error_); } return res;}StreamResult StreamTap::Write(const void* data, size_t data_len, size_t* written, int* error) { size_t backup_written; if (!written) { written = &backup_written; } StreamResult res = StreamAdapterInterface::Write(data, data_len, written, error); if ((res == SR_SUCCESS) && (tap_result_ == SR_SUCCESS)) { tap_result_ = tap_->WriteAll(data, *written, NULL, &tap_error_); } return res;}///////////////////////////////////////////////////////////////////////////////// NullStream///////////////////////////////////////////////////////////////////////////////NullStream::NullStream() {}NullStream::~NullStream() {}StreamState NullStream::GetState() const { return SS_OPEN;}StreamResult NullStream::Read(void* buffer, size_t buffer_len, size_t* read, int* error) { if (error) *error = -1; return SR_ERROR;}StreamResult NullStream::Write(const void* data, size_t data_len, size_t* written, int* error) { if (written) *written = data_len; return SR_SUCCESS;}void NullStream::Close() {}bool NullStream::GetSize(size_t* size) const { if (size) *size = 0; return true;}bool NullStream::ReserveSize(size_t size) { return true;}bool NullStream::Rewind() { return false;}///////////////////////////////////////////////////////////////////////////////// FileStream///////////////////////////////////////////////////////////////////////////////FileStream::FileStream() : file_(NULL) {}FileStream::~FileStream() { FileStream::Close();}bool FileStream::Open(const std::string& filename, const char* mode) { Close();#ifdef WIN32 int filenamelen = MultiByteToWideChar(CP_UTF8, 0, filename.c_str(), (int)filename.length() + 1, NULL, 0); int modelen = MultiByteToWideChar(CP_UTF8, 0, mode, -1, NULL, 0); wchar_t *wfilename = new wchar_t[filenamelen+4]; // 4 for "\\?\" wchar_t *wfilename_dest = wfilename; wchar_t *wmode = new wchar_t[modelen]; if (!filename.empty() && (filename[0] != '\\')) { wcscpy(wfilename, L"\\\\?\\"); wfilename_dest = wfilename + 4; } if ((MultiByteToWideChar(CP_UTF8, 0, filename.c_str(), (int)filename.length() + 1, wfilename_dest, filenamelen) > 0) && (MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, modelen) > 0)) { file_ = _wfopen(wfilename, wmode); } else { file_ = NULL; } delete[] wfilename; delete[] wmode;#else file_ = fopen(filename.c_str(), mode);#endif return (file_ != NULL);}bool FileStream::OpenShare(const std::string& filename, const char* mode, int shflag) { Close();#ifdef WIN32 int filenamelen = MultiByteToWideChar(CP_UTF8, 0, filename.c_str(), (int)filename.length() + 1, NULL, 0); int modelen = MultiByteToWideChar(CP_UTF8, 0, mode, -1, NULL, 0); wchar_t *wfilename = new wchar_t[filenamelen+4]; // 4 for "\\?\" wchar_t *wfilename_dest = wfilename; wchar_t *wmode = new wchar_t[modelen]; if (!filename.empty() && (filename[0] != '\\')) { wcscpy(wfilename, L"\\\\?\\"); wfilename_dest = wfilename + 4; } if ((MultiByteToWideChar(CP_UTF8, 0, filename.c_str(), (int)filename.length() + 1, wfilename_dest, filenamelen) > 0) && (MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, modelen) > 0)) { file_ = _wfsopen(wfilename, wmode, shflag); } else { file_ = NULL; } delete[] wfilename; delete[] wmode;#else return Open(filename, mode);#endif return (file_ != NULL);}bool FileStream::DisableBuffering() { if (!file_) return false; return (setvbuf(file_, NULL, _IONBF, 0) == 0);}StreamState FileStream::GetState() const { return (file_ == NULL) ? SS_CLOSED : SS_OPEN;}StreamResult FileStream::Read(void* buffer, size_t buffer_len, size_t* read, int* error) { if (!file_) return SR_EOS; size_t result = fread(buffer, 1, buffer_len, file_); if ((result == 0) && (buffer_len > 0)) { if (feof(file_)) return SR_EOS; if (error) *error = errno; return SR_ERROR; } if (read) *read = result; return SR_SUCCESS;}StreamResult FileStream::Write(const void* data, size_t data_len, size_t* written, int* error) { if (!file_) return SR_EOS; size_t result = fwrite(data, 1, data_len, file_); if ((result == 0) && (data_len > 0)) { if (error) *error = errno; return SR_ERROR; } if (written) *written = result; return SR_SUCCESS;}void FileStream::Close() { if (file_) { fclose(file_); file_ = NULL; }}bool FileStream::SetPosition(size_t position) { if (!file_) return false; return (fseek(file_, (long)position, SEEK_SET) == 0);}bool FileStream::GetPosition(size_t * position) const { ASSERT(position != NULL); if (!file_ || !position) return false; long result = ftell(file_); if (result < 0) return false; *position = result; return true;}bool FileStream::GetSize(size_t * size) const { ASSERT(size != NULL); if (!file_ || !size) return false; struct stat file_stats; if (fstat(fileno(file_), &file_stats) != 0) return false; *size = file_stats.st_size; return true;}bool FileStream::ReserveSize(size_t size) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -