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 }