blob: 7d4d9ade93aff3726ef589ee8c093d5e567a1f73 [file] [log] [blame]
/*
* Copyright (C) 2016 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.
*/
#include "Type.h"
#include <sstream>
#include <hidl-util/StringHelper.h>
namespace android {
Type::Type(std::vector<Qualifier*> *qualifiers)
: mQualifiers(qualifiers)
{}
Type::~Type() {
if(mArrays != NULL) {
for(auto* array : *mArrays) {
delete array;
}
}
if(mQualifiers != NULL) {
for(auto* qual : *mQualifiers) {
delete qual;
}
}
delete mQualifiers;}
void Type::setArrays(std::vector<Expression*> *arrays) {
mArrays = arrays;
}
const std::string Type::decorateName(const std::string &name) const {
std::stringstream ss;
std::string special = getSpecialTypeName();
if(special.empty()) {
ss << getHidlType();
} else {
ss << special;
}
ss << " " << name;
return ss.str();
}
// static
std::map<std::string, std::string> Type::kSignedToUnsignedMap = {
{ "char", "uint8_t" },
{ "short", "uint16_t" },
{ "int", "uint32_t" },
{ "long", "uint64_t" },
{ "int8_t", "uint8_t" },
{ "int16_t", "uint16_t" },
{ "int32_t", "uint32_t" },
{ "int64_t", "uint64_t" },
};
// static
const std::string Type::signedToUnsigned(const std::string &signedType) {
auto it = kSignedToUnsignedMap.find(signedType);
if (it == kCToHidlMap.end()) {
return "";
}
return (*it).second;
}
// static
std::map<std::string, std::string> Type::kCToHidlMap = {
{ "char", "int8_t /* NOTE: char */" },
{ "short", "int16_t" },
{ "int", "int32_t" },
{ "long", "int64_t"},
{ "native_handle_t", "handle" },
{ "size_t", "uint64_t" },
{ "int8_t", "int8_t" },
{ "uint8_t", "uint8_t" },
{ "int16_t", "int16_t" },
{ "uint16_t", "uint16_t" },
{ "int32_t", "int32_t" },
{ "uint32_t", "uint32_t" },
{ "int64_t", "int64_t" },
{ "uint64_t", "uint64_t" },
{ "float", "float" },
{ "double", "double" },
{ "bool", "bool" },
{ "wchar_t", "int32_t /* NOTE: wchar_t */"},
// { "hidl_string", "string" },
// { "hidl_vec", "vec"},
};
// static
const std::string Type::cToHidlType(const std::string &cType) {
auto it = kCToHidlMap.find(cType);
if (it == kCToHidlMap.end()) {
return "";
}
return (*it).second;
}
const std::string Type::getHidlType() const {
if (mQualifiers == NULL) {
return "";
}
std::stringstream ss;
for (auto it = mQualifiers->begin(); it != mQualifiers->end(); ++it) {
if (it != mQualifiers->begin()) {
ss << " ";
}
switch((*it)->qualification) {
case Type::Qualifier::STRUCT:
case Type::Qualifier::UNION:
case Type::Qualifier::ENUM:
case Type::Qualifier::POINTER:
case Type::Qualifier::CONST: {
ss << "/* "
<< Type::qualifierText((*it)->qualification)
<< " */";
break;
}
case Type::Qualifier::ID: {
std::string id = (*it)->id;
std::string conversion = cToHidlType(id);
if (!conversion.empty()) {
ss << conversion;
} else {
std::string baseName = StringHelper::RTrim(id, "_t");
ss << StringHelper::ToPascalCase(baseName);
}
break;
}
case Type::Qualifier::GENERICS: {
ss << "<"
<< (*it)->generics->decorateName("")
<< ">";
break;
}
case Type::Qualifier::UNSIGNED: {
auto next = it + 1;
if (next == mQualifiers->end()) {
ss << "uint32_t"; // 'unsigned a' -> 'uint32_t a'
break;
}
std::string unsignedType = signedToUnsigned((*next)->id);
if(unsignedType.empty()) {
ss << Type::qualifierText((*it)->qualification);
} else {
ss << unsignedType;
++it;
}
break;
}
default: {
ss << Type::qualifierText((*it)->qualification);
}
}
}
if (mArrays != NULL) {
for (const auto &array : *mArrays) {
ss << "[" << array->toString() << "]";
}
}
return ss.str();
}
const std::string Type::getRawQualifierList() const {
if (mQualifiers == NULL) {
return "";
}
std::stringstream ss;
for(auto* qualifier : *mQualifiers) {
ss << Type::qualifierText(qualifier->qualification) << " ";
}
return ss.str();
}
const std::string Type::getSpecialTypeName() const {
// this makes for a relatively expensive comparison, but it is
// readable until the converstion get nailed down.
std::string qualifiers = getRawQualifierList();
if (qualifiers == "const ID * " ||
qualifiers == "ID * ") {
std::string id = mQualifiers->at(mQualifiers->size() - 2)->id;
if (id == "char") {
return "string";
} else {
// can't tell if it's a hidl_vec or a pointer
// return "vec<" + id + ">";
return "";
}
}
return "";
}
bool Type::isVoid() const {
if (mQualifiers->size() == 0) {
return true;
}
return mQualifiers->size() == 1 &&
(*mQualifiers)[0]->qualification == Type::Qualifier::VOID;
}
bool Type::isHwDevice() const {
if (mQualifiers->size() < 2) {
return false;
}
return (*mQualifiers)[0]->qualification == Type::Qualifier::STRUCT &&
(*mQualifiers)[1]->qualification == Type::Qualifier::ID &&
(*mQualifiers)[1]->id == "hw_device_t";
}
std::string Type::removeLastId() {
if(mQualifiers == NULL || mQualifiers->size() == 0) {
return "";
}
Qualifier *last = (*mQualifiers)[mQualifiers->size() - 1];
if(last == NULL || last->qualification != Qualifier::ID) {
return "";
}
std::string ret{last->id};
mQualifiers->erase(mQualifiers->end() - 1);
return ret;
}
} //namespace android