1 // Filename: DistributedType.h
2 #pragma once
3 #include <stdint.h>
4 #include <string> // std::string
5 #include <vector> // std::vector
6 
7 namespace dclass   // open namespace dclass
8 {
9 
10 
11 #ifdef DCLASS_32BIT_SIZETAG
12 typedef uint32_t sizetag_t;
13 #else
14 typedef uint16_t sizetag_t;
15 #endif
16 
17 // Forward declaration
18 class ArrayType;
19 class Method;
20 class NumericType;
21 class Struct;
22 class HashGenerator;
23 
24 
25 // The Type enum are numeric constants representing the layout of the DistributedType
26 enum Type {
27     /* Numeric Types */
28     T_INT8, T_INT16, T_INT32, T_INT64,
29     T_UINT8, T_UINT16, T_UINT32, T_UINT64,
30     T_CHAR, // equivalent to uint8, except that it should be printed as a string
31     T_FLOAT32, T_FLOAT64,
32 
33     /* Array Types */
34     T_STRING,      // a human-printable string with fixed length
35     T_VARSTRING,   // a human-printable string with variable length
36     T_BLOB,        // any binary data stored as a string, fixed length
37     T_VARBLOB,     // any binary data stored as a varstring, variable length
38     T_ARRAY,       // any array with fixed byte-length (fixed array-size and element-length)
39     T_VARARRAY,    // any array with variable array-size or variable length elements
40 
41     /* Complex Types */
42     T_STRUCT,
43     T_METHOD,
44 
45     // New additions should be added at the end to prevent the file hash from changing.
46 
47     T_INVALID
48 };
49 
50 // A DistributedType is a shared type with a defined layout of data.
51 class DistributedType
52 {
53   protected:
54     inline DistributedType();
55 
56   public:
57     static DistributedType* invalid;
58     virtual ~DistributedType();
59 
60     // get_type returns the type's fundamental type as an integer constant.
61     inline Type get_type() const;
62 
63     // has_fixed_size returns true if the DistributedType has a fixed size in bytes.
64     inline bool has_fixed_size() const;
65     // get_size returns the size of the DistributedType in bytes or 0 if it is variable.
66     inline sizetag_t get_size() const;
67 
68     // has_alias returns true if this type was defined the an aliased name.
69     inline bool has_alias() const;
70     // get_alias returns the name used to define the type, or the empty string.
71     inline const std::string& get_alias() const;
72     // set_alias gives this type the alternate name <alias>.
73     inline void set_alias(const std::string& alias);
74 
75     // as_numeric returns this as a NumericType if it is numeric, or nullptr otherwise.
76     virtual NumericType* as_numeric();
77     virtual const NumericType* as_numeric() const;
78 
79     // as_array returns this as an ArrayType if it is an array, or nullptr otherwise.
80     virtual ArrayType* as_array();
81     virtual const ArrayType* as_array() const;
82 
83     // as_struct returns this as a Struct if it is a struct, or nullptr otherwise.
84     virtual Struct* as_struct();
85     virtual const Struct* as_struct() const;
86 
87     // as_method returns this as a Method if it is a method, or nullptr otherwise.
88     virtual Method* as_method();
89     virtual const Method* as_method() const;
90 
91     // has_range returns true if the type has any constraints, or false otherwise.
92     virtual bool has_range() const;
93 
94     // within_range returns true if the field information provided fits the constraints of the given type.
95     virtual bool within_range(const std::vector<uint8_t>* data, uint64_t length) const;
96 
97     // generate_hash accumulates the properties of this file into the hash.
98     virtual void generate_hash(HashGenerator& hashgen) const;
99 
100   protected:
101     Type m_type;
102     sizetag_t m_size;
103     std::string m_alias;
104 };
105 
106 
107 } // close namespace dclass
108 #include "DistributedType.ipp"
109