LPDRMETAENTRY dr_meta_add_entry(LPDRMETA meta, LPDRMETAENTRY entry, error_monitor_t em) { LPDRMETAENTRY newEntry = (LPDRMETAENTRY)(meta + 1) + meta->m_entry_count; int entryAlign = 0; if (entry->m_name_pos < 0) { CPE_ERROR_EX(em, CPE_DR_ERROR_META_NO_NAME, "entry have no name!"); return NULL; } //process type entryAlign = dr_add_meta_entry_set_type_calc_align(meta, entry, em); if (entryAlign < 0) { return NULL; } memcpy(newEntry, entry, sizeof(*newEntry)); newEntry->m_self_to_meta_pos = (char*)newEntry - (char*)meta; dr_meta_add_entry_calc_align(meta, newEntry, entryAlign, em); if (newEntry->m_version > meta->m_current_version) { meta->m_current_version = newEntry->m_version; } ++meta->m_entry_count; return newEntry; }
void dr_meta_add_entry_calc_align( LPDRMETA meta, LPDRMETAENTRY newEntry, int entryAlign, error_monitor_t em) { int align = entryAlign < meta->m_align ? entryAlign : meta->m_align; if (meta->m_type == CPE_DR_TYPE_STRUCT) { int panding = meta->m_data_size % align; if (panding) { panding = align - panding; } newEntry->m_data_start_pos = meta->m_data_size + panding; meta->m_data_size += panding + newEntry->m_unitsize; } else if (meta->m_type == CPE_DR_TYPE_UNION) { newEntry->m_data_start_pos = 0; if (meta->m_data_size < newEntry->m_unitsize) { meta->m_data_size = newEntry->m_unitsize; } } else { CPE_ERROR_EX(em, CPE_DR_ERROR_ENTRY_INVALID_TYPE_VALUE, "unknown meta type %d!", (int)meta->m_type); } }
void dr_meta_do_complete(LPDRMETA meta, error_monitor_t em) { int panding = meta->m_data_size % meta->m_align; if (panding) { panding = meta->m_align - panding; } meta->m_data_size += panding; if (meta->m_entry_count == 0) { CPE_ERROR_EX(em, CPE_DR_ERROR_META_NO_ENTRY, "meta %s have no entry", dr_meta_name(meta)); } }
enum dir_visit_next_op dir_search_i( dir_visitor_t visitor, void * ctx, int maxLevel, error_monitor_t em, mem_buffer_t buffer) { DIR * dirp; struct dirent dbuf; struct dirent * dp; char * path; int rv; size_t bufSize; enum dir_visit_next_op nextOp; if (maxLevel == 0) return dir_visit_next_go; path = (char *)mem_buffer_make_continuous(buffer, 0); bufSize = mem_buffer_size(buffer); dirp = dir_open(path, 0, em); if (dirp == NULL) return dir_visit_next_go; nextOp = dir_visit_next_go; while((rv = readdir_r(dirp, &dbuf, &dp)) == 0 && dp) { if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) continue; if ( mem_buffer_strcat(buffer, "/") != 0 || mem_buffer_strcat(buffer, dp->d_name) != 0) break; if (S_ISDIR(DTTOIF(dp->d_type))) { if (visitor->on_dir_enter) { nextOp = visitor->on_dir_enter( (const char *)mem_buffer_make_continuous(buffer, 0), dp->d_name, ctx); if (nextOp == dir_visit_next_exit) break; } else { nextOp = dir_visit_next_go; } if (nextOp == dir_visit_next_go) { nextOp = dir_search_i( visitor, ctx, maxLevel > 0 ? maxLevel - 1 : maxLevel, em, buffer); if (nextOp == dir_visit_next_exit) break; } if (visitor->on_dir_leave) { nextOp = visitor->on_dir_leave( (const char *)mem_buffer_make_continuous(buffer, 0), dp->d_name, ctx); if (nextOp == dir_visit_next_exit) break; } } else if (S_ISREG(DTTOIF(dp->d_type))) { if (visitor->on_file) { nextOp = visitor->on_file( (const char *)mem_buffer_make_continuous(buffer, 0), dp->d_name, ctx); if (nextOp == dir_visit_next_exit) break; } } /*restore curent path*/ mem_buffer_set_size(buffer, bufSize); path = (char *)mem_buffer_make_continuous(buffer, 0); if (path == NULL) { CPE_ERROR_EX(em, ENOMEM, "no memory for dir search path"); nextOp = dir_visit_next_exit; break; } path[bufSize - 1] = 0; } /*clear resources*/ dir_close(dirp, em); return nextOp == dir_visit_next_exit ? dir_visit_next_exit : dir_visit_next_go; }