open_toontown_panda3d/direct/src/dcparser/dcSwitch.h

148 lines
4.5 KiB
C++

// Filename: dcSwitch.h
// Created by: drose (23Jun04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef DCSWITCH_H
#define DCSWITCH_H
#include "dcbase.h"
#include "dcDeclaration.h"
#include "dcPackerInterface.h"
class DCParameter;
class HashGenerator;
class DCField;
////////////////////////////////////////////////////////////////////
// Class : DCSwitch
// Description : This represents a switch statement, which can appear
// inside a class body and represents two or more
// alternative unpacking schemes based on the first
// field read.
////////////////////////////////////////////////////////////////////
class EXPCL_DIRECT DCSwitch : public DCDeclaration {
public:
DCSwitch(const string &name, DCField *key_parameter);
virtual ~DCSwitch();
PUBLISHED:
virtual DCSwitch *as_switch();
virtual const DCSwitch *as_switch() const;
const string &get_name() const;
DCField *get_key_parameter() const;
int get_num_cases() const;
int get_case_by_value(const string &case_value) const;
DCPackerInterface *get_case(int n) const;
DCPackerInterface *get_default_case() const;
string get_value(int case_index) const;
int get_num_fields(int case_index) const;
DCField *get_field(int case_index, int n) const;
DCField *get_field_by_name(int case_index, const string &name) const;
public:
bool is_field_valid() const;
int add_case(const string &value);
void add_invalid_case();
bool add_default();
bool add_field(DCField *field);
void add_break();
const DCPackerInterface *apply_switch(const char *value_data, size_t length) const;
virtual void output(ostream &out, bool brief) const;
virtual void write(ostream &out, bool brief, int indent_level) const;
void output_instance(ostream &out, bool brief, const string &prename,
const string &name, const string &postname) const;
void write_instance(ostream &out, bool brief, int indent_level,
const string &prename, const string &name,
const string &postname) const;
virtual void generate_hash(HashGenerator &hashgen) const;
virtual bool pack_default_value(DCPackData &pack_data, bool &pack_error) const;
bool do_check_match_switch(const DCSwitch *other) const;
public:
typedef pvector<DCField *> Fields;
typedef pmap<string, DCField *> FieldsByName;
class SwitchFields : public DCPackerInterface {
public:
SwitchFields(const string &name);
~SwitchFields();
virtual DCPackerInterface *get_nested_field(int n) const;
bool add_field(DCField *field);
bool do_check_match_switch_case(const SwitchFields *other) const;
void output(ostream &out, bool brief) const;
void write(ostream &out, bool brief, int indent_level) const;
protected:
virtual bool do_check_match(const DCPackerInterface *other) const;
public:
Fields _fields;
FieldsByName _fields_by_name;
bool _has_default_value;
};
class SwitchCase {
public:
SwitchCase(const string &value, SwitchFields *fields);
~SwitchCase();
bool do_check_match_switch_case(const SwitchCase *other) const;
public:
string _value;
SwitchFields *_fields;
};
private:
SwitchFields *start_new_case();
private:
string _name;
DCField *_key_parameter;
typedef pvector<SwitchCase *> Cases;
Cases _cases;
SwitchFields *_default_case;
// All SwitchFields created and used by the DCSwitch object are also
// stored here; this is the vector that "owns" the pointers.
typedef pvector<SwitchFields *> CaseFields;
CaseFields _case_fields;
// All nested DCField objects that have been added to one or more of
// the above SwitchFields are also recorded here; this is the vector
// that "owns" these pointers.
Fields _nested_fields;
// These are the SwitchFields that are currently being filled up
// during this stage of the parser. There might be more than one at
// a time, if we have multiple cases being introduced in the middle
// of a series of fields (without a break statement intervening).
CaseFields _current_fields;
bool _fields_added;
// This map indexes into the _cases vector, above.
typedef pmap<string, int> CasesByValue;
CasesByValue _cases_by_value;
};
#endif