diff options
Diffstat (limited to 'geoip')
-rw-r--r-- | geoip/ip.lisp | 46 |
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 |