valaarray.vala 5.99 KB
Newer Older
1
/* valaarray.vala
2
 *
3
 * Copyright (C) 2006-2007  Raffaele Sandrini, Jürg Billeter
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.

 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 *
 * Author:
 * 	Raffaele Sandrini <rasa@gmx.ch>
21
 * 	Jürg Billeter <j@bitron.ch>
22
23
24
25
26
27
28
29
30
31
32
33
 */

using GLib;

/**
 * Represents an array type i.e. everything with direct accessable elements.
 */
public class Vala.Array : DataType {

	/**
	 * DataType of which this is an array of.
	 */
34
35
36
37
38
39
	public DataType element_type { get; set construct; }
	
	/**
	 * TypeParameter of which this is an array of.
	 */
	public TypeParameter element_type_parameter { get; set construct; }
40
	
41
42
43
44
45
	/**
	 * The rank of this array.
	 */
	public int rank { get; set construct; }
	
46
47
	private string cname;
	
48
49
50
51
	private ArrayLengthField length_field;
	
	private ArrayResizeMethod resize_method;
	
52
	public Array (DataType! _element_type, int _rank, SourceReference _source_reference) {
53
54
		rank = _rank;
		element_type = _element_type;
55
56
57
		source_reference = _source_reference;
	}
	
58
	public Array.with_type_parameter (TypeParameter! _element_type_parameter, int _rank, SourceReference _source_reference) {
59
60
61
		rank = _rank;
		element_type_parameter = _element_type_parameter;
		source_reference = _source_reference;
62
63
	}

64
	construct {
65
		/* FIXME: this implementation reveals compiler bugs 
66
67
68
69
70
71
72
73
74
75
		string commas = "";
		int i = rank - 1;
		
		while (i > 0) {
			string += ",";
			i--;
		}
			
		name = "%s[%s]".printf (element_type.name, commas); */
		
76
77
78
79
		if (rank < 1) {
			Report.error (null, "internal: attempt to create an array with rank smaller than 1");
		}
		
80
		int i = rank - 1;
81
82
83
84
85
		if (element_type != null) {
			name = "%s[".printf (element_type.name);
		} else {
			name = "%s[".printf (element_type_parameter.name);
		}
86
87
88
89
90
		while (i > 0) {
			name = "%s,".printf (name);
			i--;
		}
		name = "%s]".printf (name);
91
92
93
94
95
96
97
	}
	
	/**
	 * Returns the name of this data type as it is used in C code.
	 *
	 * @return the name to be used in C code
	 */
98
	public override string get_cname (bool const_type = false) {
99
		if (cname == null) {
100
101
102
103
104
105
			if (element_type != null) {
				if (element_type.is_reference_type ()) {
					cname = "%s*".printf (element_type.get_cname ());
				} else {
					cname = element_type.get_cname ();
				}
106
			} else {
107
				cname = "gpointer";
108
			}
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
		}
		
		return cname;
	}
	
	/**
	 * Checks whether this data type has value or reference type semantics.
	 *
	 * @return true if this data type has reference type semantics
	 */
	public override bool is_reference_type () {
		return true;
	}
	
	/**
	 * Returns the C name of this data type in upper case. Words are
	 * separated by underscores. The upper case C name of the namespace is
	 * prefix of the result.
	 *
	 * @param infix a string to be placed between namespace and data type
	 *              name or null
	 * @return      the upper case name to be used in C code
	 */
132
	public override string get_upper_case_cname (string infix) {
133
134
135
136
137
138
139
140
141
142
143
144
		return null;
	}
	
	/**
	 * Returns the C name of this data type in lower case. Words are
	 * separated by underscores. The lower case C name of the namespace is
	 * prefix of the result.
	 *
	 * @param infix a string to be placed between namespace and data type
	 *              name or null
	 * @return      the lower case name to be used in C code
	 */
145
	public override string get_lower_case_cname (string infix) {
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
		return null;
	}
	
	/**
	 * Returns the C function name that frees instances of this data type.
	 * This is only valid for data types with reference type semantics that
	 * do not support reference counting. The specified C function must
	 * accept one argument pointing to the instance to be freed.
	 *
	 * @return the name of the C function or null if this data type is not a
	 *         reference type or if it supports reference counting
	 */
	public override string get_free_function () {
		return "g_free";
	}
	
	/**
	 * Returns a list of C header filenames users of this data type must
	 * include.
	 *
	 * @return list of C header filenames for this data type
	 */
168
	public override List<weak string> get_cheader_filenames () {
169
170
171
172
173
		if (element_type != null) {
			return element_type.get_cheader_filenames ();
		} else {
			return null;
		}
174
	}
175
176
177
178
179
180
181
182
183
184
185
186
	
	public override string get_marshaller_type_name () {
		return "POINTER";
	}

	public override string get_get_value_function () {
		return "g_value_get_pointer";
	}
	
	public override string get_set_value_function () {
		return "g_value_set_pointer";
	}
187
188

	public ArrayLengthField get_length_field () {
189
190
191
192
193
194
195
196
197
198
		if (length_field == null) {
			length_field = new ArrayLengthField (source_reference);

			length_field.access = MemberAccessibility.PUBLIC;

			var root_symbol = source_reference.file.context.root;
			length_field.type_reference = new TypeReference ();
			length_field.type_reference.data_type = (DataType) root_symbol.scope.lookup ("int");

		}
199
200
201
202
		return length_field;
	}

	public ArrayResizeMethod get_resize_method () {
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
		if (resize_method == null) {
			resize_method = new ArrayResizeMethod (source_reference);

			resize_method.return_type = new TypeReference ();
			resize_method.access = MemberAccessibility.PUBLIC;

			resize_method.set_cname ("g_renew");
			
			var root_symbol = source_reference.file.context.root;
			var int_type = new TypeReference ();
			int_type.data_type = (DataType) root_symbol.scope.lookup ("int");

			resize_method.add_parameter (new FormalParameter ("length", int_type));
			
			resize_method.returns_modified_pointer = true;
		}
219
220
		return resize_method;
	}
221
}