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