Ejemplo n.º 1
0
int main()
{
	object_t *o;
	char *s;
	const char *string_type = "STRING";
	type_t *type;

	plan(9);
	
	type = type_get(string_type);
	type_set_callback(type, "free", free);

	s = calloc(20, sizeof(char));
	strcpy(s, "Hello, object world");

	o = object_new(string_type, s);
	ok(o != NULL, "object is not NULL");
	ok(object_isset(o), "object is set");
	ok(object_isa(o, string_type), "object isa '%s'", string_type);
	str_eq(object_type(o), string_type);
	ok(object_type(o) == string_type, "object_type() returns direct pointer to type string");
	str_eq(object_value(o), s);
	ok(object_value(o) == s, "object_value() returns direct pointer to value");

	object_set(o, "Goodbye");
	str_eq(object_value(o), "Goodbye");
	object_set(o, s);

	object_free(o);
	ok(object_isset(NULL) == 0, "NULL is considered as an unset object");

	types_finalize();

	return 0;
}
Ejemplo n.º 2
0
static void * object_write_primitive(n_file * file, n_array * primitive)
{
    switch (object_type(primitive))
    {
        case OBJECT_NUMBER:
        {
            n_int * int_data = (n_int *)&primitive->data;
            io_writenumber(file, int_data[0],1,0);
        }
            break;
        case OBJECT_STRING:
            io_write(file, "\"", 0);
            io_write(file, primitive->data, 0);
            io_write(file, "\"", 0);
            break;
        case OBJECT_OBJECT:
            object_top_object(file, (n_object *)primitive->data);
            break;
        case OBJECT_ARRAY:
            object_top_array(file, (n_array *)primitive->data);
            break;
        default:
            (void)SHOW_ERROR("Object kind not found");
            return 0L;
    }
    if (primitive->next)
    {
        io_write(file, ",", 0);
    }
    return primitive->next;
}
Ejemplo n.º 3
0
Geostat_grid* Simulacre_input_filter::read( const std::string& filename, 
                                           std::string* errors ) {
  QFile file( filename.c_str() );
  if( !file.open( IO_ReadOnly ) ) {
    if( errors ) 
      errors->append( "can't open file: " + filename);
    return false;
  }

  QDataStream stream( &file );
  Q_UINT32 magic_nb;
  stream >> magic_nb;
  if( magic_nb != 0xB211175D ) {
    if( errors )
      errors->append( "wrong file format" );
    return 0;
  }

  char* type;
  stream >> type;
  std::string object_type( type );
  delete [] type;

  //TL modified
  if (object_type == Reduced_grid().classname())
	  return read_reduced_grid(stream, errors);
  if( object_type == Cartesian_grid().classname() ) 
    return read_cartesian_grid( stream, errors );
  if( object_type == Point_set().classname() ) 
    return read_pointset( stream, errors );

  return 0;
}
Ejemplo n.º 4
0
bool prepare_object_event_logger(const char *log_dir)
{
	object_types_mutex = __malloc_lock_init();
	object_types_file = __init_object_type_file(log_dir);
	if (object_types_file == NULL) {
		return false;
	}
	
	// Insert vm memory type names
	for (int i = 0; i < sizeof(vm_memory_type_names) / sizeof(char *); ++i) {
		uintptr_t str_hash = __string_hash(vm_memory_type_names[i]);
		uint32_t type = object_types_file->object_type_list->size() + 1;
		object_types_file->object_type_exists->insert(str_hash);
		object_types_file->object_type_list->insert(object_type(type, vm_memory_type_names[i]));
	}
	
#ifdef USE_PRIVATE_API
    // __CFObjectAllocSetLastAllocEventNameFunction
	object_set_last_allocation_event_name_funcion = (void (**)(void *, const char *))dlsym(RTLD_DEFAULT, "__CFObjectAllocSetLastAllocEventNameFunction");
	if (object_set_last_allocation_event_name_funcion != NULL) {
		*object_set_last_allocation_event_name_funcion = object_set_last_allocation_event_name;
	}
	
	// __CFOASafe
	object_record_allocation_event_enable = (bool *)dlsym(RTLD_DEFAULT, "__CFOASafe");
	if (object_record_allocation_event_enable != NULL) {
		*object_record_allocation_event_enable = true;
	}
#endif
	
	nsobject_hook_alloc_method();
	
	return true;
}
Ejemplo n.º 5
0
	void RTBParser::delegateLastMessage (Coordinator* coordinator) throw (StrategyException,bad_exception)
	{
		switch(_parseResult.messageType)
		{
		case RADAR:		coordinator->receiveRTBMessageRadar (
						_parseResult.doubleValue[0],
						object_type(_parseResult.intValue[0]),
						_parseResult.doubleValue[1]);
					return;
		case INFO:		coordinator->receiveRTBMessageInfo (
						_parseResult.doubleValue[0],
						_parseResult.doubleValue[1],
						_parseResult.doubleValue[2]);
					return;
		case COORDINATES:	coordinator->receiveRTBMessageCoordinates (
						_parseResult.doubleValue[0],
						_parseResult.doubleValue[1],
						_parseResult.doubleValue[2]);
					return;
		case ENERGY:		coordinator->receiveRTBMessageEnergy (
						_parseResult.doubleValue[0]);
					return;
		case COLLISION:	coordinator->receiveRTBMessageCollision (
						object_type(_parseResult.intValue[0]),
						_parseResult.doubleValue[0]);
					return;
		case ROTATION_REACHED:	coordinator->receiveRTBMessageRotationReached(
						_parseResult.intValue[0]);
					return;
		case WARNING:		coordinator->receiveRTBMessageWarning (		// >> This may cause
						warning_type(_parseResult.intValue[0]),	//    an exception
						_parseResult.stringValue);		//    to be thrown
					return;
		case DEAD:		coordinator->receiveRTBMessageDead ();
					return;
		case ROBOT_INFO:	coordinator->receiveRTBMessageRobotInfo(
						_parseResult.doubleValue[0],
						_parseResult.intValue[0]);
					return;
		case ROBOTS_LEFT:	coordinator->receiveRTBMessageRobotsLeft(
						_parseResult.intValue[0]);
					return;
			default:
				throw StrategyException("Parser was requested to delegate an illegal parsing result.");

		}
	}
