diff options
Diffstat (limited to 'cpp/src/Slice/Parser.cpp')
-rwxr-xr-x | cpp/src/Slice/Parser.cpp | 257 |
1 files changed, 228 insertions, 29 deletions
diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp index 87ff6f21c9f..e7ecd451617 100755 --- a/cpp/src/Slice/Parser.cpp +++ b/cpp/src/Slice/Parser.cpp @@ -40,9 +40,31 @@ string readWriteAttribute[] = { "read", "write" }; string txAttribute[] = { "supports", "mandatory", "required", "never" }; enum { Supports, Mandatory, Required, Never }; -} +DataMemberList +filterOrderedOptionalDataMembers(const DataMemberList& members) +{ + class SortFn + { + public: + static bool compare(const DataMemberPtr& lhs, const DataMemberPtr& rhs) + { + return lhs->tag() < rhs->tag(); + } + }; + DataMemberList result; + for(DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p) + { + if((*p)->optional()) + { + result.push_back(*p); + } + } + result.sort(SortFn::compare); + return result; +} +} namespace Slice { @@ -427,6 +449,42 @@ Slice::Contained::addMetaData(const string& s) _metaData.push_back(s); } +FormatType +Slice::Contained::parseFormatMetaData(const list<string>& metaData) +{ + FormatType result = DefaultFormat; + + string tag; + string prefix = "format:"; + for(list<string>::const_iterator p = metaData.begin(); p != metaData.end(); ++p) + { + if(p->find(prefix) == 0) + { + tag = *p; + break; + } + } + + if(!tag.empty()) + { + tag = tag.substr(prefix.size()); + if(tag == "compact") + { + result = CompactFormat; + } + else if(tag == "sliced") + { + result = SlicedFormat; + } + else if(tag != "default") // TODO: Allow "default" to be specified as a format value? + { + // TODO: How to handle invalid format? + } + } + + return result; +} + bool Slice::Contained::operator<(const Contained& rhs) const { @@ -2658,7 +2716,7 @@ Slice::ClassDecl::usesClasses() const size_t Slice::ClassDecl::minWireSize() const { - return 4; // At least four bytes for an instance, if the instance is marshaled as an index. + return 1; // At least four bytes for an instance, if the instance is marshaled as an index. } bool @@ -2905,6 +2963,8 @@ Slice::ClassDef::destroy() OperationPtr Slice::ClassDef::createOperation(const string& name, const TypePtr& returnType, + bool optional, + int tag, Operation::Mode mode) { checkIdentifier(name); @@ -3003,14 +3063,15 @@ Slice::ClassDef::createOperation(const string& name, } _hasOperations = true; - OperationPtr op = new Operation(this, name, returnType, mode); + OperationPtr op = new Operation(this, name, returnType, optional, tag, mode); _contents.push_back(op); return op; } DataMemberPtr -Slice::ClassDef::createDataMember(const string& name, const TypePtr& type, const SyntaxTreeBasePtr& defaultValueType, - const string& defaultValue, const string& defaultLiteral) +Slice::ClassDef::createDataMember(const string& name, const TypePtr& type, bool optional, int tag, + const SyntaxTreeBasePtr& defaultValueType, const string& defaultValue, + const string& defaultLiteral) { checkIdentifier(name); @@ -3152,8 +3213,25 @@ Slice::ClassDef::createDataMember(const string& name, const TypePtr& type, const } } + if(optional) + { + // + // Validate the tag. + // + DataMemberList dml = allDataMembers(); + for(DataMemberList::iterator q = dml.begin(); q != dml.end(); ++q) + { + if((*q)->optional() && tag == (*q)->tag()) + { + string msg = "tag for optional data member `" + name + "' is already in use"; + _unit->error(msg); + break; + } + } + } + _hasDataMembers = true; - DataMemberPtr member = new DataMember(this, name, type, dlt, dv, dl); + DataMemberPtr member = new DataMember(this, name, type, optional, tag, dlt, dv, dl); _contents.push_back(member); return member; } @@ -3230,6 +3308,12 @@ Slice::ClassDef::dataMembers() const return result; } +DataMemberList +Slice::ClassDef::orderedOptionalDataMembers() const +{ + return filterOrderedOptionalDataMembers(dataMembers()); +} + // // Return the data members of this class and its parent classes, in base-to-derived order. // @@ -3399,6 +3483,20 @@ Slice::ClassDef::hasDefaultValues() const return false; } +bool +Slice::ClassDef::inheritsMetaData(const string& meta) const +{ + for(ClassList::const_iterator p = _bases.begin(); p != _bases.end(); ++p) + { + if((*p)->hasMetaData(meta) || (*p)->inheritsMetaData(meta)) + { + return true; + } + } + + return false; +} + Contained::ContainedType Slice::ClassDef::containedType() const { @@ -3517,8 +3615,9 @@ Slice::Exception::destroy() } DataMemberPtr -Slice::Exception::createDataMember(const string& name, const TypePtr& type, const SyntaxTreeBasePtr& defaultValueType, - const string& defaultValue, const string& defaultLiteral) +Slice::Exception::createDataMember(const string& name, const TypePtr& type, bool optional, int tag, + const SyntaxTreeBasePtr& defaultValueType, const string& defaultValue, + const string& defaultLiteral) { checkIdentifier(name); @@ -3649,7 +3748,24 @@ Slice::Exception::createDataMember(const string& name, const TypePtr& type, cons } } - DataMemberPtr p = new DataMember(this, name, type, dlt, dv, dl); + if(optional) + { + // + // Validate the tag. + // + DataMemberList dml = allDataMembers(); + for(DataMemberList::iterator q = dml.begin(); q != dml.end(); ++q) + { + if((*q)->optional() && tag == (*q)->tag()) + { + string msg = "tag for optional data member `" + name + "' is already in use"; + _unit->error(msg); + break; + } + } + } + + DataMemberPtr p = new DataMember(this, name, type, optional, tag, dlt, dv, dl); _contents.push_back(p); return p; } @@ -3669,6 +3785,12 @@ Slice::Exception::dataMembers() const return result; } +DataMemberList +Slice::Exception::orderedOptionalDataMembers() const +{ + return filterOrderedOptionalDataMembers(dataMembers()); +} + // // Return the data members of this exception and its parent exceptions, in base-to-derived order. // @@ -3828,6 +3950,17 @@ Slice::Exception::hasDefaultValues() const return false; } +bool +Slice::Exception::inheritsMetaData(const string& meta) const +{ + if(_base && (_base->hasMetaData(meta) || _base->inheritsMetaData(meta))) + { + return true; + } + + return false; +} + string Slice::Exception::kindOf() const { @@ -3858,8 +3991,9 @@ Slice::Exception::Exception(const ContainerPtr& container, const string& name, c // ---------------------------------------------------------------------- DataMemberPtr -Slice::Struct::createDataMember(const string& name, const TypePtr& type, const SyntaxTreeBasePtr& defaultValueType, - const string& defaultValue, const string& defaultLiteral) +Slice::Struct::createDataMember(const string& name, const TypePtr& type, bool optional, int tag, + const SyntaxTreeBasePtr& defaultValueType, const string& defaultValue, + const string& defaultLiteral) { checkIdentifier(name); @@ -3972,7 +4106,24 @@ Slice::Struct::createDataMember(const string& name, const TypePtr& type, const S } } - DataMemberPtr p = new DataMember(this, name, type, dlt, dv, dl); + if(optional) + { + // + // Validate the tag. + // + DataMemberList dml = dataMembers(); + for(DataMemberList::iterator q = dml.begin(); q != dml.end(); ++q) + { + if((*q)->optional() && tag == (*q)->tag()) + { + string msg = "tag for optional data member `" + name + "' is already in use"; + _unit->error(msg); + break; + } + } + } + + DataMemberPtr p = new DataMember(this, name, type, optional, tag, dlt, dv, dl); _contents.push_back(p); return p; } @@ -4443,22 +4594,13 @@ Slice::Enum::usesClasses() const size_t Slice::Enum::minWireSize() const { - size_t sz = _enumerators.size(); - if(sz <= 0x7f) - { - return 1; - } - if(sz <= 0x7fff) - { - return 2; - } - return 4; + return 1; } bool Slice::Enum::isVariableLength() const { - return false; + return true; } string @@ -4603,6 +4745,18 @@ Slice::Operation::returnType() const return _returnType; } +bool +Slice::Operation::returnIsOptional() const +{ + return _returnIsOptional; +} + +int +Slice::Operation::returnTag() const +{ + return _returnTag; +} + Operation::Mode Slice::Operation::mode() const { @@ -4623,7 +4777,7 @@ Slice::Operation::sendMode() const } ParamDeclPtr -Slice::Operation::createParamDecl(const string& name, const TypePtr& type, bool isOutParam) +Slice::Operation::createParamDecl(const string& name, const TypePtr& type, bool isOutParam, bool optional, int tag) { checkIdentifier(name); @@ -4722,7 +4876,7 @@ Slice::Operation::createParamDecl(const string& name, const TypePtr& type, bool _unit->error(msg); } - ParamDeclPtr p = new ParamDecl(this, name, type, isOutParam); + ParamDeclPtr p = new ParamDecl(this, name, type, isOutParam, optional, tag); _contents.push_back(p); return p; } @@ -4980,6 +5134,18 @@ Slice::Operation::attributes() const } } +FormatType +Slice::Operation::format() const +{ + FormatType format = parseFormatMetaData(getMetaData()); + if(format == DefaultFormat) + { + ContainedPtr cont = ContainedPtr::dynamicCast(container()); + assert(cont); + format = parseFormatMetaData(cont->getMetaData()); + } + return format; +} string Slice::Operation::kindOf() const @@ -4996,11 +5162,15 @@ Slice::Operation::visit(ParserVisitor* visitor, bool) Slice::Operation::Operation(const ContainerPtr& container, const string& name, const TypePtr& returnType, + bool returnIsOptional, + int returnTag, Mode mode) : SyntaxTreeBase(container->unit()), Contained(container, name), Container(container->unit()), _returnType(returnType), + _returnIsOptional(returnIsOptional), + _returnTag(returnTag), _mode(mode) { if(_unit->profile() == IceE) @@ -5041,6 +5211,18 @@ Slice::ParamDecl::isOutParam() const return _isOutParam; } +bool +Slice::ParamDecl::optional() const +{ + return _optional; +} + +int +Slice::ParamDecl::tag() const +{ + return _tag; +} + Contained::ContainedType Slice::ParamDecl::containedType() const { @@ -5071,11 +5253,14 @@ Slice::ParamDecl::visit(ParserVisitor* visitor, bool) visitor->visitParamDecl(this); } -Slice::ParamDecl::ParamDecl(const ContainerPtr& container, const string& name, const TypePtr& type, bool isOutParam) : +Slice::ParamDecl::ParamDecl(const ContainerPtr& container, const string& name, const TypePtr& type, bool isOutParam, + bool optional, int tag) : SyntaxTreeBase(container->unit()), Contained(container, name), _type(type), - _isOutParam(isOutParam) + _isOutParam(isOutParam), + _optional(optional), + _tag(tag) { } @@ -5089,6 +5274,18 @@ Slice::DataMember::type() const return _type; } +bool +Slice::DataMember::optional() const +{ + return _optional; +} + +int +Slice::DataMember::tag() const +{ + return _tag; +} + string Slice::DataMember::defaultValue() const { @@ -5138,11 +5335,13 @@ Slice::DataMember::visit(ParserVisitor* visitor, bool) } Slice::DataMember::DataMember(const ContainerPtr& container, const string& name, const TypePtr& type, - const SyntaxTreeBasePtr& defaultValueType, const string& defaultValue, - const string& defaultLiteral) : + bool optional, int tag, const SyntaxTreeBasePtr& defaultValueType, + const string& defaultValue, const string& defaultLiteral) : SyntaxTreeBase(container->unit()), Contained(container, name), _type(type), + _optional(optional), + _tag(tag), _defaultValueType(defaultValueType), _defaultValue(defaultValue), _defaultLiteral(defaultLiteral) |