|
15 | 15 |
|
16 | 16 | % Add a tag
|
17 | 17 | function obj = tag(obj, key, value)
|
18 |
| - obj.Tags{end + 1} = struct('key', key, 'value', value); |
| 18 | + obj.Tags{end + 1} = [key '=' value]; |
19 | 19 | end
|
20 | 20 |
|
21 | 21 | % Add multiple tags at once
|
|
58 | 58 | function lines = toLine(obj, precision)
|
59 | 59 | time_length = length(obj.Time);
|
60 | 60 | field_lengths = unique(cellfun(@(x) length(x.value), obj.Fields));
|
| 61 | + |
| 62 | + % Make sure the dimensions match |
61 | 63 | assert(~isempty(obj.Time), ...
|
62 | 64 | 'toLine:emptyTime', 'the time vector cannot be empty');
|
63 | 65 | assert(~isempty(field_lengths), ...
|
|
66 | 68 | 'toLine:sizeMismatch', 'all fields must have the same length');
|
67 | 69 | assert(time_length == field_lengths || time_length == 0, ...
|
68 | 70 | 'toLine:sizeMismatch', 'time and fields must have the same length');
|
69 |
| - builder = java.lang.StringBuilder(); |
| 71 | + |
| 72 | + % Obtain the time precision scale |
| 73 | + if nargin < 2, precision = 'ms'; end |
| 74 | + scale = obj.timeScale(precision); |
| 75 | + timestamp = int64(scale * posixtime(obj.Time)); |
| 76 | + |
| 77 | + % Create a line for each sample |
| 78 | + prefix = [strjoin([{obj.Name}, obj.Tags], ','), ' ']; |
| 79 | + builder = ''; |
70 | 80 | for i = 1:field_lengths
|
71 |
| - point = Point(obj.Name); |
72 |
| - for t = 1:length(obj.Tags) |
73 |
| - tag = obj.Tags{t}; |
74 |
| - point.tag(tag.key, tag.value); |
75 |
| - end |
| 81 | + values = ''; |
76 | 82 | for f = 1:length(obj.Fields)
|
77 | 83 | field = obj.Fields{f};
|
78 | 84 | name = field.key;
|
79 | 85 | value = field.value;
|
80 | 86 | if iscell(value)
|
81 |
| - point.field(name, value{i}); |
| 87 | + str = obj.fieldFmt(name, value{i}); |
82 | 88 | else
|
83 |
| - point.field(name, value(i)); |
| 89 | + str = obj.fieldFmt(name, value(i)); |
| 90 | + end |
| 91 | + if ~isempty(str) |
| 92 | + values = [values, str, ',']; |
84 | 93 | end
|
85 | 94 | end
|
86 |
| - point.time(obj.Time(i)); |
87 |
| - if nargin < 2 |
88 |
| - line = point.toLine(); |
89 |
| - else |
90 |
| - line = point.toLine(precision); |
| 95 | + if ~isempty(values) |
| 96 | + values = values(1:end-1); |
| 97 | + time = sprintf(' %i', timestamp(i)); |
| 98 | + builder = [builder, prefix, values, time, newline]; |
91 | 99 | end
|
92 |
| - if ~isempty(line) |
93 |
| - builder.append(line); |
94 |
| - builder.append(newline); |
| 100 | + end |
| 101 | + lines = builder(1:end-1); |
| 102 | + end |
| 103 | + end |
| 104 | + |
| 105 | + methods(Static, Access = private) |
| 106 | + % Format a field |
| 107 | + function str = fieldFmt(key, value) |
| 108 | + if isfloat(value) |
| 109 | + if ~isempty(value) && isfinite(value) |
| 110 | + str = sprintf('%s=%.8g', key, value); |
| 111 | + else |
| 112 | + str = ''; |
95 | 113 | end
|
| 114 | + elseif isinteger(value) |
| 115 | + str = sprintf('%s=%ii', key, value); |
| 116 | + elseif ischar(value) |
| 117 | + str = [key '="' value '"']; |
| 118 | + elseif islogical(value) |
| 119 | + str = [key '=' iif(value, 'true', 'false')]; |
| 120 | + else |
| 121 | + error('unsupported value type'); |
| 122 | + end |
| 123 | + end |
| 124 | + |
| 125 | + % Otain the scale for a precision |
| 126 | + function scale = timeScale(precision) |
| 127 | + switch precision |
| 128 | + case 'ns' |
| 129 | + scale = 1000000000; |
| 130 | + case 'u' |
| 131 | + scale = 1000000; |
| 132 | + case 'ms' |
| 133 | + scale = 1000; |
| 134 | + case 's' |
| 135 | + scale = 1; |
| 136 | + case 'm' |
| 137 | + scale = 1 / 60; |
| 138 | + case 'h' |
| 139 | + scale = 1 / 3600; |
| 140 | + otherwise |
| 141 | + error('precision:unknown', '"%s" is not a valid precision', precision); |
96 | 142 | end
|
97 |
| - builder.deleteCharAt(int32(builder.length() - 1)); |
98 |
| - lines = char(builder.toString()); |
99 | 143 | end
|
100 | 144 | end
|
101 | 145 |
|
|
0 commit comments