Ejemplo n.º 6
0
void print_type(struct object_heap* oh, struct Object* o) {
  struct Object* traits;
  struct Object* traitsWindow;
  struct OopArray* x;
  if (object_is_smallint(o)) {
    fprintf(stderr, "%" PRIdPTR " (0x%" PRIuPTR ")\n", object_to_smallint(o), object_to_smallint(o));
    return;
  }

  if (object_type(o) == TYPE_BYTE_ARRAY) {
    fprintf(stderr, "(");
    print_byte_array(o);
    fprintf(stderr, ") ");
    /*return;*/
  }

  x = o->map->delegates;
  if (!x || array_size(x) < 1) goto fail;

  traitsWindow = x->elements[0];

  {
    if (traitsWindow == oh->cached.compiled_method_window) {
      fprintf(stderr, "(method #");
      print_byte_array((struct Object*)(((struct CompiledMethod*)o)->method->selector));
      fprintf(stderr, ")");
    }
  }

  x = traitsWindow->map->delegates;
  if (!x || array_size(x) < 1) goto fail;

  traits = x->elements[array_size(x)-1];

  if (o == oh->cached.nil) {
    fprintf(stderr, "nil\n");
  } else if (o == oh->cached.true_object) {
    fprintf(stderr, "true\n");
  } else if (o == oh->cached.false_object) {
    fprintf(stderr, "false\n");
  } else {
    print_printname(oh, o);
    fprintf(stderr, "(");
    print_printname(oh, traits);
    fprintf(stderr, ")\n");
  }

  return;
 fail:
  fprintf(stderr, "<unknown type>\n");
}
Ejemplo n.º 7
0
static void mktree_line(char *buf, size_t len, int line_termination, int allow_missing)
{
	char *ptr, *ntr;
	unsigned mode;
	enum object_type mode_type; /* object type derived from mode */
	enum object_type obj_type; /* object type derived from sha */
	char *path;
	unsigned char sha1[20];

	ptr = buf;
	/*
	 * Read non-recursive ls-tree output format:
	 *     mode SP type SP sha1 TAB name
	 */
	mode = strtoul(ptr, &ntr, 8);
	if (ptr == ntr || !ntr || *ntr != ' ')
		die("input format error: %s", buf);
	ptr = ntr + 1; /* type */
	ntr = strchr(ptr, ' ');
	if (!ntr || buf + len <= ntr + 40 ||
	    ntr[41] != '\t' ||
	    get_sha1_hex(ntr + 1, sha1))
		die("input format error: %s", buf);

	/* It is perfectly normal if we do not have a commit from a submodule */
	if (S_ISGITLINK(mode))
		allow_missing = 1;


	*ntr++ = 0; /* now at the beginning of SHA1 */

	path = ntr + 41;  /* at the beginning of name */
	if (line_termination && path[0] == '"') {
		struct strbuf p_uq = STRBUF_INIT;
		if (unquote_c_style(&p_uq, path, NULL))
			die("invalid quoting");
		path = strbuf_detach(&p_uq, NULL);
	}

	/*
	 * Object type is redundantly derivable three ways.
	 * These should all agree.
	 */
	mode_type = object_type(mode);
	if (mode_type != type_from_string(ptr)) {
		die("entry '%s' object type (%s) doesn't match mode type (%s)",
			path, ptr, typename(mode_type));
	}
Ejemplo n.º 8
0
static void object_primitive_free(n_array ** array)
{
    n_array * referenced_array = * array;
    switch(object_type(referenced_array))
    {
        case OBJECT_ARRAY:
        case OBJECT_OBJECT:
        {
            n_array * child = (n_array *)referenced_array->data;
            obj_free(&child);
        }
        default:
            memory_free((void **)array);
            break;
    }
}
Ejemplo n.º 9
0
void GameView::dropEvent(QDropEvent *event)
{
  if (my_world == nullptr) {
    return;
  }

  if (event->mimeData()->hasFormat("mm/object")) {
    log_debug(DEBUG_EDITOR, "Drop accepted");

    const QMimeData *mime_data = event->mimeData();

    if (mime_data->hasFormat("mm/object")) {
      event->acceptProposedAction();
      QString object_type(mime_data->data("mm/object"));
      log_debug(DEBUG_EDITOR, "Drop event %s", object_type.toLatin1().data());

      bool ok = false;
      u32 index = object_type.toLatin1().toInt(&ok);

      if (index >= application().core().entity_creators().size()) {
        log_warning("Invalid object index %i, max index is %i", index,
          application().core().entity_creators().size());
        return;
      }

      if (!ok) {
        return;
      }

      sptr<Entity> entity = application().core().entity_creators()[index].create(*my_world, application().core());

      if (entity != nullptr) {
        entity->set_class_name(application().core().entity_creators()[index].name);
        log_info("Adding entity to the world");

        EntityAdd *command = new EntityAdd(entity, application().world());
        undo_stack().push(command);
      } else {
        log_warning("Error while creating object");
      }
    } else {
      log_debug(DEBUG_EDITOR, "Drop ignored");
      event->ignore();
    }
  }
}
Ejemplo n.º 10
0
void print_object(struct Object* oop) {
  if (oop == NULL) {
    fprintf(stderr, "<object NULL>\n");
    return;
  }
  if (oop_is_smallint((word_t)oop)) {
    fprintf(stderr, "<object int_value: %" PRIdPTR ">\n", object_to_smallint(oop));
  } else {
    const char* typestr=0;
    switch (object_type(oop)) {
    case TYPE_OBJECT: typestr = "normal"; break;
    case TYPE_OOP_ARRAY: typestr = "oop array"; break;
    case TYPE_BYTE_ARRAY: typestr = "byte array"; break;
    }
    fprintf(stderr, "<object at %p, hash: 0x%" PRIxPTR ", size: %" PRIdPTR ", payload size: %" PRIdPTR ", type: %s>\n", (void*)oop, object_hash(oop), object_size(oop), payload_size(oop), typestr);
  }
}
Ejemplo n.º 11
0
bool_t print_printname(struct object_heap* oh, struct Object* o) {
  word_t i;
  struct Map* map = o->map;
  struct SlotTable* slotTable = map->slotTable;
  word_t limit = slot_table_capacity(slotTable);
  for (i=0; i < limit; i++) {
    if (slotTable->slots[i].name == (struct Symbol*)oh->cached.nil) continue;
    if (strncmp((char*)slotTable->slots[i].name->elements, "printName", 9) == 0) {
      struct Object* obj = object_slot_value_at_offset(o, object_to_smallint(slotTable->slots[i].offset));
      if (object_is_smallint(obj) || object_type(obj) != TYPE_BYTE_ARRAY) {
        return FALSE;
      } else {
        print_byte_array(obj);
        return TRUE;
      }
    }
  }
  return FALSE;
}
Ejemplo n.º 12
0
void nsobject_set_last_allocation_event_name(void *ptr, const char *classname)
{
	if (!ptr) return;
	if (!classname) classname = "(no class)";
	
	uint32_t type = 0;
	
	__malloc_lock_lock(&object_types_mutex);
	
	if (object_types_file->object_type_exists->exist((uintptr_t)classname) == false) {
		type = object_types_file->object_type_list->size() + 1;
		object_types_file->object_type_exists->insert((uintptr_t)classname);
		object_types_file->object_type_list->insert(object_type(type, classname, true));
	} else {
		type = object_types_file->object_type_exists->foundIndex();
	}
	
	__malloc_lock_unlock(&object_types_mutex);
	
	__update_object_event((uint64_t)ptr, type);
}
Ejemplo n.º 13
0
void mark_tree_uninteresting(struct tree *tree)
{
	struct tree_desc desc;
	struct name_entry entry;
	struct object *obj = &tree->object;

	if (!tree)
		return;
	if (obj->flags & UNINTERESTING)
		return;
	obj->flags |= UNINTERESTING;
	if (!has_sha1_file(obj->sha1))
		return;
	if (parse_tree(tree) < 0)
		die("bad tree %s", sha1_to_hex(obj->sha1));

	init_tree_desc(&desc, tree->buffer, tree->size);
	while (tree_entry(&desc, &entry)) {
		switch (object_type(entry.mode)) {
		case OBJ_TREE:
			mark_tree_uninteresting(lookup_tree(entry.sha1));
			break;
		case OBJ_BLOB:
			mark_blob_uninteresting(lookup_blob(entry.sha1));
			break;
		default:
			/* Subproject commit - not in this repository */
			break;
		}
	}

	/*
	 * We don't care about the tree any more
	 * after it has been marked uninteresting.
	 */
	free(tree->buffer);
	tree->buffer = NULL;
}
Ejemplo n.º 14
0
static n_object * obj_get(n_object * object, n_string name)
{
    n_object * set_object;
    n_int      string_length = io_length(name, STRING_BLOCK_SIZE);
    n_uint     hash = math_hash((n_byte *)name, string_length);
    
    if (object == 0L)
    {
        object = object_new();
    }
    if (object_type(&object->primitive) == OBJECT_EMPTY)
    {
        set_object = object;
    }
    else
    {
        n_object * previous_object = object_end_or_find(object, name);
        if (previous_object == 0L)
        {
            set_object = object;
        }
        else
        {
            set_object = previous_object->primitive.next;
            if (set_object == 0L)
            {
                set_object = object_new();
            }
            previous_object->primitive.next = set_object;
        }
    }
    
    set_object->name = name;
    set_object->name_hash = hash;
    
    return set_object;
}
NTSTATUS AndroidUsbWdfObject::InitializeContext() {
  ASSERT_IRQL_LOW();
  ASSERT(IsAttached());
  if (!IsAttached())
    return STATUS_INTERNAL_ERROR;

  // Initialize our extension to that object
  AndroidUsbWdfObjectContext* context =
    GetAndroidUsbWdfObjectContext(wdf_object());
  ASSERT(NULL != context);
  if (NULL == context)
    return STATUS_INTERNAL_ERROR;

  // Make sure that extension has not been initialized
  ASSERT((0 == context->object_type) && (NULL == context->wdf_object_ext));
  if ((0 != context->object_type) || (NULL != context->wdf_object_ext))
    return STATUS_INTERNAL_ERROR;

  context->object_type = object_type();
  context->wdf_object_ext = this;
  ASSERT(this == GetAndroidUsbWdfObjectFromHandle(wdf_object()));

  return STATUS_SUCCESS;
}
Ejemplo n.º 16
0
bool SdbObjectHandle::IsObjectOfType(SdbObjectType obj_type) const {
  return (obj_type == object_type());
}
void AndroidUsbWdfObject::OnEvtCleanupCallback() {
  ASSERT_IRQL_LOW_OR_DISPATCH();
  GoogleDbgPrint("\n----- Object %p of type %u is cleaned up",
           this, object_type());
}
void AndroidUsbWdfObject::OnEvtDestroyCallback() {
  ASSERT_IRQL_LOW_OR_DISPATCH();
  GoogleDbgPrint("\n----- Object %p of type %u is destroyed",
           this, object_type());
}
Ejemplo n.º 19
0
void print_object_with_depth(struct object_heap* oh, struct Object* o, word_t depth, word_t max_depth) {

  struct Map* map;
  word_t i;

  if (depth >= max_depth || object_is_smallint(o)) {
    fprintf(stderr, "(depth limit reached) "); print_object(o);
    return;
  }

  if (o == oh->cached.nil) {
    fprintf(stderr, "<object NilObject>\n");
    return;
  }

  map = o->map;
  print_object(o);
  if (object_hash(o) >= ID_HASH_RESERVED) {
    indent(depth); fprintf(stderr, "<object is free/reserved>\n");
    return;
  }

  indent(depth); fprintf(stderr, "{\n");

  if (object_type(o) == TYPE_BYTE_ARRAY) {
    indent(depth); fprintf(stderr, "bytes: ");
    print_byte_array(o); fprintf(stderr, "\n");
  }
  if (object_type(o) == TYPE_OOP_ARRAY) {
    struct OopArray* array = (struct OopArray*)o;
    indent(depth); fprintf(stderr, "size(array) = %" PRIdPTR "\n", object_array_size(o));
    for (i=0; i < object_array_size(o); i++) {
      indent(depth); fprintf(stderr, "array[%" PRIdPTR "]: ", i); print_object_with_depth(oh, array->elements[i], depth+1, max_depth);
      if (object_array_size(o) - i > 10) {
        indent(depth); fprintf(stderr, "...\n");
        i = object_array_size(o) - 2;
      }
    }
  }
  indent(depth);
  fprintf(stderr, "map flags: %" PRIdPTR " (%s)\n", 
         object_to_smallint(map->flags),
         ((((word_t)map->flags & MAP_FLAG_RESTRICT_DELEGATION)==0)? "delegation not restricted":"delegation restricted"));
  {
    /*print if delegate*/
    struct OopArray* delegates = map->delegates;
    word_t offset = object_array_offset((struct Object*)delegates);
    word_t limit = object_total_size((struct Object*)delegates);
    for (i = 0; offset != limit; offset += sizeof(word_t), i++) {
      struct Object* delegate = object_slot_value_at_offset((struct Object*)delegates, offset);
      indent(depth); fprintf(stderr, "delegate[%" PRIdPTR "] = ", i);
      print_object_with_depth(oh, delegate, 
                              (((word_t)map->flags & MAP_FLAG_RESTRICT_DELEGATION) == 0)?  depth+1 : max(max_depth-1, depth+1), max_depth);
    }
  }

  {/*if?*/
    struct SlotTable* slotTable = map->slotTable;
    word_t limit = slot_table_capacity(map->slotTable);
    indent(depth); fprintf(stderr, "slot count: %" PRIdPTR "\n", object_to_smallint(map->slotCount));
    for (i=0; i < limit; i++) {
      if (slotTable->slots[i].name == (struct Symbol*)oh->cached.nil) continue;
      indent(depth);
      fprintf(stderr, "slot[%" PRIdPTR "]['", i); print_symbol(slotTable->slots[i].name); fprintf(stderr, "'] = ");
      {
        struct Object* obj = object_slot_value_at_offset(o, object_to_smallint(slotTable->slots[i].offset));
        if (object_is_smallint(obj) || object_type(obj) != TYPE_BYTE_ARRAY) {
          print_object(obj);
        } else {
          print_byte_array(obj); fprintf(stderr, "\n");
        }
      }
    }
  }


  /*indent(depth); fprintf(stderr, "map = "); print_object_with_depth(oh, (struct Object*)map, depth+1, max_depth);*/
    
  /*roles */
  {
    struct RoleTable* roleTable = map->roleTable;
    word_t limit = role_table_capacity(roleTable);
    indent(depth); fprintf(stderr, "role table capacity: %" PRIdPTR "\n", limit);
    for (i = 0; i < limit; i++) {
      if (roleTable->roles[i].name == (struct Symbol*)oh->cached.nil) {continue;}
      else {
        indent(depth); fprintf(stderr, "role[%" PRIdPTR "]['", i); print_symbol(roleTable->roles[i].name);
        fprintf(stderr, "'] @ 0x%04" PRIxPTR "\n", object_to_smallint(roleTable->roles[i].rolePositions));
#if 0
        print_object_with_depth(oh, (struct Object*)roleTable->roles[i].methodDefinition, max_depth, max_depth);
#endif
        if (limit - i > 50 && depth >= 2) {
          indent(depth); fprintf(stderr, "...\n");
          i = limit - 3;
        }
      }
    }
  }
  indent(depth); fprintf(stderr, "}\n");
}
Ejemplo n.º 20
0
uintptr_t
memory_frame_allocate (struct activity *activity)
{
  pager_query ();

  uintptr_t f = zalloc (PAGESIZE);
  if (! f)
    {
      /* Check if there are any pages on the available list.  */

      /* XXX: We avoid objects that require special treatment.
	 Realize this special treatment.  */
      struct object_desc *desc = available_list_head (&available);
      while (desc)
	{
	  if (desc->type != vg_cap_activity_control
	      && desc->type != vg_cap_thread)
	    /* We will detach DESC from AVAILALBE in
	       memory_object_destroy.  */
	    break;

	  desc = available_list_next (desc);
	}

      if (desc)
	{
	  assert (desc->live);
	  assert (desc->eviction_candidate);
	  assert (desc->activity);
	  assert (object_type ((struct vg_object *) desc->activity)
		  == vg_cap_activity_control);
	  assert (! desc->dirty || desc->policy.discardable);
	  assert (! desc->mapped);

	  debug (5, "Reusing OID " VG_OID_FMT " (%s)",
		 VG_OID_PRINTF (desc->oid), vg_cap_type_string (desc->type));

	  struct vg_object *object = object_desc_to_object (desc);

	  struct vg_folio *folio = objects_folio (activity, object);
	  int offset = objects_folio_offset (object);

	  bool discarded = desc->dirty;
	  if (discarded)
	    {
	      assert (desc->policy.discardable);
	      ACTIVITY_STATS (desc->activity)->discarded ++;
	    }

	  vg_oid_t oid = desc->oid;
	  memory_object_destroy (activity, object);
	  /* DESC is no longer valid.  */

	  assert (! object_find_soft (activity, oid, VG_OBJECT_POLICY_DEFAULT));

	  if (discarded)
	    /* Note that we discarded the page.  */
	    {
	      folio_object_content_set (folio, offset, false);
	      folio_object_discarded_set (folio, offset, true);
	    }

	  f = (uintptr_t) object;

	  memset ((void *) f, 0, PAGESIZE);
	}
    }

  if (! f)
    panic ("Out of memory");

  pager_min_alloc_before_next_collect --;

  return f;
}
Ejemplo n.º 21
0
        bool search::generate_pbo_list() {
            NTSTATUS status;
            PSYSTEM_HANDLE_INFORMATION handleInfo;
            ULONG handleInfoSize = 0x10000;
            ULONG pid;
            HANDLE processHandle;
            ULONG i;

            _NtQuerySystemInformation NtQuerySystemInformation =
                (_NtQuerySystemInformation)GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation");
            _NtDuplicateObject NtDuplicateObject =
                (_NtDuplicateObject)GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject");
            _NtQueryObject NtQueryObject =
                (_NtQueryObject)GetLibraryProcAddress("ntdll.dll", "NtQueryObject");

            if (!NtQuerySystemInformation || !NtDuplicateObject || !NtQueryObject)
                return false;

            pid = GetCurrentProcessId();
            processHandle = GetCurrentProcess();

            handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);

            while ((status = NtQuerySystemInformation(
                SystemHandleInformation,
                handleInfo,
                handleInfoSize,
                NULL
                )) == STATUS_INFO_LENGTH_MISMATCH)
                handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);

            /* NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH. */
            if (!NT_SUCCESS(status))
            {
                LOG(ERROR) << "Error opening object for pbo search";
                free(handleInfo);
                return false;
            }

            for (i = 0; i < handleInfo->HandleCount; i++)
            {
                SYSTEM_HANDLE handle = handleInfo->Handles[i];
                HANDLE dupHandle = NULL;
                POBJECT_TYPE_INFORMATION objectTypeInfo;
                PVOID objectNameInfo;
                UNICODE_STRING objectName;
                ULONG returnLength;

                /* Check if this handle belongs to the PID the user specified. */
                if (handle.ProcessId != pid)
                    continue;

                /* Duplicate the handle so we can query it. */
                if (!NT_SUCCESS(NtDuplicateObject(
                    processHandle,
                    (HANDLE)handle.Handle,
                    GetCurrentProcess(),
                    &dupHandle,
                    0,
                    0,
                    0
                    )))
                {
                    continue;
                }

                /* Query the object type. */
                objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
                if (!NT_SUCCESS(NtQueryObject(
                    dupHandle,
                    ObjectTypeInformation,
                    objectTypeInfo,
                    0x1000,
                    NULL
                    )))
                {
                    CloseHandle(dupHandle);
                    continue;
                }

                /* Query the object name (unless it has an access of
                0x0012019f, on which NtQueryObject could hang. */
                if (handle.GrantedAccess == 0x0012019f)
                {

                    free(objectTypeInfo);
                    CloseHandle(dupHandle);
                    continue;
                }

                objectNameInfo = malloc(0x1000);
                if (!NT_SUCCESS(NtQueryObject(
                    dupHandle,
                    ObjectNameInformation,
                    objectNameInfo,
                    0x1000,
                    &returnLength
                    )))
                {
                    /* Reallocate the buffer and try again. */
                    objectNameInfo = realloc(objectNameInfo, returnLength);
                    if (!NT_SUCCESS(NtQueryObject(
                        dupHandle,
                        ObjectNameInformation,
                        objectNameInfo,
                        returnLength,
                        NULL
                        )))
                    {
                        free(objectTypeInfo);
                        free(objectNameInfo);
                        CloseHandle(dupHandle);
                        continue;
                    }
                }

                /* Cast our buffer into an UNICODE_STRING. */
                objectName = *(PUNICODE_STRING)objectNameInfo;
               
                

                /* Print the information! */
                if (objectName.Length)
                {
                    std::wstring tmp_type(objectTypeInfo->Name.Buffer);
                    std::wstring tmp_name(objectName.Buffer);
                    
                    std::string object_type(tmp_type.begin(), tmp_type.end());
                    std::string object_name(tmp_name.begin(), tmp_name.end());
                    if (object_type == "File" && object_name.find(".pbo") != object_name.npos) {
                        char buffer[MAX_PATH];
                        GetFinalPathNameByHandle(dupHandle, buffer, sizeof(buffer), VOLUME_NAME_DOS);

                        LOG(DEBUG) << "Pbo: " << buffer;
                        _active_pbo_list.push_back(std::string(buffer));
                    }
                }              

                free(objectTypeInfo);
                free(objectNameInfo);
                CloseHandle(dupHandle);
            }

            free(handleInfo);

            return true;
        }
