| % Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| % use this file except in compliance with the License. You may obtain a copy of |
| % the License at |
| % |
| % http://www.apache.org/licenses/LICENSE-2.0 |
| % |
| % Unless required by applicable law or agreed to in writing, software |
| % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| % License for the specific language governing permissions and limitations under |
| % the License. |
| |
| -module(couch_ejson_size). |
| |
| -export([encoded_size/1]). |
| |
| %% Compound objects |
| |
| encoded_size({[]}) -> |
| % opening { and closing } |
| 2; |
| encoded_size({KVs}) -> |
| % Would add 2 because opening { and closing }, but then inside the LC |
| % would accumulate an extra , at the end so subtract 2 - 1 |
| 1 + lists:sum([encoded_size(K) + encoded_size(V) + 2 || {K, V} <- KVs]); |
| encoded_size([]) -> |
| % opening [ and closing ] |
| 2; |
| encoded_size(List) when is_list(List) -> |
| % 2 is for [ and ] but inside LC would accumulate an extra , so subtract |
| % 2 - 1 |
| 1 + lists:sum([encoded_size(V) + 1 || V <- List]); |
| %% Floats. |
| |
| encoded_size(0.0) -> |
| 3; |
| encoded_size(1.0) -> |
| 3; |
| encoded_size(Float) when is_float(Float), Float < 0.0 -> |
| encoded_size(-Float) + 1; |
| encoded_size(Float) when is_float(Float), Float < 1.0 -> |
| if |
| % close enough to 0.0 |
| Float =< 1.0e-300 -> 3; |
| % Xe-YYY |
| Float =< 1.0e-100 -> 6; |
| % Xe-YY |
| Float =< 1.0e-10 -> 5; |
| % Xe-Y, 0.0X |
| Float =< 0.01 -> 4; |
| % 0.X |
| true -> 3 |
| end; |
| encoded_size(Float) when is_float(Float) -> |
| if |
| % XeYYY |
| Float >= 1.0e100 -> 5; |
| % XeYY |
| Float >= 1.0e10 -> 4; |
| % XeY, X.Y |
| true -> 3 |
| end; |
| %% Integers |
| |
| encoded_size(0) -> |
| 1; |
| encoded_size(Integer) when is_integer(Integer), Integer < 0 -> |
| encoded_size(-Integer) + 1; |
| encoded_size(Integer) when is_integer(Integer) -> |
| if |
| Integer < 10 -> 1; |
| Integer < 100 -> 2; |
| Integer < 1000 -> 3; |
| Integer < 10000 -> 4; |
| true -> trunc(math:log10(Integer)) + 1 |
| end; |
| %% Strings |
| |
| encoded_size(Binary) when is_binary(Binary) -> |
| 2 + byte_size(Binary); |
| %% Special terminal symbols as atoms |
| |
| encoded_size(null) -> |
| 4; |
| encoded_size(true) -> |
| 4; |
| encoded_size(false) -> |
| 5; |
| %% Other atoms |
| |
| encoded_size(Atom) when is_atom(Atom) -> |
| encoded_size(atom_to_binary(Atom, utf8)). |