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 //////////////////////////////////////////////////////////////////////////////
32 template<typename POD, int TYPEID>
GetPODValue(Value value)33 POD GetPODValue(Value value) {
34   return value.type == TYPEID ? *reinterpret_cast<POD*>(value.value) : POD();
35 }
36 
37 template<typename PTR, int TYPEID>
GetPtrValue(Value value)38 PTR GetPtrValue(Value value) {
39   return value.type == TYPEID ? reinterpret_cast<PTR>(value.value) : NULL;
40 }
41 
42 template<typename POD, int TYPEID>
MakePODValue(POD value)43 Value 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 
52 template<typename BASE, int TYPEID>
MakePtrValue(const BASE * values,int count)53 Value 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 
62 template<typename POD, int TYPEID>
SetPODValue(Value * value,POD new_value)63 int 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 
76 template<typename BASE, int TYPEID>
SetPtrValue(Value * value,const BASE * new_values,int count)77 int 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 //////////////////////////////////////////////////////////////////////////////////////
GetIntValue(Value value)91 int GetIntValue(Value value) {
92   return GetPODValue<int, INT_VALUE_TYPE>(value);
93 }
94 
GetFloatValue(Value value)95 float GetFloatValue(Value value) {
96   return GetPODValue<float, FLOAT_VALUE_TYPE>(value);
97 }
98 
GetStringValue(Value value)99 const char* GetStringValue(Value value) {
100   return GetPtrValue<const char*, STRING_VALUE_TYPE>(value);
101 }
102 
GetBufferValue(Value value)103 const 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 
GetMutableBufferValue(Value value)109 char* GetMutableBufferValue(Value value) {
110   return GetPtrValue<char*, MUTABLE_BUFFER_VALUE_TYPE>(value);
111 }
112 
GetIntArrayValue(Value value)113 int* GetIntArrayValue(Value value) {
114   return GetPtrValue<int*, INT_ARRAY_VALUE_TYPE>(value);
115 }
116 
GetFloatArrayValue(Value value)117 float* GetFloatArrayValue(Value value) {
118   return GetPtrValue<float*, FLOAT_ARRAY_VALUE_TYPE>(value);
119 }
120 
ValueIsNull(Value value)121 int ValueIsNull(Value value) {
122   return value.type == NULL_VALUE_TYPE;
123 }
124 
ValueIsInt(Value value)125 int ValueIsInt(Value value) {
126   return value.type == INT_VALUE_TYPE;
127 }
128 
ValueIsFloat(Value value)129 int ValueIsFloat(Value value) {
130   return value.type == FLOAT_VALUE_TYPE;
131 }
132 
ValueIsString(Value value)133 int ValueIsString(Value value) {
134   return value.type == STRING_VALUE_TYPE;
135 }
136 
ValueIsBuffer(Value value)137 int ValueIsBuffer(Value value) {
138   return value.type == BUFFER_VALUE_TYPE || value.type == MUTABLE_BUFFER_VALUE_TYPE;
139 }
140 
ValueIsIntArray(Value value)141 int ValueIsIntArray(Value value) {
142   return value.type == INT_ARRAY_VALUE_TYPE;
143 }
144 
ValueIsFloatArray(Value value)145 int ValueIsFloatArray(Value value) {
146   return value.type == FLOAT_ARRAY_VALUE_TYPE;
147 }
148 
MakeNullValue()149 Value MakeNullValue() {
150   Value result;
151   result.type = NULL_VALUE_TYPE;
152   result.value = NULL;
153   result.count = 0;
154   return result;
155 }
156 
MakeIntValue(int value)157 Value MakeIntValue(int value) {
158   return MakePODValue<int, INT_VALUE_TYPE>(value);
159 }
160 
MakeFloatValue(float value)161 Value MakeFloatValue(float value) {
162   return MakePODValue<float, FLOAT_VALUE_TYPE>(value);
163 }
164 
MakeStringValue(const char * value)165 Value MakeStringValue(const char* value) {
166   return MakePtrValue<char, STRING_VALUE_TYPE>(value, strlen(value) + 1);
167 }
168 
MakeBufferValue(const char * buffer,int size)169 Value MakeBufferValue(const char* buffer, int size) {
170   return MakePtrValue<char, BUFFER_VALUE_TYPE>(buffer, size);
171 }
172 
MakeBufferValueNoCopy(const char * buffer,int size)173 Value 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 
MakeMutableBufferValue(const char * buffer,int size)181 Value MakeMutableBufferValue(const char* buffer, int size) {
182   return MakePtrValue<const char, MUTABLE_BUFFER_VALUE_TYPE>(buffer, size);
183 }
184 
MakeMutableBufferValueNoCopy(char * buffer,int size)185 Value 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 
MakeIntArrayValue(const int * values,int count)193 Value MakeIntArrayValue(const int* values, int count) {
194   return MakePtrValue<int, INT_ARRAY_VALUE_TYPE>(values, count);
195 }
196 
MakeFloatArrayValue(const float * values,int count)197 Value MakeFloatArrayValue(const float* values, int count) {
198   return MakePtrValue<float, FLOAT_ARRAY_VALUE_TYPE>(values, count);
199 }
200 
SetIntValue(Value * value,int new_value)201 int SetIntValue(Value* value, int new_value) {
202   return SetPODValue<int, INT_VALUE_TYPE>(value, new_value);
203 }
204 
SetFloatValue(Value * value,float new_value)205 int SetFloatValue(Value* value, float new_value) {
206   return SetPODValue<float, FLOAT_VALUE_TYPE>(value, new_value);
207 }
208 
SetStringValue(Value * value,const char * new_value)209 int SetStringValue(Value* value, const char* new_value) {
210   return SetPtrValue<char, STRING_VALUE_TYPE>(value, new_value, strlen(new_value) + 1);
211 }
212 
SetMutableBufferValue(Value * value,const char * new_data,int size)213 int SetMutableBufferValue(Value* value, const char* new_data, int size) {
214   return SetPtrValue<char, MUTABLE_BUFFER_VALUE_TYPE>(value, new_data, size);
215 }
216 
SetIntArrayValue(Value * value,const int * new_values,int count)217 int SetIntArrayValue(Value* value, const int* new_values, int count) {
218   return SetPtrValue<int, INT_ARRAY_VALUE_TYPE>(value, new_values, count);
219 }
220 
SetFloatArrayValue(Value * value,const float * new_values,int count)221 int SetFloatArrayValue(Value* value, const float* new_values, int count) {
222   return SetPtrValue<float, FLOAT_ARRAY_VALUE_TYPE>(value, new_values, count);
223 }
224 
GetValueCount(Value value)225 int GetValueCount(Value value) {
226   return value.count;
227 }
228 
ReleaseValue(Value * value)229 void 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