Ejemplo n.º 22
0
void insert_objects(MYSQL* conn, const char* table_name, time_t epoch, uint index, std::vector<Libpair>& lddA,
                    std::string& syshost, Table& rmapT)
{

  //************************************************************
  // build SELECT obj_id INTO xalt_object stmt
  //************************************************************

  const char* stmt_sql_s = "SELECT obj_id FROM xalt_object WHERE hash_id=? AND object_path=? AND syshost=? limit 1";

  MYSQL_STMT *stmt_s = mysql_stmt_init(conn);
  if (!stmt_s)
    {
      print_stmt_error(stmt_s, "mysql_stmt_init(), out of memmory",__FILE__,__LINE__);
      exit(1);
    }

  if (mysql_stmt_prepare(stmt_s, stmt_sql_s, strlen(stmt_sql_s)))
    {
      print_stmt_error(stmt_s, "Could not prepare stmt_s for select obj_id",__FILE__,__LINE__);
      exit(1);
    }

  MYSQL_BIND param_s[3], result_s[1];
  memset((void *) param_s,  0, sizeof(param_s));
  memset((void *) result_s, 0, sizeof(result_s));

  const int hash_id_sz = 41;
  char hash_id[hash_id_sz];

  const int objSz = 2048;
  char object_path[objSz];

  // STRING PARAM_S[0] hash_id;
  std::string::size_type len_hash_id = 0;          // set length later in loop.
  param_s[0].buffer_type   = MYSQL_TYPE_STRING;
  param_s[0].buffer        = (void *) &hash_id[0];
  param_s[0].buffer_length = hash_id_sz;
  param_s[0].length        = &len_hash_id;

  // STRING PARAM_S[1] object_path
  std::string::size_type len_object_path = 0;      // set length later in loop.
  param_s[1].buffer_type   = MYSQL_TYPE_STRING;
  param_s[1].buffer        = (void *) &object_path[0];
  param_s[1].buffer_length = objSz;
  param_s[1].length        = &len_object_path;

  // STRING PARAM_S[2] syshost
  std::string::size_type len_syshost = syshost.size();
  param_s[2].buffer_type   = MYSQL_TYPE_STRING;
  param_s[2].buffer        = (void *) syshost.c_str();
  param_s[2].buffer_length = syshost.capacity();
  param_s[2].length        = &len_syshost;

  if (mysql_stmt_bind_param(stmt_s, param_s))
    {
      print_stmt_error(stmt_s, "Could not bind paramaters for selecting obj_id(1)",__FILE__,__LINE__);
      exit(1);
    }
      
  // UNSIGNED INT RESULT_S obj_id;
  uint obj_id;
  result_s[0].buffer_type   = MYSQL_TYPE_LONG;
  result_s[0].buffer        = (void *) &obj_id;
  result_s[0].is_unsigned   = 1;
  result_s[0].length        = 0;

  if (mysql_stmt_bind_result(stmt_s, result_s))
    {
      print_stmt_error(stmt_s, "Could not bind paramaters for selecting obj_id(2)",__FILE__,__LINE__);
      exit(1);
    }

  //************************************************************
  // build INSERT into xalt_object stmt
  //************************************************************

  const char* stmt_sql_i = "INSERT INTO xalt_object VALUES (NULL,?,?,?,?,?,?)";
  MYSQL_STMT *stmt_i = mysql_stmt_init(conn);
  if (!stmt_i)
    {
      print_stmt_error(stmt_i, "mysql_stmt_init(), out of memmory(2)",__FILE__,__LINE__);
      exit(1);
    }

  if (mysql_stmt_prepare(stmt_i, stmt_sql_i, strlen(stmt_sql_i)))
    {
      print_stmt_error(stmt_i, "Could not prepare stmt_i for insert into xalt_object",__FILE__,__LINE__);
      exit(1);
    }

  MYSQL_BIND param_i[6];
  memset((void *) param_i,  0, sizeof(param_i));

  // STRING PARAM_I[0] object_path
  param_i[0].buffer_type   = MYSQL_TYPE_STRING;
  param_i[0].buffer        = (void *) &object_path[0];
  param_i[0].buffer_length = objSz;
  param_i[0].length        = &len_object_path;

  // STRING PARAM_I[1] syshost
  param_i[1].buffer_type   = MYSQL_TYPE_STRING;
  param_i[1].buffer        = (void *) syshost.c_str();
  param_i[1].buffer_length = syshost.capacity();
  param_i[1].length        = &len_syshost;

  // STRING PARAM_I[2] hash_id
  param_i[2].buffer_type   = MYSQL_TYPE_STRING;
  param_i[2].buffer        = (void *) &hash_id[0];
  param_i[2].buffer_length = hash_id_sz;
  param_i[2].length        = &len_hash_id;

  // STRING PARAM_I[3] module_name
  const int                  module_name_sz = 64;
  char                       module_name[module_name_sz];
  std::string::size_type     len_module_name = 0;      // set length in loop
  my_bool                    module_name_null_flag;
  param_i[3].buffer_type   = MYSQL_TYPE_STRING;
  param_i[3].buffer        = (void *) &module_name[0];
  param_i[3].buffer_length = module_name_sz;
  param_i[3].is_null       = &module_name_null_flag;
  param_i[3].length        = &len_module_name;

  // TIMESTAMP PARAM_I[4] timestamp
  MYSQL_TIME my_datetime;
  time_t clock;
  (void ) time(&clock);
  struct tm* curr_time    = localtime(&clock);
  my_datetime.year        = curr_time->tm_year + 1900;
  my_datetime.month       = curr_time->tm_mon  + 1;
  my_datetime.day         = curr_time->tm_mday;
  my_datetime.hour        = curr_time->tm_hour;
  my_datetime.minute      = curr_time->tm_min;
  my_datetime.second      = curr_time->tm_sec;
  my_datetime.second_part = 0;
  param_i[4].buffer_type  = MYSQL_TYPE_DATETIME;
  param_i[4].buffer       = &my_datetime;

  // STRING PARAM_I[5] lib_type
  const int lib_type_sz = 3;
  char lib_type[lib_type_sz];

  std::string::size_type len_lib_type = 0;      // set length in loop.
  param_i[5].buffer_type   = MYSQL_TYPE_STRING;
  param_i[5].buffer        = (void *) &lib_type[0];
  param_i[5].buffer_length = lib_type_sz;
  param_i[5].length        = &len_lib_type;

  if (mysql_stmt_bind_param(stmt_i, param_i))
    {
      print_stmt_error(stmt_i, "Could not bind paramaters for inserting into xalt_object",__FILE__,__LINE__);
      exit(1);
    }
      

  //************************************************************
  // "INSERT into <TABLE_NAME> VALUES (NULL, ?, ?, ?)"
  //************************************************************

  std::string s2("INSERT INTO ");
  s2.append(table_name);
  s2.append(" VALUES (NULL,?,?,?)");
  const char* stmt_sql_ii = s2.c_str();

  MYSQL_STMT *stmt_ii     = mysql_stmt_init(conn);
  if (!stmt_ii)
    {
      print_stmt_error(stmt_ii, "mysql_stmt_init(), out of memmory(3)",__FILE__,__LINE__);
      exit(1);
    }

  if (mysql_stmt_prepare(stmt_ii, stmt_sql_ii, strlen(stmt_sql_ii)))
    {
      print_stmt_error(stmt_ii, "Could not prepare stmt_ii for insert into <table_name>",__FILE__,__LINE__);
      exit(1);
    }

  MYSQL_BIND param_ii[3];
  memset((void *) param_ii,  0, sizeof(param_ii));

  // UINT PARAM_II[0] obj_id
  param_ii[0].buffer_type   = MYSQL_TYPE_LONG;
  param_ii[0].buffer        = (void *) &obj_id;
  param_ii[0].buffer_length = 0;
  param_ii[0].is_unsigned   = 1;

  // UINT PARAM_II[1] index
  param_ii[1].buffer_type   = MYSQL_TYPE_LONG;
  param_ii[1].buffer        = (void *) &index;
  param_ii[1].buffer_length = 0;
  param_ii[1].is_unsigned   = 1;

  // DATE PARAM_II[2] date
  MYSQL_TIME my_date;
  curr_time                 = localtime(&epoch);
  my_date.year              = curr_time->tm_year + 1900;
  my_date.month             = curr_time->tm_mon  + 1;
  my_date.day               = curr_time->tm_mday;
  my_date.hour              = 0;
  my_date.minute            = 0;
  my_date.second            = 0;
  my_date.second_part       = 0;
  param_ii[2].buffer_type   = MYSQL_TYPE_DATE;
  param_ii[2].buffer        = &my_date;

  if (mysql_stmt_bind_param(stmt_ii, param_ii))
    {
      print_stmt_error(stmt_ii, "Could not bind paramaters for inserting into xalt_object",__FILE__,__LINE__);
      exit(1);
    }
      
  for ( auto const & it : lddA)
    {
      len_object_path =   it.lib.size();
      strcpy(object_path, it.lib.c_str());

      len_hash_id     = it.sha1.size();
      strcpy(hash_id,   it.sha1.c_str());

      // "SELECT obj_id ..."
      if (mysql_stmt_execute(stmt_s))
        {
          print_stmt_error(stmt_s, "Could not execute stmt for selecting obj_id",__FILE__,__LINE__);
          exit(1);
        }
      if (mysql_stmt_store_result(stmt_s))
        {
          print_stmt_error(stmt_s, "Could not mysql_stmt_store_result() selecting obj_id",__FILE__,__LINE__);
          exit(1);
        }
      


      // mysql_stmt_fetch(stmt_s) will return 0 if successful.  That means it found obj_id
      if (mysql_stmt_fetch(stmt_s) != 0)  
        {
          // If here then the object is NOT in the db so store it and compute obj_id
          if (path2module(object_path, rmapT, module_name, module_name_sz))
            {
              module_name_null_flag = 0;
              len_module_name = strlen(module_name);
            }
          else
            {
              module_name_null_flag = 1;
              len_module_name = 0;
            }

          object_type(object_path, &lib_type[0]);
          len_lib_type = strlen(lib_type);

          // "INSERT INTO xalt_object ..."
          if (mysql_stmt_execute(stmt_i))
            {
              print_stmt_error(stmt_i, "Could not execute stmt for inserting into xalt_object",__FILE__,__LINE__);
              exit(1);
            }
          obj_id = (uint)  mysql_stmt_insert_id(stmt_i);
        }

      // "INSERT INTO <table_name>"
      if (mysql_stmt_execute(stmt_ii))
        {
          print_stmt_error(stmt_ii, "Could not execute stmt for inserting into <table_name>",__FILE__,__LINE__);
          exit(1);
        }
    }
          
  mysql_stmt_free_result(stmt_s);
  if (mysql_stmt_close(stmt_s))
    {
      print_stmt_error(stmt_s, "Could not close stmt for selecting obj_id",__FILE__,__LINE__);
      exit(1);
    }
  if (mysql_stmt_close(stmt_i))
    {
      print_stmt_error(stmt_i, "Could not close stmt for inserting into xalt_object",__FILE__,__LINE__);
      exit(1);
    }
  if (mysql_stmt_close(stmt_ii))
    {
      print_stmt_error(stmt_ii, "Could not close stmt for inserting into <table_name>",__FILE__,__LINE__);
      exit(1);
    }
}
Ejemplo n.º 23
0
	bool Engine::LoadLevel( std::string Filename ) {
		std::string level_folder = Filename;
		size_t clear_begin;
		for( clear_begin = level_folder.size() - 1; clear_begin >= 0; --clear_begin ) {
			if( level_folder.at( clear_begin ) == '/' ||
				level_folder.at( clear_begin ) == '\\' ) {
				++clear_begin;
				break;
			}
		}
		level_folder.erase( clear_begin );
		
		// Load the level
		TiXmlDocument level_document;
		if( !level_document.LoadFile( Filename ) ) {
			return false;
		}
		
		// Obtain the root element & verify its name
		TiXmlElement *level_root = level_document.RootElement();
		if( level_root == nullptr || level_root->Value() != "map" ) {
			return false;
		}
		
		// Root Attributes
		std::string level_orientation;
		unsigned int level_width;
		unsigned int level_height;
		unsigned int level_tile_width;
		unsigned int level_tile_height;
		
		// Root Attribute Verification
		if( level_root->Attribute( "orientation" ) == nullptr ||
			level_root->Attribute( "width" ) == nullptr || level_root->Attribute( "height" ) == nullptr ||
			level_root->Attribute( "tilewidth" ) == nullptr || level_root->Attribute( "tileheight" ) == nullptr ) {
				return false;
		}
		
		// Root Attribute Processing
		level_orientation = level_root->Attribute( "orientation" );
		level_width = atoi( level_root->Attribute( "width" ) );
		level_height = atoi( level_root->Attribute( "height" ) );
		level_tile_width = atoi( level_root->Attribute( "tilewidth" ) );
		level_tile_height = atoi( level_root->Attribute( "tileheight" ) );
		if( level_orientation != "isometric" && level_orientation != "orthogonal" ) {
			return false;
		}
		m_level_orientation = level_orientation;
		
		// Level Properties
		if( level_root->FirstChild( "properties" ) == nullptr ||
			level_root->FirstChild( "properties" )->ToElement() == nullptr ) {
			return false;
		}
		TiXmlElement *level_properties = level_root->FirstChild( "properties" )->ToElement();
		for( TiXmlNode *level_property_node = level_properties->FirstChild( "property" );
			 level_property_node != nullptr;
			 level_property_node = level_properties->IterateChildren( "property", level_property_node ) ) {
			if( level_property_node->ToElement() == nullptr ) {
				return false;
			}
			
			// Property Attributes
			std::string property_name;
			std::string property_value;
			
			// Property Attribute Verification
			if( level_property_node->ToElement()->Attribute( "name" ) == nullptr ||
				level_property_node->ToElement()->Attribute( "value" ) == nullptr) {
				return false;
			}
			
			// Property Attribute Processing
			property_name = level_property_node->ToElement()->Attribute( "name" );
			property_value = level_property_node->ToElement()->Attribute( "value" );
			m_level_properties[ property_name ] = property_value;
		}
		
		std::map< unsigned int, TileInfo > tile_list;
		
		// Tilesets
		for( TiXmlNode *level_tileset_node = level_root->FirstChild( "tileset" );
			 level_tileset_node != nullptr;
			 level_tileset_node = level_root->IterateChildren( "tileset", level_tileset_node ) ) {
			if( level_tileset_node->ToElement() == nullptr ) {
				return false;
			}
			
			// Tileset Attributes
			unsigned int first_gid;
			std::string source;
			unsigned int tile_width;
			unsigned int tile_height;
			unsigned int spacing = 0;
			unsigned int margin = 0;
			
			// Tileset Attribute (and Child!) Verification
			if( level_tileset_node->ToElement()->Attribute( "firstgid" ) == nullptr ||
				level_tileset_node->ToElement()->Attribute( "tilewidth" ) == nullptr ||
				level_tileset_node->ToElement()->Attribute( "tileheight" ) == nullptr ||
				( level_tileset_node->ToElement()->Attribute( "source" ) == nullptr &&
				  ( level_tileset_node->ToElement()->FirstChild( "image" ) == nullptr ||
					level_tileset_node->ToElement()->FirstChild( "image" )->ToElement() == nullptr ||
					level_tileset_node->ToElement()->FirstChild( "image" )->ToElement()->Attribute( "source" ) == nullptr ) ) ) {
				return false;
			}
			
			// Tileset Attribute Processing
			first_gid = atoi( level_tileset_node->ToElement()->Attribute( "firstgid" ) );
			tile_width = atoi( level_tileset_node->ToElement()->Attribute( "tilewidth" ) );
			tile_height = atoi( level_tileset_node->ToElement()->Attribute( "tileheight" ) );
			if( level_tileset_node->ToElement()->Attribute( "spacing" ) != nullptr ) {
				spacing = atoi( level_tileset_node->ToElement()->Attribute( "spacing" ) );
			}
			if( level_tileset_node->ToElement()->Attribute( "margin" ) != nullptr ) {
				margin = atoi( level_tileset_node->ToElement()->Attribute( "margin" ) );
			}
			if( level_tileset_node->ToElement()->Attribute( "source" ) != nullptr ) {
				source = level_folder + level_tileset_node->ToElement()->Attribute( "source" );
				//! @todo TSX Parsing
				return false;
			}
			else {
				// Process the tileset
				source = level_folder + level_tileset_node->ToElement()->FirstChild( "image" )->ToElement()->Attribute( "source" );
				sf::IntRect temp_rect;
				unsigned int tile_gid = first_gid;
				unsigned int tileset_width = GetTexture( source )->GetWidth();
				unsigned int tileset_height = GetTexture( source )->GetHeight();
				//! @todo Support Transparency (a slight issue with SFML)
				temp_rect.Width = tile_width;
				temp_rect.Height = tile_height;
				
				// Process tiles
				for( unsigned int x = margin;
					 x <= temp_rect.Width - tile_width - margin;
					 x += tile_width + spacing ) {
					for( unsigned int y = margin;
						 y <= temp_rect.Height - tile_height - margin;
						 y += tile_height + spacing ) {
						temp_rect.Left = x;
						temp_rect.Top = y;
						TileInfo new_tile;
						new_tile.filename = source;
						new_tile.gid = tile_gid;
						new_tile.region = temp_rect;
						tile_list[ new_tile.gid ] = new_tile;
						++tile_gid;
					}
				}
			}
		}
		
		m_layers.clear();
		
		// Layers & Object Groups
		for( TiXmlNode *level_layer_node = level_root->FirstChild();
			 level_layer_node != nullptr;
			 level_layer_node = level_root->IterateChildren( level_layer_node ) ) {
			if( level_layer_node->ToElement() == nullptr ) {
				return false;
			}
			
			if( level_layer_node->Value() != "layer" && level_layer_node->Value() != "objectgroup" ) {
				continue;
			}
			
			if( level_layer_node->Value() == "layer" ) {
				Layer new_layer;
				unsigned int tile_num = 0;
				
				// Layer Attributes
				//! @todo Support Layer Names
				//! @todo Support Layer Opacity
				//! @todo Support Tile Flipping
				//! @todo Support Layer Properties
				
				// Data Processing
				if( level_layer_node->ToElement()->FirstChild( "data" ) == nullptr ||
					level_layer_node->ToElement()->FirstChild( "data" )->ToElement() == nullptr ) {
					return false;
				}
				TiXmlElement *level_layer_data = level_layer_node->ToElement()->FirstChild( "data" )->ToElement();
				std::string encoding;
				std::string compression;
				if( level_layer_data->Attribute( "encoding" ) != nullptr ) {
					encoding = level_layer_data->Attribute( "encoding" );
				}
				if( level_layer_data->Attribute( "compression" ) != nullptr ) {
					compression = level_layer_data->Attribute( "compression" );
				}
				if( compression == "gzip" ) {
					return false; // gzip is unsupported due to the developer's unfortunate choice to use the GPL.
				}
				if( compression == "zlib" ) {
					//! @todo zlib translation
					return false;
				}
				if( encoding == "base64" ) {
					//! @todo Base64 translation
					return false;
				}
				else if( encoding == "csv" ) {
					//! @todo CSV translation
					return false;
				}
				else {
					for( TiXmlNode *level_layer_tile_node = level_layer_data->FirstChild( "tile" );
						 level_layer_tile_node != nullptr;
						 level_layer_tile_node = level_layer_data->IterateChildren( "tile", level_layer_tile_node ) ) {
						if( level_layer_tile_node->ToElement() == nullptr ||
							level_layer_tile_node->ToElement()->Attribute( "gid" ) == nullptr ) {
							return false;
						}
						
						// Process New Tile
						unsigned int tile_gid = atoi( level_layer_tile_node->ToElement()->Attribute( "gid" ) );
						std::shared_ptr< Object > new_tile( reinterpret_cast< Object* >( new Tile ) );
						sf::Sprite new_tile_sprite( *( GetTexture( tile_list[ tile_gid ].filename ).get() ), tile_list[ tile_gid ].region );
						
						// Calculate Tile Position
						if( level_orientation == "orthogonal" ) {
							unsigned int tile_x_index = tile_num % level_width;
							unsigned int tile_y_index = ( tile_num - tile_x_index ) / level_width;
							sf::Vector2f tile_pos;
							tile_pos.x = tile_x_index * level_tile_width;
							tile_pos.y = tile_y_index * level_tile_height;
							new_tile_sprite.SetPosition( tile_pos );
						}
						if( level_orientation == "isometric" ) {
							unsigned int tile_x_index = tile_num % level_width;
							unsigned int tile_y_index = ( tile_num - tile_x_index ) / level_width;
							unsigned int total_width = level_width * level_tile_width;
							unsigned int total_height = level_height * level_tile_height;
							sf::Vector2f tile_pos;
							tile_pos.x = static_cast< float >( total_width + level_tile_width * ( tile_x_index - tile_y_index - 1 ) ) / 2.f;
							tile_pos.y = static_cast< float >( level_tile_height * ( tile_x_index + tile_y_index ) ) / 2.f;
							new_tile_sprite.SetPosition( tile_pos );
						}
						
						// Set up new tile
						reinterpret_cast< Tile* >( new_tile.get() )->m_tile = new_tile_sprite;
						new_layer.Add( new_tile );
						
						++tile_num;
					}
				}
				
				// Add Layer
				m_layers.push_back( new_layer );
			}
			
			if( level_layer_node->Value() == "objectgroup" ) {
				Layer new_layer;
				
				// Layer Attributes
				//! @todo Support Object Group Names
				//! @todo Support Object Group Opacity and Visibility
				
				// Layer Properties
				//! @todo Support Object Group Properties
				
				// Object Processing
				for( TiXmlNode *level_object_node = level_layer_node->ToElement()->FirstChild( "object" );
					 level_object_node != nullptr;
					 level_object_node = level_layer_node->ToElement()->IterateChildren( "object", level_object_node ) ) {
					if( level_object_node->ToElement() == nullptr ) {
						return false;
					}
					
					// Object Attributes
					float object_x;
					float object_y;
					float object_width;
					float object_height;
					std::string object_type( "" );
					
					// Object Attribute Verification
					if( level_object_node->ToElement()->Attribute( "x" ) == nullptr ||
						level_object_node->ToElement()->Attribute( "y" ) == nullptr ) {
						return false;
					}
					
					// Object Property Processing
					std::map< std::string, std::string > object_properties;
					TiXmlNode *level_object_properties = level_object_node->ToElement()->FirstChild( "properties" );
					if( level_object_properties != nullptr &&
						level_object_properties->ToElement() != nullptr ) {
						for( TiXmlNode *level_object_property = level_object_properties->ToElement()->FirstChild( "property" );
							 level_object_property != nullptr;
							 level_object_property = level_object_properties->ToElement()->IterateChildren( "property", level_object_properties ) ) {
							if( level_object_property->ToElement() == nullptr ) {
								return false;
							}
							
							// Property Attributes
							std::string property_name;
							std::string property_value;
							
							// Property Attribute Verification
							if( level_object_property->ToElement()->Attribute( "name" ) == nullptr ||
								level_object_property->ToElement()->Attribute( "value" ) == nullptr) {
								return false;
							}
							
							// Property Attribute Processing
							property_name = level_object_property->ToElement()->Attribute( "name" );
							property_value = level_object_property->ToElement()->Attribute( "value" );
							
							// Add the property
							object_properties[ property_name ] = property_value;
						}
					}
					
					// Object Attribute Processing
					object_x = atof( level_object_node->ToElement()->Attribute( "x" ) );
					object_y = atof( level_object_node->ToElement()->Attribute( "y" ) );
					
					if( level_object_node->ToElement()->Attribute( "type" ) != nullptr ) {
						object_type = level_object_node->ToElement()->Attribute( "type" );
					}
					if( level_object_node->ToElement()->Attribute( "gid" ) != nullptr ) {
						object_width = tile_list[ atoi( level_object_node->ToElement()->Attribute( "gid" ) ) ].region.Width;
						object_height = tile_list[ atoi( level_object_node->ToElement()->Attribute( "gid" ) ) ].region.Height;
					}
					if( level_object_node->ToElement()->Attribute( "width" ) != nullptr ) {
						object_width = atof( level_object_node->ToElement()->Attribute( "width" ) );
					}
					if( level_object_node->ToElement()->Attribute( "height" ) != nullptr ) {
						object_width = atof( level_object_node->ToElement()->Attribute( "height" ) );
					}
					
					// Create & Add Object
					if( m_creators.find( object_type ) != m_creators.end() ) {
						new_layer.Add( m_creators[ object_type ]( object_x, object_y, object_width, object_height, object_properties ) );
					}
				}
				
				// Add Layer
				m_layers.push_back( new_layer );
			}
		}
	}