Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "libts.h"
00025
00026 #include "P_RecCore.h"
00027 #include "P_RecFile.h"
00028 #include "P_RecMessage.h"
00029 #include "P_RecUtils.h"
00030 #include "P_RecCore.h"
00031 #include "I_Layout.h"
00032
00033 static RecMessageRecvCb g_recv_cb = NULL;
00034 static void *g_recv_cookie = NULL;
00035
00036
00037
00038
00039 RecMessage *
00040 RecMessageAlloc(RecMessageT msg_type, int initial_size)
00041 {
00042 RecMessage *msg;
00043
00044 msg = (RecMessage *)ats_malloc(sizeof(RecMessageHdr) + initial_size);
00045 memset(msg, 0, sizeof(RecMessageHdr) + initial_size);
00046 msg->msg_type = msg_type;
00047 msg->o_start = sizeof(RecMessageHdr);
00048 msg->o_write = sizeof(RecMessageHdr);
00049 msg->o_end = sizeof(RecMessageHdr) + initial_size;
00050 msg->entries = 0;
00051
00052 return msg;
00053 }
00054
00055
00056
00057
00058
00059 int
00060 RecMessageFree(RecMessage * msg)
00061 {
00062 ats_free(msg);
00063 return REC_ERR_OKAY;
00064 }
00065
00066
00067
00068
00069 RecMessage *
00070 RecMessageMarshal_Realloc(RecMessage * msg, const RecRecord * record)
00071 {
00072 int msg_ele_size;
00073 int rec_name_len = -1;
00074 int rec_data_str_len = -1;
00075 int rec_data_def_str_len = -1;
00076 int rec_cfg_chk_len = -1;
00077 RecMessageEleHdr *ele_hdr;
00078 RecRecord *r;
00079 char *p;
00080
00081
00082 msg_ele_size = sizeof(RecMessageEleHdr) + sizeof(RecRecord);
00083 if (record->name) {
00084 rec_name_len = strlen(record->name) + 1;
00085 msg_ele_size += rec_name_len;
00086 }
00087 if (record->data_type == RECD_STRING) {
00088 if (record->data.rec_string) {
00089 rec_data_str_len = strlen(record->data.rec_string) + 1;
00090 msg_ele_size += rec_data_str_len;
00091 }
00092 if (record->data_default.rec_string) {
00093 rec_data_def_str_len = strlen(record->data_default.rec_string) + 1;
00094 msg_ele_size += rec_data_def_str_len;
00095 }
00096 }
00097 if (REC_TYPE_IS_CONFIG(record->rec_type) && (record->config_meta.check_expr)) {
00098 rec_cfg_chk_len = strlen(record->config_meta.check_expr) + 1;
00099 msg_ele_size += rec_cfg_chk_len;
00100 }
00101
00102
00103
00104
00105
00106 msg_ele_size = INK_ALIGN_DEFAULT(msg_ele_size);
00107
00108 while (msg->o_end - msg->o_write < msg_ele_size) {
00109 int realloc_size = (msg->o_end - msg->o_start) * 2;
00110 msg = (RecMessage *)ats_realloc(msg, sizeof(RecMessageHdr) + realloc_size);
00111 msg->o_end = msg->o_start + realloc_size;
00112 }
00113 ele_hdr = (RecMessageEleHdr *) ((char *) msg + msg->o_write);
00114
00115
00116
00117 memset((char *) msg + msg->o_write, 0, msg->o_end - msg->o_write);
00118 msg->o_write += msg_ele_size;
00119
00120
00121 ele_hdr->magic = REC_MESSAGE_ELE_MAGIC;
00122 ele_hdr->o_next = msg->o_write;
00123 p = (char *) ele_hdr + sizeof(RecMessageEleHdr);
00124 memcpy(p, record, sizeof(RecRecord));
00125 r = (RecRecord *) p;
00126 p += sizeof(RecRecord);
00127 if (rec_name_len != -1) {
00128 ink_assert((msg->o_end - ((uintptr_t) p - (uintptr_t) msg)) >= (uintptr_t) rec_name_len);
00129 memcpy(p, record->name, rec_name_len);
00130 r->name = (char *) ((uintptr_t) p - (uintptr_t) r);
00131 p += rec_name_len;
00132 }
00133 if (rec_data_str_len != -1) {
00134 ink_assert((msg->o_end - ((uintptr_t) p - (uintptr_t) msg)) >= (uintptr_t) rec_data_str_len);
00135 memcpy(p, record->data.rec_string, rec_data_str_len);
00136 r->data.rec_string = (char *) ((uintptr_t) p - (uintptr_t) r);
00137 p += rec_data_str_len;
00138 }
00139 if (rec_data_def_str_len != -1) {
00140 ink_assert((msg->o_end - ((uintptr_t) p - (uintptr_t) msg)) >= (uintptr_t) rec_data_def_str_len);
00141 memcpy(p, record->data_default.rec_string, rec_data_def_str_len);
00142 r->data_default.rec_string = (char *) ((uintptr_t) p - (uintptr_t) r);
00143 p += rec_data_def_str_len;
00144 }
00145 if (rec_cfg_chk_len != -1) {
00146 ink_assert((msg->o_end - ((uintptr_t) p - (uintptr_t) msg)) >= (uintptr_t) rec_cfg_chk_len);
00147 memcpy(p, record->config_meta.check_expr, rec_cfg_chk_len);
00148 r->config_meta.check_expr = (char *) ((uintptr_t) p - (uintptr_t) r);
00149 }
00150
00151 msg->entries += 1;
00152
00153 return msg;
00154 }
00155
00156
00157
00158
00159
00160 int
00161 RecMessageUnmarshalFirst(RecMessage * msg, RecMessageItr * itr, RecRecord ** record)
00162 {
00163 itr->ele_hdr = (RecMessageEleHdr *) ((char *) msg + msg->o_start);
00164 itr->next = 1;
00165
00166 return RecMessageUnmarshalNext(msg, NULL, record);
00167 }
00168
00169
00170
00171
00172
00173 int
00174 RecMessageUnmarshalNext(RecMessage * msg, RecMessageItr * itr, RecRecord ** record)
00175 {
00176 RecMessageEleHdr *eh;
00177 RecRecord *r;
00178
00179 if (itr == NULL) {
00180 if (msg->entries == 0) {
00181 return REC_ERR_FAIL;
00182 } else {
00183 eh = (RecMessageEleHdr *) ((char *) msg + msg->o_start);
00184 }
00185 } else {
00186 if (itr->next >= msg->entries) {
00187 return REC_ERR_FAIL;
00188 }
00189 itr->ele_hdr = (RecMessageEleHdr *) ((char *) (msg) + itr->ele_hdr->o_next);
00190 itr->next += 1;
00191 eh = itr->ele_hdr;
00192 }
00193
00194 ink_assert(eh->magic == REC_MESSAGE_ELE_MAGIC);
00195
00196
00197 if (eh->magic != REC_MESSAGE_ELE_MAGIC) {
00198 Warning("Persistent statistics file records.stat is corrupted. Ignoring the rest of the file\n");
00199 return REC_ERR_FAIL;
00200 }
00201
00202 r = (RecRecord *) ((char *) eh + sizeof(RecMessageEleHdr));
00203
00204 if (r->name) {
00205 r->name = (char *) r + (intptr_t) (r->name);
00206 }
00207 if (r->data_type == RECD_STRING) {
00208 if (r->data.rec_string) {
00209 r->data.rec_string = (char *) r + (intptr_t) (r->data.rec_string);
00210 }
00211 if (r->data_default.rec_string) {
00212 r->data_default.rec_string = (char *) r + (intptr_t) (r->data_default.rec_string);
00213 }
00214 }
00215 if (REC_TYPE_IS_CONFIG(r->rec_type) && (r->config_meta.check_expr)) {
00216 r->config_meta.check_expr = (char *) r + (intptr_t) (r->config_meta.check_expr);
00217 }
00218
00219 *record = r;
00220
00221 return REC_ERR_OKAY;
00222 }
00223
00224
00225
00226
00227
00228 int
00229 RecMessageRegisterRecvCb(RecMessageRecvCb recv_cb, void *cookie)
00230 {
00231 if (g_recv_cb) {
00232 return REC_ERR_FAIL;
00233 }
00234 g_recv_cookie = cookie;
00235 g_recv_cb = recv_cb;
00236
00237 return REC_ERR_OKAY;
00238 }
00239
00240
00241
00242
00243
00244 void *
00245 RecMessageRecvThis(void * , char *data_raw, int )
00246 {
00247 RecMessage *msg = (RecMessage *) data_raw;
00248 g_recv_cb(msg, msg->msg_type, g_recv_cookie);
00249 return NULL;
00250 }
00251
00252
00253
00254
00255
00256 RecMessage *
00257 RecMessageReadFromDisk(const char *fpath)
00258 {
00259 RecMessageHdr msg_hdr;
00260 RecMessage *msg = NULL;
00261 RecHandle h_file;
00262 int bytes_read;
00263
00264 if ((h_file = RecFileOpenR(fpath)) == REC_HANDLE_INVALID) {
00265 goto Lerror;
00266 }
00267 if (RecFileRead(h_file, (char *) (&msg_hdr), sizeof(RecMessageHdr), &bytes_read) == REC_ERR_FAIL) {
00268 goto Lerror;
00269 }
00270 msg = (RecMessage *)ats_malloc((msg_hdr.o_end - msg_hdr.o_start) + sizeof(RecMessageHdr));
00271 memcpy(msg, &msg_hdr, sizeof(RecMessageHdr));
00272 if (RecFileRead(h_file, (char *) (msg) + msg_hdr.o_start,
00273 msg_hdr.o_end - msg_hdr.o_start, &bytes_read) == REC_ERR_FAIL) {
00274 goto Lerror;
00275 }
00276
00277 goto Ldone;
00278
00279 Lerror:
00280 ats_free(msg);
00281 msg = NULL;
00282
00283 Ldone:
00284 if (h_file != REC_HANDLE_INVALID) {
00285 RecFileClose(h_file);
00286 }
00287
00288 return msg;
00289 }
00290
00291
00292
00293
00294
00295 int
00296 RecMessageWriteToDisk(RecMessage *msg, const char *fpath)
00297 {
00298 int msg_size;
00299 RecHandle h_file;
00300 int bytes_written;
00301
00302
00303
00304
00305 msg->o_end = msg->o_write;
00306
00307 msg_size = sizeof(RecMessageHdr) + (msg->o_write - msg->o_start);
00308 if ((h_file = RecFileOpenW(fpath)) != REC_HANDLE_INVALID) {
00309 if (RecFileWrite(h_file, (char *) msg, msg_size, &bytes_written) == REC_ERR_FAIL) {
00310 RecFileClose(h_file);
00311 return REC_ERR_FAIL;
00312 }
00313 RecFileClose(h_file);
00314 }
00315
00316 return REC_ERR_OKAY;
00317 }