|
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