summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorAdam Vartanian <flooey@google.com>2017-03-16 14:26:08 +0000
committerAdam Vartanian <flooey@google.com>2017-03-16 14:26:08 +0000
commitbefc86a711b876ed6523fbe453dfa7a9adb345af (patch)
treedd1177808bde0e31927055b8b17331f3a1cdfc90 /tools
parent4980cf459974e7595ae13be09bd4801ffef694f1 (diff)
Add special table formatting for Cipher.
Extracts a new file for JSON loading and cleans up a couple style issues. Updates the support for GCM to 10+, it was available at least in that version. Bug: 35793879 Test: Manual inspection of output Change-Id: I84f74fd14506cb36e0744a77c0223f5e3b86ca1b
Diffstat (limited to 'tools')
-rw-r--r--tools/docs/crypto/crypto_docs.py31
-rw-r--r--tools/docs/crypto/data/crypto_support.json4
-rwxr-xr-xtools/docs/crypto/format_supported_algorithm_table.py126
-rwxr-xr-xtools/docs/crypto/update_crypto_support.py13
4 files changed, 154 insertions, 20 deletions
diff --git a/tools/docs/crypto/crypto_docs.py b/tools/docs/crypto/crypto_docs.py
new file mode 100644
index 0000000000..d1f220dc87
--- /dev/null
+++ b/tools/docs/crypto/crypto_docs.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# 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.
+
+'''Utility functions for crypto doc updating tools.'''
+
+import json
+
+
+def load_json(filename):
+ '''Returns an object containing the JSON data from the provided file.'''
+ f = open(filename)
+ # JSON doesn't allow comments, but we have some header docs in our file,
+ # so strip comments out before parsing
+ stripped_contents = ''
+ for line in f:
+ if not line.strip().startswith('#'):
+ stripped_contents += line
+ data = json.loads(stripped_contents)
+ f.close()
+ return data
diff --git a/tools/docs/crypto/data/crypto_support.json b/tools/docs/crypto/data/crypto_support.json
index 8e6cc4f8de..0a32e5716f 100644
--- a/tools/docs/crypto/data/crypto_support.json
+++ b/tools/docs/crypto/data/crypto_support.json
@@ -224,7 +224,7 @@
},
{
"name": "AES/GCM/NOPADDING",
- "supported_api_levels": "21+"
+ "supported_api_levels": "10+"
},
{
"name": "AES/OFB/ISO10126PADDING",
@@ -1227,5 +1227,5 @@
"name": "TrustManagerFactory"
}
],
- "last_updated": "2017-03-16 10:29:21 UTC"
+ "last_updated": "2017-03-16 12:35:47 UTC"
} \ No newline at end of file
diff --git a/tools/docs/crypto/format_supported_algorithm_table.py b/tools/docs/crypto/format_supported_algorithm_table.py
index f07f9d9c5e..1460099078 100755
--- a/tools/docs/crypto/format_supported_algorithm_table.py
+++ b/tools/docs/crypto/format_supported_algorithm_table.py
@@ -20,9 +20,11 @@ Outputs HTML tables suitable for inclusion in the Android documentation that
reflect the crypto algorithm support shown in the provided data file.
"""
-import json
+import operator
import sys
+import crypto_docs
+
def sort_by_name(seq):
return sorted(seq, key=lambda x: x['name'])
@@ -32,7 +34,7 @@ def main():
if len(sys.argv) < 2:
print 'Must supply argument to data file.'
sys.exit(1)
- data = json.load(open(sys.argv[1]))
+ data = crypto_docs.load_json(sys.argv[1])
categories = sort_by_name(data['categories'])
print '<h2 id="SupportedAlgorithms">Supported Algorithms</h2>'
print
@@ -42,25 +44,131 @@ def main():
'<code>{name}</code></a></li>'.format(**category))
print '</ul>'
for category in categories:
- print '''
+ if category['name'] == 'Cipher':
+ # We display ciphers in a four-column table to conserve space and
+ # so that it's more comprehensible. To do this, we have to
+ # collapse all our ciphers into "equivalence classes" of a sort.
+
+ # First, collect the relevant data for each algorithm into a tuple.
+ # The mode and padding are in lists because we are going to collapse
+ # multiple tuples with those in later steps.
+ algorithms = sort_by_name(category['algorithms'])
+ tuples = []
+ for algorithm in algorithms:
+ name, mode, padding = algorithm['name'].split('/')
+ tuples.append((
+ name,
+ [mode],
+ [padding],
+ algorithm['supported_api_levels'],
+ 'deprecated' in algorithm and algorithm['deprecated']))
+ # Sort the tuples by all items except padding, then collapse
+ # items with all non-padding values the same (which will always be
+ # neighboring items) into a single item.
+ tuples.sort(key=operator.itemgetter(0, 1, 3, 4))
+ i = 0
+ while i < len(tuples) - 1:
+ if (tuples[i][0] == tuples[i+1][0]
+ and tuples[i][1] == tuples[i+1][1]
+ and tuples[i][3] == tuples[i+1][3]
+ and tuples[i][4] == tuples[i+1][4]):
+ tuples[i][2].extend(tuples[i+1][2])
+ del tuples[i+1]
+ else:
+ i += 1
+ # Do the same thing as above, but with modes.
+ tuples.sort(key=operator.itemgetter(0, 2, 3, 4))
+ i = 0
+ while i < len(tuples) - 1:
+ if (tuples[i][0] == tuples[i+1][0]
+ and tuples[i][2] == tuples[i+1][2]
+ and tuples[i][3] == tuples[i+1][3]
+ and tuples[i][4] == tuples[i+1][4]):
+ tuples[i][1].extend(tuples[i+1][1])
+ del tuples[i+1]
+ else:
+ i += 1
+ # Display the table with rowspans for those entries where all the
+ # items have the same algorithm, mode, etc
+ print '''
<h3 id="Supported{name}">{name}</h3>
<table>
<thead>
<th>Algorithm</th>
+ <th>Modes</th>
+ <th>Paddings</th>
<th>Supported API Levels</th>
</thead>
<tbody>'''.format(**category)
- algorithms = sort_by_name(category['algorithms'])
- for algorithm in algorithms:
- dep_class = ''
- if 'deprecated' in algorithm and algorithm['deprecated']:
- dep_class = ' class="deprecated"'
+ tuples.sort(key=operator.itemgetter(0, 4, 1, 2, 3))
+ i = 0
+ cur_deprecated = None
+ cur_algorithm = None
+ cur_mode = None
+ while i < len(tuples):
+ row = tuples[i]
+ if row[4] != cur_deprecated:
+ cur_deprecated = row[4]
+ cur_algorithm = None
+ cur_mode = None
+ if cur_deprecated:
+ print ' <tr class="deprecated">'
+ else:
+ print ' <tr>'
+ if row[0] != cur_algorithm:
+ cur_algorithm = row[0]
+ cur_mode = None
+ j = i + 1
+ while (j < len(tuples)
+ and tuples[j][4] == cur_deprecated
+ and tuples[j][0] == cur_algorithm):
+ j += 1
+ rowspan = j - i
+ if rowspan > 1:
+ print ' <td rowspan="%d">%s</td>' % (rowspan, cur_algorithm)
+ else:
+ print ' <td>%s</td>' % cur_algorithm
+ if row[1] != cur_mode:
+ cur_mode = row[1]
+ j = i + 1
+ while (j < len(tuples)
+ and tuples[j][4] == cur_deprecated
+ and tuples[j][0] == cur_algorithm
+ and tuples[j][1] == cur_mode):
+ j += 1
+ rowspan = j - i
+ modestring = '<br>'.join(cur_mode)
+ if rowspan > 1:
+ print ' <td rowspan="%d">%s</td>' % (rowspan, modestring)
+ else:
+ print ' <td>%s</td>' % modestring
+ print ' <td>%s</td>' % '<br>'.join(row[2])
+ print ' <td>%s</td>' % row[3]
+ print ' </tr>'
+ i += 1
print '''
+ </tbody>
+</table>'''
+ else:
+ print '''
+<h3 id="Supported{name}">{name}</h3>
+<table>
+ <thead>
+ <th>Algorithm</th>
+ <th>Supported API Levels</th>
+ </thead>
+ <tbody>'''.format(**category)
+ algorithms = sort_by_name(category['algorithms'])
+ for algorithm in algorithms:
+ dep_class = ''
+ if 'deprecated' in algorithm and algorithm['deprecated']:
+ dep_class = ' class="deprecated"'
+ print '''
<tr{deprecated_class}>
<td>{name}</td>
<td>{supported_api_levels}</td>
</tr>'''.format(deprecated_class=dep_class, **algorithm)
- print '''
+ print '''
</tbody>
</table>'''
diff --git a/tools/docs/crypto/update_crypto_support.py b/tools/docs/crypto/update_crypto_support.py
index 7d7861f975..8d39cf8638 100755
--- a/tools/docs/crypto/update_crypto_support.py
+++ b/tools/docs/crypto/update_crypto_support.py
@@ -29,6 +29,8 @@ import datetime
import json
import sys
+import crypto_docs
+
SUPPORTED_CATEGORIES = [
'AlgorithmParameterGenerator',
'AlgorithmParameters',
@@ -81,6 +83,7 @@ def normalize_name(name):
name = name[:-1 * len("/PKCS7PADDING")] + "/PKCS5PADDING"
return name
+
def get_current_data(f):
"""Returns a map of the algorithms in the given input.
@@ -205,15 +208,7 @@ def main():
help='The JSON file to update')
args = parser.parse_args()
- f = open(args.file)
- # JSON doesn't allow comments, but we have some header docs in our file,
- # so strip comments out before parsing
- stripped_contents = ''
- for line in f:
- if not line.strip().startswith('#'):
- stripped_contents += line
- prev_data = json.loads(stripped_contents)
- f.close()
+ prev_data = crypto_docs.load_json(args.file)
current_data = get_current_data(sys.stdin)