1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stddef.h>
18#include <stdlib.h>
19
20#include "value.h"
21
22#define NULL_VALUE_TYPE           0
23#define INT_VALUE_TYPE            1
24#define FLOAT_VALUE_TYPE          2
25#define STRING_VALUE_TYPE         3
26#define BUFFER_VALUE_TYPE         4
27#define MUTABLE_BUFFER_VALUE_TYPE 5
28#define INT_ARRAY_VALUE_TYPE      6
29#define FLOAT_ARRAY_VALUE_TYPE    7
30
31// Templated versions //////////////////////////////////////////////////////////////////////////////
32template<typename POD, int TYPEID>
33POD GetPODValue(Value value) {
34  return value.type == TYPEID ? *reinterpret_cast<POD*>(value.value) : POD();
35}
36
37template<typename PTR, int TYPEID>
38PTR GetPtrValue(Value value) {
39  return value.type == TYPEID ? reinterpret_cast<PTR>(value.value) : NULL;
40}
41
42template<typename POD, int TYPEID>
43Value MakePODValue(POD value) {
44  Value result;
45  result.type = TYPEID;
46  result.value = malloc(sizeof(POD));
47  result.count = 1;
48  *reinterpret_cast<POD*>(result.value) = value;
49  return result;
50}
51
52template<typename BASE, int TYPEID>
53Value MakePtrValue(const BASE* values, int count) {
54  Value result;
55  result.type = TYPEID;
56  result.value = malloc(sizeof(BASE) * count);
57  memcpy(result.value, values, sizeof(BASE) * count);
58  result.count = count;
59  return result;
60}
61
62template<typename POD, int TYPEID>
63int SetPODValue(Value* value, POD new_value) {
64  if (value->type == NULL_VALUE_TYPE) {
65    value->type = TYPEID;
66    value->value = malloc(sizeof(POD));
67    value->count = 1;
68  }
69  if (value->type == TYPEID) {
70    *reinterpret_cast<POD*>(value->value) = new_value;
71    return 1;
72  }
73  return 0;
74}
75
76template<typename BASE, int TYPEID>
77int SetPtrValue(Value* value, const BASE* new_values, int count) {
78  if (value->type == NULL_VALUE_TYPE) {
79    value->type = TYPEID;
80    value->value = malloc(sizeof(BASE) * count);
81    value->count = count;
82  }
83  if (value->type == TYPEID && value->count == count) {
84    memcpy(value->value, new_values, sizeof(BASE) * count);
85    return 1;
86  }
87  return 0;
88}
89
90// C Wrappers //////////////////////////////////////////////////////////////////////////////////////
91int GetIntValue(Value value) {
92  return GetPODValue<int, INT_VALUE_TYPE>(value);
93}
94
95float GetFloatValue(Value value) {
96  return GetPODValue<float, FLOAT_VALUE_TYPE>(value);
97}
98
99const char* GetStringValue(Value value) {
100  return GetPtrValue<const char*, STRING_VALUE_TYPE>(value);
101}
102
103const char* GetBufferValue(Value value) {
104  return (value.type == BUFFER_VALUE_TYPE || value.type == MUTABLE_BUFFER_VALUE_TYPE)
105    ? (const char*)value.value
106    : NULL;
107}
108
109char* GetMutableBufferValue(Value value) {
110  return GetPtrValue<char*, MUTABLE_BUFFER_VALUE_TYPE>(value);
111}
112
113int* GetIntArrayValue(Value value) {
114  return GetPtrValue<int*, INT_ARRAY_VALUE_TYPE>(value);
115}
116
117float* GetFloatArrayValue(Value value) {
118  return GetPtrValue<float*, FLOAT_ARRAY_VALUE_TYPE>(value);
119}
120
121int ValueIsNull(Value value) {
122  return value.type == NULL_VALUE_TYPE;
123}
124
125int ValueIsInt(Value value) {
126  return value.type == INT_VALUE_TYPE;
127}
128
129int ValueIsFloat(Value value) {
130  return value.type == FLOAT_VALUE_TYPE;
131}
132
133int ValueIsString(Value value) {
134  return value.type == STRING_VALUE_TYPE;
135}
136
137int ValueIsBuffer(Value value) {
138  return value.type == BUFFER_VALUE_TYPE || value.type == MUTABLE_BUFFER_VALUE_TYPE;
139}
140
141int ValueIsIntArray(Value value) {
142  return value.type == INT_ARRAY_VALUE_TYPE;
143}
144
145int ValueIsFloatArray(Value value) {
146  return value.type == FLOAT_ARRAY_VALUE_TYPE;
147}
148
149Value MakeNullValue() {
150  Value result;
151  result.type = NULL_VALUE_TYPE;
152  result.value = NULL;
153  result.count = 0;
154  return result;
155}
156
157Value MakeIntValue(int value) {
158  return MakePODValue<int, INT_VALUE_TYPE>(value);
159}
160
161Value MakeFloatValue(float value) {
162  return MakePODValue<float, FLOAT_VALUE_TYPE>(value);
163}
164
165Value MakeStringValue(const char* value) {
166  return MakePtrValue<char, STRING_VALUE_TYPE>(value, strlen(value) + 1);
167}
168
169Value MakeBufferValue(const char* buffer, int size) {
170  return MakePtrValue<char, BUFFER_VALUE_TYPE>(buffer, size);
171}
172
173Value MakeBufferValueNoCopy(const char* buffer, int size) {
174  Value result;
175  result.type = BUFFER_VALUE_TYPE;
176  result.value = (void*)buffer;
177  result.count = size;
178  return result;
179}
180
181Value MakeMutableBufferValue(const char* buffer, int size) {
182  return MakePtrValue<const char, MUTABLE_BUFFER_VALUE_TYPE>(buffer, size);
183}
184
185Value MakeMutableBufferValueNoCopy(char* buffer, int size) {
186  Value result;
187  result.type = MUTABLE_BUFFER_VALUE_TYPE;
188  result.value = (void*)buffer;
189  result.count = size;
190  return result;
191}
192
193Value MakeIntArrayValue(const int* values, int count) {
194  return MakePtrValue<int, INT_ARRAY_VALUE_TYPE>(values, count);
195}
196
197Value MakeFloatArrayValue(const float* values, int count) {
198  return MakePtrValue<float, FLOAT_ARRAY_VALUE_TYPE>(values, count);
199}
200
201int SetIntValue(Value* value, int new_value) {
202  return SetPODValue<int, INT_VALUE_TYPE>(value, new_value);
203}
204
205int SetFloatValue(Value* value, float new_value) {
206  return SetPODValue<float, FLOAT_VALUE_TYPE>(value, new_value);
207}
208
209int SetStringValue(Value* value, const char* new_value) {
210  return SetPtrValue<char, STRING_VALUE_TYPE>(value, new_value, strlen(new_value) + 1);
211}
212
213int SetMutableBufferValue(Value* value, const char* new_data, int size) {
214  return SetPtrValue<char, MUTABLE_BUFFER_VALUE_TYPE>(value, new_data, size);
215}
216
217int SetIntArrayValue(Value* value, const int* new_values, int count) {
218  return SetPtrValue<int, INT_ARRAY_VALUE_TYPE>(value, new_values, count);
219}
220
221int SetFloatArrayValue(Value* value, const float* new_values, int count) {
222  return SetPtrValue<float, FLOAT_ARRAY_VALUE_TYPE>(value, new_values, count);
223}
224
225int GetValueCount(Value value) {
226  return value.count;
227}
228
229void ReleaseValue(Value* value) {
230  if (value && value->value) {
231    free(value->value);
232    value->value = NULL;
233    value->type = NULL_VALUE_TYPE;
234  }
235}
236
237