|
108 | 108 | % jsonencode, if presents (MATLAB R2016b or Octave |
109 | 109 | % 6) first. If jsonencode does not exist or failed, |
110 | 110 | % this function falls back to the jsonlab savejson |
| 111 | +% Whitespaces_: a struct customizing delimiters, including |
| 112 | +% tab: sprintf('\t') indentation |
| 113 | +% newline: sprintf('\n') newline between items |
| 114 | +% sep: ',' delim. between items |
| 115 | +% quote: '"' quotes for obj name |
| 116 | +% array: '[]' start/end of array |
| 117 | +% obj: '{}' start/end of object |
| 118 | +% for example, when printing a compact JSON string, |
| 119 | +% the savejson function internally use |
| 120 | +% struct('tab', '', 'newline', '', 'sep', ',') |
111 | 121 | % |
112 | 122 | % opt can be replaced by a list of ('param',value) pairs. The param |
113 | 123 | % string is equivalent to a field in opt and is case sensitive. |
|
228 | 238 | rootname = 'root'; |
229 | 239 | end |
230 | 240 |
|
231 | | -whitespaces = struct('tab', sprintf('\t'), 'newline', sprintf('\n'), 'sep', sprintf(',\n')); |
| 241 | +whitespaces = struct('tab', sprintf('\t'), 'newline', sprintf('\n'), 'sep', sprintf(',\n'), 'quote', '"', 'array', '[]', 'obj', '{}'); |
232 | 242 | if (opt.compact == 1) |
233 | | - whitespaces = struct('tab', '', 'newline', '', 'sep', ','); |
| 243 | + whitespaces = struct('tab', '', 'newline', '', 'sep', ',', 'quote', '"', 'array', '[]', 'obj', '{}'); |
234 | 244 | end |
235 | 245 | if (~isfield(opt, 'whitespaces_')) |
236 | 246 | opt.whitespaces_ = whitespaces; |
| 247 | +else |
| 248 | + opt.whitespaces_ = mergestruct(whitespaces, opt.whitespaces_); |
237 | 249 | end |
238 | 250 |
|
239 | 251 | nl = whitespaces.newline; |
|
342 | 354 | bracketlevel = ~varargin{1}.singletcell; |
343 | 355 | if (len > bracketlevel) |
344 | 356 | if (~isempty(name)) |
345 | | - txt = {padding0, '"', decodevarname(name, varargin{1}.unpackhex), '":[', nl}; |
| 357 | + txt = {padding0, ws.quote, decodevarname(name, varargin{1}.unpackhex), ws.quote, ':', ws.array(1), nl}; |
346 | 358 | name = ''; |
347 | 359 | else |
348 | | - txt = {padding0, '[', nl}; |
| 360 | + txt = {padding0, ws.array(1), nl}; |
349 | 361 | end |
350 | 362 | elseif (len == 0) |
351 | 363 | if (~isempty(name)) |
352 | | - txt = {padding0, '"' decodevarname(name, varargin{1}.unpackhex) '":[]'}; |
| 364 | + txt = {padding0, ws.quote decodevarname(name, varargin{1}.unpackhex) ws.quote ':' ws.array}; |
353 | 365 | name = ''; |
354 | 366 | else |
355 | | - txt = {padding0, '[]'}; |
| 367 | + txt = {padding0, ws.array}; |
356 | 368 | end |
357 | 369 | txt = sprintf('%s', txt{:}); |
358 | 370 | return |
|
365 | 377 | txt = [txt{:}, cellfun(@(x, id) [obj2json(name, x, level + (dim(1) > 1) + (len > bracketlevel), varargin{:}), sep{(id == length(item)) + 1}], item, idx, 'UniformOutput', false)]; |
366 | 378 |
|
367 | 379 | if (len > bracketlevel) |
368 | | - txt(end + 1:end + 3) = {nl, padding0, ']'}; |
| 380 | + txt(end + 1:end + 3) = {nl, padding0, ws.array(2)}; |
369 | 381 | end |
370 | 382 | txt = sprintf('%s', txt{:}); |
371 | 383 |
|
|
393 | 405 |
|
394 | 406 | if (isempty(item)) |
395 | 407 | if (~isempty(name)) |
396 | | - txt = {padding0, '"', decodevarname(name, varargin{1}.unpackhex), '":[]'}; |
| 408 | + txt = {padding0, ws.quote, decodevarname(name, varargin{1}.unpackhex), ws.quote, ':', ws.array}; |
397 | 409 | else |
398 | | - txt = {padding0, '[]'}; |
| 410 | + txt = {padding0, ws.array}; |
399 | 411 | end |
400 | 412 | txt = sprintf('%s', txt{:}); |
401 | 413 | return |
402 | 414 | end |
403 | 415 | if (~isempty(name)) |
404 | 416 | if (forcearray) |
405 | | - txt = {padding0, '"', decodevarname(name, varargin{1}.unpackhex), '":[', nl}; |
| 417 | + txt = {padding0, ws.quote, decodevarname(name, varargin{1}.unpackhex), ws.quote ':', ws.array(1), nl}; |
406 | 418 | end |
407 | 419 | else |
408 | 420 | if (forcearray) |
409 | | - txt = {padding0, '[', nl}; |
| 421 | + txt = {padding0, ws.array(1), nl}; |
410 | 422 | end |
411 | 423 | end |
412 | 424 | for j = 1:dim(2) |
413 | 425 | if (dim(1) > 1) |
414 | | - txt(end + 1:end + 3) = {padding2, '[', nl}; |
| 426 | + txt(end + 1:end + 3) = {padding2, ws.array(1), nl}; |
415 | 427 | end |
416 | 428 | for i = 1:dim(1) |
417 | 429 | names = fieldnames(item(i, j)); |
418 | 430 | if (~isempty(name) && len == 1 && ~forcearray) |
419 | | - txt(end + 1:end + 5) = {padding1, '"', decodevarname(name, varargin{1}.unpackhex), '":{', nl}; |
| 431 | + txt(end + 1:end + 7) = {padding1, ws.quote, decodevarname(name, varargin{1}.unpackhex), ws.quote, ':', ws.obj(1), nl}; |
420 | 432 | else |
421 | | - txt(end + 1:end + 3) = {padding1, '{', nl}; |
| 433 | + txt(end + 1:end + 3) = {padding1, ws.obj(1), nl}; |
422 | 434 | end |
423 | 435 | if (~isempty(names)) |
424 | 436 | for e = 1:length(names) |
|
436 | 448 | txt{end + 1} = nl; |
437 | 449 | end |
438 | 450 | end |
439 | | - txt(end + 1:end + 2) = {padding1, '}'}; |
| 451 | + txt(end + 1:end + 2) = {padding1, ws.obj(2)}; |
440 | 452 | if (i < dim(1)) |
441 | 453 | txt(end + 1:end + 2) = {',' nl}; |
442 | 454 | end |
443 | 455 | end |
444 | 456 | if (dim(1) > 1) |
445 | | - txt(end + 1:end + 3) = {nl, padding2, ']'}; |
| 457 | + txt(end + 1:end + 3) = {nl, padding2, ws.array(2)}; |
446 | 458 | end |
447 | 459 | if (j < dim(2)) |
448 | 460 | txt(end + 1:end + 2) = {',' nl}; |
449 | 461 | end |
450 | 462 | end |
451 | 463 | if (forcearray) |
452 | | - txt(end + 1:end + 3) = {nl, padding0, ']'}; |
| 464 | + txt(end + 1:end + 3) = {nl, padding0, ws.array(2)}; |
453 | 465 | end |
454 | 466 | txt = sprintf('%s', txt{:}); |
455 | 467 |
|
|
502 | 514 |
|
503 | 515 | if (isempty(item)) |
504 | 516 | if (~isempty(name)) |
505 | | - txt = {padding0, '"', decodevarname(name, varargin{1}.unpackhex), '":[]'}; |
| 517 | + txt = {padding0, ws.quote, decodevarname(name, varargin{1}.unpackhex), ws.quote, ':', ws.array}; |
506 | 518 | else |
507 | | - txt = {padding0, '[]'}; |
| 519 | + txt = {padding0, ws.array}; |
508 | 520 | end |
509 | 521 | txt = sprintf('%s', txt{:}); |
510 | 522 | return |
511 | 523 | end |
512 | 524 | if (~isempty(name)) |
513 | | - txt = {padding0, '"', decodevarname(name, varargin{1}.unpackhex), '":{', nl}; |
| 525 | + txt = {padding0, ws.quote, decodevarname(name, varargin{1}.unpackhex), ws.quote, ':', ws.obj(1), nl}; |
514 | 526 | else |
515 | | - txt = {padding0, '{', nl}; |
| 527 | + txt = {padding0, ws.obj(1), nl}; |
516 | 528 | end |
517 | 529 |
|
518 | 530 | for i = 1:dim(1) |
|
528 | 540 | txt{end + 1} = nl; |
529 | 541 | end |
530 | 542 | end |
531 | | -txt(end + 1:end + 3) = {nl, padding0, '}'}; |
| 543 | +txt(end + 1:end + 3) = {nl, padding0, ws.obj(2)}; |
532 | 544 | txt = sprintf('%s', txt{:}); |
533 | 545 |
|
534 | 546 | %% ------------------------------------------------------------------------- |
|
547 | 559 |
|
548 | 560 | if (~isempty(name)) |
549 | 561 | if (len > 1) |
550 | | - txt = {padding1, '"', decodevarname(name, varargin{1}.unpackhex), '":[', nl}; |
| 562 | + txt = {padding1, ws.quote, decodevarname(name, varargin{1}.unpackhex), ws.quote ':', ws.array(1), nl}; |
551 | 563 | end |
552 | 564 | else |
553 | 565 | if (len > 1) |
554 | | - txt = {padding1, '[', nl}; |
| 566 | + txt = {padding1, ws.array(1), nl}; |
555 | 567 | end |
556 | 568 | end |
557 | 569 | for e = 1:len |
|
561 | 573 | val = item(e, :); |
562 | 574 | end |
563 | 575 | if (len == 1) |
564 | | - obj = ['"' decodevarname(name, varargin{1}.unpackhex) '":' '"', val, '"']; |
| 576 | + obj = [ws.quote decodevarname(name, varargin{1}.unpackhex) ws.quote ':' ws.quote, val, ws.quote]; |
565 | 577 | if (isempty(name)) |
566 | | - obj = ['"', val, '"']; |
| 578 | + obj = [ws.quote, val, ws.quote]; |
567 | 579 | end |
568 | 580 | txt(end + 1:end + 2) = {padding1, obj}; |
569 | 581 | else |
570 | | - txt(end + 1:end + 4) = {padding0, '"', val, '"'}; |
| 582 | + txt(end + 1:end + 4) = {padding0, ws.quote, val, ws.quote}; |
571 | 583 | end |
572 | 584 | if (e == len) |
573 | 585 | sep = ''; |
574 | 586 | end |
575 | 587 | txt{end + 1} = sep; |
576 | 588 | end |
577 | 589 | if (len > 1) |
578 | | - txt(end + 1:end + 3) = {nl, padding1, ']'}; |
| 590 | + txt(end + 1:end + 3) = {nl, padding1, ws.array(2)}; |
579 | 591 | end |
580 | 592 | txt = sprintf('%s', txt{:}); |
581 | 593 |
|
|
623 | 635 | txt = sprintf('%s%s', padding1, numtxt); |
624 | 636 | else |
625 | 637 | if (numel(item) == 1 && varargin{1}.singletarray == 0) |
626 | | - txt = sprintf('%s"%s":%s', padding1, decodevarname(name, opt.unpackhex), numtxt); |
| 638 | + txt = sprintf('%s%s%s%s:%s', padding1, ws.quote, decodevarname(name, opt.unpackhex), ws.quote, numtxt); |
627 | 639 | else |
628 | | - txt = sprintf('%s"%s":%s', padding1, decodevarname(name, opt.unpackhex), numtxt); |
| 640 | + txt = sprintf('%s%s%s%s:%s', padding1, ws.quote, decodevarname(name, opt.unpackhex), ws.quote, numtxt); |
629 | 641 | end |
630 | 642 | end |
631 | 643 | return |
|
658 | 670 | fulldata = [ix, iy, data]; |
659 | 671 | end |
660 | 672 | txt = sprintf(dataformat, txt, padding0, '"_ArrayZipSize_":', regexprep(mat2str(size(fulldata)), '\s+', ','), sep); |
661 | | - txt = sprintf(dataformat, txt, padding0, '"_ArrayZipType_":"', dozip, ['"' sep]); |
| 673 | + txt = sprintf(dataformat, txt, padding0, '"_ArrayZipType_":"', dozip, [ws.quote sep]); |
662 | 674 | compfun = str2func([dozip 'encode']); |
663 | | - txt = sprintf(dataformat, txt, padding0, '"_ArrayZipData_":"', base64encode(compfun(typecast(fulldata(:), 'uint8'))), ['"' nl]); |
| 675 | + txt = sprintf(dataformat, txt, padding0, '"_ArrayZipData_":"', base64encode(compfun(typecast(fulldata(:), 'uint8'))), [ws.quote nl]); |
664 | 676 | else |
665 | 677 | if (size(item, 1) == 1) |
666 | 678 | % Row vector, store only column indices. |
|
690 | 702 | fulldata = [real(item(:)) imag(item(:))]'; |
691 | 703 | end |
692 | 704 | txt = sprintf(dataformat, txt, padding0, '"_ArrayZipSize_":', regexprep(mat2str(size(fulldata)), '\s+', ','), sep); |
693 | | - txt = sprintf(dataformat, txt, padding0, '"_ArrayZipType_":"', dozip, ['"' sep]); |
| 705 | + txt = sprintf(dataformat, txt, padding0, '"_ArrayZipType_":"', dozip, [ws.quote sep]); |
694 | 706 | encodeparam = {}; |
695 | 707 | if (~isempty(regexp(dozip, '^blosc2', 'once'))) |
696 | 708 | compfun = @blosc2encode; |
697 | 709 | encodeparam = {dozip, 'nthread', jsonopt('nthread', 1, opt), 'shuffle', jsonopt('shuffle', 1, opt), 'typesize', jsonopt('typesize', length(typecast(fulldata(1), 'uint8')), opt)}; |
698 | 710 | else |
699 | 711 | compfun = str2func([dozip 'encode']); |
700 | 712 | end |
701 | | - txt = sprintf(dataformat, txt, padding0, '"_ArrayZipData_":"', char(base64encode(compfun(typecast(fulldata(:), 'uint8'), encodeparam{:}))), ['"' nl]); |
| 713 | + txt = sprintf(dataformat, txt, padding0, '"_ArrayZipData_":"', char(base64encode(compfun(typecast(fulldata(:), 'uint8'), encodeparam{:}))), [ws.quote nl]); |
702 | 714 | else |
703 | 715 | if (isreal(item)) |
704 | 716 | txt = sprintf(dataformat, txt, padding0, '"_ArrayData_":', ... |
|
711 | 723 | end |
712 | 724 | end |
713 | 725 |
|
714 | | -txt = sprintf('%s%s%s', txt, padding1, '}'); |
| 726 | +txt = sprintf('%s%s%s', txt, padding1, ws.obj(2)); |
715 | 727 |
|
716 | 728 | %% ------------------------------------------------------------------------- |
717 | 729 | function txt = matlabobject2json(name, item, level, varargin) |
|
775 | 787 | post = ''; |
776 | 788 | level = level - 1; |
777 | 789 | else |
778 | | - pre = sprintf('[%s', nl); |
779 | | - post = sprintf('%s%s]', nl, repmat(tab, 1, level - 1)); |
| 790 | + pre = sprintf('%s%s', ws.array(1), nl); |
| 791 | + post = sprintf('%s%s%s', nl, repmat(tab, 1, level - 1), ws.array(2)); |
780 | 792 | end |
781 | 793 |
|
782 | 794 | if (isempty(mat)) |
783 | 795 | if (varargin{1}.emptyarrayasnull) |
784 | 796 | txt = 'null'; |
785 | 797 | else |
786 | | - txt = '[]'; |
| 798 | + txt = ws.array; |
787 | 799 | end |
788 | 800 | return |
789 | 801 | end |
|
795 | 807 | if (numel(mat) == 1 && varargin{1}.singletarray == 0 && level > 0) |
796 | 808 | formatstr = [repmat([floatformat ','], 1, size(mat, 2) - 1) [floatformat sprintf(',%s', nl)]]; |
797 | 809 | else |
798 | | - formatstr = ['[' repmat([floatformat ','], 1, size(mat, 2) - 1) [floatformat sprintf('],%s', nl)]]; |
| 810 | + formatstr = [ws.array(1), repmat([floatformat ','], 1, size(mat, 2) - 1) [floatformat sprintf('%s,%s', ws.array(2), nl)]]; |
799 | 811 | end |
800 | 812 | if (nargin >= 2 && size(mat, 1) > 1 && varargin{1}.arrayindent == 1) |
801 | 813 | formatstr = [repmat(tab, 1, level) formatstr]; |
|
0 commit comments