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