user_file.h 4.25 KB
Newer Older
1
// Copyright (C) 2013-2015,2017 Internet Systems Consortium, Inc. ("ISC")
2
//
3 4 5
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 7 8
#ifndef _USER_FILE_H
#define _USER_FILE_H

9
/// @file user_file.h Defines the class, UserFile, which implements the UserDataSource interface for text files.
10 11 12 13 14 15 16 17

#include <user_data_source.h>
#include <user.h>

#include <boost/shared_ptr.hpp>
#include <fstream>
#include <string>

18 19
namespace user_chk {

20 21 22
/// @brief Thrown a UserFile encounters an error.
/// Note that it derives from UserDataSourceError to comply with the interface.
class UserFileError : public UserDataSourceError {
23
public:
24 25 26
    UserFileError(const char* file, size_t line, const char* what) :
        UserDataSourceError(file, line, what)
    {}
27 28
};

29 30 31 32 33 34 35 36 37
/// @brief Provides a UserDataSource implementation for JSON text files.
/// This class allows a text file of JSON entries to be treated as a source of
/// User entries.  The format of the file is one user entry per line, where
/// each line contains a JSON string as follows:
///
/// { "type" : "<user type>", "id" : "<user_id>" (options)  }
///
/// where:
///
38 39
/// &lt;user_type&gt;  text label of the id type: "HW_ADDR" or "DUID"
/// &lt;user_id&gt;  the user's id as a string of hex digits with or without
40
/// colons (':') as a delimiter
41 42 43 44 45
/// (options) zero or more string elements as name-value pairs, separated by
/// commas: "opt1" : "val1",  "other_opt", "77" ...
///
/// Each entry must have a valid entry for "type" and a valid entry or "id".
///
46
/// If an entry contains duplicate option names, that option will be assigned
47 48 49 50 51 52 53 54 55 56 57
/// the last value found. This is typical JSON behavior.
/// Currently, only string option values (i.e. enclosed in quotes) are
/// supported.
///
/// Example file entries might look like this:
/// @code
///
/// { "type" : "HW_ADDR", "id" : "01AC00F03344", "opt1" : "true" }
/// { "type" : "DUID", "id" : "225060de0a0b", "opt1" : "false" }
///
/// @endcode
58 59
class UserFile : public UserDataSource {
public:
60 61 62 63 64
    /// @brief Maximum length of a single user entry.
    /// This value is somewhat arbitrary. 4K seems reasonably large.  If it
    /// goes beyond this, then a flat file is not likely the way to go.
    static const size_t USER_ENTRY_MAX_LEN = 4096;

65 66 67 68 69 70
    /// @brief Constructor
    ///
    /// Create a UserFile for the given file name without opening the file.
    /// @param fname pathname to the input file.
    ///
    /// @throw UserFileError if given file name is empty.
71 72
    UserFile(const std::string& fname);

73 74 75
    /// @brief Destructor.
    ////
    /// The destructor does call the close method.
76 77
    virtual ~UserFile();

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
    /// @brief Opens the input file for reading.
    ///
    /// Upon successful completion, the file is opened and positioned to start
    /// reading from the beginning of the file.
    ///
    /// @throw UserFileError if the file cannot be opened.
    virtual void open();

    /// @brief Fetches the next user from the file.
    ///
    /// Reads the next user entry from the file and attempts to create a
    /// new User from the text therein.  If there is no more data to be read
    /// it returns an empty UserPtr.
    ///
    /// @return A UserPtr pointing to the new User or an empty pointer on EOF.
    ///
    /// @throw UserFileError if an error occurs while reading.
    virtual UserPtr readNextUser();

    /// @brief Closes the underlying file.
    ///
    /// Method is exception safe.
    virtual void close();

    /// @brief Returns true if the file is open.
    ///
    /// @return True if the underlying file is open, false otherwise.
    virtual bool isOpen() const;

    /// @brief Creates a new User instance from JSON text.
    ///
    /// @param user_string string the JSON text for a user entry.
    ///
    /// @return A pointer to the newly created User instance.
    ///
    /// @throw UserFileError if the entry is invalid.
114 115 116
    UserPtr makeUser(const std::string& user_string);

private:
117
    /// @brief Pathname of the input text file.
118
    std::string fname_;
119

120
    /// @brief Input file stream.
121
    std::ifstream file_;
122 123 124

};

125
/// @brief Defines a smart pointer to a UserFile.
126 127
typedef boost::shared_ptr<UserFile> UserFilePtr;

128 129
} // namespace user_chk

130
#endif