http://git-wip-us.apache.org/repos/asf/geode-native/blob/97ded703/contrib/pdxautoserializer/src/InputParser.cpp ---------------------------------------------------------------------- diff --git a/contrib/pdxautoserializer/src/InputParser.cpp b/contrib/pdxautoserializer/src/InputParser.cpp new file mode 100644 index 0000000..67d2e83 --- /dev/null +++ b/contrib/pdxautoserializer/src/InputParser.cpp @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 "base_types.hpp" +#include "InputParser.hpp" + +namespace apache { +namespace geode { +namespace client { +namespace pdx_auto_serializer { +// ClassInfo method definitions + +void ClassInfo::init(InputParser* parser) { m_parser = parser; } + +// InputParser method definitions + +bool InputParser::select(const std::string& className) { + ASClassFlagMap::iterator findClass = m_classes.find(className); + if (findClass != m_classes.end()) { + findClass->second.second = true; + return true; + } + return false; +} + +void InputParser::getSelectedClasses(ASClassVector& classes) const { + for (ASClassFlagMap::const_iterator mapIterator = m_classes.begin(); + mapIterator != m_classes.end(); ++mapIterator) { + if (mapIterator->second.second) { + classes.push_back(mapIterator->second.first); + } + } +} + +bool InputParser::contains(const std::string& className) const { + ASClassFlagMap::const_iterator findClass = m_classes.find(className); + return (findClass != m_classes.end()); +} +} // namespace pdx_auto_serializer +} // namespace client +} // namespace geode +} // namespace apache
http://git-wip-us.apache.org/repos/asf/geode-native/blob/97ded703/contrib/pdxautoserializer/src/InputParser.hpp ---------------------------------------------------------------------- diff --git a/contrib/pdxautoserializer/src/InputParser.hpp b/contrib/pdxautoserializer/src/InputParser.hpp new file mode 100644 index 0000000..bfb36db --- /dev/null +++ b/contrib/pdxautoserializer/src/InputParser.hpp @@ -0,0 +1,184 @@ +#pragma once + +#ifndef GEODE_PDXAUTOSERIALIZER_INPUTPARSER_H_ +#define GEODE_PDXAUTOSERIALIZER_INPUTPARSER_H_ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 "base_types.hpp" +#include "CodeGenerator.hpp" + +namespace apache { +namespace geode { +namespace client { +namespace pdx_auto_serializer { +// Forward declaration. +class InputParser; + +/** + * This class describes the interface to be implemented by the + * front-end parsers to represent each class in the resource. + */ +class ClassInfo { + public: + /** + * Destruct the class. + */ + virtual ~ClassInfo() {} + + /** + * Initialize with a handle to <code>InputParser</code>. + * + * @param parser Pointer to the <code>InputParser</code> object. + */ + virtual void init(InputParser* parser); + + /** + * Get the name of the class. + * + * @return The name of this class. + */ + virtual std::string getName() const = 0; + + /** + * Get the set of references required for the class. + * + * @param references The vector of references. + */ + virtual void getReferences(ReferenceVector& references) const = 0; + + /** + * Get the class information (with the namespace information) for this + * class. + * + * @param classType The <code>TypeInfo</code> for the class. + */ + virtual void getTypeInfo(TypeInfo& classType) const = 0; + + /** + * Get the list of members of this class to be serialized/deserialized. + * + * @param members The vector of variables that contains the list + * of variables that need to be serialized/deserialized. + */ + virtual void getMembers(VariableVector& members) const = 0; + + virtual std::string getMethodPrefix() const = 0; + + protected: + /** + * The <code>InputParser</code> object for which classes are being + * extracted. + */ + InputParser* m_parser; +}; + +/** Shorthand for a vector of <code>ClassInfo</code> objects. */ +typedef std::vector<const ClassInfo*> ASClassVector; + +/** + * Shorthand for a map of class names to corresponding + * <code>ClassInfo</code> objects. + */ +typedef std::map<std::string, const ClassInfo*> ASClassMap; + +/** + * Shorthand for a map of class names to corresponding + * <code>ClassInfo</code> objects with a flag for selection. + */ +typedef std::map<std::string, std::pair<ClassInfo*, bool> > ASClassFlagMap; + +/** + * This class describes the interface to be implemented by front-end + * parsers. + */ +class InputParser { + public: + /** + * Destruct the parser. + */ + virtual ~InputParser() {} + + /** + * Get a list of options and usage for the parser. + * + * @param options Output parameter for options along-with their usage. + */ + virtual void getOptions(OptionMap& options) const = 0; + + /** + * Initialize the parser with the given properties. + * + * @param properties The set of properties for the resource as given + * on the command-line. The function should modify + * this map so as to remove the properties used by + * the implementation. This should also match the + * usage as provided by + * <code>InputParser::getOptions</code> method. + */ + virtual void init(PropertyMap& properties) = 0; + + /** + * Select some or all classes in the given resources. + * + * @param resources The resources to parse. + * @param classNames The names of the classes which constitute the + * initial selection as specified by the user. + * If this is empty then all the classes are marked + * as selected. + */ + virtual void selectClasses(const StringVector& resources, + const StringVector& classNames) = 0; + + /** + * Add the given class to the current selection of classes. + * + * @param className The name of the new class to be added. + * @return True if the given class name exists in the global list. + */ + virtual bool select(const std::string& className); + + /** + * Search the given class name in the global list of classes. + * + * @param className The name of the class to search. + * @return True if the given class name exists in the global list. + */ + virtual bool contains(const std::string& className) const; + + /** + * Get the selected list of classes. + * + * @param classes Output parameter containing the vector of + * selected classes. + */ + virtual void getSelectedClasses(ASClassVector& classes) const; + + protected: + /** + * Stores the set of all the classes with the classes selected so far + * as marked selected. + */ + ASClassFlagMap m_classes; +}; +} // namespace pdx_auto_serializer +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_PDXAUTOSERIALIZER_INPUTPARSER_H_ http://git-wip-us.apache.org/repos/asf/geode-native/blob/97ded703/contrib/pdxautoserializer/src/InputParserFactory.cpp ---------------------------------------------------------------------- diff --git a/contrib/pdxautoserializer/src/InputParserFactory.cpp b/contrib/pdxautoserializer/src/InputParserFactory.cpp new file mode 100644 index 0000000..a9dea87 --- /dev/null +++ b/contrib/pdxautoserializer/src/InputParserFactory.cpp @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 "base_types.hpp" +#include "InputParserFactory.hpp" +#include <stdio.h> +#ifndef WIN32 +#include <strings.h> +#endif +#include "impl/CPPParser/CPPInputParser.hpp" +#ifdef GEMFIRE_CLR +#include "impl/DotNetParser.hpp" +#endif + +namespace apache { +namespace geode { +namespace client { +namespace pdx_auto_serializer { +InputParserFactory::InputParserFactory() { + // Register the available parsers here. + m_parserMap["C++"] = CPPInputParser::create; +#ifdef GEMFIRE_CLR + m_parserMap[".NET"] = DotNetParser::create; +#endif // GEMFIRE_CLR +} + +InputParser* InputParserFactory::getInstance( + const std::string& parserName) const { + std::map<std::string, InputParserFn>::const_iterator mapIterator = + m_parserMap.find(parserName); + if (mapIterator != m_parserMap.end()) { + return mapIterator->second(); + } + return NULL; +} + +StringVector InputParserFactory::getParsers() const { + StringVector parserList; + + for (std::map<std::string, InputParserFn>::const_iterator parserIterator = + m_parserMap.begin(); + parserIterator != m_parserMap.end(); ++parserIterator) { + parserList.push_back(parserIterator->first); + } + return parserList; +} + +InputParserFactory::~InputParserFactory() { m_parserMap.clear(); } +} // namespace pdx_auto_serializer +} // namespace client +} // namespace geode +} // namespace apache http://git-wip-us.apache.org/repos/asf/geode-native/blob/97ded703/contrib/pdxautoserializer/src/InputParserFactory.hpp ---------------------------------------------------------------------- diff --git a/contrib/pdxautoserializer/src/InputParserFactory.hpp b/contrib/pdxautoserializer/src/InputParserFactory.hpp new file mode 100644 index 0000000..75a3c94 --- /dev/null +++ b/contrib/pdxautoserializer/src/InputParserFactory.hpp @@ -0,0 +1,76 @@ +#pragma once + +#ifndef GEODE_PDXAUTOSERIALIZER_INPUTPARSERFACTORY_H_ +#define GEODE_PDXAUTOSERIALIZER_INPUTPARSERFACTORY_H_ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 "InputParser.hpp" +#include <utility> + +namespace apache { +namespace geode { +namespace client { +namespace pdx_auto_serializer { +/** + * Defines a function returning a pointer to an + * <code>InputParser</code> object. + * + * @return The <code>InputParser</code> object. + */ +typedef InputParser* (*InputParserFn)(void); + +/** + * Factory class to obtain instances of <code>InputParser</code> + * implementations. + */ +class InputParserFactory { + public: + /** + * Default constructor that registers all the available + * <code>InputParser</code> implementations. + */ + InputParserFactory(); + + /** + * Get an instance of an <code>InputParser</code> using name of a parser. + * + * @param parserName The name of the parser frontend. + * @return An instance of <code>InputParser</code>. + */ + InputParser* getInstance(const std::string& parserName) const; + + /** Get a list of all registered parser frontends. */ + StringVector getParsers() const; + + /** Virtual destructor. */ + virtual ~InputParserFactory(); + + private: + /** + * The map containing the mappings from the names of parsers to their + * factory functions. + */ + std::map<std::string, InputParserFn> m_parserMap; +}; +} // namespace pdx_auto_serializer +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_PDXAUTOSERIALIZER_INPUTPARSERFACTORY_H_ http://git-wip-us.apache.org/repos/asf/geode-native/blob/97ded703/contrib/pdxautoserializer/src/OutputFormatter.cpp ---------------------------------------------------------------------- diff --git a/contrib/pdxautoserializer/src/OutputFormatter.cpp b/contrib/pdxautoserializer/src/OutputFormatter.cpp new file mode 100644 index 0000000..a733389 --- /dev/null +++ b/contrib/pdxautoserializer/src/OutputFormatter.cpp @@ -0,0 +1,149 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 "OutputFormatter.hpp" +#include <cstring> +#include <cerrno> + +namespace apache { +namespace geode { +namespace client { +namespace pdx_auto_serializer { +// OutputFormatStreamBuf method definitions + +OutputFormatStreamBuf::OutputFormatStreamBuf() + : m_buf(NULL), + m_indentSize(0), + m_indentLevel(0), + m_newLine(true), + m_openBrace(false) { + std::streambuf::setp(NULL, NULL); + std::streambuf::setg(NULL, NULL, NULL); +} + +void OutputFormatStreamBuf::init(std::streambuf* buf, char indentChar, + int indentSize) { + m_buf = buf; + m_indentChar = indentChar; + m_indentSize = indentSize; +} + +void OutputFormatStreamBuf::setIndentChar(char indentChar) { + m_indentChar = indentChar; +} + +void OutputFormatStreamBuf::setIndentSize(int indentSize) { + m_indentSize = indentSize; +} + +void OutputFormatStreamBuf::increaseIndent() { ++m_indentLevel; } + +void OutputFormatStreamBuf::decreaseIndent() { --m_indentLevel; } + +int OutputFormatStreamBuf::getIndent() const { return m_indentLevel; } + +void OutputFormatStreamBuf::setIndent(int indentLevel) { + m_indentLevel = indentLevel; +} + +int OutputFormatStreamBuf::overflow(int c) { + if (c != EOF) { + if (m_newLine && c != '\n') { + if (c != '#') { + if (c == '}') { + --m_indentLevel; + } + for (int i = 0; i < m_indentLevel * m_indentSize; ++i) { + if (m_buf->sputc(m_indentChar) == EOF) { + return EOF; + } + } + } + m_newLine = false; + } + if (c == '\n') { + m_newLine = true; + if (m_openBrace) { + ++m_indentLevel; + } + } + if (c == '{') { + m_openBrace = true; + } else { + m_openBrace = false; + } + return m_buf->sputc(c); + } + return 0; +} + +int OutputFormatStreamBuf::sync() { return m_buf->pubsync(); } + +OutputFormatStreamBuf::~OutputFormatStreamBuf() {} + +// OutputFormatter method definitions + +OutputFormatter::OutputFormatter() + : std::ostream(NULL), m_ofstream(), m_streamBuf() { + m_streamBuf.init(m_ofstream.rdbuf(), DefaultIndentChar, DefaultIndentSize); + std::ostream::init(&m_streamBuf); +} + +void OutputFormatter::open(const std::string& fileName, ios_base::openmode mode, + char indentChar, int indentSize) { + m_fileName = fileName; + m_ofstream.open(fileName.c_str(), mode); + if (!m_ofstream) { + throw std::ios_base::failure(std::strerror(errno)); + } + m_streamBuf.setIndentChar(indentChar); + m_streamBuf.setIndentSize(indentSize); +} + +void OutputFormatter::setIndentChar(char indentChar) { + m_streamBuf.setIndentChar(indentChar); +} + +void OutputFormatter::setIndentSize(int indentSize) { + m_streamBuf.setIndentSize(indentSize); +} + +void OutputFormatter::increaseIndent() { m_streamBuf.increaseIndent(); } + +void OutputFormatter::decreaseIndent() { m_streamBuf.decreaseIndent(); } + +int OutputFormatter::getIndent() const { return m_streamBuf.getIndent(); } + +void OutputFormatter::setIndent(int indentLevel) { + m_streamBuf.setIndent(indentLevel); +} + +std::string OutputFormatter::getFileName() const { return m_fileName; } + +void OutputFormatter::flush() { + std::ostream::flush(); + m_ofstream.flush(); +} + +void OutputFormatter::close() { + std::ostream::flush(); + m_ofstream.close(); +} +} // namespace pdx_auto_serializer +} // namespace client +} // namespace geode +} // namespace apache http://git-wip-us.apache.org/repos/asf/geode-native/blob/97ded703/contrib/pdxautoserializer/src/OutputFormatter.hpp ---------------------------------------------------------------------- diff --git a/contrib/pdxautoserializer/src/OutputFormatter.hpp b/contrib/pdxautoserializer/src/OutputFormatter.hpp new file mode 100644 index 0000000..244973f --- /dev/null +++ b/contrib/pdxautoserializer/src/OutputFormatter.hpp @@ -0,0 +1,230 @@ +#pragma once + +#ifndef GEODE_PDXAUTOSERIALIZER_OUTPUTFORMATTER_H_ +#define GEODE_PDXAUTOSERIALIZER_OUTPUTFORMATTER_H_ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 <ostream> +#include <streambuf> +#include <fstream> +#include <string> + +namespace apache { +namespace geode { +namespace client { +namespace pdx_auto_serializer { +/** The default character to use for indentation. */ +const char DefaultIndentChar = ' '; + +/** The default indentation size. */ +const int DefaultIndentSize = 2; + +/** + * A<code>std::streambuf</code> class that formats the buffer with + * appropriate indentation. + * + * It derives from the standard <code>std::streambuf</code> class and + * turns off buffering while delegating the actual task to another + * <code>std::streambuf</code> contained in it. This is required so that + * the <code>OutputFormatStreamBuf::overflow</code> method is called for + * every write. + */ +class OutputFormatStreamBuf : public std::streambuf { + public: + /** Default constructor. */ + OutputFormatStreamBuf(); + + /** + * Initialize the buffer with the given <code>std::streambuf</code> + * and given indentation character, indentation size. + * + * @param buf The actual <code>std::streambuf</code> to be used for + * buffering. + * @param indentChar The character to use for indentation of each line. + * @param indentSize The size for each level of indentation. + */ + void init(std::streambuf* buf, char indentChar, int indentSize); + + /** + * Change the indentation character. + * + * @param indentChar The new indentation character. + */ + void setIndentChar(char indentChar); + + /** + * Change the number of characters for each indentation level. + * + * @param indentSize The new size for indentation. + */ + void setIndentSize(int indentSize); + + /** Increase the current indentation level by one. */ + void increaseIndent(); + + /** Decrease the current indentation level by one. */ + void decreaseIndent(); + + /** + * Get the current indentation level. + * + * @return The current indentation level. + */ + virtual int getIndent() const; + + /** + * Set the current indentation level. + * + * @param indentLevel The indentation level to set. + */ + virtual void setIndent(int indentLevel); + + /** Virtual destructor. */ + virtual ~OutputFormatStreamBuf(); + + protected: + /** + * The overriden <code>std::streambuf::overflow</code> method that + * inserts the indentation characters when starting a new line. + * + * Note that buffering for this <code>streambuf</code> is turned off so + * that this is called for every write and the contained + * <code>m_buf</code> is the one actually used. + * + * @param c The character to be written. + */ + virtual int overflow(int c); + + /** Overriden <code>std::streambuf::sync</code> method. */ + virtual int sync(); + + /** + * The contained <code>streambuf</code> that does the actual work of + * buffering/writing. + */ + std::streambuf* m_buf; + + /** The indentation character to be used. */ + char m_indentChar; + + /** The size of indentation in each level. */ + int m_indentSize; + + /** The current indentation level. */ + int m_indentLevel; + + /** True when a newline has just been encountered. */ + bool m_newLine; + + /** True when an opening brace has just been encountered. */ + bool m_openBrace; +}; + +/** + * A<code>std::ostream</code> class that writes the output to a given file + * and formats the output with appropriate indentation. + */ +class OutputFormatter : public std::ostream { + public: + /** The default constructor */ + OutputFormatter(); + + /** + * Open a given file for writing (just like <code>std::ofstream</code> + * in the given mode and use the provided indentation character and size. + * + * @param fileName Name of the file to open. + * @param mode The mode to use when opening the file -- default is to + * truncate the file and open in write mode. + * @param indentChar The character to use for indentation. + * @param indentSize The number of characters to use for indentation. + */ + virtual void open(const std::string& fileName, + ios_base::openmode mode = ios_base::out | ios_base::trunc, + char indentChar = DefaultIndentChar, + int indentSize = DefaultIndentSize); + + /** + * Change the indentation character. + * + * @param indentChar The new indentation character. + */ + virtual void setIndentChar(char indentChar); + + /** + * Change the number of characters for each indentation level. + * + * @param indentSize The new size for indentation. + */ + virtual void setIndentSize(int indentSize); + + /** Increase the current indentation level by one. */ + virtual void increaseIndent(); + + /** Decrease the current indentation level by one. */ + virtual void decreaseIndent(); + + /** + * Get the current indentation level. + * + * @return The current indentation level. + */ + virtual int getIndent() const; + + /** + * Set the current indentation level. + * + * @param indentLevel The indentation level to set. + */ + virtual void setIndent(int indentLevel); + + /** + * Get the underlying name of output file. + * + * @return The path of the output file. + */ + std::string getFileName() const; + + /** Overrides the <code>std::ostream::flush</code> method to flush the + * output stream to the file. + */ + virtual void flush(); + + /** + * Overrides the <code>std::ostream::close</code> method to close the + * underlying stream and file. + */ + virtual void close(); + + protected: + /** The underlying output file stream object. */ + std::ofstream m_ofstream; + + /** The name of the output file. */ + std::string m_fileName; + + /** The formatter to use for formatting the output. */ + OutputFormatStreamBuf m_streamBuf; +}; +} // namespace pdx_auto_serializer +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_PDXAUTOSERIALIZER_OUTPUTFORMATTER_H_ http://git-wip-us.apache.org/repos/asf/geode-native/blob/97ded703/contrib/pdxautoserializer/src/base_types.hpp ---------------------------------------------------------------------- diff --git a/contrib/pdxautoserializer/src/base_types.hpp b/contrib/pdxautoserializer/src/base_types.hpp new file mode 100644 index 0000000..09f8b54 --- /dev/null +++ b/contrib/pdxautoserializer/src/base_types.hpp @@ -0,0 +1,256 @@ +#pragma once + +#ifndef GEODE_PDXAUTOSERIALIZER_BASE_TYPES_H_ +#define GEODE_PDXAUTOSERIALIZER_BASE_TYPES_H_ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 <string> +#include <vector> +#include <set> +#include <map> +#include <cassert> +#include <stdexcept> + +namespace apache { +namespace geode { +namespace client { +namespace pdx_auto_serializer { +/** Shorthand for vector of strings. */ +typedef std::vector<std::string> StringVector; + +/** Shorthand for set of strings. */ +typedef std::set<std::string> StringSet; + +/** + * Shorthand for the <code>std::map</code> containing property + * key-value pairs. + */ +typedef std::map<std::string, StringVector> PropertyMap; + +/** + * Shorthand for the <code>std::map</code> containing string + * key-value pairs. + */ +typedef std::map<std::string, std::string> StringMap; + +/** + * Shorthand for the <code>std::map</code> containing string + * keys mapped to usage string and boolean indicator of option + * requiring a value. + */ +typedef std::map<std::string, std::pair<bool, std::string> > OptionMap; + +/** Shorthand for iterator of vector of strings. */ +typedef std::vector<std::string>::const_iterator StringVectorIterator; + +/** Shorthand for iterator of set of strings. */ +typedef std::set<std::string>::const_iterator StringSetIterator; + +/** + * Encapsulates different kinds of references (headers/dlls etc). + */ +class Reference { + public: + enum Kind { + /** Indicates a C++ header file. */ + HEADER, + + /** Indicates a library (so/dll). */ + LIB, + + /** Indicates a jar file (Java). */ + JAR + }; +}; + +/** + * Structure to hold information of a reference (e.g. header/dll). + */ +struct ReferenceInfo { + /** Path of the reference. */ + std::string m_path; + + /** the <code>Reference::Kind</code> of the reference. */ + Reference::Kind m_kind; +}; + +/** + * Encapsulates different kinds of types like <code>VALUE</code>, + * <code>ARRAY</code> etc. + * + * Also includes the information whether the type is a built-in one or + * a user-defined type, and whether the type is a .NET managed type. + */ +class TypeKind { + public: + /** An invalid type. */ + static const int INVALID = 0x0; + + /** A value type. */ + static const int VALUE = 0x01; + + /** A pointer type. */ + static const int POINTER = 0x02; + + /** A reference type or pass by reference. */ + static const int REFERENCE = 0x04; + + /** An array type with fixed/dynamic size. */ + static const int ARRAY = 0x08; + + /** + * The array is of fixed size -- both this and <code>ARRAY</code> + * bits should be set for fixed size arrays. + */ + static const int FIXEDARRAY = 0x10; + + /** A C++ template or .NET/Java generic type. */ + static const int TEMPLATE = 0x20; + + /** The type is actually a template parameter symbol. */ + static const int TEMPLATEPARAM = 0x40; + + /** + * Indicates that the type is a .NET managed type -- required for + * generators like C++/CLI that understand both normal objects as + * well as .NET types. + */ + static const int MANAGED = 0x100; + + /** + * Indicates that the type is a builtin one. This will be normally + * OR'd with one of the actual kinds above. If this bit is not set + * then the type is assumed to be a user-defined type. + */ + static const int BUILTIN = 0x200; +}; + +/** + * Mask to extract the Type part only from the constants in + * <code>TypeKind</code> class. + */ +const int TYPEKIND_TYPEMASK = 0xFF; + +/** + * Constants for the possible kinds of type modifiers. + */ +class TypeModifier { + public: + /** No modifier. */ + static const int NONE = 0x01; + + /** The type is defined to be a constant. */ + static const int CONSTANT = 0x02; + + /** The type is defined to be volatile. */ + static const int VOLATILE = 0x04; + + /** The member is private to the class. */ + static const int PRIVATE = 0x08; + + /** The member is declared to be protected. */ + static const int PROTECTED = 0x10; + + /** The member is declared to be public. */ + static const int PUBLIC = 0x20; + + /** The member is declared to be internal (.NET). */ + static const int INTERNAL = 0x40; + + /** The member is a property (.NET). */ + static const int PROPERTY = 0x80; + + /** The member is defined to be transient (Java). */ + static const int TRANSIENT = 0x100; +}; + +/** + * Structure to hold information for a type. + */ +struct TypeInfo { + /** The {@link apache::geode::client::pdx_auto_serializer::TypeKind} of the + * type. */ + int m_kind; + + /** The {@link apache::geode::client::pdx_auto_serializer::TypeModifier} for + * the type. */ + int m_modifier; + + /** + * Contains either the name of the variable, or for the case of + * <code>FIXEDARRAY</code> or <code>ARRAY</code>, the size of the array, + * name of variable containing the size respectively. + */ + std::string m_nameOrSize; + + std::string m_nameOfArrayElemSize; + + /** The namespace for the type expressed as a vector. */ + StringVector m_namespaces; + + /** + * Information of any child sub-types for the case of + * <code>POINTER</code>, <code>REFERENCE</code> or + * <code>TEMPLATE</code> types. + */ + TypeInfo* m_children; + + /** + * The number of child sub-types. Can be greater than one for the case + * of <code>TEMPLATE</code> types. + */ + int m_numChildren; +}; + +/** + * Structure to hold information for a variable. + */ +struct VariableInfo { + /** The type of the variable. */ + TypeInfo m_type; + + bool m_markIdentityField; + bool m_markPdxUnreadField; + /** The name of the variable. */ + std::string m_name; +}; + +/** Shorthand for a vector of <code>ReferenceInfo</code>. */ +typedef std::vector<ReferenceInfo> ReferenceVector; + +/** + * Shorthand for <code>const_iterator</code> of a vector of + * <code>ReferenceInfo</code>. + */ +typedef std::vector<ReferenceInfo>::const_iterator ReferenceVectorIterator; + +/** Shorthand for a vector of <code>VariableInfo</code>. */ +typedef std::vector<VariableInfo> VariableVector; + +/** + * Shorthand for <code>const_iterator</code> of a vector of + * <code>VariableInfo</code>. + */ +typedef std::vector<VariableInfo>::const_iterator VariableVectorIterator; +} // namespace pdx_auto_serializer +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_PDXAUTOSERIALIZER_BASE_TYPES_H_ http://git-wip-us.apache.org/repos/asf/geode-native/blob/97ded703/contrib/pdxautoserializer/src/impl/CPPCodeGenerator.cpp ---------------------------------------------------------------------- diff --git a/contrib/pdxautoserializer/src/impl/CPPCodeGenerator.cpp b/contrib/pdxautoserializer/src/impl/CPPCodeGenerator.cpp new file mode 100644 index 0000000..2206003 --- /dev/null +++ b/contrib/pdxautoserializer/src/impl/CPPCodeGenerator.cpp @@ -0,0 +1,539 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 "../base_types.hpp" +#include "CPPCodeGenerator.hpp" +#include "Log.hpp" +#include "Helper.hpp" +#include <iostream> + +namespace apache { +namespace geode { +namespace client { +namespace pdx_auto_serializer { +int CPPCodeGenerator::s_classId = -1; + +std::string CPPCodeGenerator::s_GFSerializerNamespace = + "apache::geode::client::PdxAutoSerializable"; +std::string CPPCodeGenerator::s_TempVarPrefix = "var_"; + +/** The option name for classId. */ +std::string CPPCodeGenerator::s_ClassIdOption = "classId"; + +/** The option name for the output directory. */ +std::string CPPCodeGenerator::s_OutDirOption = "outDir"; + +/** +* The directory to be used in generated files for the included headers. +* If not provided the path of the header file as provided on +* command-line is used. +*/ +std::string CPPCodeGenerator::s_HeaderDirOption = "headerDir"; + +/** +* The option name for the suffix to use for generated files and classes. +*/ +std::string CPPCodeGenerator::s_GenSuffixOption = "suffix"; + +// CodeGenerator method implementations + +void CPPCodeGenerator::getOptions(OptionMap& options) const { + std::pair<bool, std::string> optionPair; + // optionPair.first = true; + // optionPair.second + // = "\tThe base classId to be used for the serializers [>= 0, < 2^31] " + // "(SINGLE,OPTIONAL)"; + // options[s_ClassIdOption] = optionPair; + + optionPair.second = + "\tThe output directory of the generated files " + "(SINGLE,OPTIONAL)"; + options[s_OutDirOption] = optionPair; + + optionPair.second = + "\tThe suffix of the generated filenames " + "-- default is '" + + defaultGenSuffix() + "' (SINGLE,OPTIONAL)"; + options[s_GenSuffixOption] = optionPair; + + // optionPair.second = "\tThe directory to be used in generated files for " + // "the included headers.\n\t\t\tIf not provided the " + // "path of the header file as provided on the " + // "command-line is used (SINGLE,OPTIONAL)"; + // options[s_HeaderDirOption] = optionPair; +} + +void CPPCodeGenerator::init(PropertyMap& properties) { + Helper::getSingleProperty(properties, s_OutDirOption, m_outDir); + m_outDir += '/'; + std::string classIdStr; + bool classIdFound = + Helper::getSingleProperty(properties, s_ClassIdOption, classIdStr); + if (!classIdFound) { + // Log::warn(m_moduleName, "No classId given or found for the " + // "class; will not generate the classId method."); + } else { + try { + Helper::lexical_cast(classIdStr, s_classId); + } catch (const std::invalid_argument&) { + Log::fatal(m_moduleName, "classId not a valid integer"); + } + if (s_classId < 0) { + Log::fatal(m_moduleName, "classId should be >= 0."); + } + } + Helper::getSingleProperty(properties, s_GenSuffixOption, m_genSuffix); + if (m_genSuffix.length() == 0) { + m_genSuffix = defaultGenSuffix(); + } + if (Helper::getSingleProperty(properties, s_HeaderDirOption, m_headerDir) && + (m_headerDir.length() > 0)) { + char lastChar = m_headerDir[m_headerDir.length() - 1]; + if (lastChar != '/' && lastChar != '\\') { + m_headerDir += '/'; + } + } +} + +void CPPCodeGenerator::initClass(const TypeInfo& classInfo) { + std::string namespacePrefixString = ""; + StringVector nameSpaceList = classInfo.m_namespaces; + for (StringVector::iterator iter = nameSpaceList.begin(); + iter != nameSpaceList.end(); ++iter) { + namespacePrefixString += *iter; + } + std::string outFile = ""; + if (namespacePrefixString == "") { + outFile = m_outDir + classInfo.m_nameOrSize + m_genSuffix + ".cpp"; + } else { + outFile = m_outDir + namespacePrefixString + "_" + classInfo.m_nameOrSize + + m_genSuffix + ".cpp"; + } + Log::info(m_moduleName, "Writing: " + outFile); + m_cppFormatter->open(outFile); + m_classInfo = classInfo; +} + +void CPPCodeGenerator::addFileHeader(int argc, char** argv) { + *m_cppFormatter + << "// This is auto generated file using \"pdxautoserializer\"" + << "\n"; + *m_cppFormatter + << "// Do not edit this file, unless you are sure what you are doing " + << "\n"; + *m_cppFormatter << "// Options used to generate this files are : " + << "\n"; + for (int i = 1; i < argc; i++) { + *m_cppFormatter << "//\t" << argv[i] << "\n"; + } + *m_cppFormatter << "\n"; +} + +void CPPCodeGenerator::addReferences(const ReferenceVector& references) { + for (ReferenceVectorIterator referenceIterator = references.begin(); + referenceIterator != references.end(); ++referenceIterator) { + if (referenceIterator->m_kind == Reference::HEADER) { + std::string headerPath; + std::string::size_type lastSlash = + referenceIterator->m_path.find_last_of("/\\"); + if (lastSlash != std::string::npos) { + headerPath = + m_headerDir + referenceIterator->m_path.substr(lastSlash + 1); + } else { + headerPath = m_headerDir + referenceIterator->m_path; + } + *m_cppFormatter << "#include \"" << headerPath << "\"\n\n"; + } + } + *m_cppFormatter << "#include <geode/PdxWriter.hpp>" + << "\n"; + *m_cppFormatter << "#include <geode/PdxReader.hpp>" + << "\n"; + *m_cppFormatter << "#include <geode/PdxAutoSerializer.hpp>" + << "\n\n"; +} + +void CPPCodeGenerator::startClass(const VariableVector& members) { + genNamespaceHeader(m_classInfo.m_namespaces, m_cppFormatter); +} +// Ticket #905 Changes starts here +void CPPCodeGenerator::addTryBlockStart(const Method::Type type) { + switch (type) { + case Method::TODATA: { + *m_cppFormatter << "try\n"; + *m_cppFormatter << "{\n"; + break; + } + case Method::FROMDATA: { + *m_cppFormatter << "try\n"; + *m_cppFormatter << "{\n"; + break; + } + default: { break; } + } + return; +} +void CPPCodeGenerator::finishTryBlock(const Method::Type type) { + switch (type) { + case Method::TODATA: { + *m_cppFormatter << "}\n"; + *m_cppFormatter + << "catch(apache::geode::client::IllegalStateException exception)\n"; + *m_cppFormatter << "{\n"; + *m_cppFormatter << "}\n"; + break; + } + case Method::FROMDATA: { + *m_cppFormatter << "}\n"; + *m_cppFormatter + << "catch(apache::geode::client::IllegalStateException exception)\n"; + *m_cppFormatter << "{\n"; + *m_cppFormatter << "}\n"; + break; + } + default: { break; } + } + return; +} +// Ticket #905 Changes ends here + +void CPPCodeGenerator::startMethod(const Method::Type type, + const std::string& varName, + const std::string& methodPrefix) { + std::string var; + StringVector varVec; + std::string className = getTypeString(m_classInfo); + + switch (type) { + case Method::TODATA: { + varVec.push_back("apache::geode::client::PdxWriterPtr __var"); + + genFunctionHeader("toData", className, "void", varVec, true, false, + m_cppFormatter, methodPrefix); + break; + } + case Method::FROMDATA: { + varVec.push_back("apache::geode::client::PdxReaderPtr __var "); + + genFunctionHeader("fromData", className, "void", varVec, true, false, + m_cppFormatter, methodPrefix); + break; + } + default: { throw std::invalid_argument("unexpected execution"); } + } +} + +void CPPCodeGenerator::genMethod(const Method::Type type, + const std::string& varName, + const VariableInfo& var) { + switch (type) { + case Method::TODATA: { + if (var.m_markPdxUnreadField == true) { + *m_cppFormatter << varName << "->writeUnreadFields(" << var.m_name; + } else { + *m_cppFormatter << s_GFSerializerNamespace << "::writePdxObject(" + << varName << ", " + << "\"" << var.m_name << "\"" + << ", " << var.m_name; + if (var.m_type.m_kind & TypeKind::ARRAY) { + *m_cppFormatter << ", " << var.m_type.m_nameOrSize; + if (var.m_type.m_nameOfArrayElemSize.size() > 0) { + *m_cppFormatter << ", " << var.m_type.m_nameOfArrayElemSize; + } + } + } + *m_cppFormatter << ");\n"; + if (var.m_markIdentityField == true) { + *m_cppFormatter << varName << "->markIdentityField(" + << "\"" << var.m_name << "\"" + << ");" + << "\n" + << "\n"; + } + break; + } + case Method::FROMDATA: { + if (var.m_markPdxUnreadField == true) { + *m_cppFormatter << var.m_name << " = " << varName + << "->readUnreadFields("; + } else { + *m_cppFormatter << s_GFSerializerNamespace << "::readPdxObject(" + << varName << ", " + << "\"" << var.m_name << "\"" + << ", " << var.m_name; + if (var.m_type.m_kind & TypeKind::ARRAY) { + *m_cppFormatter << ", " << var.m_type.m_nameOrSize; + if (var.m_type.m_nameOfArrayElemSize.size() > 0) { + *m_cppFormatter << ", " << var.m_type.m_nameOfArrayElemSize; + } + } + } + *m_cppFormatter << ");\n"; + break; + } + default: { throw std::invalid_argument("unexpected execution"); } + } +} + +void CPPCodeGenerator::endMethod(const Method::Type type, + const std::string& varName) { + switch (type) { + case Method::TODATA: { + genFunctionFooter(m_cppFormatter); + break; + } + case Method::FROMDATA: { + //*m_cppFormatter << "return this;\n"; + genFunctionFooter(m_cppFormatter); + break; + } + default: { throw std::invalid_argument("unexpected execution"); } + } +} + +void CPPCodeGenerator::genTypeId(const std::string& methodPrefix) { + if (s_classId >= 0) { + StringVector varVec; + std::string className = getTypeString(m_classInfo); + + genFunctionHeader("classId", className, "int32_t", varVec, true, true, + m_cppFormatter, methodPrefix); + *m_cppFormatter << "return " << s_classId << ";\n"; + genFunctionFooter(m_cppFormatter); + ++s_classId; + } +} + +void CPPCodeGenerator::genClassNameMethod( + std::map<std::string, std::string>& classNameStringMap, + const std::string& methodPrefix) { + StringVector varVec; + std::string className = getTypeString(m_classInfo); + std::map<std::string, std::string>::iterator found = + classNameStringMap.find(className); + genFunctionHeader("getClassName", className, "const char*", varVec, true, + true, m_cppFormatter, methodPrefix); + + if (found != classNameStringMap.end()) { + *m_cppFormatter << "return " + << "\"" << found->second << "\"" + << ";\n"; + } else { + *m_cppFormatter << "return " + << "\""; + for (StringVector::const_iterator itr = m_classInfo.m_namespaces.begin(); + itr != m_classInfo.m_namespaces.end(); ++itr) { + *m_cppFormatter << *itr << "."; + } + *m_cppFormatter << className << "\"" + << ";\n"; + } + genFunctionFooter(m_cppFormatter); +} + +void CPPCodeGenerator::genCreateDeserializable( + const std::string& methodPrefix) { + StringVector varVec; + std::string className = getTypeString(m_classInfo); + genFunctionHeader("createDeserializable", className, + "apache::geode::client::PdxSerializable*", varVec, true, + false, m_cppFormatter, methodPrefix); + *m_cppFormatter << "return new " << className << "()" + << ";\n"; + genFunctionFooter(m_cppFormatter); +} + +void CPPCodeGenerator::endClass() { + genNamespaceFooter(m_classInfo.m_namespaces, m_cppFormatter); + m_cppFormatter->close(); +} + +void CPPCodeGenerator::cleanup() { + std::string fileName; + if (m_cppFormatter != NULL) { + fileName = m_cppFormatter->getFileName(); + m_cppFormatter->close(); + if (fileName.length() > 0) { + remove(fileName.c_str()); + } + } +} + +// End CodeGenerator methods + +std::string CPPCodeGenerator::defaultGenSuffix() const { + return "Serializable"; +} + +std::string CPPCodeGenerator::getNamespacePrefix( + const StringVector& namespaces) const { + std::string namespacePrefix; + for (StringVectorIterator namespaceIterator = namespaces.begin(); + namespaceIterator != namespaces.end(); ++namespaceIterator) { + namespacePrefix += *namespaceIterator + "::"; + } + return namespacePrefix; +} + +std::string CPPCodeGenerator::getTypeString(const TypeInfo& type, + bool prependNS, + std::string* postVarStr, + StringSet* templateArgs) const { + std::string typeString; + if (type.m_kind & TypeKind::VALUE) { + if (prependNS) { + typeString += getNamespacePrefix(type.m_namespaces); + } + typeString += type.m_nameOrSize; + } else if (type.m_kind & TypeKind::TEMPLATEPARAM) { + typeString += type.m_nameOrSize; + if (templateArgs != NULL) { + templateArgs->insert(type.m_nameOrSize); + } + } else if (type.m_kind & TypeKind::POINTER) { + assert(type.m_numChildren == 1); + assert(type.m_children != NULL); + + typeString += + getTypeString(*(type.m_children), prependNS, postVarStr, templateArgs); + if (postVarStr == NULL || postVarStr->length() == 0) { + typeString += '*'; + } else { + typeString += "(*"; + postVarStr->insert(0, ")"); + } + } else if (type.m_kind & TypeKind::REFERENCE) { + assert(type.m_numChildren == 1); + assert(type.m_children != NULL); + + typeString += + getTypeString(*(type.m_children), prependNS, postVarStr, templateArgs); + if (postVarStr == NULL || postVarStr->length() == 0) { + typeString += '&'; + } else { + typeString += "(&"; + postVarStr->insert(0, ")"); + } + } else if (type.m_kind & TypeKind::TEMPLATE) { + if (prependNS) { + typeString += getNamespacePrefix(type.m_namespaces); + } + typeString += type.m_nameOrSize + "< "; + if (type.m_numChildren > 0) { + typeString += + getTypeString(*type.m_children, prependNS, postVarStr, templateArgs); + for (int childIndex = 1; childIndex < type.m_numChildren; ++childIndex) { + typeString += ", "; + typeString += getTypeString(type.m_children[childIndex], prependNS, + postVarStr, templateArgs); + } + } + typeString += " >"; + } else if (type.m_kind & TypeKind::ARRAY) { + assert(type.m_numChildren == 1); + assert(type.m_children != NULL); + + typeString += + getTypeString(*(type.m_children), prependNS, postVarStr, templateArgs); + if (postVarStr == NULL) { + typeString += '*'; + } else { + postVarStr->append("[]"); + } + } else if (type.m_kind & TypeKind::FIXEDARRAY) { + assert(type.m_numChildren == 1); + assert(type.m_children != NULL); + + typeString += + getTypeString(*(type.m_children), prependNS, postVarStr, templateArgs); + if (postVarStr == NULL) { + typeString += '*'; + } else { + postVarStr->append("[" + type.m_nameOrSize + "]"); + } + } + return typeString; +} + +void CPPCodeGenerator::genNamespaceHeader(const StringVector& namespaces, + OutputFormatter* formatter) { + for (StringVectorIterator namespaceIterator = namespaces.begin(); + namespaceIterator != namespaces.end(); ++namespaceIterator) { + *formatter << "namespace " << *namespaceIterator << "\n{\n"; + } + *formatter << '\n'; +} + +void CPPCodeGenerator::genFunctionHeader(const std::string& functionName, + const std::string& className, + const std::string& returnType, + const StringVector& arguments, + bool isDefinition, bool isConst, + OutputFormatter* formatter, + const std::string& methodPrefix) { + *formatter << returnType << ' '; + if (isDefinition) { + if (methodPrefix != "") { + *formatter << methodPrefix << className << "::"; + } else { + *formatter << className << "::"; + } + } + *formatter << functionName << "("; + if (arguments.size() > 0) { + StringVectorIterator argumentIterator = arguments.begin(); + *formatter << *argumentIterator; + while (++argumentIterator != arguments.end()) { + *formatter << ", " << *argumentIterator; + } + } + *formatter << ")"; + if (isConst) { + *formatter << " const"; + } + *formatter << "\n{\n"; +} + +void CPPCodeGenerator::genFunctionFooter(OutputFormatter* formatter) { + *formatter << "}\n\n"; +} + +void CPPCodeGenerator::genNamespaceFooter(const StringVector& namespaces, + OutputFormatter* formatter) { + for (StringVector::size_type i = 0; i < namespaces.size(); ++i) { + *formatter << "}\n"; + } +} + +CodeGenerator* CPPCodeGenerator::create() { return new CPPCodeGenerator(); } + +CPPCodeGenerator::CPPCodeGenerator() + : m_cppFormatter(new OutputFormatter()), + m_outDir("."), + m_moduleName("CPPCodeGenerator") {} + +CPPCodeGenerator::~CPPCodeGenerator() { + if (m_cppFormatter != NULL) { + m_cppFormatter->close(); + delete m_cppFormatter; + m_cppFormatter = NULL; + } +} +} // namespace pdx_auto_serializer +} // namespace client +} // namespace geode +} // namespace apache http://git-wip-us.apache.org/repos/asf/geode-native/blob/97ded703/contrib/pdxautoserializer/src/impl/CPPCodeGenerator.hpp ---------------------------------------------------------------------- diff --git a/contrib/pdxautoserializer/src/impl/CPPCodeGenerator.hpp b/contrib/pdxautoserializer/src/impl/CPPCodeGenerator.hpp new file mode 100644 index 0000000..7b28b35 --- /dev/null +++ b/contrib/pdxautoserializer/src/impl/CPPCodeGenerator.hpp @@ -0,0 +1,239 @@ +#pragma once + +#ifndef GEODE_PDXAUTOSERIALIZER_IMPL_CPPCODEGENERATOR_H_ +#define GEODE_PDXAUTOSERIALIZER_IMPL_CPPCODEGENERATOR_H_ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 "../CodeGenerator.hpp" +#include "../OutputFormatter.hpp" + +namespace apache { +namespace geode { +namespace client { +namespace pdx_auto_serializer { +/** + * The C++ code generator backend. + */ +class CPPCodeGenerator : public CodeGenerator { + public: + // CodeGenerator method implementations + + virtual void getOptions(OptionMap& options) const; + + virtual void init(PropertyMap& properties); + + virtual void initClass(const TypeInfo& classInfo); + + virtual void addReferences(const ReferenceVector& references); + virtual void addFileHeader(int, char**); + + virtual void startClass(const VariableVector& members); + + virtual void startMethod(const Method::Type type, const std::string& varName, + const std::string& methodPrefix); + + // Ticket #905 Changes starts here + virtual void addTryBlockStart(const Method::Type type); + virtual void finishTryBlock(const Method::Type type); + // Ticket #905 Changes ends here + virtual void genMethod(const Method::Type type, const std::string& varName, + const VariableInfo& var); + + virtual void endMethod(const Method::Type type, const std::string& varName); + + virtual void genTypeId(const std::string& methodPrefix); + virtual void genClassNameMethod(std::map<std::string, std::string>&, + const std::string& methodPrefix); + virtual void genCreateDeserializable(const std::string& methodPrefix); + virtual void endClass(); + + virtual void cleanup(); + + // End CodeGenerator implementations + + /** + * Static factory function to create an object of + * <code>CPPCodeGenerator</code> class. This is registered with the + * <code>CodeGeneratorFactory</code>. + * + * @return An instance of <code>CPPCodeGenerator</code>. + */ + static CodeGenerator* create(); + + /** Virtual destructor. */ + virtual ~CPPCodeGenerator(); + + protected: + /** + * Get the default suffix to use for generated files and classes. + */ + virtual std::string defaultGenSuffix() const; + + /** + * Get the prefix for a namespace nesting. + * + * @param namespaces The nested namespace names. + * @return Prefix for nested namespaces. + */ + virtual std::string getNamespacePrefix(const StringVector& namespaces) const; + + /** + * Get the string representation for a given type. + * + * @param type Reference to the <code>TypeInfo</code> for the type. + * @param prependNS Whether to prepend the namespace to the type. + * @param postVarStr Returns a string that may be required after + * the variable (for C++ arrays). If this is + * NULL, then it is assumed to be in return type + * where there is no variable. + * @return The string representation of the type. + */ + virtual std::string getTypeString(const TypeInfo& type, + bool prependNS = false, + std::string* postVarStr = NULL, + StringSet* templateArgs = NULL) const; + + /** + * Generate the namespace header for the given list of namespaces. + * + * @param namespaces The vector of namespaces. + * @param formatter The formatter to use for generating the output. + */ + virtual void genNamespaceHeader(const StringVector& namespaces, + OutputFormatter* formatter); + + /** + * Generate the function header with the given name, arguments, + * return type and in the given class. + * + * @param functionName The name of the function. + * @param className The name of the class containing the function. + * @param returnType The return type of the function. + * @param arguments The list of arguments to the function. + * @param isDefinition Whether to generate a definition or declaration. + * @param isConst Whether the method is a const method. + * @param formatter The formatter to use for generating the output. + */ + virtual void genFunctionHeader(const std::string& functionName, + const std::string& className, + const std::string& returnType, + const StringVector& arguments, + bool isDefinition, bool isConst, + OutputFormatter* formatter, + const std::string& methodPrefix); + + /** + * Generate the function footer. + * + * @param formatter The formatter to use for generating the footer. + */ + virtual void genFunctionFooter(OutputFormatter* formatter); + + /** + * Generate the namespace footer for the given list of namespaces. + * + * @param namespaces The vector of namespaces. + * @param formatter The formatter to use for generating the output. + */ + virtual void genNamespaceFooter(const StringVector& namespaces, + OutputFormatter* formatter); + + /** + * Default constructor -- this is not exposed to public which should + * use the {@link CPPCodeGenerator::create} function. + */ + CPPCodeGenerator(); + + /** + * The <code>OutputFormatter</code> to be used for writing the output + * cpp file. + */ + OutputFormatter* m_cppFormatter; + + /** + * <code>TypeInfo</code> of the class for which <code>toData</code> + * and <code>fromData</code> methods are to be generated. + */ + TypeInfo m_classInfo; + + /** The name of the output directory. */ + std::string m_outDir; + + /** + * The suffix to be used for generated files and classes -- default is + * given by <code>defaultGenSuffix</code>. + */ + std::string m_genSuffix; + + /** + * The directory of the header file to be used in the '#include' in the + * generated files. + */ + std::string m_headerDir; + + /** + * The name of the variable of this class that is passed to static + * <code>writeObject/readObject</code> methods. + */ + std::string m_objPrefix; + + /** The name of this module to be used for logging. */ + std::string m_moduleName; + + /** The current classId being used for this class. */ + static int s_classId; + + // Constants + + /** + * The namespace containing the global overloaded <code>writeObject</code> + * and <code>readObject</code> methods for builtin types. + */ + static std::string s_GFSerializerNamespace; + + /** + * The prefix to use for declaring temporary and function argument + * variables. + */ + static std::string s_TempVarPrefix; + + /** The option name for classId. */ + static std::string s_ClassIdOption; + + /** The option name for the output directory. */ + static std::string s_OutDirOption; + + /** + * The directory to be used in generated files for the included headers. + * If not provided the path of the header file as provided on + * command-line is used. + */ + static std::string s_HeaderDirOption; + + /** + * The option name for the suffix to use for generated files and classes. + */ + static std::string s_GenSuffixOption; +}; +} // namespace pdx_auto_serializer +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_PDXAUTOSERIALIZER_IMPL_CPPCODEGENERATOR_H_ http://git-wip-us.apache.org/repos/asf/geode-native/blob/97ded703/contrib/pdxautoserializer/src/impl/CPPParser/CPPDictionary.hpp ---------------------------------------------------------------------- diff --git a/contrib/pdxautoserializer/src/impl/CPPParser/CPPDictionary.hpp b/contrib/pdxautoserializer/src/impl/CPPParser/CPPDictionary.hpp new file mode 100644 index 0000000..f09fb25 --- /dev/null +++ b/contrib/pdxautoserializer/src/impl/CPPParser/CPPDictionary.hpp @@ -0,0 +1,83 @@ +/* + * PUBLIC DOMAIN PCCTS-BASED C++ GRAMMAR (cplusplus.g, stat.g, expr.g) + * + * Authors: Sumana Srinivasan, NeXT Inc.; [email protected] + * Terence Parr, Parr Research Corporation; [email protected] + * Russell Quong, Purdue University; [email protected] + * + * SOFTWARE RIGHTS + * + * This file is a part of the ANTLR-based C++ grammar and is free + * software. We do not reserve any LEGAL rights to its use or + * distribution, but you may NOT claim ownership or authorship of this + * grammar or support code. An individual or company may otherwise do + * whatever they wish with the grammar distributed herewith including the + * incorporation of the grammar or the output generated by ANTLR into + * commerical software. You may redistribute in source or binary form + * without payment of royalties to us as long as this header remains + * in all source distributions. + * + * We encourage users to develop parsers/tools using this grammar. + * In return, we ask that credit is given to us for developing this + * grammar. By "credit", we mean that if you incorporate our grammar or + * the generated code into one of your programs (commercial product, + * research project, or otherwise) that you acknowledge this fact in the + * documentation, research report, etc.... In addition, you should say nice + * things about us at every opportunity. + * + * As long as these guidelines are kept, we expect to continue enhancing + * this grammar. Feel free to send us enhancements, fixes, bug reports, + * suggestions, or general words of encouragement at [email protected]. + * + * NeXT Computer Inc. + * 900 Chesapeake Dr. + * Redwood City, CA 94555 + * 12/02/1994 + * + * Restructured for public consumption by Terence Parr late February, 1995. + * + * Requires PCCTS 1.32b4 or higher to get past ANTLR. + * + * DISCLAIMER: we make no guarantees that this grammar works, makes sense, + * or can be used to do anything useful. + */ +/* 1999-2005 Version 3.1 November 2005 + * Modified by David Wigg at London South Bank University for CPP_parser.g + * + * See MyReadMe.txt for further information + * + * This file is best viewed in courier font with tabs set to 4 spaces + */ + +#ifndef CPPDictionary_hpp +#define CPPDictionary_hpp + +#include <geode/geode_globals.hpp> +#include "Dictionary.hpp" + +class CPPDictionary : public Dictionary { + public: + CPPDictionary(int nb = 43, int ns = 50, int nc = 30000) + : Dictionary(nb, ns, nc) {} + + protected: + void dumpSymbol(FILE *f, DictEntry *de) { + CPPSymbol *cs ATTR_UNUSED = (CPPSymbol *)de; + +#ifdef DIAG_MSGES + if (!(cs->getType() == CPPSymbol::otTypedef || + cs->getType() == CPPSymbol::otClass || + cs->getType() == CPPSymbol::otEnum || + cs->getType() == CPPSymbol::otUnion || + cs->getType() == CPPSymbol::otStruct)) + fprintf(f, "[non-"); + else + fprintf(f, "["); + fprintf(f, "type: %s]\n", cs->getKey()); +#endif + } +}; + +#define antlrTrace(x) + +#endif http://git-wip-us.apache.org/repos/asf/geode-native/blob/97ded703/contrib/pdxautoserializer/src/impl/CPPParser/CPPInputParser.cpp ---------------------------------------------------------------------- diff --git a/contrib/pdxautoserializer/src/impl/CPPParser/CPPInputParser.cpp b/contrib/pdxautoserializer/src/impl/CPPParser/CPPInputParser.cpp new file mode 100644 index 0000000..be756df --- /dev/null +++ b/contrib/pdxautoserializer/src/impl/CPPParser/CPPInputParser.cpp @@ -0,0 +1,319 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 "../../base_types.hpp" +#include <stdio.h> +#ifndef WIN32 +#include <strings.h> +#endif +#include "CPPInputParser.hpp" +#include "../../impl/Log.hpp" +#include <fstream> +#include <antlr/ANTLRException.hpp> + +// Used to control selected tracing at statement level. +extern int statementTrace; + +int deferredLineCount = 0; + +void process_line_directive(const char* includedFile, + const char* includedLineNo) {} + +ANTLR_USING_NAMESPACE(antlr); + +namespace apache { +namespace geode { +namespace client { +namespace pdx_auto_serializer { +/** The name of this module to be used for logging. */ +static std::string ModuleName = "CPPInputParser"; + +// CPPClassInfo definitions + +std::string CPPClassInfo::getName() const { return m_className; } + +std::string CPPClassInfo::getMethodPrefix() const { return m_method_prefix; } + +void CPPClassInfo::getReferences(ReferenceVector& references) const { + if (m_headerName.length() > 0) { + ReferenceInfo classHeader = {m_headerName, Reference::HEADER}; + + references.push_back(classHeader); + } + + /*ReferenceInfo builtinHeader = { "ASBuiltins.hpp", + Reference::HEADER };*/ + + // references.push_back(builtinHeader); + + /*ReferenceInfo builtinHeaderWriter = { "geode/PdxWriter.hpp", + Reference::HEADER }; + references.push_back(builtinHeaderWriter); + + ReferenceInfo builtinHeaderReader = { "geode/PdxWriter.hpp", + Reference::HEADER }; + references.push_back(builtinHeaderReader);*/ +} + +void CPPClassInfo::getTypeInfo(TypeInfo& classInfo) const { + classInfo.m_kind = TypeKind::VALUE; + classInfo.m_nameOrSize = m_className; + classInfo.m_nameOfArrayElemSize = m_className; + classInfo.m_children = NULL; + classInfo.m_numChildren = 0; + classInfo.m_namespaces = m_NamespacesList; +} + +void CPPClassInfo::getMembers(VariableVector& members) const { + for (VariableVectorIterator memberIterator = m_members.begin(); + memberIterator != m_members.end(); ++memberIterator) { + members.push_back(*memberIterator); + } +} + +void CPPClassInfo::setHeaderName(const std::string headerName) { + m_headerName = headerName; +} + +void CPPClassInfo::setClassName(const std::string className) { + m_className = className; +} + +void CPPClassInfo::setMethodPrefix(const std::string className) { + m_method_prefix = m_method_prefix + className + "::"; +} + +void CPPClassInfo::addMember(const VariableInfo& member) { + m_members.push_back(member); +} + +void CPPClassInfo::addNamespace(std::vector<std::string>& inNamespaceVector) { + for (std::vector<std::string>::iterator itr = inNamespaceVector.begin(); + itr != inNamespaceVector.end(); ++itr) { + m_NamespacesList.push_back(*itr); + } +} + +CPPClassInfo::CPPClassInfo() { m_method_prefix = ""; } + +CPPClassInfo::~CPPClassInfo() {} + +// CPPHeaderParser definitions + +void CPPHeaderParser::beginClassDefinition(TypeSpecifier ts, const char* tag) { + CPPParser::beginClassDefinition(ts, tag); + m_currentClassesVector.push_back(new CPPClassInfo()); + m_currentClassesVector.back()->setHeaderName(getFilename()); + m_currentClassesVector.back()->setClassName(tag); + + if (m_currentClassesVector.size() > 1) { + for (std::vector<CPPClassInfo*>::iterator iter = + m_currentClassesVector.begin(); + iter != m_currentClassesVector.end() - 1; ++iter) { + m_currentClassesVector.back()->setMethodPrefix((*iter)->getName()); + } + } + m_currentClassScope = symbols->getCurrentScopeIndex(); +} + +void CPPHeaderParser::exitNamespaceScope() { m_namespaceVector.pop_back(); } + +void CPPHeaderParser::endClassDefinition() { + CPPParser::endClassDefinition(); + if (m_currentClassesVector.size() == 0) return; + if (m_arraySizeRefMap.size() > 0) { + for (VariableVector::iterator memberIterator = + m_currentClassesVector.back()->m_members.begin(); + memberIterator != m_currentClassesVector.back()->m_members.end(); + memberIterator++) { + StringMap::const_iterator findMember = + m_arraySizeRefMap.find(memberIterator->m_name); + if (findMember != m_arraySizeRefMap.end()) { + memberIterator->m_type.m_kind |= TypeKind::ARRAY; + memberIterator->m_type.m_nameOrSize = findMember->second; + Log::info(ModuleName, + "Using \"" + findMember->second + "\" as size of array \"" + + memberIterator->m_name + '"'); + } + + StringMap::const_iterator findMemberElem = + m_arrayElemSizeRefMap.find(memberIterator->m_name); + if (findMemberElem != m_arrayElemSizeRefMap.end()) { + memberIterator->m_type.m_kind |= TypeKind::ARRAY; + memberIterator->m_type.m_nameOfArrayElemSize = findMemberElem->second; + Log::info(ModuleName, + "Using \"" + findMemberElem->second + + "\" as size of array \"" + memberIterator->m_name + '"'); + } + } + } + /* + * add the namespace informaton here + */ + m_currentClassesVector.back()->addNamespace(m_namespaceVector); + + m_classes[m_currentClassesVector.back()->getName()] = std::make_pair( + static_cast<ClassInfo*>(m_currentClassesVector.back()), m_selectAll); + m_currentClassesVector.pop_back(); + m_currentClassScope = -1; +} + +void CPPHeaderParser::declaratorID(const char* id, QualifiedItem item) { + CPPParser::declaratorID(id, item); + if (item == qiNamespace) { + m_namespaceVector.push_back(id); + } + if (m_currentClassesVector.size() != 0 && m_currentClassScope >= 0 && + m_currentClassScope == symbols->getCurrentScopeIndex()) { + if (item == qiVar) { // check if this is a member field declaration + if (m_currentInclude && m_currentArraySizeRef.length() == 0 && + m_currentArrayElemSizeRef.length() == 0) { + VariableInfo var; + + var.m_type.m_kind = TypeKind::VALUE; + var.m_type.m_modifier = TypeModifier::NONE; + var.m_type.m_children = NULL; + var.m_type.m_numChildren = 0; + var.m_name = id; + if (m_markIdentityField == true) { + var.m_markIdentityField = true; + } else { + var.m_markIdentityField = false; + } + + if (m_markPdxUnreadField == true) { + var.m_markPdxUnreadField = true; + } else { + var.m_markPdxUnreadField = false; + } + + m_currentClassesVector.back()->addMember(var); + } + /*else if ( item == qiType ) { + m_currentClass->addNamespace(id); + }*/ + else if (m_currentArraySizeRef.length() > 0) { + if (NULL == strchr(m_currentArraySizeRef.c_str(), ',')) { + m_arraySizeRefMap[m_currentArraySizeRef] = id; + } else { + m_currentArraySizeRef.erase(m_currentArraySizeRef.begin()); + m_currentArraySizeRef.erase(m_currentArraySizeRef.end() - 1); + char* p = + strtok(const_cast<char*>(m_currentArraySizeRef.c_str()), ","); + while (p) { + m_arraySizeRefMap[p] = id; + p = strtok(NULL, ","); + } + } + } else if (m_currentArrayElemSizeRef.length() > 0) { + // std::cout << "Map Entries --> " << "m_arrayElemSizeRefMap[" << + // m_currentArrayElemSizeRef <<"] = " << id << std::endl; + m_arrayElemSizeRefMap[m_currentArrayElemSizeRef] = id; + } + } + } + // m_currentInclude = true; + m_currentArraySizeRef = ""; + m_currentArrayElemSizeRef = ""; +} + +void CPPHeaderParser::declarationSpecifier(bool td, bool fd, StorageClass sc, + TypeQualifier tq, TypeSpecifier ts, + FunctionSpecifier fs) { + CPPParser::declarationSpecifier(td, fd, sc, tq, ts, fs); + if ((tq & tqCONST) || ((tq & tqGFEXCLUDE) && !(tq & tqGFINCLUDE))) { + m_currentInclude = false; + } else { + m_currentInclude = true; + } + if (tq & tqGFID) { + m_markIdentityField = true; + } else { + m_markIdentityField = false; + } + if (tq & tqGFUNREAD) { + m_markPdxUnreadField = true; + } else { + m_markPdxUnreadField = false; + } +} + +void CPPHeaderParser::gfArraySize(const char* id) { + m_currentArraySizeRef = id; +} + +void CPPHeaderParser::gfArrayElemSize(const char* id) { + m_currentArrayElemSizeRef = id; +} + +CPPHeaderParser::CPPHeaderParser(CPPLexer& lexer, ASClassFlagMap& classes, + const bool selectAll) + : CPPParser(lexer), + m_classes(classes), + m_selectAll(selectAll), + m_currentClassesVector(std::vector<CPPClassInfo*>()), + m_currentClassScope(-1), + m_currentInclude(true), + m_markIdentityField(false), + m_markPdxUnreadField(false) {} + +// CPPInputParser definitions + +void CPPInputParser::getOptions(OptionMap& options) const {} + +void CPPInputParser::init(PropertyMap& properties) {} + +void CPPInputParser::selectClasses(const StringVector& resources, + const StringVector& classNames) { +#ifndef _DEBUG + statementTrace = 0; +#endif + statementTrace = 0; + bool selectAll = (classNames.size() == 0); + for (StringVectorIterator resourceIterator = resources.begin(); + resourceIterator != resources.end(); ++resourceIterator) { + try { + std::ifstream istream(resourceIterator->c_str()); + CPPLexer lexer(istream); + CPPHeaderParser parser(lexer, m_classes, selectAll); + parser.init(); + parser.setFilename(*resourceIterator); + parser.translation_unit(); + } catch (const ANTLRException& ex) { + throw std::invalid_argument(ex.getMessage()); + } + } + + for (StringVectorIterator classIterator = classNames.begin(); + classIterator != classNames.end(); ++classIterator) { + if (!select(*classIterator)) { + std::string warnMsg = + "Could not load class '" + *classIterator + "'; skipping it."; + Log::warn(ModuleName, warnMsg); + } + } +} + +CPPInputParser::CPPInputParser() {} + +InputParser* CPPInputParser::create() { return new CPPInputParser(); } + +CPPInputParser::~CPPInputParser() {} +} // namespace pdx_auto_serializer +} // namespace client +} // namespace geode +} // namespace apache http://git-wip-us.apache.org/repos/asf/geode-native/blob/97ded703/contrib/pdxautoserializer/src/impl/CPPParser/CPPInputParser.hpp ---------------------------------------------------------------------- diff --git a/contrib/pdxautoserializer/src/impl/CPPParser/CPPInputParser.hpp b/contrib/pdxautoserializer/src/impl/CPPParser/CPPInputParser.hpp new file mode 100644 index 0000000..030ff07 --- /dev/null +++ b/contrib/pdxautoserializer/src/impl/CPPParser/CPPInputParser.hpp @@ -0,0 +1,189 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +#ifndef _GFAS_CPPINPUTPARSER_HPP_ +#define _GFAS_CPPINPUTPARSER_HPP_ + +#include "../../InputParser.hpp" +#include "CPPLexer.hpp" +#include "CPPParser.hpp" + +namespace apache { +namespace geode { +namespace client { +namespace pdx_auto_serializer { +class CPPHeaderParser; + +/** + * This class implements <code>ClassInfo</code> interface for C++. + */ +class CPPClassInfo : public ClassInfo { + public: + // ClassInfo implementations + + virtual std::string getName() const; + + virtual void getReferences(ReferenceVector& references) const; + + virtual void getTypeInfo(TypeInfo& classType) const; + + virtual void getMembers(VariableVector& members) const; + + // Setter methods for various fields. + + void setHeaderName(const std::string headerName); + + void setClassName(const std::string className); + + void addMember(const VariableInfo& member); + + void addNamespace(std::vector<std::string>& inNamespaceVector); + + /** Default constructor. */ + CPPClassInfo(); + + /** Virtual destructor. */ + virtual ~CPPClassInfo(); + + void setMethodPrefix(const std::string className); + virtual std::string getMethodPrefix() const; + + private: + /** The name of the header file containing this class. */ + std::string m_headerName; + + /** The name of the class. */ + std::string m_className; + + /** Vector of the members of the class. */ + VariableVector m_members; + + std::vector<std::string> m_NamespacesList; + + std::string m_method_prefix; + + friend class CPPHeaderParser; + friend class CPPInputParser; +}; + +/** This class parses the classes from header files. */ +class CPPHeaderParser : public CPPParser { + public: + /** + * Construct the object using the given <code>CPPLexer</code>. + * + * @param lexer The <code>CPPLexer</code> used as the tokenizer. + * @param classes The global classes map to be populated. + * @param selectAll True to mark all the classes as selected. + */ + CPPHeaderParser(CPPLexer& lexer, ASClassFlagMap& classes, + const bool selectAll); + + // CPPParser overrides + + virtual void beginClassDefinition(TypeSpecifier ts, const char* tag); + + virtual void exitNamespaceScope(); + + virtual void endClassDefinition(); + + virtual void declaratorID(const char* id, QualifiedItem item); + + virtual void declarationSpecifier(bool td, bool fd, StorageClass sc, + TypeQualifier tq, TypeSpecifier ts, + FunctionSpecifier fs); + + virtual void gfArraySize(const char* id); + + virtual void gfArrayElemSize(const char* id); + + private: + /** Accumulates the classes as the classes are parsed. */ + ASClassFlagMap& m_classes; + + /** True to mark all the classes as selected. */ + const bool m_selectAll; + + /** Stores the current class being parsed. */ + std::vector<CPPClassInfo*> m_currentClassesVector; + + /** The scope of the current class. */ + int m_currentClassScope; + + /** True when the current field has to be excluded. */ + bool m_currentInclude; + + /** True when the current fiels is marked as identify field */ + bool m_markIdentityField; + + bool m_markPdxUnreadField; + + /** + * If the current field is an array size specification of field 'x', + * then this stores the name of 'x'. + */ + std::string m_currentArraySizeRef; + + std::string m_currentArrayElemSizeRef; + + /** + * The map of all fields that are array sizes for other fields. + */ + StringMap m_arraySizeRefMap; + StringMap m_arrayElemSizeRefMap; + + std::vector<std::string> m_namespaceVector; +}; + +/** + * This class implements <code>InputParser</code> interface for C++. + */ +class CPPInputParser : public InputParser { + public: + // InputParser implementations + + virtual void getOptions(OptionMap& options) const; + + virtual void init(PropertyMap& properties); + + virtual void selectClasses(const StringVector& resources, + const StringVector& classNames); + + /** + * Defines the static function returning an <code>InputParser</code> + * object, which is registered with <code>InputParserFactory</code>. + * + * @return The <code>InputParser</code> object. + */ + static InputParser* create(); + + /** @brief Virtual destructor. */ + virtual ~CPPInputParser(); + + private: + /** + * Default constructor -- this is not exposed to public which should use + * the {@link CPPInputParser::create} function. + */ + CPPInputParser(); +}; +} // namespace pdx_auto_serializer +} // namespace client +} // namespace geode +} // namespace apache + +#endif // _GFAS_CPPINPUTPARSER_HPP_
