1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
3/*
4**********************************************************************
5* Copyright (c) 2003, International Business Machines
6* Corporation and others.  All Rights Reserved.
7**********************************************************************
8* Author: Alan Liu
9* Created: March 19 2003
10* Since: ICU 2.6
11**********************************************************************
12*/
13#include "unicode/ucat.h"
14#include "unicode/ustring.h"
15#include "cstring.h"
16#include "uassert.h"
17
18/* Separator between set_num and msg_num */
19static const char SEPARATOR = '%';
20
21/* Maximum length of a set_num/msg_num key, incl. terminating zero.
22 * Longest possible key is "-2147483648%-2147483648" */
23#define MAX_KEY_LEN (24)
24
25/**
26 * Fill in buffer with a set_num/msg_num key string, given the numeric
27 * values. Numeric values must be >= 0. Buffer must be of length
28 * MAX_KEY_LEN or more.
29 */
30static char*
31_catkey(char* buffer, int32_t set_num, int32_t msg_num) {
32    int32_t i = 0;
33    i = T_CString_integerToString(buffer, set_num, 10);
34    buffer[i++] = SEPARATOR;
35    T_CString_integerToString(buffer+i, msg_num, 10);
36    return buffer;
37}
38
39U_CAPI u_nl_catd U_EXPORT2
40u_catopen(const char* name, const char* locale, UErrorCode* ec) {
41    return (u_nl_catd) ures_open(name, locale, ec);
42}
43
44U_CAPI void U_EXPORT2
45u_catclose(u_nl_catd catd) {
46    ures_close((UResourceBundle*) catd); /* may be nullptr */
47}
48
49U_CAPI const char16_t* U_EXPORT2
50u_catgets(u_nl_catd catd, int32_t set_num, int32_t msg_num,
51          const char16_t* s,
52          int32_t* len, UErrorCode* ec) {
53
54    char key[MAX_KEY_LEN];
55    const char16_t* result;
56
57    if (ec == nullptr || U_FAILURE(*ec)) {
58        goto ERROR;
59    }
60
61    result = ures_getStringByKey((const UResourceBundle*) catd,
62                                 _catkey(key, set_num, msg_num),
63                                 len, ec);
64    if (U_FAILURE(*ec)) {
65        goto ERROR;
66    }
67
68    return result;
69
70 ERROR:
71    /* In case of any failure, return s */
72    if (len != nullptr) {
73        *len = u_strlen(s);
74    }
75    return s;
76}
77
78/*eof*/
79