1 // © 2019 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 
4 #include "unicode/utypes.h"
5 
6 #if U_ENABLE_TRACING
7 
8 #include "restrace.h"
9 #include "charstr.h"
10 #include "cstring.h"
11 #include "utracimp.h"
12 #include "uresimp.h"
13 #include "uassert.h"
14 #include "util.h"
15 
16 U_NAMESPACE_BEGIN
17 
18 ResourceTracer::~ResourceTracer() = default;
19 
trace(const char * resType) const20 void ResourceTracer::trace(const char* resType) const {
21     U_ASSERT(fResB || fParent);
22     UTRACE_ENTRY(UTRACE_UDATA_RESOURCE);
23     UErrorCode status = U_ZERO_ERROR;
24 
25     CharString filePath;
26     getFilePath(filePath, status);
27 
28     CharString resPath;
29     getResPath(resPath, status);
30 
31     // The longest type ("intvector") is 9 chars
32     const char kSpaces[] = "         ";
33     CharString format;
34     format.append(kSpaces, sizeof(kSpaces) - 1 - uprv_strlen(resType), status);
35     format.append("(%s) %s @ %s", status);
36 
37     UTRACE_DATA3(UTRACE_VERBOSE,
38         format.data(),
39         resType,
40         filePath.data(),
41         resPath.data());
42     UTRACE_EXIT_STATUS(status);
43 }
44 
traceOpen() const45 void ResourceTracer::traceOpen() const {
46     U_ASSERT(fResB);
47     UTRACE_ENTRY(UTRACE_UDATA_BUNDLE);
48     UErrorCode status = U_ZERO_ERROR;
49 
50     CharString filePath;
51     UTRACE_DATA1(UTRACE_VERBOSE, "%s", getFilePath(filePath, status).data());
52     UTRACE_EXIT_STATUS(status);
53 }
54 
getFilePath(CharString & output,UErrorCode & status) const55 CharString& ResourceTracer::getFilePath(CharString& output, UErrorCode& status) const {
56     if (fResB) {
57         output.append(fResB->fData->fPath, status);
58         output.append('/', status);
59         output.append(fResB->fData->fName, status);
60         output.append(".res", status);
61     } else {
62         fParent->getFilePath(output, status);
63     }
64     return output;
65 }
66 
getResPath(CharString & output,UErrorCode & status) const67 CharString& ResourceTracer::getResPath(CharString& output, UErrorCode& status) const {
68     if (fResB) {
69         output.append('/', status);
70         output.append(fResB->fResPath, status);
71         // removing the trailing /
72         U_ASSERT(output[output.length()-1] == '/');
73         output.truncate(output.length()-1);
74     } else {
75         fParent->getResPath(output, status);
76     }
77     if (fKey) {
78         output.append('/', status);
79         output.append(fKey, status);
80     }
81     if (fIndex != -1) {
82         output.append('[', status);
83         UnicodeString indexString;
84         ICU_Utility::appendNumber(indexString, fIndex);
85         output.appendInvariantChars(indexString, status);
86         output.append(']', status);
87     }
88     return output;
89 }
90 
traceOpen(const char * path,const char * type,const char * name)91 void FileTracer::traceOpen(const char* path, const char* type, const char* name) {
92     if (uprv_strcmp(type, "res") == 0) {
93         traceOpenResFile(path, name);
94     } else {
95         traceOpenDataFile(path, type, name);
96     }
97 }
98 
traceOpenDataFile(const char * path,const char * type,const char * name)99 void FileTracer::traceOpenDataFile(const char* path, const char* type, const char* name) {
100     UTRACE_ENTRY(UTRACE_UDATA_DATA_FILE);
101     UErrorCode status = U_ZERO_ERROR;
102 
103     CharString filePath;
104     filePath.append(path, status);
105     filePath.append('/', status);
106     filePath.append(name, status);
107     filePath.append('.', status);
108     filePath.append(type, status);
109 
110     UTRACE_DATA1(UTRACE_VERBOSE, "%s", filePath.data());
111     UTRACE_EXIT_STATUS(status);
112 }
113 
traceOpenResFile(const char * path,const char * name)114 void FileTracer::traceOpenResFile(const char* path, const char* name) {
115     UTRACE_ENTRY(UTRACE_UDATA_RES_FILE);
116     UErrorCode status = U_ZERO_ERROR;
117 
118     CharString filePath;
119     filePath.append(path, status);
120     filePath.append('/', status);
121     filePath.append(name, status);
122     filePath.append(".res", status);
123 
124     UTRACE_DATA1(UTRACE_VERBOSE, "%s", filePath.data());
125     UTRACE_EXIT_STATUS(status);
126 }
127 
128 U_NAMESPACE_END
129 
130 #endif // U_ENABLE_TRACING
131