1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <fbl/algorithm.h>
6 #include <fbl/alloc_checker.h>
7 #include <fbl/unique_ptr.h>
8 #include <string.h>
9 
10 #include "usb-audio.h"
11 
12 namespace audio {
13 namespace usb {
14 
FetchStringDescriptor(const usb_protocol_t & usb,uint8_t desc_id,uint16_t lang_id,uint16_t * out_lang_id)15 fbl::Array<uint8_t> FetchStringDescriptor(const usb_protocol_t& usb,
16                                           uint8_t desc_id,
17                                           uint16_t lang_id,
18                                           uint16_t* out_lang_id) {
19     uint8_t str_buf[512];
20     size_t buflen = sizeof(str_buf);
21     zx_status_t res = usb_get_string_descriptor(&usb, desc_id, lang_id, &lang_id, str_buf, buflen,
22                                                 &buflen);
23 
24     if (out_lang_id) {
25         *out_lang_id = lang_id;
26     }
27 
28     if (res != ZX_OK) {
29         return fbl::Array<uint8_t>();
30     }
31 
32     buflen = fbl::min(buflen, sizeof(str_buf));
33 
34     fbl::AllocChecker ac;
35     fbl::unique_ptr<uint8_t[]> mem(new (&ac) uint8_t[buflen + 1]);
36     if (!ac.check()) {
37         return fbl::Array<uint8_t>();
38     }
39 
40     ::memcpy(mem.get(), str_buf, buflen);
41     mem[buflen] = 0;
42 
43     return fbl::Array<uint8_t>(mem.release(), buflen);
44 }
45 
46 }  // namespace usb
47 }  // namespace audio
48