"Fossies" - the Fresh Open Source Software Archive

Member "poppler-0.82.0/utils/InMemoryFile.cc" (25 Oct 2019, 2592 Bytes) of package /linux/misc/poppler-0.82.0.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "InMemoryFile.cc" see the Fossies "Dox" file reference documentation.

    1 //========================================================================
    2 //
    3 // InMemoryFile.cc
    4 //
    5 // Represents a file in-memory with GNU's stdio wrappers.
    6 // NOTE as of this writing, open() depends on the glibc 'fopencookie'
    7 // extension and is not supported on other platforms. The
    8 // HAVE_IN_MEMORY_FILE macro is intended to reflect whether this class is
    9 // usable.
   10 //
   11 // This file is licensed under the GPLv2 or later
   12 //
   13 // Copyright (C) 2018, 2019 Greg Knight <lyngvi@gmail.com>
   14 //
   15 //========================================================================
   16 
   17 #include "InMemoryFile.h"
   18 
   19 #include <string.h>
   20 #include <sstream>
   21 
   22 InMemoryFile::InMemoryFile()
   23     : iohead(0)
   24     , fptr(nullptr)
   25 {
   26 }
   27 
   28 #ifdef HAVE_IN_MEMORY_FILE_FOPENCOOKIE
   29 ssize_t InMemoryFile::_read(char* buf, size_t sz)
   30 {
   31     auto toRead = std::min<size_t>(data.size() - iohead, sz);
   32     memcpy(&buf[0], &data[iohead], toRead);
   33     iohead += toRead;
   34     return toRead;
   35 }
   36 
   37 ssize_t InMemoryFile::_write(const char* buf, size_t sz)
   38 {
   39     if (iohead + sz > data.size())
   40         data.resize(iohead + sz);
   41     memcpy(&data[iohead], buf, sz);
   42     iohead += sz;
   43     return sz;        
   44 }
   45 
   46 int InMemoryFile::_seek(off64_t* offset, int whence)
   47 {
   48     switch (whence) {
   49         case SEEK_SET: iohead  = (*offset); break;
   50         case SEEK_CUR: iohead += (*offset); break;
   51         case SEEK_END: iohead -= (*offset); break;
   52     }
   53     (*offset) = std::min<off64_t>(std::max<off64_t>(iohead, 0l), data.size());
   54     iohead = static_cast<size_t>(*offset);
   55     return 0;
   56 }
   57 #endif // def HAVE_IN_MEMORY_FILE_FOPENCOOKIE
   58 
   59 FILE* InMemoryFile::open(const char* mode)
   60 {
   61 #ifdef HAVE_IN_MEMORY_FILE_FOPENCOOKIE
   62     if (fptr != nullptr) {
   63         fprintf(stderr, "InMemoryFile: BUG: Why is this opened more than once?");
   64         return nullptr; // maybe there's some legit reason for it, whoever comes up with one can remove this line
   65     }
   66     static cookie_io_functions_t methods = {
   67         /* .read = */ [](void* self, char* buf, size_t sz) { return ((InMemoryFile*)self)->_read(buf, sz); },
   68         /* .write = */ [](void* self, const char* buf, size_t sz) { return ((InMemoryFile*)self)->_write(buf, sz); },
   69         /* .seek = */ [](void* self, off64_t* offset, int whence) { return ((InMemoryFile*)self)->_seek(offset, whence); },
   70         /* .close = */ [](void* self) { ((InMemoryFile*)self)->fptr = nullptr; return 0; },
   71     };
   72     return fptr = fopencookie(this, mode, methods);
   73 #else
   74     fprintf (stderr, "If you can read this, your platform does not support the features necessary to achieve your goals.");
   75     return nullptr;
   76 #endif
   77 }