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 #include <string.h>
20 
21 #include "value.h"
22 
23 #define NULL_VALUE_TYPE           0
24 #define INT_VALUE_TYPE            1
25 #define FLOAT_VALUE_TYPE          2
26 #define STRING_VALUE_TYPE         3
27 #define BUFFER_VALUE_TYPE         4
28 #define MUTABLE_BUFFER_VALUE_TYPE 5
29 #define INT_ARRAY_VALUE_TYPE      6
30 #define FLOAT_ARRAY_VALUE_TYPE    7
31 
32 // Templated versions //////////////////////////////////////////////////////////////////////////////
33 template<typename POD, int TYPEID>
GetPODValue(Value value)34 POD GetPODValue(Value value) {
35   return value.type == TYPEID ? *reinterpret_cast<POD*>(value.value) : POD();
36 }
37 
38 template<typename PTR, int TYPEID>
GetPtrValue(Value value)39 PTR GetPtrValue(Value value) {
40   return value.type == TYPEID ? reinterpret_cast<PTR>(value.value) : NULL;
41 }
42 
43 template<typename POD, int TYPEID>
MakePODValue(POD value)44 Value MakePODValue(POD value) {
45   Value result;
46   result.type = TYPEID;
47   result.value = malloc(sizeof(POD));
48   result.count = 1;
49   *reinterpret_cast<POD*>(result.value) = value;
50   return result;
51 }
52 
53 template<typename BASE, int TYPEID>
MakePtrValue(const BASE * values,int count)54 Value MakePtrValue(const BASE* values, int count) {
55   Value result;
56   result.type = TYPEID;
57   result.value = malloc(sizeof(BASE) * count);
58   memcpy(result.value, values, sizeof(BASE) * count);
59   result.count = count;
60   return result;
61 }
62 
63 template<typename POD, int TYPEID>
SetPODValue(Value * value,POD new_value)64 int SetPODValue(Value* value, POD new_value) {
65   if (value->type == NULL_VALUE_TYPE) {
66     value->type = TYPEID;
67     value->value = malloc(sizeof(POD));
68     value->count = 1;
69   }
70   if (value->type == TYPEID) {
71     *reinterpret_cast<POD*>(value->value) = new_value;
72     return 1;
73   }
74   return 0;
75 }
76 
77 template<typename BASE, int TYPEID>
SetPtrValue(Value * value,const BASE * new_values,int count)78 int SetPtrValue(Value* value, const BASE* new_values, int count) {
79   if (value->type == NULL_VALUE_TYPE) {
80     value->type = TYPEID;
81     value->value = malloc(sizeof(BASE) * count);
82     value->count = count;
83   }
84   if (value->type == TYPEID && value->count == count) {
85     memcpy(value->value, new_values, sizeof(BASE) * count);
86     return 1;
87   }
88   return 0;
89 }
90 
91 // C Wrappers //////////////////////////////////////////////////////////////////////////////////////
GetIntValue(Value value)92 int GetIntValue(Value value) {
93   return GetPODValue<int, INT_VALUE_TYPE>(value);
94 }
95 
GetFloatValue(Value value)96 float GetFloatValue(Value value) {
97   return GetPODValue<float, FLOAT_VALUE_TYPE>(value);
98 }
99 
GetStringValue(Value value)100 const char* GetStringValue(Value value) {
101   return GetPtrValue<const char*, STRING_VALUE_TYPE>(value);
102 }
103 
GetBufferValue(Value value)104 const char* GetBufferValue(Value value) {
105   return (value.type == BUFFER_VALUE_TYPE || value.type == MUTABLE_BUFFER_VALUE_TYPE)
106     ? (const char*)value.value
107     : NULL;
108 }
109 
GetMutableBufferValue(Value value)110 char* GetMutableBufferValue(Value value) {
111   return GetPtrValue<char*, MUTABLE_BUFFER_VALUE_TYPE>(value);
112 }
113 
GetIntArrayValue(Value value)114 int* GetIntArrayValue(Value value) {
115   return GetPtrValue<int*, INT_ARRAY_VALUE_TYPE>(value);
116 }
117 
GetFloatArrayValue(Value value)118 float* GetFloatArrayValue(Value value) {
119   return GetPtrValue<float*, FLOAT_ARRAY_VALUE_TYPE>(value);
120 }
121 
ValueIsNull(Value value)122 int ValueIsNull(Value value) {
123   return value.type == NULL_VALUE_TYPE;
124 }
125 
ValueIsInt(Value value)126 int ValueIsInt(Value value) {
127   return value.type == INT_VALUE_TYPE;
128 }
129 
ValueIsFloat(Value value)130 int ValueIsFloat(Value value) {
131   return value.type == FLOAT_VALUE_TYPE;
132 }
133 
ValueIsString(Value value)134 int ValueIsString(Value value) {
135   return value.type == STRING_VALUE_TYPE;
136 }
137 
ValueIsBuffer(Value value)138 int ValueIsBuffer(Value value) {
139   return value.type == BUFFER_VALUE_TYPE || value.type == MUTABLE_BUFFER_VALUE_TYPE;
140 }
141 
ValueIsIntArray(Value value)142 int ValueIsIntArray(Value value) {
143   return value.type == INT_ARRAY_VALUE_TYPE;
144 }
145 
ValueIsFloatArray(Value value)146 int ValueIsFloatArray(Value value) {
147   return value.type == FLOAT_ARRAY_VALUE_TYPE;
148 }
149 
MakeNullValue()150 Value MakeNullValue() {
151   Value result;
152   result.type = NULL_VALUE_TYPE;
153   result.value = NULL;
154   result.count = 0;
155   return result;
156 }
157 
MakeIntValue(int value)158 Value MakeIntValue(int value) {
159   return MakePODValue<int, INT_VALUE_TYPE>(value);
160 }
161 
MakeFloatValue(float value)162 Value MakeFloatValue(float value) {
163   return MakePODValue<float, FLOAT_VALUE_TYPE>(value);
164 }
165 
MakeStringValue(const char * value)166 Value MakeStringValue(const char* value) {
167   return MakePtrValue<char, STRING_VALUE_TYPE>(value, strlen(value) + 1);
168 }
169 
MakeBufferValue(const char * buffer,int size)170 Value MakeBufferValue(const char* buffer, int size) {
171   return MakePtrValue<char, BUFFER_VALUE_TYPE>(buffer, size);
172 }
173 
MakeBufferValueNoCopy(const char * buffer,int size)174 Value MakeBufferValueNoCopy(const char* buffer, int size) {
175   Value result;
176   result.type = BUFFER_VALUE_TYPE;
177   result.value = (void*)buffer;
178   result.count = size;
179   return result;
180 }
181 
MakeMutableBufferValue(const char * buffer,int size)182 Value MakeMutableBufferValue(const char* buffer, int size) {
183   return MakePtrValue<const char, MUTABLE_BUFFER_VALUE_TYPE>(buffer, size);
184 }
185 
MakeMutableBufferValueNoCopy(char * buffer,int size)186 Value MakeMutableBufferValueNoCopy(char* buffer, int size) {
187   Value result;
188   result.type = MUTABLE_BUFFER_VALUE_TYPE;
189   result.value = (void*)buffer;
190   result.count = size;
191   return result;
192 }
193 
MakeIntArrayValue(const int * values,int count)194 Value MakeIntArrayValue(const int* values, int count) {
195   return MakePtrValue<int, INT_ARRAY_VALUE_TYPE>(values, count);
196 }
197 
MakeFloatArrayValue(const float * values,int count)198 Value MakeFloatArrayValue(const float* values, int count) {
199   return MakePtrValue<float, FLOAT_ARRAY_VALUE_TYPE>(values, count);
200 }
201 
SetIntValue(Value * value,int new_value)202 int SetIntValue(Value* value, int new_value) {
203   return SetPODValue<int, INT_VALUE_TYPE>(value, new_value);
204 }
205 
SetFloatValue(Value * value,float new_value)206 int SetFloatValue(Value* value, float new_value) {
207   return SetPODValue<float, FLOAT_VALUE_TYPE>(value, new_value);
208 }
209 
SetStringValue(Value * value,const char * new_value)210 int SetStringValue(Value* value, const char* new_value) {
211   return SetPtrValue<char, STRING_VALUE_TYPE>(value, new_value, strlen(new_value) + 1);
212 }
213 
SetMutableBufferValue(Value * value,const char * new_data,int size)214 int SetMutableBufferValue(Value* value, const char* new_data, int size) {
215   return SetPtrValue<char, MUTABLE_BUFFER_VALUE_TYPE>(value, new_data, size);
216 }
217 
SetIntArrayValue(Value * value,const int * new_values,int count)218 int SetIntArrayValue(Value* value, const int* new_values, int count) {
219   return SetPtrValue<int, INT_ARRAY_VALUE_TYPE>(value, new_values, count);
220 }
221 
SetFloatArrayValue(Value * value,const float * new_values,int count)222 int SetFloatArrayValue(Value* value, const float* new_values, int count) {
223   return SetPtrValue<float, FLOAT_ARRAY_VALUE_TYPE>(value, new_values, count);
224 }
225 
GetValueCount(Value value)226 int GetValueCount(Value value) {
227   return value.count;
228 }
229 
ReleaseValue(Value * value)230 void ReleaseValue(Value* value) {
231   if (value && value->value) {
232     free(value->value);
233     value->value = NULL;
234     value->type = NULL_VALUE_TYPE;
235   }
236 }
237 
238