1 /*
2  * Copyright (C) 2018 The Android Open Source Project
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 #include <C2ParamInternal.h>
18 #include <util/C2Debug-interface.h>
19 #include <util/C2Debug-param.h>
20 #include <util/C2InterfaceUtils.h>
21 
22 #include <iostream>
23 
24 #include <android-base/stringprintf.h>
25 
26 using android::base::StringPrintf;
27 
28 /* -------------------------------- asString -------------------------------- */
29 
asString(c2_status_t i,const char * def)30 const char *asString(c2_status_t i, const char *def) {
31     switch (i) {
32         case C2_OK:        return "OK";
33         case C2_BAD_VALUE: return "BAD_VALUE";
34         case C2_BAD_INDEX: return "BAD_INDEX";
35         case C2_CANNOT_DO: return "CANNOT_DO";
36         case C2_DUPLICATE: return "DUPLICATE";
37         case C2_NOT_FOUND: return "NOT_FOUND";
38         case C2_BAD_STATE: return "BAD_STATE";
39         case C2_BLOCKING:  return "BLOCKING";
40         case C2_CANCELED:  return "CANCELED";
41         case C2_NO_MEMORY: return "NO_MEMORY";
42         case C2_REFUSED:   return "REFUSED";
43         case C2_TIMED_OUT: return "TIMED_OUT";
44         case C2_OMITTED:   return "OMITTED";
45         case C2_CORRUPTED: return "CORRUPTED";
46         case C2_NO_INIT:   return "NO_INIT";
47         default:           return def;
48     }
49 }
50 
asString(C2FieldDescriptor::type_t i,const char * def)51 const char *asString(C2FieldDescriptor::type_t i, const char *def) {
52     switch (i) {
53         case C2FieldDescriptor::BLOB:   return "u8";
54         case C2FieldDescriptor::CNTR32: return "c32";
55         case C2FieldDescriptor::CNTR64: return "c64";
56         case C2FieldDescriptor::FLOAT:  return "fp";
57         case C2FieldDescriptor::INT32:  return "i32";
58         case C2FieldDescriptor::INT64:  return "i64";
59         case C2FieldDescriptor::STRING: return "chr";
60         case C2FieldDescriptor::UINT32: return "u32";
61         case C2FieldDescriptor::UINT64: return "u64";
62         default: return (i & C2FieldDescriptor::STRUCT_FLAG) ? "struct" : def;
63     }
64 }
65 
66 /* ------------------------------ C2ParamField ------------------------------ */
67 
attribParamCoreIndex(const C2Param::CoreIndex & i)68 static std::string attribParamCoreIndex(const C2Param::CoreIndex &i) {
69     return StringPrintf("%c%c%03x",
70             i.isFlexible() ? 'F' : '-',
71             i.isVendor() ? 'V' : '-',
72             i.coreIndex());
73 }
74 
attribParamIndex(const C2Param::Type & i,bool addStream,unsigned streamId)75 static std::string attribParamIndex(
76         const C2Param::Type &i, bool addStream, unsigned streamId) {
77     std::string v = StringPrintf("%c%c",
78             i.forInput() ? 'I' : i.forOutput() ? 'O' : '-',
79             i.forStream() ? 'S' : i.forPort() ? 'P' : 'G');
80     if (addStream) {
81         if (i.forStream()) {
82             v += StringPrintf("%02d", streamId);
83         } else {
84             v += "--";
85         }
86     }
87 
88     return v
89             + StringPrintf("%c ",
90                        i.kind() == C2Param::STRUCT  ? 'S' :
91                        i.kind() == C2Param::INFO    ? 'i' :
92                        i.kind() == C2Param::TUNING  ? 't' :
93                        i.kind() == C2Param::SETTING ? 's' :
94                        i.kind() == C2Param::NONE    ? '-' : '?')
95             + attribParamCoreIndex(i);
96 }
97 
operator <<(std::ostream & os,const C2Param::CoreIndex & i)98 std::ostream& operator<<(std::ostream& os, const C2Param::CoreIndex &i) {
99     return os << "Param::CoreIndex(" << attribParamCoreIndex(i) << ")";
100 }
101 
operator <<(std::ostream & os,const C2Param::Type & i)102 std::ostream& operator<<(std::ostream& os, const C2Param::Type &i) {
103     return os << StringPrintf("Param::Type(%08x: ", i.type())
104             << attribParamIndex(i, false, 0) << ")";
105 }
106 
operator <<(std::ostream & os,const C2Param::Index & i)107 std::ostream& operator<<(std::ostream& os, const C2Param::Index &i) {
108     return os << StringPrintf("Param::Index(%08x: ", (uint32_t)i)
109             << attribParamIndex(i, true, i.stream()) << ")";
110 }
111 
attribFieldId(const _C2FieldId & i)112 static std::string attribFieldId(const _C2FieldId &i) {
113     return StringPrintf("Field(@%02x+%02x)",
114             _C2ParamInspector::GetOffset(i),
115             _C2ParamInspector::GetSize(i));
116 }
117 
118 
operator <<(std::ostream & os,const _C2FieldId & i)119 std::ostream& operator<<(std::ostream& os, const _C2FieldId &i) {
120     return os << "<" << attribFieldId(i) << ">";
121 }
122 
123 
operator <<(std::ostream & os,const C2FieldDescriptor & i)124 std::ostream& operator<<(std::ostream& os, const C2FieldDescriptor &i) {
125     os << attribFieldId(_C2ParamInspector::GetField(i)) << " ";
126     if (i.namedValues().size()) {
127         os << "enum ";
128     }
129     return os << asString(i.type()) << " " << i.name()
130             << StringPrintf("[%zu]", i.extent());
131 }
132 
133 
operator <<(std::ostream & os,const C2ParamField & i)134 std::ostream& operator<<(std::ostream& os, const C2ParamField &i) {
135     os << "<" << C2Param::Index(_C2ParamInspector::GetIndex(i))
136             << StringPrintf("::Field(@%02x+%02x)>",
137                             _C2ParamInspector::GetOffset(i),
138                             _C2ParamInspector::GetSize(i));
139     return os;
140 }
141 
142 
143 /* -------------------------- _C2FieldValueHelper -------------------------- */
144 
put(std::ostream & os,const C2Value::Primitive & p)145 std::ostream& _C2FieldValueHelper<char>::put(std::ostream &os, const C2Value::Primitive &p) {
146     if (isprint(p.i32)) {
147         return os << StringPrintf("'%c'", p.i32);
148     } else {
149         return os << StringPrintf("'\\x%02x'", (uint32_t)p.i32);
150     }
151 }
152 
put(std::ostream & os,const C2Value::Primitive & p)153 std::ostream& _C2FieldValueHelper<uint8_t>::put(std::ostream &os, const C2Value::Primitive &p) {
154     return os << StringPrintf("0x%02x", p.u32);
155 }
156 
157 /* ---------------------- C2FieldSupportedValuesHelper ---------------------- */
158 
159 template<typename T>
operator <<(std::ostream & os,const c2_cntr_t<T> & v)160 std::ostream& operator<<(std::ostream &os, const c2_cntr_t<T> &v) {
161     return os << "ctr(" << v.peeku() << ")";
162 }
163 
164 template<typename T>
operator <<(std::ostream & os,const C2SupportedRange<T> & i)165 std::ostream& operator<<(std::ostream& os, const C2SupportedRange<T> &i) {
166     os << "Range(";
167     _C2FieldValueHelper<T>::put(os, i.min());
168     os << "..";
169     _C2FieldValueHelper<T>::put(os, i.max());
170     os << " *= " << i.num() << " /= " << i.denom() << " += " << i.step() << ")";
171     return os;
172 }
173 template std::ostream& operator<<(std::ostream& os, const C2SupportedRange<char> &i);
174 template std::ostream& operator<<(std::ostream& os, const C2SupportedRange<uint8_t> &i);
175 template std::ostream& operator<<(std::ostream& os, const C2SupportedRange<int32_t> &i);
176 template std::ostream& operator<<(std::ostream& os, const C2SupportedRange<uint32_t> &i);
177 //template std::ostream& operator<<(std::ostream& os, const C2SupportedRange<c2_cntr32_t> &i);
178 template std::ostream& operator<<(std::ostream& os, const C2SupportedRange<int64_t> &i);
179 template std::ostream& operator<<(std::ostream& os, const C2SupportedRange<uint64_t> &i);
180 //template std::ostream& operator<<(std::ostream& os, const C2SupportedRange<c2_cntr64_t> &i);
181 template std::ostream& operator<<(std::ostream& os, const C2SupportedRange<float> &i);
182 
183 template<typename T>
operator <<(std::ostream & os,const C2SupportedFlags<T> & i)184 std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<T> &i) {
185     os << "Flags[";
186     if (!i.isEmpty()) {
187         os << "min=";
188         _C2FieldValueHelper<T>::put(os, i.min());
189     }
190     bool comma = false;
191     for (const T &v : i.flags()) {
192         if (comma) {
193             os << ", ";
194         }
195         _C2FieldValueHelper<T>::put(os, v);
196         comma = true;
197     }
198     os << "]";
199     return os;
200 }
201 template std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<char> &i);
202 template std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<uint8_t> &i);
203 template std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<int32_t> &i);
204 template std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<uint32_t> &i);
205 //template std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<c2_cntr32_t> &i);
206 template std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<int64_t> &i);
207 template std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<uint64_t> &i);
208 //template std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<c2_cntr64_t> &i);
209 template std::ostream& operator<<(std::ostream& os, const C2SupportedFlags<float> &i);
210 
211 template<typename T>
operator <<(std::ostream & os,const C2SupportedValueSet<T> & i)212 std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<T> &i) {
213     os << "Values[";
214     bool comma = false;
215     for (const T &v : i.values()) {
216         if (comma) {
217             os << ", ";
218         }
219         _C2FieldValueHelper<T>::put(os, v);
220         comma = true;
221     }
222     os << "]";
223     return os;
224 }
225 template std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<char> &i);
226 template std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<uint8_t> &i);
227 template std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<int32_t> &i);
228 template std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<uint32_t> &i);
229 //template std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<c2_cntr32_t> &i);
230 template std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<int64_t> &i);
231 template std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<uint64_t> &i);
232 //template std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<c2_cntr64_t> &i);
233 template std::ostream& operator<<(std::ostream& os, const C2SupportedValueSet<float> &i);
234 
235 template<typename T>
236 struct C2FieldSupportedValuesHelper<T>::Impl {
237     Impl(const C2FieldSupportedValues &values);
238 
239 private:
240     typedef typename _C2FieldValueHelper<T>::ValueType ValueType;
241     C2FieldSupportedValues::type_t _mType;
242     C2SupportedRange<ValueType> _mRange;
243     C2SupportedValueSet<ValueType> _mValues;
244     C2SupportedFlags<ValueType> _mFlags;
245 
246 public:
247 //    friend std::ostream& operator<< <T>(std::ostream& os, const C2FieldSupportedValuesHelper<T>::Impl &i);
248 //    friend std::ostream& operator<<(std::ostream& os, const Impl &i);
249     std::ostream& streamOut(std::ostream& os) const;
250 };
251 
252 template<typename T>
streamOut(std::ostream & os) const253 std::ostream& C2FieldSupportedValuesHelper<T>::Impl::streamOut(std::ostream& os) const {
254     if (_mType == C2FieldSupportedValues::RANGE) {
255         os << _mRange;
256     } else if (_mType == C2FieldSupportedValues::VALUES) {
257         os << _mValues;
258     } else if (_mType == C2FieldSupportedValues::FLAGS) {
259         os << _mFlags;
260     } else {
261         os << "Unknown FSV type: " << (uint32_t)_mType;
262     }
263     return os;
264 }
265 
266 template<typename T>
operator <<(std::ostream & os,const C2FieldSupportedValuesHelper<T> & i)267 std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<T> &i) {
268     return i._mImpl->streamOut(os);
269 }
270 template std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<char> &i);
271 template std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<uint8_t> &i);
272 template std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<int32_t> &i);
273 template std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<uint32_t> &i);
274 //template std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<c2_cntr32_t> &i);
275 template std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<int64_t> &i);
276 template std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<uint64_t> &i);
277 //template std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<c2_cntr64_t> &i);
278 template std::ostream& operator<<(std::ostream& os, const C2FieldSupportedValuesHelper<float> &i);
279 
280