aboutsummaryrefslogtreecommitdiffstats
path: root/geoip/ip.lisp
diff options
context:
space:
mode:
Diffstat (limited to 'geoip/ip.lisp')
-rw-r--r--geoip/ip.lisp46
1 files changed, 32 insertions, 14 deletions
diff --git a/geoip/ip.lisp b/geoip/ip.lisp
index 5190143..95d2ae2 100644
--- a/geoip/ip.lisp
+++ b/geoip/ip.lisp
@@ -107,7 +107,8 @@
(make-maxmind-database
:ptr ptr :fd fd :filename file :size size
:metadata metadata
- :data-offset (+ 16 (* (/ (* 2 record-size) 8) node-count))))))
+ ;; :data-offset (+ 16 (* (/ (* 2 record-size) 8) node-count))
+ :data-offset (+ 16 (/ (* record-size node-count) 4))))))
(defun make-mmdb (file)
(multiple-value-bind (ptr fd size) (mmap:mmap file)
@@ -118,38 +119,55 @@
(prog1 (mem-ref db-ptr :uchar)
(incf-pointer db-ptr))))
-(defun bytes-from-foreign (db-ptr data-length)
+(defun bytes-from-foreign (reader data-length)
(let ((bytes (make-array data-length :element-type '(unsigned-byte 8))))
- (loop for i below data-length
- do (setf (aref bytes i) (read-db-char db-ptr)))
+ (with-slots (db-ptr) reader
+ (foreign-array-to-lisp db-ptr
+ `(:array :uchar ,data-length)
+ :element-type '(unsigned-byte 8)
+ :displaced-to bytes)
+ (incf-pointer db-ptr data-length))
bytes))
-(defun mread-unsigned (ptr size &key (big-endian t))
- (octet-to-int
- (bytes-from-foreign ptr size)
- :big-endian big-endian))
+(defun mread-uft8 (reader length)
+ (with-slots (db-ptr) reader
+ (prog1 (foreign-string-to-lisp db-ptr :count length :encoding :utf-8)
+ (incf-pointer db-ptr length))))
+
+(defun mread-unsigned (reader size)
+ (with-slots (db-ptr) reader
+ (let ((r 0))
+ (dotimes (i size)
+ (setf r (+ (ash r 8) (mem-ref db-ptr :uint8 i))))
+ (incf-pointer db-ptr size)
+ r)))
+
+(5am:test reader
+ (with-foreign-array (a #(0 0 1 23 126 195 159 195 156) '(:array :uint8 9))
+ (let ((r (make-db-reader :db-ptr a)))
+ (5am:is (= 279 (mread-unsigned r 4)))
+ (5am:is (equal "~ßÜ" (mread-uft8 r 5))))))
+
+(5am:run-all-tests)
+
(defun mread-datafield-metadata (db-ptr)
(let* ((control-byte (read-db-char db-ptr))
(type (ldb (byte 3 5) control-byte))
(length (ldb (byte 5 0) control-byte)))
- (when (= type 0)
+ (when (zerop type)
(setf type (+ 7 (read-db-char db-ptr))))
(list type
(cond
((or (= type 1) (< length 29))
length)
((= length 29)
- (+ 29 (read-uchar db-ptr)))
+ (+ 29 (read-db-char db-ptr)))
((= length 30)
(+ 285 (mread-unsigned db-ptr 2)))
((= length 31)
(+ 65821 (mread-unsigned db-ptr 3)))))))
-(defun mread-uft8 (db-ptr length)
- (babel:octets-to-string
- (bytes-from-foreign db-ptr length)))
-
(defun mread-map (db-ptr length)
(loop repeat length