1 static const char version[] = "$Id: layout.c,v 1.7 2013/04/06 13:04:53 valtri Exp $";
2
3 /*
4 * layout.c
5 *
6 * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
7 *
8 * See the COPYING file for the terms of usage and distribution.
9 */
10
11 #include <log4c/layout.h>
12 #include <log4c/layout_type_basic.h>
13 #include <log4c/layout_type_dated.h>
14 #include <log4c/priority.h>
15 #include <sd/hash.h>
16 #include <sd/malloc.h>
17 #include <sd/factory.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21
22 struct __log4c_layout
23 {
24 char* lo_name;
25 const log4c_layout_type_t* lo_type;
26 void* lo_udata;
27 };
28
29 sd_factory_t* log4c_layout_factory = NULL;
30
31 /*******************************************************************************/
log4c_layout_types(void)32 static sd_hash_t* log4c_layout_types(void)
33 {
34 static sd_hash_t* types = NULL;
35
36 if (!types)
37 types = sd_hash_new(20, NULL);
38
39 return types;
40 }
41
log4c_layout_types_free(void)42 extern void log4c_layout_types_free( void ) {
43 sd_hash_t * types = log4c_layout_types();
44 if ( types != NULL ) {
45 sd_hash_delete( types );
46 }
47 }
48
log4c_layout_types_print(FILE * fp)49 extern void log4c_layout_types_print(FILE *fp)
50 {
51 sd_hash_iter_t* i;
52
53 fprintf(fp, "layout types:");
54 for (i = sd_hash_begin(log4c_layout_types());
55 i != sd_hash_end(log4c_layout_types());
56 i = sd_hash_iter_next(i) )
57 {
58 fprintf(fp, "'%s' ",((log4c_layout_type_t *)(i->data))->name );
59 }
60 fprintf(fp, "\n");
61 }
62
63 /*******************************************************************************/
log4c_layout_type_get(const char * a_name)64 extern const log4c_layout_type_t* log4c_layout_type_get(const char* a_name)
65 {
66 sd_hash_iter_t* i;
67
68 if (!a_name)
69 return NULL;
70
71 if ( (i = sd_hash_lookup(log4c_layout_types(), a_name)) != NULL)
72 return i->data;
73
74 return NULL;
75 }
76
77 /*******************************************************************************/
log4c_layout_type_set(const log4c_layout_type_t * a_type)78 extern const log4c_layout_type_t* log4c_layout_type_set(
79 const log4c_layout_type_t* a_type)
80 {
81 sd_hash_iter_t* i = NULL;
82 void* previous = NULL;
83
84 if (!a_type)
85 return NULL;
86
87 if ( (i = sd_hash_lookadd(log4c_layout_types(), a_type->name)) == NULL)
88 return NULL;
89
90 previous = i->data;
91 i->data = (void*) a_type;
92
93 return previous;
94 }
95 /*******************************************************************************/
log4c_layout_get(const char * a_name)96 extern log4c_layout_t* log4c_layout_get(const char* a_name)
97 {
98 static const sd_factory_ops_t log4c_layout_factory_ops = {
99 (void*) log4c_layout_new,
100 (void*) log4c_layout_delete,
101 (void*) log4c_layout_print,
102 };
103
104 if (!log4c_layout_factory) {
105 log4c_layout_factory = sd_factory_new("log4c_layout_factory",
106 &log4c_layout_factory_ops);
107 /* build default layouts */
108 log4c_layout_set_type(log4c_layout_get("dated"), &log4c_layout_type_dated);
109 log4c_layout_set_type(log4c_layout_get("basic"), &log4c_layout_type_basic);
110 }
111
112 return sd_factory_get(log4c_layout_factory, a_name);
113 }
114
115 /*******************************************************************************/
log4c_layout_new(const char * a_name)116 extern log4c_layout_t* log4c_layout_new(const char* a_name)
117 {
118 log4c_layout_t* this;
119
120 if (!a_name)
121 return NULL;
122
123 this = sd_calloc(1, sizeof(log4c_layout_t));
124 this->lo_name = sd_strdup(a_name);
125 this->lo_type = &log4c_layout_type_basic;
126 this->lo_udata = NULL;
127
128 return this;
129 }
130
131 /*******************************************************************************/
log4c_layout_delete(log4c_layout_t * this)132 extern void log4c_layout_delete(log4c_layout_t* this)
133 {
134 if (!this)
135 return;
136
137 free(this->lo_name);
138 free(this);
139 }
140
141 /*******************************************************************************/
log4c_layout_get_name(const log4c_layout_t * this)142 extern const char* log4c_layout_get_name(const log4c_layout_t* this)
143 {
144 return (this ? this->lo_name : NULL);
145 }
146
147 /*******************************************************************************/
log4c_layout_get_type(const log4c_layout_t * this)148 extern const log4c_layout_type_t* log4c_layout_get_type(const log4c_layout_t* this)
149 {
150 return (this ? this->lo_type : NULL);
151 }
152
153 /*******************************************************************************/
log4c_layout_set_type(log4c_layout_t * this,const log4c_layout_type_t * a_type)154 extern const log4c_layout_type_t* log4c_layout_set_type(
155 log4c_layout_t* this,
156 const log4c_layout_type_t* a_type)
157 {
158 const log4c_layout_type_t* previous;
159
160 if (!this)
161 return NULL;
162
163 previous = this->lo_type;
164 this->lo_type = a_type;
165 return previous;
166 }
167
168 /*******************************************************************************/
log4c_layout_get_udata(const log4c_layout_t * this)169 extern void* log4c_layout_get_udata(const log4c_layout_t* this)
170 {
171 return (this ? this->lo_udata : NULL);
172 }
173
174 /*******************************************************************************/
log4c_layout_set_udata(log4c_layout_t * this,void * a_udata)175 extern void* log4c_layout_set_udata(log4c_layout_t* this, void* a_udata)
176 {
177 void* previous;
178
179 if (!this)
180 return NULL;
181
182 previous = this->lo_udata;
183 this->lo_udata = a_udata;
184 return previous;
185 }
186
187 /*******************************************************************************/
log4c_layout_format(const log4c_layout_t * this,const log4c_logging_event_t * a_event)188 extern const char* log4c_layout_format(
189 const log4c_layout_t* this,
190 const log4c_logging_event_t*a_event)
191 {
192 if (!this)
193 return NULL;
194
195 if (!this->lo_type)
196 return NULL;
197
198 if (!this->lo_type->format)
199 return NULL;
200
201 return this->lo_type->format(this, a_event);
202 }
203
204 /*******************************************************************************/
log4c_layout_print(const log4c_layout_t * this,FILE * a_stream)205 extern void log4c_layout_print(const log4c_layout_t* this, FILE* a_stream)
206 {
207 if (!this)
208 return;
209
210 fprintf(a_stream, "{ name:'%s' type:'%s' udata:%p }",
211 this->lo_name,
212 this->lo_type ? this->lo_type->name : "(no set)",
213 this->lo_udata);
214 }
215