1 /*
2  * Copyright 2020 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 <string.h>
18 #include <errno.h>
19 
20 #include <audio_utils/Metadata.h>
21 
22 using namespace android::audio_utils::metadata;
23 
audio_metadata_create()24 audio_metadata_t *audio_metadata_create() {
25     return reinterpret_cast<audio_metadata_t *>
26             (new(std::nothrow) Data());
27 }
28 
audio_metadata_put_int32(audio_metadata_t * metadata,const char * key,int32_t value)29 int audio_metadata_put_int32(audio_metadata_t *metadata, const char *key, int32_t value) {
30     if (metadata == nullptr || key == nullptr) {
31         return -EINVAL;
32     }
33     reinterpret_cast<Data *>(metadata)->emplace(key, value);
34     return 0;
35 }
36 
audio_metadata_put_int64(audio_metadata_t * metadata,const char * key,int64_t value)37 int audio_metadata_put_int64(audio_metadata_t *metadata, const char *key, int64_t value) {
38     if (metadata == nullptr || key == nullptr) {
39         return -EINVAL;
40     }
41     reinterpret_cast<Data *>(metadata)->emplace(key, value);
42     return 0;
43 }
44 
audio_metadata_put_float(audio_metadata_t * metadata,const char * key,float value)45 int audio_metadata_put_float(audio_metadata_t *metadata, const char *key, float value) {
46     if (metadata == nullptr || key == nullptr) {
47         return -EINVAL;
48     }
49     reinterpret_cast<Data *>(metadata)->emplace(key, value);
50     return 0;
51 }
52 
audio_metadata_put_double(audio_metadata_t * metadata,const char * key,double value)53 int audio_metadata_put_double(audio_metadata_t *metadata, const char *key, double value) {
54     if (metadata == nullptr || key == nullptr) {
55         return -EINVAL;
56     }
57     reinterpret_cast<Data *>(metadata)->emplace(key, value);
58     return 0;
59 }
60 
audio_metadata_put_string(audio_metadata_t * metadata,const char * key,const char * value)61 int audio_metadata_put_string(audio_metadata_t *metadata, const char *key, const char *value) {
62     if (metadata == nullptr || key == nullptr || value == nullptr) {
63         return -EINVAL;
64     }
65     reinterpret_cast<Data *>(metadata)->emplace(key, value);
66     return 0;
67 }
68 
audio_metadata_put_data(audio_metadata_t * metadata,const char * key,audio_metadata_t * value)69 int audio_metadata_put_data(
70         audio_metadata_t *metadata, const char *key, audio_metadata_t *value) {
71     if (metadata == nullptr || key == nullptr || value == nullptr) {
72         return -EINVAL;
73     }
74     reinterpret_cast<Data *>(metadata)->emplace(key, *reinterpret_cast<Data *>(value));
75     return 0;
76 }
77 
78 // audio_metadata_put_unknown() is declared but not implemented
79 
audio_metadata_get_int32(audio_metadata_t * metadata,const char * key,int32_t * value)80 int audio_metadata_get_int32(audio_metadata_t *metadata, const char *key, int32_t *value) {
81     if (metadata == nullptr || key == nullptr || value == nullptr) {
82         return -EINVAL;
83     }
84     int32_t *val = reinterpret_cast<Data *>(metadata)->get_ptr(Key<int32_t>(key));
85     if (val == nullptr) {
86         return -ENOENT;
87     }
88     *value = *val;
89     return 0;
90 }
91 
audio_metadata_get_int64(audio_metadata_t * metadata,const char * key,int64_t * value)92 int audio_metadata_get_int64(audio_metadata_t *metadata, const char *key, int64_t *value) {
93     if (metadata == nullptr || key == nullptr || value == nullptr) {
94         return -EINVAL;
95     }
96     int64_t *val = reinterpret_cast<Data *>(metadata)->get_ptr(Key<int64_t>(key));
97     if (val == nullptr) {
98         return -ENOENT;
99     }
100     *value = *val;
101     return 0;
102 }
103 
audio_metadata_get_float(audio_metadata_t * metadata,const char * key,float * value)104 int audio_metadata_get_float(audio_metadata_t *metadata, const char *key, float *value) {
105     if (metadata == nullptr || key == nullptr || value == nullptr) {
106         return -EINVAL;
107     }
108     float *val = reinterpret_cast<Data *>(metadata)->get_ptr(Key<float>(key));
109     if (val == nullptr) {
110         return -ENOENT;
111     }
112     *value = *val;
113     return 0;
114 }
115 
audio_metadata_get_double(audio_metadata_t * metadata,const char * key,double * value)116 int audio_metadata_get_double(audio_metadata_t *metadata, const char *key, double *value) {
117     if (metadata == nullptr || key == nullptr || value == nullptr) {
118         return -EINVAL;
119     }
120     double *val = reinterpret_cast<Data *>(metadata)->get_ptr(Key<double>(key));
121     if (val == nullptr) {
122         return -ENOENT;
123     }
124     *value = *val;
125     return 0;
126 }
127 
audio_metadata_get_string(audio_metadata_t * metadata,const char * key,char ** value)128 int audio_metadata_get_string(audio_metadata_t *metadata, const char *key, char **value) {
129     if (metadata == nullptr || key == nullptr || value == nullptr) {
130         return -EINVAL;
131     }
132     std::string *valueStr = reinterpret_cast<Data *>(metadata)->get_ptr(Key<std::string>(key));
133     if (valueStr == nullptr) {
134         return -ENOENT;
135     }
136     *value = strdup(valueStr->c_str());
137     return *value == nullptr ? -ENOMEM : 0;
138 }
139 
audio_metadata_get_data(audio_metadata_t * metadata,const char * key,audio_metadata_t ** value)140 int audio_metadata_get_data(
141         audio_metadata_t *metadata, const char *key, audio_metadata_t **value) {
142     if (metadata == nullptr || key == nullptr || value == nullptr) {
143         return -EINVAL;
144     }
145     Data *valueData = reinterpret_cast<Data *>(metadata)->get_ptr(Key<Data>(key));
146     if (valueData == nullptr) {
147         *value = nullptr;
148         return -ENOENT;
149     }
150     *value = reinterpret_cast<audio_metadata_t *>(
151             new(std::nothrow) Data(*valueData));
152     return *value == nullptr ? -ENOMEM : 0;
153 }
154 
155 // audio_metadata_get_unknown() is declared but not implemented
156 
audio_metadata_erase(audio_metadata_t * metadata,const char * key)157 ssize_t audio_metadata_erase(audio_metadata_t *metadata, const char *key) {
158     if (metadata == nullptr || key == nullptr) {
159         return -EINVAL;
160     }
161     return reinterpret_cast<Data *>(metadata)->erase(key);
162 }
163 
audio_metadata_destroy(audio_metadata_t * metadata)164 void audio_metadata_destroy(audio_metadata_t *metadata) {
165     delete reinterpret_cast<Data *>(metadata);
166 }
167 
audio_metadata_from_byte_string(const uint8_t * byteString,size_t length)168 audio_metadata_t *audio_metadata_from_byte_string(const uint8_t *byteString, size_t length) {
169     if (byteString == nullptr) {
170         return nullptr;
171     }
172     return reinterpret_cast<audio_metadata_t *>(
173             new(std::nothrow) Data(dataFromByteString(ByteString(byteString, length))));
174 }
175 
byte_string_from_audio_metadata(audio_metadata_t * metadata,uint8_t ** byteString)176 ssize_t byte_string_from_audio_metadata(audio_metadata_t *metadata, uint8_t **byteString) {
177     if (metadata == nullptr || byteString == nullptr) {
178         return -EINVAL;
179     }
180     ByteString bs = byteStringFromData(*reinterpret_cast<Data *>(metadata));
181     *byteString = (uint8_t *) malloc(bs.size());
182     if (*byteString == nullptr) {
183         return -ENOMEM;
184     }
185     memcpy(*byteString, bs.c_str(), bs.size());
186     return bs.size();
187 }
188 
audio_metadata_byte_string_len(const uint8_t * byteString)189 size_t audio_metadata_byte_string_len(const uint8_t *byteString) {
190     return dataByteStringLen(byteString);
191 }
192