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> 33 POD GetPODValue(Value value) { 34 return value.type == TYPEID ? *reinterpret_cast<POD*>(value.value) : POD(); 35 } 36 37 template<typename PTR, int TYPEID> 38 PTR GetPtrValue(Value value) { 39 return value.type == TYPEID ? reinterpret_cast<PTR>(value.value) : NULL; 40 } 41 42 template<typename POD, int TYPEID> 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> 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> 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> 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 ////////////////////////////////////////////////////////////////////////////////////// 91 int GetIntValue(Value value) { 92 return GetPODValue<int, INT_VALUE_TYPE>(value); 93 } 94 95 float GetFloatValue(Value value) { 96 return GetPODValue<float, FLOAT_VALUE_TYPE>(value); 97 } 98 99 const char* GetStringValue(Value value) { 100 return GetPtrValue<const char*, STRING_VALUE_TYPE>(value); 101 } 102 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 109 char* GetMutableBufferValue(Value value) { 110 return GetPtrValue<char*, MUTABLE_BUFFER_VALUE_TYPE>(value); 111 } 112 113 int* GetIntArrayValue(Value value) { 114 return GetPtrValue<int*, INT_ARRAY_VALUE_TYPE>(value); 115 } 116 117 float* GetFloatArrayValue(Value value) { 118 return GetPtrValue<float*, FLOAT_ARRAY_VALUE_TYPE>(value); 119 } 120 121 int ValueIsNull(Value value) { 122 return value.type == NULL_VALUE_TYPE; 123 } 124 125 int ValueIsInt(Value value) { 126 return value.type == INT_VALUE_TYPE; 127 } 128 129 int ValueIsFloat(Value value) { 130 return value.type == FLOAT_VALUE_TYPE; 131 } 132 133 int ValueIsString(Value value) { 134 return value.type == STRING_VALUE_TYPE; 135 } 136 137 int ValueIsBuffer(Value value) { 138 return value.type == BUFFER_VALUE_TYPE || value.type == MUTABLE_BUFFER_VALUE_TYPE; 139 } 140 141 int ValueIsIntArray(Value value) { 142 return value.type == INT_ARRAY_VALUE_TYPE; 143 } 144 145 int ValueIsFloatArray(Value value) { 146 return value.type == FLOAT_ARRAY_VALUE_TYPE; 147 } 148 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 157 Value MakeIntValue(int value) { 158 return MakePODValue<int, INT_VALUE_TYPE>(value); 159 } 160 161 Value MakeFloatValue(float value) { 162 return MakePODValue<float, FLOAT_VALUE_TYPE>(value); 163 } 164 165 Value MakeStringValue(const char* value) { 166 return MakePtrValue<char, STRING_VALUE_TYPE>(value, strlen(value) + 1); 167 } 168 169 Value MakeBufferValue(const char* buffer, int size) { 170 return MakePtrValue<char, BUFFER_VALUE_TYPE>(buffer, size); 171 } 172 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 181 Value MakeMutableBufferValue(const char* buffer, int size) { 182 return MakePtrValue<const char, MUTABLE_BUFFER_VALUE_TYPE>(buffer, size); 183 } 184 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 193 Value MakeIntArrayValue(const int* values, int count) { 194 return MakePtrValue<int, INT_ARRAY_VALUE_TYPE>(values, count); 195 } 196 197 Value MakeFloatArrayValue(const float* values, int count) { 198 return MakePtrValue<float, FLOAT_ARRAY_VALUE_TYPE>(values, count); 199 } 200 201 int SetIntValue(Value* value, int new_value) { 202 return SetPODValue<int, INT_VALUE_TYPE>(value, new_value); 203 } 204 205 int SetFloatValue(Value* value, float new_value) { 206 return SetPODValue<float, FLOAT_VALUE_TYPE>(value, new_value); 207 } 208 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 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 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 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 225 int GetValueCount(Value value) { 226 return value.count; 227 } 228 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