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