master_loader.cc 4.06 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

#include <dns/master_loader.h>
16
17
18
19
20
21
22
23
#include <dns/master_lexer.h>
#include <dns/name.h>
#include <dns/rrttl.h>
#include <dns/rrclass.h>
#include <dns/rrtype.h>
#include <dns/rrset.h>

using std::string;
24
25
26
27
28
29
30
31

namespace isc {
namespace dns {

class MasterLoader::MasterLoaderImpl {
public:
    MasterLoaderImpl(const char* master_file,
                     const Name& zone_origin,
32
33
34
                     const RRClass& zone_class,
                     const MasterLoaderCallbacks& callbacks,
                     const AddRRsetCallback& add_callback,
35
36
37
38
39
                     MasterLoader::Options options) :
        lexer_(),
        zone_origin_(zone_origin),
        zone_class_(zone_class),
        callbacks_(callbacks),
40
        add_callback_(add_callback),
41
42
43
44
45
        options_(options)
    {
        lexer_.pushSource(master_file);
    }

46
47
48
49
50
    // Get a string token. Handle it as error if it is not string.
    const string getString() {
        return (lexer_.getNextToken(MasterToken::QSTRING).getString());
    }

51
52
    bool loadIncremental(size_t count_limit) {
        size_t count = 0;
53
54
        while (count < count_limit) {
            // Skip all EOLNs (empty lines) and finish on EOF
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
            bool empty = true;
            do {
                const MasterToken& empty_token(lexer_.getNextToken());
                if (empty_token.getType() == MasterToken::END_OF_FILE) {
                    // TODO: Check if this is the last source, possibly pop
                    return (true);
                }
                empty = empty_token.getType() == MasterToken::END_OF_LINE;
            } while (empty);
            // Return the last token, as it was not empty
            lexer_.ungetToken();

            const string name_string(getString());
            // TODO $ handling
            const Name name(name_string); // TODO: Origin
            // TODO: Some more flexibility. We don't allow omitting anything yet

            // The parameters
            const RRTTL ttl(getString());
            const RRClass rrclass(getString());
            const RRType rrtype(getString());

            // Create the RRset. We don't need the RRSIG, so we are good
            // with the basic one
            RRsetPtr rrset(new BasicRRset(name, rrclass, rrtype, ttl));

            // TODO: Create the RData

            // OK now, so give the RRset with single RR to the caller
            add_callback_(rrset);
        }
86
87
88
89
90
91
92
93
        return (false);
    }

private:
    MasterLexer lexer_;
    const Name& zone_origin_;
    const RRClass zone_class_;
    MasterLoaderCallbacks callbacks_;
94
    AddRRsetCallback add_callback_;
95
96
97
98
99
100
    MasterLoader::Options options_;
    RRsetPtr current_rrset_;
};

MasterLoader::MasterLoader(const char* master_file,
                           const Name& zone_origin,
101
102
103
                           const RRClass& zone_class,
                           const MasterLoaderCallbacks& callbacks,
                           const AddRRsetCallback& add_callback,
104
105
106
                           Options options)
{
    impl_ = new MasterLoaderImpl(master_file, zone_origin,
107
                                 zone_class, callbacks, add_callback, options);
108
109
110
111
112
113
114
115
116
117
118
119
120
}

MasterLoader::~MasterLoader() {
    delete impl_;
}

bool
MasterLoader::loadIncremental(size_t count_limit) {
    return (impl_->loadIncremental(count_limit));
}

} // end namespace dns
} // end namespace isc