diff options
author | qrort <qrort@yandex-team.com> | 2022-11-30 23:47:12 +0300 |
---|---|---|
committer | qrort <qrort@yandex-team.com> | 2022-11-30 23:47:12 +0300 |
commit | 22f8ae0e3f5d68b92aecccdf96c1d841a0334311 (patch) | |
tree | bffa27765faf54126ad44bcafa89fadecb7a73d7 /library/cpp/deprecated | |
parent | 332b99e2173f0425444abb759eebcb2fafaa9209 (diff) | |
download | ydb-22f8ae0e3f5d68b92aecccdf96c1d841a0334311.tar.gz |
validate canons without yatest_common
Diffstat (limited to 'library/cpp/deprecated')
-rw-r--r-- | library/cpp/deprecated/autoarray/README.md | 3 | ||||
-rw-r--r-- | library/cpp/deprecated/autoarray/autoarray.cpp | 1 | ||||
-rw-r--r-- | library/cpp/deprecated/autoarray/autoarray.h | 264 | ||||
-rw-r--r-- | library/cpp/deprecated/datafile/README.md | 3 | ||||
-rw-r--r-- | library/cpp/deprecated/datafile/datafile.cpp | 42 | ||||
-rw-r--r-- | library/cpp/deprecated/datafile/datafile.h | 88 | ||||
-rw-r--r-- | library/cpp/deprecated/datafile/loadmode.cpp | 1 | ||||
-rw-r--r-- | library/cpp/deprecated/datafile/loadmode.h | 20 | ||||
-rw-r--r-- | library/cpp/deprecated/fgood/README.md | 15 | ||||
-rw-r--r-- | library/cpp/deprecated/fgood/ffb.cpp | 407 | ||||
-rw-r--r-- | library/cpp/deprecated/fgood/ffb.h | 264 | ||||
-rw-r--r-- | library/cpp/deprecated/fgood/fgood.cpp | 70 | ||||
-rw-r--r-- | library/cpp/deprecated/fgood/fgood.h | 328 | ||||
-rw-r--r-- | library/cpp/deprecated/fgood/fput.h | 79 | ||||
-rw-r--r-- | library/cpp/deprecated/mapped_file/mapped_file.cpp | 64 |
15 files changed, 1649 insertions, 0 deletions
diff --git a/library/cpp/deprecated/autoarray/README.md b/library/cpp/deprecated/autoarray/README.md new file mode 100644 index 0000000000..1d83147cee --- /dev/null +++ b/library/cpp/deprecated/autoarray/README.md @@ -0,0 +1,3 @@ +Pre-C++11 vector-like container. + +Just use std::vector. If you need to fill your vector with custom-constructed data, use reserve+emplace_back (but make sure that your elements are movable). diff --git a/library/cpp/deprecated/autoarray/autoarray.cpp b/library/cpp/deprecated/autoarray/autoarray.cpp new file mode 100644 index 0000000000..15167f27f6 --- /dev/null +++ b/library/cpp/deprecated/autoarray/autoarray.cpp @@ -0,0 +1 @@ +#include "autoarray.h" diff --git a/library/cpp/deprecated/autoarray/autoarray.h b/library/cpp/deprecated/autoarray/autoarray.h new file mode 100644 index 0000000000..2aa12c5916 --- /dev/null +++ b/library/cpp/deprecated/autoarray/autoarray.h @@ -0,0 +1,264 @@ +#pragma once + +#include <util/system/compat.h> +#include <util/system/yassert.h> +#include <util/system/defaults.h> +#include <util/system/sys_alloc.h> + +#include <util/generic/typetraits.h> +#include <utility> + +#include <new> +#include <util/generic/noncopyable.h> + +struct autoarray_getindex { + autoarray_getindex() = default; +}; + +struct aarr_b0 { + aarr_b0() = default; +}; + +struct aarr_nofill { + aarr_nofill() = default; +}; + +template <typename T> +struct ynd_type_traits { + enum { + empty_destructor = TTypeTraits<T>::IsPod, + }; +}; + +template <class T> +class autoarray : TNonCopyable { +protected: + T* arr; + size_t _size; + +private: + void AllocBuf(size_t siz) { + arr = nullptr; + _size = 0; + if (siz) { + arr = (T*)y_allocate(sizeof(T) * siz); + _size = siz; + } + } + +public: + using value_type = T; + using iterator = T*; + using const_iterator = const T*; + + autoarray() + : arr(nullptr) + , _size(0) + { + } + autoarray(size_t siz) { + AllocBuf(siz); + T* curr = arr; + try { + for (T* end = arr + _size; curr != end; ++curr) + new (curr) T(); + } catch (...) { + for (--curr; curr >= arr; --curr) + curr->~T(); + y_deallocate(arr); + throw; + } + } + template <class A> + explicit autoarray(size_t siz, A& fill) { + AllocBuf(siz); + T* curr = arr; + try { + for (T* end = arr + _size; curr != end; ++curr) + new (curr) T(fill); + } catch (...) { + for (--curr; curr >= arr; --curr) + curr->~T(); + y_deallocate(arr); + throw; + } + } + explicit autoarray(size_t siz, autoarray_getindex) { + AllocBuf(siz); + size_t nCurrent = 0; + try { + for (nCurrent = 0; nCurrent < _size; ++nCurrent) + new (&arr[nCurrent]) T(nCurrent); + } catch (...) { + for (size_t n = 0; n < nCurrent; ++n) + arr[n].~T(); + y_deallocate(arr); + throw; + } + } + explicit autoarray(size_t siz, aarr_b0) { + AllocBuf(siz); + memset(arr, 0, _size * sizeof(T)); + } + explicit autoarray(size_t siz, aarr_nofill) { + AllocBuf(siz); + } + template <class A> + explicit autoarray(const A* fill, size_t siz) { + AllocBuf(siz); + size_t nCurrent = 0; + try { + for (nCurrent = 0; nCurrent < _size; ++nCurrent) + new (&arr[nCurrent]) T(fill[nCurrent]); + } catch (...) { + for (size_t n = 0; n < nCurrent; ++n) + arr[n].~T(); + y_deallocate(arr); + throw; + } + } + template <class A, class B> + explicit autoarray(const A* fill, const B* cfill, size_t siz) { + AllocBuf(siz); + size_t nCurrent = 0; + try { + for (nCurrent = 0; nCurrent < _size; ++nCurrent) + new (&arr[nCurrent]) T(fill[nCurrent], cfill); + } catch (...) { + for (size_t n = 0; n < nCurrent; ++n) + arr[n].~T(); + y_deallocate(arr); + throw; + } + } + template <class A> + explicit autoarray(const A* fill, size_t initsiz, size_t fullsiz) { + AllocBuf(fullsiz); + size_t nCurrent = 0; + try { + for (nCurrent = 0; nCurrent < ((initsiz < _size) ? initsiz : _size); ++nCurrent) + new (&arr[nCurrent]) T(fill[nCurrent]); + for (; nCurrent < _size; ++nCurrent) + new (&arr[nCurrent]) T(); + } catch (...) { + for (size_t n = 0; n < nCurrent; ++n) + arr[n].~T(); + y_deallocate(arr); + throw; + } + } + template <class A> + explicit autoarray(const A* fill, size_t initsiz, size_t fullsiz, const T& dummy) { + AllocBuf(fullsiz); + size_t nCurrent = 0; + try { + for (nCurrent = 0; nCurrent < ((initsiz < _size) ? initsiz : _size); ++nCurrent) + new (&arr[nCurrent]) T(fill[nCurrent]); + for (; nCurrent < _size; ++nCurrent) + new (&arr[nCurrent]) T(dummy); + } catch (...) { + for (size_t n = 0; n < nCurrent; ++n) + arr[n].~T(); + y_deallocate(arr); + throw; + } + } + + template <class... R> + explicit autoarray(size_t siz, R&&... fill) { + AllocBuf(siz); + T* curr = arr; + try { + for (T* end = arr + _size; curr != end; ++curr) + new (curr) T(std::forward<R>(fill)...); + } catch (...) { + for (--curr; curr >= arr; --curr) + curr->~T(); + y_deallocate(arr); + throw; + } + } + ~autoarray() { + if (_size) { + if (!ynd_type_traits<T>::empty_destructor) + for (T *curr = arr, *end = arr + _size; curr != end; ++curr) + curr->~T(); + y_deallocate(arr); + } + } + T& operator[](size_t pos) { + Y_ASSERT(pos < _size); + return arr[pos]; + } + const T& operator[](size_t pos) const { + Y_ASSERT(pos < _size); + return arr[pos]; + } + size_t size() const { + return _size; + } + void swap(autoarray& with) { + T* tmp_arr = arr; + size_t tmp_size = _size; + arr = with.arr; + _size = with._size; + with.arr = tmp_arr; + with._size = tmp_size; + } + void resize(size_t siz) { + autoarray<T> tmp(arr, _size, siz); + swap(tmp); + } + void resize(size_t siz, const T& dummy) { + autoarray<T> tmp(arr, _size, siz, dummy); + swap(tmp); + } + T* rawpointer() { + return arr; + } + const T* operator~() const { + return arr; + } + T* begin() { + return arr; + } + T* end() { + return arr + _size; + } + T& back() { + Y_ASSERT(_size); + return arr[_size - 1]; + } + bool empty() const { + return !_size; + } + bool operator!() const { + return !_size; + } + size_t operator+() const { + return _size; + } + const T* begin() const { + return arr; + } + const T* end() const { + return arr + _size; + } + const T& back() const { + Y_ASSERT(_size); + return arr[_size - 1]; + } + //operator T*() { return arr; } +}; + +template <class T> +inline bool operator==(const autoarray<T>& a, const autoarray<T>& b) { + size_t count = a.size(); + if (count != b.size()) + return false; + for (size_t i = 0; i < count; ++i) { + if (a[i] != b[i]) + return false; + } + return true; +} diff --git a/library/cpp/deprecated/datafile/README.md b/library/cpp/deprecated/datafile/README.md new file mode 100644 index 0000000000..7f8547108e --- /dev/null +++ b/library/cpp/deprecated/datafile/README.md @@ -0,0 +1,3 @@ +A wrapper on top of some user-defined custom file format. + +Just write your own if you need it. It's going to be way easier than figuring out how to use this one. diff --git a/library/cpp/deprecated/datafile/datafile.cpp b/library/cpp/deprecated/datafile/datafile.cpp new file mode 100644 index 0000000000..ff93f11c6b --- /dev/null +++ b/library/cpp/deprecated/datafile/datafile.cpp @@ -0,0 +1,42 @@ +#include "datafile.h" + +void TDataFileBase::DoLoad(const char* fname, int loadMode) { + Destroy(); + TFile f(fname, RdOnly); + DoLoad(f, loadMode, nullptr, 0); +} + +void TDataFileBase::DoLoad(TFile& f, int loadMode, void* hdrPtr, size_t hdrSize) { + if (hdrPtr) { + if (loadMode & DLM_EXACT_SIZE && f.GetLength() != (i64)Length) + throw yexception() << f.GetName() << " size does not match its header value"; + } else { + Length = f.GetLength(); + hdrSize = 0; + } + if ((loadMode & DLM_LD_TYPE_MASK) == DLM_READ) { + MemData = TVector<char>(Length); + memcpy(MemData.begin(), hdrPtr, hdrSize); + f.Load(MemData.begin() + hdrSize, Length - hdrSize); + Start = MemData.begin(); + } else { + FileData.init(f); + if (FileData.getSize() < Length) + throw yexception() << f.GetName() << " is smaller than what its header value says"; + if ((loadMode & DLM_LD_TYPE_MASK) == DLM_MMAP_PRC) + FileData.precharge(); + Start = (const char*)FileData.getData(); + } +} + +void TDataFileBase::Destroy() { + TVector<char>().swap(MemData); + FileData.term(); + Start = nullptr; + Length = 0; +} + +void TDataFileBase::Precharge() const { + if (Length && Start == (char*)FileData.getData()) + FileData.precharge(); +} diff --git a/library/cpp/deprecated/datafile/datafile.h b/library/cpp/deprecated/datafile/datafile.h new file mode 100644 index 0000000000..a438baceca --- /dev/null +++ b/library/cpp/deprecated/datafile/datafile.h @@ -0,0 +1,88 @@ +#pragma once + +#include "loadmode.h" + +#include <library/cpp/deprecated/mapped_file/mapped_file.h> + +#include <util/generic/vector.h> +#include <util/system/file.h> +#include <util/system/filemap.h> + +/** Simple helper that allows a file to be either mapped or read into malloc'ed memory. + This behaviour is controlled by EDataLoadMode enum defined in loadmode.h. + Unlike TBlob it provides Precharge() function and simple file size - based integrity check. + + To use this code, inherit your class from TDataFile<TFileHeader>. + TFileHeader must be a pod-type structure with byte layout of the file header. + File must start with that header. + TFileHeader must have FileSize() member function that determines expected file size or + length of data that need to be read from the beginning of file. + */ + +class TDataFileBase { +protected: + TVector<char> MemData; + TMappedFile FileData; + + const char* Start; + size_t Length; + + TDataFileBase() + : Start(nullptr) + , Length(0) + { + } + + void DoLoad(TFile& f, int loadMode, void* hdrPtr, size_t hdrSize); + void DoLoad(const char* fname, int loadMode); // just whole file + void Destroy(); + void swap(TDataFileBase& with) { + MemData.swap(with.MemData); + FileData.swap(with.FileData); + DoSwap(Start, with.Start); + DoSwap(Length, with.Length); + } + +public: + void Precharge() const; +}; + +template <class TFileHeader> +class TDataFile: public TDataFileBase { +protected: + void Load(const char* fname, EDataLoadMode loadMode) { + Destroy(); + TFile f(fname, RdOnly | Seq); + TFileHeader hdr; + f.Load(&hdr, sizeof(hdr)); + Length = hdr.FileSize(); + DoLoad(f, (int)loadMode, &hdr, sizeof(hdr)); + } + const TFileHeader& Hdr() const { + return *(TFileHeader*)Start; + } +}; + +// Use: class TFoo: public TDataFileEx<Foo> {...}; +// Additional requrement: TFileHeader must have Validate(fname) function that throws exception. +// Class TUser itself must have Init(fname) function +// Adds Load() function to your class (TUser) +template <class TUser, class TFileHeader> +class TDataFileEx: public TDataFile<TFileHeader> { +private: + using TBase = TDataFile<TFileHeader>; + TUser& User() const { + return *(TUser*)this; + } + +public: + TDataFileEx(const char* fname, EDataLoadMode loadMode = DLM_DEFAULT) { + if (fname) + Load(fname, loadMode); + } + void Load(const char* fname, EDataLoadMode loadMode = DLM_DEFAULT) { + TBase::Load(fname, loadMode); + TBase::Hdr().Validate(fname); + User().Init(fname); + } +}; diff --git a/library/cpp/deprecated/datafile/loadmode.cpp b/library/cpp/deprecated/datafile/loadmode.cpp new file mode 100644 index 0000000000..a857830326 --- /dev/null +++ b/library/cpp/deprecated/datafile/loadmode.cpp @@ -0,0 +1 @@ +#include "loadmode.h" diff --git a/library/cpp/deprecated/datafile/loadmode.h b/library/cpp/deprecated/datafile/loadmode.h new file mode 100644 index 0000000000..f04054dd64 --- /dev/null +++ b/library/cpp/deprecated/datafile/loadmode.h @@ -0,0 +1,20 @@ +#pragma once + +// It is recommended to support all reasonal value combinations via this enum, +// to let Load() function argument be of EDataLoadMode type, not just int type + +enum EDataLoadMode { + DLM_READ = 0, + DLM_MMAP_PRC = 1, // precharge + DLM_MMAP = 2, // w/o precharge + DLM_MMAP_AUTO_PRC = 3, // precharge automatically (same as DLM_MMAP unless specifically supported) + DLM_LD_TYPE_MASK = 15, + DLM_EXACT_SIZE = 16, // fail if input file is larger than what header says + + DLM_READ_ESZ = DLM_READ | DLM_EXACT_SIZE, + DLM_MMAP_PRC_ESZ = DLM_MMAP_PRC | DLM_EXACT_SIZE, + DLM_MMAP_ESZ = DLM_MMAP | DLM_EXACT_SIZE, + DLM_MMAP_APRC_ESZ = DLM_MMAP_AUTO_PRC | DLM_EXACT_SIZE, + + DLM_DEFAULT = DLM_MMAP_PRC_ESZ, +}; diff --git a/library/cpp/deprecated/fgood/README.md b/library/cpp/deprecated/fgood/README.md new file mode 100644 index 0000000000..4f66289657 --- /dev/null +++ b/library/cpp/deprecated/fgood/README.md @@ -0,0 +1,15 @@ +Some ancient wrappers on top of FILE*, and some string manupulation functions. + +Alternatives are as follows. + +For TFILEPtr. Use TIFStream or TOFStream if you need IO. For some rare use cases a TFileMap might also do. + +For fput/fget/getline. Use streams API. + +For struct ffb and struct prnstr. Just don't use them. Even if you can figure out what they do. + +For sf family of functions and TLineSplitter. Just use Split* from util/string/split.h + +For TSFReader. Use TMapTsvFile. + +For read_or_die family of functions. Use streams API. diff --git a/library/cpp/deprecated/fgood/ffb.cpp b/library/cpp/deprecated/fgood/ffb.cpp new file mode 100644 index 0000000000..aa9da861a6 --- /dev/null +++ b/library/cpp/deprecated/fgood/ffb.cpp @@ -0,0 +1,407 @@ +#include "ffb.h" + +#include <util/string/util.h> // str_spn +#include <util/system/compat.h> +#include <util/generic/yexception.h> + +#include <cstdio> +#include <algorithm> + +#include <ctype.h> + +#ifdef _win_ +#include <io.h> +#else +#include <unistd.h> +#endif + +ffb::ffb(FILE* file) + : TFILEPtr(file) +{ + if (file && !isatty(fileno(file)) && BUFSIZ < 512 * 1024) + setvbuf(file, nullptr, _IOFBF, 512 * 1024); +} + +void ffb::operator=(FILE* f) { + TFILEPtr::operator=(f); + if (f && !isatty(fileno(f)) && BUFSIZ < 512 * 1024) + setvbuf(f, nullptr, _IOFBF, 512 * 1024); +} + +void ffb::open(const char* name, const char* mode) { + TFILEPtr::open(name, mode); + if (!isatty(fileno(*this)) && BUFSIZ < 512 * 1024) + setvbuf(*this, nullptr, _IOFBF, 512 * 1024); +} + +int sf(char** fb, char* buf) { //don't want to call sf(fb, buf, 32) + if (!(*buf && *buf != 10)) { + *fb = nullptr; + return 0; + } + int n = 1; + fb[0] = buf; + while (*buf && *buf != 10 && n < 31) { + if (*buf == '\t') { + *buf++ = 0; + fb[n++] = buf; + continue; + } + buf++; + } + if (*buf == 10 && buf[-1] == 13) + buf[-1] = 0; + *buf = 0; + fb[n] = nullptr; + return n; +} + +int sf(char** fb, char* buf, size_t fb_sz) { + if (!(*buf && *buf != 10)) { + *fb = nullptr; + return 0; + } + fb_sz--; + int n = 1; + fb[0] = buf; + while (*buf && *buf != 10 && n < (int)fb_sz) { + if (*buf == '\t') { + *buf++ = 0; + fb[n++] = buf; + continue; + } + buf++; + } + if (*buf == 10 && buf[-1] == 13) + buf[-1] = 0; + *buf = 0; + fb[n] = nullptr; + return n; +} + +inline int sf_blank(char** fb, char* buf, size_t fb_sz) { + while (isspace((ui8)*buf)) + buf++; + if (!*buf) { + *fb = nullptr; + return 0; + } + fb_sz--; + int n = 1; + fb[0] = buf; + while (*buf && *buf != 10 && n < (int)fb_sz) { + if (isspace((ui8)*buf)) { + *buf++ = 0; + while (isspace((ui8)*buf)) + buf++; + if (*buf) + fb[n++] = buf; + continue; + } + buf++; + } + if (*buf == 10 && buf[-1] == 13) + buf[-1] = 0; + *buf = 0; + fb[n] = nullptr; + return n; +} + +int sf(char fs, char** fb, char* buf, size_t fb_sz) { + if (fs == ' ') + return sf_blank(fb, buf, fb_sz); + while (*buf == fs) + buf++; + if (!(*buf && *buf != 10)) { + *fb = nullptr; + return 0; + } + fb_sz--; + int n = 1; + fb[0] = buf; + while (*buf && *buf != 10 && n < (int)fb_sz) { + if (*buf == fs) { + *buf++ = 0; + while (*buf == fs) + buf++; + fb[n++] = buf; + continue; + } + buf++; + } + if (*buf == 10 && buf[-1] == 13) + buf[-1] = 0; + *buf = 0; + fb[n] = nullptr; + return n; +} + +int sf(const char* fs, char** fb, char* buf, size_t fb_sz) { + if (!(*buf && *buf != 10)) { + *fb = nullptr; + return 0; + } + int fs_len = strlen(fs); + fb_sz--; + int n = 1; + fb[0] = buf; + while (*buf && *buf != 10 && n < (int)fb_sz) { + if (*buf == *fs && !strncmp(buf + 1, fs + 1, fs_len - 1)) { + *buf = 0; + buf += fs_len; + fb[n++] = buf; + continue; + } + buf++; + } + if (*buf == 10 && buf[-1] == 13) + buf[-1] = 0; + *buf = 0; + fb[n] = nullptr; + return n; +} + +inline bool is_end(const char* p) { + return !p || !p[0]; +} + +int sf(const char* seps, char* buf, char** fb, size_t fb_sz) { + if (fb_sz < 1 || is_end(buf)) { + *fb = nullptr; + return 0; + } + str_spn sseps(seps); + fb[0] = nullptr; + int n = 0; + // skip leading delimeters + buf = sseps.cbrk(buf); + if (is_end(buf)) + return 0; + // store fields + while (n < (int)fb_sz) { + fb[n++] = buf; + // find delimeters + buf = sseps.brk(buf + 1); + if (is_end(buf)) + break; + *buf = 0; + // skip delimiters + buf = sseps.cbrk(buf + 1); + if (is_end(buf)) + break; + } + fb[n] = nullptr; + return n; +} + +void TLineSplitter::operator()(char* p, TVector<char*>& fields) const { + if (!p || !*p) + return; + char* q = p; + while (1) { + p = Sep.brk(p); + if (q && (p - q || !SkipEmpty())) + fields.push_back(q); + q = nullptr; + if (!*p) + break; + if (SepStrLen == 1 || (SepStrLen > 1 && !strncmp(p + 1, SepStr + 1, SepStrLen - 1))) { + *p = 0; + p += SepStrLen; + q = p; + } else + p++; + } +} + +void TLineSplitter::operator()(const char* p, TVector<std::pair<const char*, size_t>>& fields) const { + if (!p || !*p) + return; + const char* q = p; + while (1) { + p = Sep.brk(p); + if (q && (p - q || !SkipEmpty())) + fields.push_back(std::make_pair(q, p - q)); + q = nullptr; + if (!*p) + break; + if (SepStrLen == 1 || (SepStrLen > 1 && !strncmp(p + 1, SepStr + 1, SepStrLen - 1))) { + p += SepStrLen; + q = p; + } else + p++; + } +} + +TSFReader::TSFReader(const char* fname, char sep, i32 nfrq) // if sep == ' ' isspace will be imitated (for compat) + : Split(str_spn(sep == ' ' ? "\t\n\v\f\r " : TString(1, sep).data()), sep == ' ') + , OpenPipe(false) +{ + Open(fname, nfrq); +} + +TSFReader::TSFReader(const char* fname, const char* sep, i32 nfrq) + : Split(sep, false) + , OpenPipe(false) +{ + Open(fname, nfrq); +} + +TSFReader::TSFReader(const char* fname, const TLineSplitter& spl, i32 nfrq) + : Split(spl) + , OpenPipe(false) +{ + Open(fname, nfrq); +} + +void TSFReader::Open(const char* fname, i32 nfrq, size_t vbuf_size) { + FieldsRequired = nfrq; + NF = NR = 0; + + if (IsOpen()) + File.close(); + + if (!fname) + return; + + if (!strcmp(fname, "/dev/stdin")) { + File.assign(stdin, "/dev/stdin"); + } else { + if (OpenPipe) + File.popen(fname, "r"); + else + File.open(fname, "r"); + } + OpenPipe = false; + if (!isatty(fileno(File))) + setvbuf(File, nullptr, _IOFBF, vbuf_size); +} + +void TSFReader::Popen(const char* pname, i32 nfrq, size_t vbuf_size) { + OpenPipe = true; + Open(pname, nfrq, vbuf_size); +} + +bool TSFReader::NextLine(segmented_string_pool* pool) { + size_t line_len = 0; + +#ifdef __FreeBSD__ + char* ptr = fgetln(File, &line_len); + if (!ptr) + return false; + if (!line_len || ptr[line_len - 1] != '\n') { // last line w/o newline + Buf.AssignNoAlias(ptr, line_len); + ptr = Buf.begin(); + } else { + // can safely replace newline with \0 + ptr[line_len - 1] = 0; + --line_len; + } +#else + if (!getline(File, Buf)) + return false; + char* ptr = Buf.begin(); + line_len = Buf.size(); +#endif + if (line_len && ptr[line_len - 1] == '\r') + ptr[line_len - 1] = 0; + + if (pool) { + char* nptr = pool->append(ptr); + Y_ASSERT(!strcmp(ptr, nptr)); + ptr = nptr; + } + + ++NR; + Fields.clear(); + Split(ptr, Fields); + NF = Fields.size(); + + if (FieldsRequired != -1 && FieldsRequired != (int)NF) + ythrow yexception() << File.name() << " line " << NR << ": " << NF << " fields, expected " << FieldsRequired; + + return true; +} + +int prnstr::f(const char* c, ...) { + va_list params; + int n = asize - pos, k; + va_start(params, c); + while ((k = vsnprintf(buf + pos, n, c, params)) >= n) { + n += asize, asize *= 2; + while (k + pos >= n) + n += asize, asize *= 2; + char* t = new char[asize]; + memcpy(t, buf, pos); + delete[] buf; + buf = t; + va_end(params); + va_start(params, c); + } + pos += k; + va_end(params); + return k; +} +int prnstr::s(const char* c, size_t k) { + if (!c) + return 0; + size_t n = asize - pos; + if (k >= n) { + n += asize, asize *= 2; + while (k + pos >= n) + n += asize, asize *= 2; + char* t = new char[asize]; + memcpy(t, buf, pos); + delete[] buf; + buf = t; + } + memcpy(buf + pos, c, k); + pos += k; + buf[pos] = 0; + return k; +} +void prnstr::clear() { + pos = 0; + if (asize > 32768) { + asize = 32768; + delete[] buf; + buf = new char[asize]; + } +} + +void prnstr::swap(prnstr& w) { + std::swap(buf, w.buf); + std::swap(pos, w.pos); + std::swap(asize, w.asize); +} + +FILE* read_or_die(const char* fname) { + FILE* f = fopen(fname, "rb"); + if (!f) + err(1, "%s", fname); + return f; +} +FILE* write_or_die(const char* fname) { + FILE* f = fopen(fname, "wb"); + if (!f) + err(1, "%s", fname); + return f; +} +FILE* fopen_or_die(const char* fname, const char* mode) { + FILE* f = fopen(fname, mode); + if (!f) + err(1, "%s (mode '%s')", fname, mode); + return f; +} + +FILE* fopen_chk(const char* fname, const char* mode) { + FILE* f = fopen(fname, mode); + if (!f) + ythrow yexception() << fname << " (mode '" << mode << "'): " << LastSystemErrorText(); + return f; +} + +void fclose_chk(FILE* f, const char* fname) { + if (fclose(f)) + ythrow yexception() << "file " << fname << ": " << LastSystemErrorText(); +} diff --git a/library/cpp/deprecated/fgood/ffb.h b/library/cpp/deprecated/fgood/ffb.h new file mode 100644 index 0000000000..ca229eb65a --- /dev/null +++ b/library/cpp/deprecated/fgood/ffb.h @@ -0,0 +1,264 @@ +#pragma once + +#include "fgood.h" + +#include <util/string/util.h> // str_spn +#include <util/string/split.h> // str_spn +#include <util/memory/segmented_string_pool.h> +#include <util/generic/string.h> +#include <util/generic/vector.h> +#include <util/generic/noncopyable.h> + +#include <utility> + +#include <cstdarg> +#include <cstring> + +struct ffb: public TFILEPtr { + ffb() { + } + ffb(FILE* file); + ffb(const char* name, const char* mode) { + open(name, mode); + } + void operator=(FILE* f); // take ownership + void open(const char* name, const char* mode); + int f(const char* c, ...) { + va_list args; + va_start(args, c); + return vfprintf(*this, c, args); + } + void s(const char* c) { + fsput(c, strlen(c)); + } + void b(const void* cc, int n) { + fsput((const char*)cc, n); + } + void B(const void* cc, int N) { + fsput((const char*)cc, N); + } + void c(char c) { + fputc(c); + } + void cbe(wchar16 c) { // big endian utf-16 + fputc(char(c >> 8)); //Hi8 + fputc(char(c & 255)); //Lo8 + } + void sbe(const wchar16* c) { + for (; *c; c++) + cbe(*c); + } + void fclose() { + close(); + } +}; + +// split fields of tab-delimited line of text +// here and below fb actual size must be fb_sz + 1 to allow fb[fb_sz] be zero +int sf(char** fb, char* buf, size_t fb_sz); +int sf(char** fb, char* buf /* fb_sz == 32 */); + +// split fields of char-delimited line of text +// Achtung: delim = ' ' imitates awk: initial separators are skipped, +// repeated seps treated as one, all chars less than ' ' treated as separators. +int sf(char fs, char** fb, char* buf, size_t fb_sz = 32); + +// split fields of string-delimited line of text (fs is NOT a regexp) +// (usually fs is "@@") +int sf(const char* fs, char** fb, char* buf, size_t fb_sz = 32); + +// split fields of char-delimited line of text, set of char-separators is given +// Achtung: repeated seps treated as one, initial seps are skipped +// newlines are NOT ignored. +int sf(const char* seps, char* buf, char** fb, size_t fb_sz = 32); + +inline char* chomp(char* buf) { + char* c = buf + strlen(buf); + if (c > buf && c[-1] == '\n') { + *--c = 0; +#ifdef _win32_ + if (c > buf && c[-1] == '\r') + *--c = 0; +#endif + } + return buf; +} + +inline char* chomp_cr(char* buf) { + char* c = buf + strlen(buf); + if (c > buf && c[-1] == '\n') + *--c = 0; + if (c > buf && c[-1] == '\r') + *--c = 0; + return buf; +} + +class TLineSplitter { +protected: + enum { // Default: Split string by SepStr + SplitByAnySep = 1, // Split string by Sep + NoEmptyFields = 2 // Skip all empty fields between separators + }; + +private: + ui32 Flags; + const str_spn Sep; // collection of separators + const char* SepStr; // pointer exact string to separate by + size_t SepStrLen; // length of separator string + +public: + TLineSplitter(const char* sep, bool noEmpty) + : Flags(noEmpty ? NoEmptyFields : 0) + , Sep(TString(sep, 1).data()) + , SepStr(sep) + , SepStrLen(strlen(sep)) + { + } + TLineSplitter(const str_spn& sep, bool noEmpty = false) + : Flags(SplitByAnySep | (noEmpty ? NoEmptyFields : 0)) + , Sep(sep) + , SepStr(nullptr) + , SepStrLen(1) + { + } + bool AnySep() const { + return Flags & SplitByAnySep; + } + bool SkipEmpty() const { + return Flags & NoEmptyFields; + } + /// Separates string onto tokens + /// Expecting a zero-terminated string + /// By default returns empty fields between sequential separators + void operator()(char* p, TVector<char*>& fields) const; + /// Same, but for const string - fills vector of pairs (pointer, length) + void operator()(const char* p, TVector<std::pair<const char*, size_t>>& fields) const; +}; + +/** + * Use library/cpp/map_text_file/map_tsv_file.h instead. + */ +class TSFReader { + TString Buf; // buffer used for non-'\n'-terminated string and for non-freebsd work + TLineSplitter Split; + TVector<char*> Fields; + size_t NF; // Fields.size() + size_t NR; + + TFILEPtr File; + + bool OpenPipe; // internal flag that turns open() to popen() + + i32 FieldsRequired; // if != -1, != nf, terminate program + +public: + // char separator + // Achtung: delim = ' ' imitates awk: initial separators are skipped, + // all chars less than ' ' treated as separators. + TSFReader(const char* fname = nullptr, char sep = '\t', i32 nf_reqired = -1); + // exact string separator + TSFReader(const char* fname, const char* sep, i32 nf_reqired = -1); + // fully customizable + TSFReader(const char* fname, const TLineSplitter& spl, i32 nf_reqired = -1); + + void Open(const char* fname, i32 nf_reqired = -1, size_t vbufsize = 1u << 21); // use "/dev/stdin" for stdin + void Popen(const char* pname, i32 nf_reqired = -1, size_t vbufsize = 1u << 21); + + bool NextLine(segmented_string_pool* pool = nullptr); + + bool IsOpen() const { + return (FILE*)File != nullptr; + } + bool IsEof() const { + return feof(File); + } + void Close() { + File.close(); + } + void Rewind() { + File.seek(0, SEEK_SET); + } + void Seek(i64 offset, int mode = SEEK_SET) { + File.seek(offset, mode); + } + i64 Tell() const { + return ftell(File); + } + char*& operator[](size_t ind) { + //if (ind >= NF) + // throw yexception("Can't return reference to unexisting field %" PRISZT, ind); + return Fields[ind]; + } + const char* operator[](size_t ind) const { + if (ind >= NF) + return nullptr; + return Fields[ind]; + } + operator int() const { // note: empty input line makes 0 fields + return (int)NF; + } + const char* Name() const { + return File.name().data(); + } + size_t Line() const { + return NR; + } + const TVector<char*>& GetFields() const { + return Fields; + } +}; + +struct prnstr { + char* buf; + int pos; + int asize; + prnstr() + : pos(0) + { + asize = 32; + buf = new char[asize]; + } + explicit prnstr(int asz) + : pos(0) + { + asize = asz; + buf = new char[asize]; + } + int f(const char* c, ...); + int s(const char* c1, const char* c2); + int s(const char* c1, const char* c2, const char* c3); + int s(const char* c, size_t len); + //int s(const char *c); + int s(const char* c) { + return c ? s(c, strlen(c)) : 0; + } + int s(const TString& c); + int s_htmesc(const char* c, bool enc_utf = false); + int s_htmesc_w(const char* c); + int c(char c); + int cu(wchar32 c); //for utf-8 + void restart() { + *buf = 0; + pos = 0; + } + const char* operator~() const { + return buf; + } + int operator+() const { + return pos; + } + ~prnstr() { + delete[] buf; + } + void clear(); + void swap(prnstr& w); +}; + +// functions that terminate program upon failure +FILE* read_or_die(const char* fname); +FILE* write_or_die(const char* fname); +FILE* fopen_or_die(const char* fname, const char* mode); + +// functions that throw upon failure +FILE* fopen_chk(const char* fname, const char* mode); +void fclose_chk(FILE* f, const char* fname_dbg); diff --git a/library/cpp/deprecated/fgood/fgood.cpp b/library/cpp/deprecated/fgood/fgood.cpp new file mode 100644 index 0000000000..5d4725bfae --- /dev/null +++ b/library/cpp/deprecated/fgood/fgood.cpp @@ -0,0 +1,70 @@ +#include "fgood.h" + +#include <util/generic/cast.h> +#include <util/string/cast.h> +#include <util/system/fstat.h> + +#ifdef _win32_ +#include <io.h> +#endif + +i64 TFILEPtr::length() const { +#ifdef _win32_ + FHANDLE fd = (FHANDLE)_get_osfhandle(fileno(m_file)); +#else + FHANDLE fd = fileno(m_file); +#endif + i64 rv = GetFileLength(fd); + if (rv < 0) + ythrow yexception() << "TFILEPtr::length() " << Name.data() << ": " << LastSystemErrorText(); + return rv; +} + +FILE* OpenFILEOrFail(const TString& name, const char* mode) { + FILE* res = ::fopen(name.data(), mode); + if (!res) { + ythrow yexception() << "can't open \'" << name << "\' with mode \'" << mode << "\': " << LastSystemErrorText(); + } + return res; +} + +void TFILECloser::Destroy(FILE* file) { + ::fclose(file); +} + +#ifdef _freebsd_ // fgetln +#define getline getline_alt_4test +#endif // _freebsd_ + +bool getline(TFILEPtr& f, TString& s) { + char buf[4096]; + char* buf_ptr; + if (s.capacity() > sizeof(buf)) { + s.resize(s.capacity()); + if ((buf_ptr = fgets(s.begin(), IntegerCast<int>(s.capacity()), f)) == nullptr) + return false; + } else { + if ((buf_ptr = fgets(buf, sizeof(buf), f)) == nullptr) + return false; + } + size_t buf_len = strlen(buf_ptr); + bool line_complete = buf_len && buf_ptr[buf_len - 1] == '\n'; + if (line_complete) + buf_len--; + if (buf_ptr == s.begin()) + s.resize(buf_len); + else + s.AssignNoAlias(buf, buf_len); + if (line_complete) + return true; + while (fgets(buf, sizeof(buf), f)) { + size_t buf_len2 = strlen(buf); + if (buf_len2 && buf[buf_len2 - 1] == '\n') { + buf[buf_len2 - 1] = 0; + s.append(buf, buf_len2 - 1); + return true; + } + s.append(buf, buf_len2); + } + return true; +} diff --git a/library/cpp/deprecated/fgood/fgood.h b/library/cpp/deprecated/fgood/fgood.h new file mode 100644 index 0000000000..0aaf910c0f --- /dev/null +++ b/library/cpp/deprecated/fgood/fgood.h @@ -0,0 +1,328 @@ +#pragma once + +#include <util/system/yassert.h> +#include <util/system/defaults.h> +#include <util/generic/string.h> +#include <util/generic/yexception.h> +#include <util/generic/ptr.h> + +#include "fput.h" + +#include <cstdio> + +#include <fcntl.h> + +#ifdef _unix_ +extern "C" int __ungetc(int, FILE*); +#endif + +#if (!defined(__FreeBSD__) && !defined(__linux__) && !defined(_darwin_) && !defined(_cygwin_)) || defined(_bionic_) +#define feof_unlocked(_stream) feof(_stream) +#define ferror_unlocked(_stream) ferror(_stream) +#endif + +#ifndef _unix_ +#if defined(_MSC_VER) && (_MSC_VER < 1900) +#define getc_unlocked(_stream) (--(_stream)->_cnt >= 0 ? 0xff & *(_stream)->_ptr++ : _filbuf(_stream)) +#define putc_unlocked(_c, _stream) (--(_stream)->_cnt >= 0 ? 0xff & (*(_stream)->_ptr++ = (char)(_c)) : _flsbuf((_c), (_stream))) +#else +#define getc_unlocked(_stream) getc(_stream) +#define putc_unlocked(_c, _stream) putc(_c, _stream) +#endif +#endif + +inline bool fgood(FILE* f) { + return !feof_unlocked(f) && !ferror_unlocked(f); +} + +#ifdef _win32_ +// These functions will work only with static MSVC runtime linkage. For dynamic linkage, +// fseeki64.c and ftelli64.c from CRT sources should be included in project +extern "C" int __cdecl _fseeki64(FILE*, __int64, int); +extern "C" __int64 __cdecl _ftelli64(FILE*); + +inline i64 ftello(FILE* stream) { + return _ftelli64(stream); +} + +inline int fseeko(FILE* stream, i64 offset, int origin) { + return _fseeki64(stream, offset, origin); +} +#endif + +class TFILEPtr { +private: + enum { SHOULD_CLOSE = 1, + IS_PIPE = 2 }; + FILE* m_file; + int m_Flags; + TString Name; + +public: + TFILEPtr() noexcept { + m_file = nullptr; + m_Flags = 0; + } + TFILEPtr(const TString& name, const char* mode) { + m_file = nullptr; + m_Flags = 0; + open(name, mode); + } + TFILEPtr(const TFILEPtr& src) noexcept { + m_file = src.m_file; + m_Flags = 0; + } + TFILEPtr& operator=(const TFILEPtr& src) { + if (src.m_file != m_file) { + close(); + m_file = src.m_file; + m_Flags = 0; + } + return *this; + } + explicit TFILEPtr(FILE* f) noexcept { // take ownership + m_file = f; + m_Flags = SHOULD_CLOSE; + } + TFILEPtr& operator=(FILE* f) { // take ownership + if (f != m_file) { + close(); + m_file = f; + m_Flags = SHOULD_CLOSE; + } + return *this; + } + const TString& name() const { + return Name; + } + operator FILE*() const noexcept { + return m_file; + } + FILE* operator->() const noexcept { + return m_file; + } + bool operator!() const noexcept { + return m_file == nullptr; + } + bool operator!=(FILE* f) const noexcept { + return m_file != f; + } + bool operator==(FILE* f) const noexcept { + return m_file == f; + } + ~TFILEPtr() { + close(); + } + void Y_PRINTF_FORMAT(2, 3) check(const char* message, ...) const { + if (Y_UNLIKELY(!fgood(m_file))) { + va_list args; + va_start(args, message); + char buf[512]; + vsnprintf(buf, 512, message, args); + // XXX: errno is undefined here + ythrow yexception() << buf << ": " << LastSystemErrorText() << ", " << Name.data() << " at offset " << (i64)ftell(); + } + } + TFILEPtr& assign(FILE* f, const char* name = nullptr) { // take ownership and have a name + *this = f; + if (name) + Name = name; + return *this; + } + void open(const TString& name, const char* mode) { + Y_ASSERT(!name.empty()); + Y_ASSERT(m_file == nullptr); + m_file = ::fopen(name.data(), mode); + if (!m_file) + ythrow yexception() << "can't open \'" << name << "\' with mode \'" << mode << "\': " << LastSystemErrorText(); + m_Flags = SHOULD_CLOSE; + Name = name; + } + void popen(const TString& command, const char* mode) { + Y_ASSERT(!command.empty()); + Y_ASSERT(m_file == nullptr); + m_file = ::popen(command.data(), mode); + if (!m_file) + ythrow yexception() << "can't execute \'" << command << "\' with mode \'" << mode << "\': " << LastSystemErrorText(); + m_Flags = IS_PIPE | SHOULD_CLOSE; + Name = command; + } + void close() { + if (m_file != nullptr && (m_Flags & SHOULD_CLOSE)) { + if ((m_Flags & IS_PIPE) ? ::pclose(m_file) : ::fclose(m_file)) { + m_file = nullptr; + m_Flags = 0; + if (!UncaughtException()) + ythrow yexception() << "can't close file " << Name.data() << ": " << LastSystemErrorText(); + } + } + m_file = nullptr; + m_Flags = 0; + Name.clear(); + } + size_t write(const void* buffer, size_t size, size_t count) const { + Y_ASSERT(m_file != nullptr); + size_t r = ::fwrite(buffer, size, count, m_file); + check("can't write %lu bytes", (unsigned long)size * count); + return r; + } + size_t read(void* buffer, size_t size, size_t count) const { + Y_ASSERT(m_file != nullptr); + size_t r = ::fread(buffer, size, count, m_file); + if (ferror_unlocked(m_file)) + ythrow yexception() << "can't read " << (unsigned long)size * count << " bytes: " << LastSystemErrorText() << ", " << Name.data() << " at offset " << (i64)ftell(); + return r; + } + char* fgets(char* buffer, int size) const { + Y_ASSERT(m_file != nullptr); + char* r = ::fgets(buffer, size, m_file); + if (ferror_unlocked(m_file)) + ythrow yexception() << "can't read string of maximum size " << size << ": " << LastSystemErrorText() << ", " << Name.data() << " at offset " << (i64)ftell(); + return r; + } + void Y_PRINTF_FORMAT(2, 3) fprintf(const char* format, ...) { + Y_ASSERT(m_file != nullptr); + va_list args; + va_start(args, format); + vfprintf(m_file, format, args); + check("can't write"); + } + void seek(i64 offset, int origin) const { + Y_ASSERT(m_file != nullptr); +#if defined(_unix_) || defined(_win32_) + if (fseeko(m_file, offset, origin) != 0) +#else + Y_ASSERT(offset == (i64)(i32)offset); + if (::fseek(m_file, (long)offset, origin) != 0) +#endif + ythrow yexception() << "can't seek " << Name.data() << " by " << offset << ": " << LastSystemErrorText(); + } + i64 length() const; // uses various system headers -> in fileptr.cpp + + void setDirect() const { +#if !defined(_win_) && !defined(_darwin_) + if (!m_file) + ythrow yexception() << "file not open"; + if (fcntl(fileno(m_file), F_SETFL, O_DIRECT) == -1) + ythrow yexception() << "Cannot set O_DIRECT flag"; +#endif + } + + // for convenience + + i64 ftell() const noexcept { +#if defined(_unix_) || defined(_win32_) + return ftello(m_file); +#else + return ftell(m_file); +#endif + } + bool eof() const noexcept { + Y_ASSERT(m_file != nullptr); + return feof_unlocked(m_file) != 0; + } + int fputc(int c) { + Y_ASSERT(m_file != nullptr); + return putc_unlocked(c, m_file); + } + size_t fputs(const char* buffer) const { + return write(buffer, strlen(buffer), 1); + } + int fgetc() { + Y_ASSERT(m_file != nullptr); + return getc_unlocked(m_file); + } + int ungetc(int c) { + Y_ASSERT(m_file != nullptr); + return ::ungetc(c, m_file); + } + template <class T> + size_t fput(const T& a) { + Y_ASSERT(m_file != nullptr); + return ::fput(m_file, a); + } + template <class T> + size_t fget(T& a) { + Y_ASSERT(m_file != nullptr); + return ::fget(m_file, a); + } + size_t fsput(const char* s, size_t l) { + Y_ASSERT(m_file != nullptr); + return ::fsput(m_file, s, l); + } + size_t fsget(char* s, size_t l) { + Y_ASSERT(m_file != nullptr); + return ::fsget(m_file, s, l); + } + + void fflush() { + ::fflush(m_file); + } + + /* This block contains some TFile/TStream - compatible names */ + size_t Read(void* bufferIn, size_t numBytes) { + size_t r = fsget((char*)bufferIn, numBytes); + if (Y_UNLIKELY(ferror_unlocked(m_file))) + ythrow yexception() << "can't read " << numBytes << " bytes: " << LastSystemErrorText() << ", " << Name << " at offset " << (i64)ftell(); + return r; + } + void Write(const void* buffer, size_t numBytes) { + write(buffer, 1, numBytes); + } + i64 Seek(i64 offset, int origin /*SeekDir*/) { + seek(offset, origin); + return ftell(); + } + i64 GetPosition() const noexcept { + return ftell(); + } + i64 GetLength() const noexcept { + return length(); + } + bool ReadLine(TString& st); + + /* Similar to TAutoPtr::Release - return pointer and forget about it. */ + FILE* Release() noexcept { + FILE* result = m_file; + m_file = nullptr; + m_Flags = 0; + Name.clear(); + return result; + } +}; + +inline void fclose(TFILEPtr& F) { + F.close(); +} + +inline void fseek(const TFILEPtr& F, i64 offset, int whence) { + F.seek(offset, whence); +} + +#ifdef _freebsd_ // fgetln +inline bool getline(TFILEPtr& f, TString& s) { + size_t len; + char* buf = fgetln(f, &len); + if (!buf) + return false; + if (len && buf[len - 1] == '\n') + len--; + s.AssignNoAlias(buf, len); + return true; +} +#else +bool getline(TFILEPtr& f, TString& s); +#endif //_freebsd_ + +inline bool TFILEPtr::ReadLine(TString& st) { + return getline(*this, st); +} + +FILE* OpenFILEOrFail(const TString& name, const char* mode); + +//Should be used with THolder +struct TFILECloser { + static void Destroy(FILE* file); +}; + +using TFILEHolder = THolder<FILE, TFILECloser>; diff --git a/library/cpp/deprecated/fgood/fput.h b/library/cpp/deprecated/fgood/fput.h new file mode 100644 index 0000000000..690b06332d --- /dev/null +++ b/library/cpp/deprecated/fgood/fput.h @@ -0,0 +1,79 @@ +#pragma once + +#include <util/system/defaults.h> +#include <util/system/valgrind.h> + +#include <cstdio> + +#ifdef __FreeBSD__ +#include <cstring> + +template <class T> +Y_FORCE_INLINE size_t fput(FILE* F, const T& a) { + if (Y_LIKELY(F->_w >= int(sizeof(a)))) { + memcpy(F->_p, &a, sizeof(a)); + F->_p += sizeof(a); + F->_w -= sizeof(a); + return 1; + } else { + return fwrite(&a, sizeof(a), 1, F); + } +} + +template <class T> +Y_FORCE_INLINE size_t fget(FILE* F, T& a) { + if (Y_LIKELY(F->_r >= int(sizeof(a)))) { + memcpy(&a, F->_p, sizeof(a)); + F->_p += sizeof(a); + F->_r -= sizeof(a); + return 1; + } else { + return fread(&a, sizeof(a), 1, F); + } +} + +inline size_t fsput(FILE* F, const char* s, size_t l) { + VALGRIND_CHECK_READABLE(s, l); + + if ((size_t)F->_w >= l) { + memcpy(F->_p, s, l); + F->_p += l; + F->_w -= l; + return l; + } else { + return fwrite(s, 1, l, F); + } +} + +inline size_t fsget(FILE* F, char* s, size_t l) { + if ((size_t)F->_r >= l) { + memcpy(s, F->_p, l); + F->_p += l; + F->_r -= l; + return l; + } else { + return fread(s, 1, l, F); + } +} +#else +template <class T> +Y_FORCE_INLINE size_t fput(FILE* F, const T& a) { + return fwrite(&a, sizeof(a), 1, F); +} + +template <class T> +Y_FORCE_INLINE size_t fget(FILE* F, T& a) { + return fread(&a, sizeof(a), 1, F); +} + +inline size_t fsput(FILE* F, const char* s, size_t l) { +#ifdef WITH_VALGRIND + VALGRIND_CHECK_READABLE(s, l); +#endif + return fwrite(s, 1, l, F); +} + +inline size_t fsget(FILE* F, char* s, size_t l) { + return fread(s, 1, l, F); +} +#endif diff --git a/library/cpp/deprecated/mapped_file/mapped_file.cpp b/library/cpp/deprecated/mapped_file/mapped_file.cpp new file mode 100644 index 0000000000..b0e4511299 --- /dev/null +++ b/library/cpp/deprecated/mapped_file/mapped_file.cpp @@ -0,0 +1,64 @@ +#include "mapped_file.h" + +#include <util/generic/yexception.h> +#include <util/system/defaults.h> +#include <util/system/hi_lo.h> +#include <util/system/filemap.h> + +TMappedFile::TMappedFile(TFileMap* map, const char* dbgName) { + Map_ = map; + i64 len = Map_->Length(); + if (Hi32(len) != 0 && sizeof(size_t) <= sizeof(ui32)) + ythrow yexception() << "File '" << dbgName << "' mapping error: " << len << " too large"; + + Map_->Map(0, static_cast<size_t>(len)); +} + +TMappedFile::TMappedFile(const TFile& file, TFileMap::EOpenMode om, const char* dbgName) + : Map_(nullptr) +{ + init(file, om, dbgName); +} + +void TMappedFile::precharge(size_t off, size_t size) const { + if (!Map_) + return; + + Map_->Precharge(off, size); +} + +void TMappedFile::init(const TString& name) { + THolder<TFileMap> map(new TFileMap(name)); + TMappedFile newFile(map.Get(), name.data()); + Y_UNUSED(map.Release()); + newFile.swap(*this); + newFile.term(); +} + +void TMappedFile::init(const TString& name, size_t length, TFileMap::EOpenMode om) { + THolder<TFileMap> map(new TFileMap(name, length, om)); + TMappedFile newFile(map.Get(), name.data()); + Y_UNUSED(map.Release()); + newFile.swap(*this); + newFile.term(); +} + +void TMappedFile::init(const TFile& file, TFileMap::EOpenMode om, const char* dbgName) { + THolder<TFileMap> map(new TFileMap(file, om)); + TMappedFile newFile(map.Get(), dbgName); + Y_UNUSED(map.Release()); + newFile.swap(*this); + newFile.term(); +} + +void TMappedFile::init(const TString& name, TFileMap::EOpenMode om) { + THolder<TFileMap> map(new TFileMap(name, om)); + TMappedFile newFile(map.Get(), name.data()); + Y_UNUSED(map.Release()); + newFile.swap(*this); + newFile.term(); +} + +void TMappedFile::flush() { + Map_->Flush(); +} |