diff --git a/README.rst b/README.rst index e4d7fa8..5d72089 100644 --- a/README.rst +++ b/README.rst @@ -11,7 +11,7 @@ :alt: Downloads The oslo.serialization library provides support for representing objects -in transmittable and storable formats, such as JSON and MessagePack. +in transmittable and storable formats, such as Base64, JSON and MessagePack. * Free software: Apache license * Documentation: http://docs.openstack.org/developer/oslo.serialization diff --git a/doc/source/api.rst b/doc/source/api.rst index c722b3a..85589b1 100644 --- a/doc/source/api.rst +++ b/doc/source/api.rst @@ -1,3 +1,9 @@ +base64 +====== + +.. automodule:: oslo_serialization.base64 + :members: + jsonutils ========= diff --git a/oslo_serialization/base64.py b/oslo_serialization/base64.py new file mode 100644 index 0000000..0223f6a --- /dev/null +++ b/oslo_serialization/base64.py @@ -0,0 +1,79 @@ +# Copyright 2015 Red Hat +# All Rights Reserved. +# +# 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. + +from __future__ import absolute_import + +import base64 + +import six + + +def encode_as_bytes(s, encoding='utf-8'): + """Encode a string using Base64. + + If *s* is a text string, first encode it to *encoding* (UTF-8 by default). + + :param s: bytes or text string to be encoded + :param encoding: encoding used to encode *s* if it's a text string + :returns: Base64 encoded byte string (bytes) + + Use encode_as_text() to get the Base64 encoded string as text. + """ + if isinstance(s, six.text_type): + s = s.encode(encoding) + return base64.b64encode(s) + + +def encode_as_text(s, encoding='utf-8'): + """Encode a string using Base64. + + If *s* is a text string, first encode it to *encoding* (UTF-8 by default). + + :param s: bytes or text string to be encoded + :param encoding: encoding used to encode *s* if it's a text string + :returns: Base64 encoded text string (Unicode) + + Use encode_as_bytes() to get the Base64 encoded string as bytes. + """ + encoded = encode_as_bytes(s, encoding=encoding) + return encoded.decode('ascii') + + +def decode_as_bytes(encoded): + """Decode a Base64 encoded string. + + :param encoded: bytes or text Base64 encoded string to be decoded + :returns: decoded bytes string (bytes) + + Use decode_as_text() to get the decoded string as text. + """ + if isinstance(encoded, bytes): + encoded = encoded.decode('ascii') + return base64.b64decode(encoded) + + +def decode_as_text(encoded, encoding='utf-8'): + """Decode a Base64 encoded string. + + Decode the Base64 string and then decode the result from *encoding* + (UTF-8 by default). + + :param encoded: bytes or text Base64 encoded string to be decoded + :returns: decoded text string (bytes) + + Use decode_as_bytes() to get the decoded string as bytes. + """ + decoded = decode_as_bytes(encoded) + return decoded.decode(encoding) diff --git a/oslo_serialization/tests/test_base64.py b/oslo_serialization/tests/test_base64.py new file mode 100644 index 0000000..8d52780 --- /dev/null +++ b/oslo_serialization/tests/test_base64.py @@ -0,0 +1,56 @@ +# Copyright 2015 Red Hat +# All Rights Reserved. +# +# 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. + +from oslo_serialization import base64 +from oslotest import base as test_base + + +class Base64Tests(test_base.BaseTestCase): + + def test_encode_as_bytes(self): + self.assertEqual(base64.encode_as_bytes(b'text'), + b'dGV4dA==') + self.assertEqual(base64.encode_as_bytes(u'text'), + b'dGV4dA==') + self.assertEqual(base64.encode_as_bytes(u'e:\xe9'), + b'ZTrDqQ==') + self.assertEqual(base64.encode_as_bytes(u'e:\xe9', encoding='latin1'), + b'ZTrp') + + def test_encode_as_text(self): + self.assertEqual(base64.encode_as_text(b'text'), + u'dGV4dA==') + self.assertEqual(base64.encode_as_text(u'text'), + u'dGV4dA==') + self.assertEqual(base64.encode_as_text(u'e:\xe9'), + u'ZTrDqQ==') + self.assertEqual(base64.encode_as_text(u'e:\xe9', encoding='latin1'), + u'ZTrp') + + def test_decode_as_bytes(self): + self.assertEqual(base64.decode_as_bytes(b'dGV4dA=='), + b'text') + self.assertEqual(base64.decode_as_bytes(u'dGV4dA=='), + b'text') + + def test_decode_as_text(self): + self.assertEqual(base64.decode_as_text(b'dGV4dA=='), + u'text') + self.assertEqual(base64.decode_as_text(u'dGV4dA=='), + u'text') + self.assertEqual(base64.decode_as_text(u'ZTrDqQ=='), + u'e:\xe9') + self.assertEqual(base64.decode_as_text(u'ZTrp', encoding='latin1'), + u'e:\xe9')