File: file.hh

package info (click to toggle)
zbackup 1.5-4
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 868 kB
  • sloc: cpp: 6,957; ansic: 468; python: 207; makefile: 10
file content (168 lines) | stat: -rw-r--r-- 5,006 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// Copyright (c) 2012-2014 Konstantin Isakov <ikm@zbackup.org> and ZBackup contributors, see CONTRIBUTORS
// Part of ZBackup. Licensed under GNU GPLv2 or later + OpenSSL, see LICENSE

#ifndef FILE_HH_INCLUDED
#define FILE_HH_INCLUDED

#include <stddef.h>
#include <cstdio>
#include <exception>
#include <string>

#include "ex.hh"

using std::string;

/// A simple wrapper over FILE * operations with added write-buffering
class File
{
  FILE * f;
  char * writeBuffer;
  size_t writeBufferLeft;

public:
  DEF_EX( Ex, "File exception", std::exception )
  DEF_EX_STR( exCantOpen, "Can't open", Ex )
  DEF_EX( exReadError, "Error reading from file", Ex )
  DEF_EX( exShortRead, "Short read from the file", exReadError )
  DEF_EX( exWriteError, "Error writing to the file", Ex )
  DEF_EX( exSeekError, "File seek error", Ex )
  DEF_EX_STR( exCantErase, "Can't erase file", Ex )
  DEF_EX_STR( exCantRename, "Can't rename file", Ex )

  enum OpenMode
  {
    ReadOnly,
    WriteOnly,
    Update
  };

  typedef long Offset;

  File( char const * filename, OpenMode );

  File( std::string const & filename, OpenMode );

  File( int fd, OpenMode );

  /// Reads the number of bytes to the buffer, throws an error if it
  /// failed to fill the whole buffer (short read, i/o error etc)
  void read( void * buf, size_t size );

  template< typename T >
  void read( T & value )
  { read( &value, sizeof( value ) ); }

  template< typename T >
  T read()
  { T value; read( value ); return value; }

  /// Attempts reading at most 'count' records sized 'size'. Returns
  /// the number of records it managed to read, up to 'count'
  size_t readRecords( void * buf, size_t size, size_t count );

  /// Writes the number of bytes from the buffer, throws an error if it
  /// failed to write the whole buffer (short write, i/o error etc).
  /// This function employs write buffering, and as such, writes may not
  /// end up on disk immediately, or a short write may occur later
  /// than it really did. If you don't want write buffering, use
  /// writeRecords() function instead
  void write( void const * buf, size_t size );

  template< typename T >
  void write( T const & value )
  { write( &value, sizeof( value ) ); }

  /// Attempts writing at most 'count' records sized 'size'. Returns
  /// the number of records it managed to write, up to 'count'.
  /// This function does not employ buffering, but flushes the buffer if it
  /// was used before
  size_t writeRecords( void const * buf, size_t size, size_t count );

  /// Reads a string from the file. Unlike the normal fgets(), this one
  /// can strip the trailing newline character, if this was requested.
  /// Returns either s or 0 if no characters were read
  char * gets( char * s, int size, bool stripNl = false );

  /// Like the above, but uses its own local internal buffer (1024 bytes
  /// currently), and strips newlines by default
  std::string gets( bool stripNl = true );

  /// Seeks in the file, relative to its beginning
  void seek( long offset );
  /// Seeks in the file, relative to the current position
  void seekCur( long offset );
  /// Seeks in the file, relative to the end of file
  void seekEnd( long offset = 0 );

  /// Seeks to the beginning of file
  void rewind();

  /// Tells the current position within the file, relative to its beginning
  size_t tell();

  /// Returns file size
  size_t size();

  /// Returns true if end-of-file condition is set
  bool eof();

  /// Returns ferror
  int error();

  /// Returns the underlying FILE * record, so other operations can be
  /// performed on it
  FILE * file();

  /// Releases the file handle out of the control of the class. No further
  /// operations are valid. The file will not be closed on destruction
  FILE * release();

  /// Closes the file. No further operations are valid
  void close();

  /// Checks if the file exists or not
  static bool exists( char const * filename );

  static bool exists( std::string const & filename )
  { return exists( filename.c_str() ); }

  /// Returns false when lstat returns stat::st_mode having 
  /// S_IFREG (filename is a file, or softlink to a file, and
  /// is not a socket, fifo, device node, etc.
  static bool special( std::string const & filename );

  ~File();

  /// Erases the given file
  static void erase( std::string const & );

  /// Renames the given file
  static void rename( std::string const & from,
                      std::string const & to );

  /// Throwing this class instead of exReadError will make the description
  /// include the file name
  class exReadErrorDetailed: public exReadError
  {
    string description;

  public:
    exReadErrorDetailed( int fd );
    exReadErrorDetailed( FILE * f );
    virtual const char * what();
    virtual ~exReadErrorDetailed();

  private:
    void buildDescription( int fd );
  };

private:

  void open( char const * filename, OpenMode );
  void open( int fd, OpenMode );
  void flushWriteBuffer();
  void releaseWriteBuffer();
};

#endif