279943031ab5535f4b42a28367e65d17bbe501eb
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / devel-api / builder / base64-encoding.cpp
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // EXTERNAL INCLUDES
19 #include <sstream>
20 #include <iterator>
21
22 #include <dali/public-api/object/property-value.h>
23 #include <dali/public-api/object/property-array.h>
24 #include <dali-toolkit/devel-api/builder/base64-encoding.h>
25 #include <dali-toolkit/third-party/base-n/basen.hpp>
26
27 namespace Dali
28 {
29
30 namespace Toolkit
31 {
32
33 namespace
34 {
35 const int MAX_PROPERTY_STRING_LENGTH(64); // Cuts larger strings into blocks of this size.
36
37 bool GetStringFromProperty( const Property::Value& value, std::string& output )
38 {
39   bool extracted = false;
40   if( value.Get( output ) )
41   {
42     extracted = true;
43   }
44   else
45   {
46     Property::Array* array = value.GetArray();
47     if( array )
48     {
49       const unsigned int arraySize = array->Size();
50       for( unsigned int i = 0; i < arraySize; ++i )
51       {
52         std::string element;
53         if( array->GetElementAt( i ).Get( element ) )
54         {
55           extracted = true;
56           output += element;
57         }
58         else
59         {
60           // If property in array is anything other than a string, then it is invalid so break and clear output.
61           output.clear();
62           extracted = false;
63           break;
64         }
65       }
66     }
67   }
68   return extracted;
69 }
70
71 }//anonymous namespace
72
73 bool DecodeBase64PropertyData( const Property::Value& value, std::vector<uint32_t>& outputData )
74 {
75   bool decoded = false;
76   std::string encodedString;
77
78
79   if( GetStringFromProperty( value, encodedString ) )
80   {
81     std::vector<unsigned char> outputTmpData;
82     outputTmpData.reserve( ceil( encodedString.size() * 0.75f ) );
83     bn::decode_b64( encodedString.begin(), encodedString.end(), std::back_inserter(outputTmpData) );
84
85     outputData.clear();
86     outputData.resize( outputTmpData.size() / sizeof(uint32_t) );
87     // Treat as a block of data
88     memcpy( &outputData[0], &outputTmpData[0], outputTmpData.size() );
89
90     decoded = true;
91   }
92   return decoded;
93 }
94
95 void EncodeBase64PropertyData( Property::Value& value, const std::vector<uint32_t>& inputData )
96 {
97   std::ostringstream oss;
98
99   bn::encode_b64( reinterpret_cast<const char*>(&inputData[0]),
100                   reinterpret_cast<const char*>(&inputData[0]+inputData.size()),
101                   std::ostream_iterator<unsigned char>(oss, "") );
102
103
104   std::string encodedString = oss.str();
105   if( encodedString.length() > MAX_PROPERTY_STRING_LENGTH)
106   {
107     // cut string up into blocks of MAX_PROPERTY_STRING_LENGTH and store to an array
108     auto numStrings = encodedString.length() / MAX_PROPERTY_STRING_LENGTH +
109                       ((encodedString.length() % MAX_PROPERTY_STRING_LENGTH) != 0);
110
111     Property::Array array;
112     for(auto i=0u; i<numStrings; ++i)
113     {
114       array.PushBack( encodedString.substr( i*MAX_PROPERTY_STRING_LENGTH, MAX_PROPERTY_STRING_LENGTH));
115     }
116     value = array;
117   }
118   else
119   {
120     value = encodedString;
121   }
122 }
123
124
125 } // namespace Toolkit
126
127 } // namespace Dali