| /* Copyright (c) 2015 Google Inc | 
 |  * Davide Libenzi <dlibenzi@google.com> | 
 |  * See LICENSE for details. | 
 |  */ | 
 |  | 
 | #include <ros/errno.h> | 
 | #include <sys/types.h> | 
 | #include <stdio.h> | 
 | #include <sort.h> | 
 | #include <address_range.h> | 
 |  | 
 | static int address_range_cmp(const void *f1, const void *f2) | 
 | { | 
 | 	return ((const struct address_range *) f1)->start < | 
 | 		((const struct address_range *) f2)->start ? -1 : 1; | 
 | } | 
 |  | 
 | int address_range_validate(const struct address_range *ars, size_t count) | 
 | { | 
 | 	for (size_t i = 0; i < count; i++) { | 
 | 		if (ars[i].start > ars[i].end) | 
 | 			return -EINVAL; | 
 | 		if ((i > 0) && (ars[i - 1].end >= ars[i].start)) | 
 | 			return -EINVAL; | 
 | 	} | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | int address_range_init(struct address_range *ars, size_t count) | 
 | { | 
 | 	sort(ars, count, sizeof(*ars), address_range_cmp); | 
 |  | 
 | 	return address_range_validate(ars, count); | 
 | } | 
 |  | 
 | const struct address_range *address_range_find(const struct address_range *ars, | 
 | 					       size_t count, uintptr_t addr) | 
 | { | 
 | 	ssize_t l = 0, r = count - 1; | 
 |  | 
 | 	while (l <= r) { | 
 | 		ssize_t x = l + (r - l) / 2; | 
 | 		const struct address_range *car = ars + x; | 
 |  | 
 | 		if (car->end < addr) | 
 | 			l = x + 1; | 
 | 		else if (car->start > addr) | 
 | 			r = x - 1; | 
 | 		else | 
 | 			return car; | 
 | 	} | 
 |  | 
 | 	return NULL; | 
 | } |