Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Faster writing due to a new writing system.
When using the json* method, a stream is used to write the data. Writing of json forms will likely benefit from not using streams in the future.
- Loading branch information
1 parent
5fe3c86
commit 7fb6973
Showing
2 changed files
with
75 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,95 @@ | ||
(in-package :jsown) | ||
|
||
(declaim (optimize (speed 0) (debug 3) (safety 3))) | ||
(declaim (optimize (speed 3) (debug 3) (safety 0))) | ||
|
||
;;;;;;;;;;;;;;;;;; | ||
;; generic writing | ||
(defgeneric to-json (object) | ||
(:documentation "Writes the given object to json")) | ||
(:documentation "Writes the given object to json in a generic way.")) | ||
|
||
(defmethod to-json ((string string)) | ||
(with-output-to-string (stream) | ||
(write string :stream stream))) | ||
(write-string string stream))) | ||
(defmethod to-json ((number number)) | ||
(with-output-to-string (stream) | ||
(write number :stream stream))) | ||
(write number :stream stream :pretty nil))) | ||
(defmethod to-json ((ratio ratio)) | ||
(to-json (coerce ratio 'float))) | ||
|
||
(defmethod to-json ((list list)) | ||
(if (eq (car list) :obj) | ||
(object-to-json (cdr list)) | ||
(list-to-json list))) | ||
(let ((*print-pretty* nil)) ;; *pretty-print* makes printing very slow, internal json objects needn't have this | ||
(if (eq (car list) :obj) | ||
(object-to-json (cdr list)) | ||
(list-to-json list)))) | ||
|
||
(defun object-to-json (list) | ||
(format nil "{~{~{~A:~A~}~^,~}}" | ||
(loop for item in list collect | ||
(list (to-json (car item)) | ||
(to-json (cdr item)))))) | ||
|
||
(defun list-to-json (list) | ||
(format nil "[~{~A~^,~}]" | ||
(mapcar #'to-json list))) | ||
|
||
;;;;;;;;;;;;;;;;; | ||
;; speedy writing | ||
(defun list-is-object-p (list) | ||
(declare (type (or cons nil) list)) | ||
(and (consp list) | ||
(eq (car list) :obj))) | ||
|
||
(defun to-json* (object) | ||
"Converts an object in internal jsown representation to a string containing the json representation" | ||
(let ((*print-pretty* nil)) | ||
(with-output-to-string (output) | ||
(write-object-to-stream object output)))) | ||
|
||
(defun write-number* (object output) | ||
(declare (type number object) | ||
(type stream output)) | ||
(write object :stream output)) | ||
|
||
(defun write-string* (object output) | ||
(declare (type string object) | ||
(type stream output)) | ||
(write-string object output)) | ||
|
||
(declaim (inline write-number* write-string*)) | ||
|
||
(defun write-object-to-stream (object output) | ||
(declare (type stream output)) | ||
(typecase object | ||
(ratio (write (coerce object 'float) :stream output)) | ||
(number (write-number* object output)) | ||
(string (write-string* object output)) | ||
(T (if (list-is-object-p object) | ||
(if (null (cdr object)) | ||
"{}" | ||
(progn | ||
(format output "{") | ||
(write-string* (caadr object) output) | ||
(format output ":") | ||
(write-object-to-stream (cdadr object) output) | ||
(loop | ||
for curr-obj in (cdr object) | ||
do (progn | ||
(let ((k (car curr-obj)) | ||
(v (cdr curr-obj))) | ||
(declare (type string k)) | ||
(format output ",") | ||
(write-string* k output) | ||
(format output ":") | ||
(write-object-to-stream v output)))) | ||
(format output "}"))) | ||
(progn | ||
(if (null (cdr object)) | ||
(format output "[]") | ||
(progn | ||
(format output "[") | ||
(write-object-to-stream (first object) output) | ||
(loop for item in (rest object) | ||
do (progn | ||
(format output ",") | ||
(write-object-to-stream item output))) | ||
(format output "]")))))))) |