1 | /* $NetBSD: prop_ingest.c,v 1.5 2014/09/05 05:19:24 matt Exp $ */ |
2 | |
3 | /*- |
4 | * Copyright (c) 2006 The NetBSD Foundation, Inc. |
5 | * All rights reserved. |
6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Jason R. Thorpe. |
9 | * |
10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions |
12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. |
15 | * 2. Redistributions in binary form must reproduce the above copyright |
16 | * notice, this list of conditions and the following disclaimer in the |
17 | * documentation and/or other materials provided with the distribution. |
18 | * |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ |
31 | |
32 | #include "prop_object_impl.h" |
33 | #include <prop/proplib.h> |
34 | |
35 | struct _prop_ingest_context { |
36 | prop_ingest_error_t pic_error; |
37 | prop_type_t pic_type; |
38 | const char * pic_key; |
39 | void * pic_private; |
40 | }; |
41 | |
42 | /* |
43 | * prop_ingest_context_alloc -- |
44 | * Allocate and initialize an ingest context. |
45 | */ |
46 | prop_ingest_context_t |
47 | prop_ingest_context_alloc(void *xprivate) |
48 | { |
49 | prop_ingest_context_t ctx; |
50 | |
51 | ctx = _PROP_MALLOC(sizeof(*ctx), M_TEMP); |
52 | if (ctx != NULL) { |
53 | ctx->pic_error = PROP_INGEST_ERROR_NO_ERROR; |
54 | ctx->pic_type = PROP_TYPE_UNKNOWN; |
55 | ctx->pic_key = NULL; |
56 | ctx->pic_private = xprivate; |
57 | } |
58 | return (ctx); |
59 | } |
60 | |
61 | /* |
62 | * prop_ingest_context_free -- |
63 | * Free an ingest context. |
64 | */ |
65 | void |
66 | prop_ingest_context_free(prop_ingest_context_t ctx) |
67 | { |
68 | |
69 | _PROP_FREE(ctx, M_TEMP); |
70 | } |
71 | |
72 | /* |
73 | * prop_ingest_context_error -- |
74 | * Get the error code from an ingest context. |
75 | */ |
76 | prop_ingest_error_t |
77 | prop_ingest_context_error(prop_ingest_context_t ctx) |
78 | { |
79 | |
80 | return (ctx->pic_error); |
81 | } |
82 | |
83 | /* |
84 | * prop_ingest_context_type -- |
85 | * Return the type of last object visisted by an ingest context. |
86 | */ |
87 | prop_type_t |
88 | prop_ingest_context_type(prop_ingest_context_t ctx) |
89 | { |
90 | |
91 | return (ctx->pic_type); |
92 | } |
93 | |
94 | /* |
95 | * prop_ingest_context_key -- |
96 | * Return the last key looked up by an ingest context. |
97 | */ |
98 | const char * |
99 | prop_ingest_context_key(prop_ingest_context_t ctx) |
100 | { |
101 | |
102 | return (ctx->pic_key); |
103 | } |
104 | |
105 | /* |
106 | * prop_ingest_context_private -- |
107 | * Return the caller-private data associated with an ingest context. |
108 | */ |
109 | void * |
110 | prop_ingest_context_private(prop_ingest_context_t ctx) |
111 | { |
112 | |
113 | return (ctx->pic_private); |
114 | } |
115 | |
116 | /* |
117 | * prop_dictionary_ingest -- |
118 | * Ingest a dictionary using handlers for each object to translate |
119 | * into an arbitrary binary format. |
120 | */ |
121 | bool |
122 | prop_dictionary_ingest(prop_dictionary_t dict, |
123 | const prop_ingest_table_entry rules[], |
124 | prop_ingest_context_t ctx) |
125 | { |
126 | const prop_ingest_table_entry *pite; |
127 | prop_object_t obj; |
128 | |
129 | ctx->pic_error = PROP_INGEST_ERROR_NO_ERROR; |
130 | |
131 | for (pite = rules; pite->pite_key != NULL; pite++) { |
132 | ctx->pic_key = pite->pite_key; |
133 | obj = prop_dictionary_get(dict, pite->pite_key); |
134 | ctx->pic_type = prop_object_type(obj); |
135 | if (obj == NULL) { |
136 | if (pite->pite_flags & PROP_INGEST_FLAG_OPTIONAL) { |
137 | if ((*pite->pite_handler)(ctx, NULL) == false) { |
138 | ctx->pic_error = |
139 | PROP_INGEST_ERROR_HANDLER_FAILED; |
140 | return (false); |
141 | } |
142 | continue; |
143 | } |
144 | ctx->pic_error = PROP_INGEST_ERROR_NO_KEY; |
145 | return (false); |
146 | } |
147 | if (ctx->pic_type != pite->pite_type && |
148 | pite->pite_type != PROP_TYPE_UNKNOWN) { |
149 | ctx->pic_error = PROP_INGEST_ERROR_WRONG_TYPE; |
150 | return (false); |
151 | } |
152 | if ((*pite->pite_handler)(ctx, obj) == false) { |
153 | ctx->pic_error = PROP_INGEST_ERROR_HANDLER_FAILED; |
154 | return (false); |
155 | } |
156 | } |
157 | |
158 | return (true); |
159 | } |
160 | |