Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RRawFileWin.cxx
Go to the documentation of this file.
1 // @(#)root/io:$Id$
2 // Author: Jakob Blomer
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2018, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "ROOT/RRawFileWin.hxx"
13 #include "ROOT/RMakeUnique.hxx"
14 
15 #include "TError.h"
16 
17 #include <cerrno>
18 #include <cstddef>
19 #include <cstdint>
20 #include <cstdio>
21 #include <cstring>
22 #include <stdexcept>
23 #include <string>
24 
25 namespace {
26 constexpr int kDefaultBlockSize = 4096; // Read files in 4k pages unless told otherwise
27 } // anonymous namespace
28 
29 ROOT::Internal::RRawFileWin::RRawFileWin(std::string_view url, ROptions options)
30  : RRawFile(url, options), fFilePtr(nullptr)
31 {
32 }
33 
34 ROOT::Internal::RRawFileWin::~RRawFileWin()
35 {
36  if (fFilePtr != nullptr)
37  fclose(fFilePtr);
38 }
39 
40 std::unique_ptr<ROOT::Internal::RRawFile> ROOT::Internal::RRawFileWin::Clone() const
41 {
42  return std::make_unique<RRawFileWin>(fUrl, fOptions);
43 }
44 
45 std::uint64_t ROOT::Internal::RRawFileWin::GetSizeImpl()
46 {
47  Seek(0L, SEEK_END);
48  long size = ftell(fFilePtr);
49  if (size < 0)
50  throw std::runtime_error("Cannot tell position counter in '" + fUrl +
51  "', error: " + std::string(strerror(errno)));
52  Seek(fFilePos, SEEK_SET);
53  return size;
54 }
55 
56 void ROOT::Internal::RRawFileWin::OpenImpl()
57 {
58  fFilePtr = fopen(GetLocation(fUrl).c_str(), "rb");
59  if (fFilePtr == nullptr)
60  throw std::runtime_error("Cannot open '" + fUrl + "', error: " + std::string(strerror(errno)));
61  // Prevent double buffering
62  int res = setvbuf(fFilePtr, nullptr, _IONBF, 0);
63  R__ASSERT(res == 0);
64  if (fOptions.fBlockSize < 0)
65  fOptions.fBlockSize = kDefaultBlockSize;
66 }
67 
68 size_t ROOT::Internal::RRawFileWin::ReadAtImpl(void *buffer, size_t nbytes, std::uint64_t offset)
69 {
70  Seek(offset, SEEK_SET);
71  size_t res = fread(buffer, 1, nbytes, fFilePtr);
72  if ((res < nbytes) && (ferror(fFilePtr) != 0)) {
73  clearerr(fFilePtr);
74  throw std::runtime_error("Cannot read from '" + fUrl + "', error: " + std::string(strerror(errno)));
75  }
76  return res;
77 }
78 
79 void ROOT::Internal::RRawFileWin::Seek(long offset, int whence)
80 {
81  int res = fseek(fFilePtr, offset, whence);
82  if (res != 0)
83  throw std::runtime_error("Cannot seek in '" + fUrl + "', error: " + std::string(strerror(errno)));
84 }