//
// file_bitreader  --  file bitreader
//
// Copyright (c) 2003 by Joergen Ibsen / Jibz
// All Rights Reserved
//
// http://www.ibsensoftware.com/
//

/// @file   file_bitreader.hpp
/// @brief  bitreader specialization for files.
/// @author Jibz
/// @date   2003.08.02

#ifndef FILE_BITREADER_HPP_INCLUDED
#define FILE_BITREADER_HPP_INCLUDED

#include <fstream>

#include "bitreader.hpp"

/// Specialization for files.
///
/// This class opens a file and reads from it. Unlike the stream_bitreader
/// it manages the file that it operates on, and thus hides the details of
/// file access.
///
/// It adds the member function error(), which checks if there was
/// an error opening the file in the constructor.
///
/// @ingroup bitio
///
class file_bitreader : public bitreader {

public:
    /// Constructor. Sets the number of bits available
    /// to the size of the file.
    /// @param name - the name of the file to open.
    file_bitreader(const char *name)
	: s(name, std::ios::binary)
    {
	if (s)
	{
	    length = 8 * s.seekg(0, std::ios::end).tellg();
	    s.seekg(0);
	}
    }
    /// Constructor with size specification.
    /// @param name         - the name of the file to open.
    /// @param size_in_bits - the number of bits available.
    file_bitreader(const char *name, size_t size_in_bits)
	: bitreader(size_in_bits), s(name, std::ios::binary) { ; }

    ~file_bitreader() { finalize(); }

    /// Check the state of the file.
    /// @return @c true if a file error has occurred.
    bool error() const { return !s; }

    bool supports_seek() const { return true; }

protected:
    char read_next_byte() { char c; s.get(c); return c; }
    void set_position(size_t pos) { s.seekg((std::streamoff)pos); }

    std::ifstream s;
};

#endif // FILE_BITREADER_HPP_INCLUDED
