CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Common/Buffer.cpp
Views: 1401
#include <cstdarg>1#include <cstdlib>2#include <cstring>34#include "Common/Buffer.h"5#include "Common/File/FileUtil.h"6#include "Common/File/Path.h"7#include "Common/Log.h"89Buffer::Buffer() { }10Buffer::~Buffer() { }1112char *Buffer::Append(size_t length) {13if (length > 0) {14size_t old_size = data_.size();15data_.resize(old_size + length);16return &data_[0] + old_size;17} else {18return nullptr;19}20}2122void Buffer::Append(const std::string &str) {23char *ptr = Append(str.size());24if (ptr) {25memcpy(ptr, str.data(), str.size());26}27}2829void Buffer::Append(const char *str) {30size_t len = strlen(str);31char *dest = Append(len);32memcpy(dest, str, len);33}3435void Buffer::Append(const Buffer &other) {36size_t len = other.size();37if (len > 0) {38char *dest = Append(len);39memcpy(dest, &other.data_[0], len);40}41}4243void Buffer::AppendValue(int value) {44char buf[16];45// This is slow.46snprintf(buf, sizeof(buf), "%i", value);47Append(buf);48}4950void Buffer::Take(size_t length, std::string *dest) {51if (length > data_.size()) {52ERROR_LOG(Log::IO, "Truncating length in Buffer::Take()");53length = data_.size();54}55dest->resize(length);56if (length > 0) {57Take(length, &(*dest)[0]);58}59}6061void Buffer::Take(size_t length, char *dest) {62memcpy(dest, &data_[0], length);63data_.erase(data_.begin(), data_.begin() + length);64}6566int Buffer::TakeLineCRLF(std::string *dest) {67int after_next_line = OffsetToAfterNextCRLF();68if (after_next_line < 0) {69return after_next_line;70} else {71_dbg_assert_(after_next_line >= 2);72if (after_next_line != 2)73Take((size_t)after_next_line - 2, dest);74Skip(2); // Skip the CRLF75return after_next_line - 2;76}77}7879void Buffer::Skip(size_t length) {80if (length > data_.size()) {81ERROR_LOG(Log::IO, "Truncating length in Buffer::Skip()");82length = data_.size();83}84data_.erase(data_.begin(), data_.begin() + length);85}8687int Buffer::SkipLineCRLF() {88int after_next_line = OffsetToAfterNextCRLF();89if (after_next_line < 0) {90return after_next_line;91} else {92Skip(after_next_line);93return after_next_line - 2;94}95}9697int Buffer::OffsetToAfterNextCRLF() {98for (int i = 0; i < (int)data_.size() - 1; i++) {99if (data_[i] == '\r' && data_[i + 1] == '\n') {100return i + 2;101}102}103return -1;104}105106void Buffer::Printf(const char *fmt, ...) {107char buffer[2048];108va_list vl;109va_start(vl, fmt);110size_t retval = vsnprintf(buffer, sizeof(buffer), fmt, vl);111if ((int)retval >= (int)sizeof(buffer)) {112// Output was truncated. TODO: Do something.113ERROR_LOG(Log::IO, "Buffer::Printf truncated output");114}115if ((int)retval < 0) {116ERROR_LOG(Log::IO, "Buffer::Printf failed");117}118va_end(vl);119char *ptr = Append(retval);120memcpy(ptr, buffer, retval);121}122123bool Buffer::FlushToFile(const Path &filename) {124FILE *f = File::OpenCFile(filename, "wb");125if (!f)126return false;127if (data_.size()) {128fwrite(&data_[0], 1, data_.size(), f);129}130fclose(f);131return true;132}133134void Buffer::PeekAll(std::string *dest) {135dest->resize(data_.size());136memcpy(&(*dest)[0], &data_[0], data_.size());137}138139140