summaryrefslogtreecommitdiffstats
path: root/intl/icu/source/tools/toolutil/package.h
blob: ea60c13a74a57b94057882e39b6aa05314c4ca1f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
*   Copyright (C) 2005-2014, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*******************************************************************************
*   file name:  package.h
*   encoding:   UTF-8
*   tab size:   8 (not used)
*   indentation:4
*
*   created on: 2005aug25
*   created by: Markus W. Scherer
*
*   Read, modify, and write ICU .dat data package files.
*/

#ifndef __PACKAGE_H__
#define __PACKAGE_H__

#include "unicode/utypes.h"

#include <stdio.h>

// .dat package file representation ---------------------------------------- ***

#define STRING_STORE_SIZE 100000
#define MAX_PKG_NAME_LENGTH 64

typedef void CheckDependency(void *context, const char *itemName, const char *targetName);

U_NAMESPACE_BEGIN

struct Item {
    char *name;
    uint8_t *data;
    int32_t length;
    UBool isDataOwned;
    char type;
};

class U_TOOLUTIL_API Package {
public:
    /*
     * Constructor.
     * Prepare this object for a new, empty package.
     */
    Package();

    /* Destructor. */
    ~Package();

    /**
     * Uses the prefix of the first entry of the package in readPackage(),
     * rather than the package basename.
     */
    void setAutoPrefix() { doAutoPrefix=true; }
    /**
     * Same as setAutoPrefix(), plus the prefix must end with the platform type letter.
     */
    void setAutoPrefixWithType() {
        doAutoPrefix=true;
        prefixEndsWithType=true;
    }
    void setPrefix(const char *p);

    /*
     * Read an existing .dat package file.
     * The header and item name strings are swapped into this object,
     * but the items are left unswapped.
     */
    void readPackage(const char *filename);
    /*
     * Write a .dat package file with the items in this object.
     * Swap all pieces to the desired output platform properties.
     * The package becomes unusable:
     * The item names are swapped and sorted in the outCharset rather than the local one.
     * Also, the items themselves are swapped in-place
     */
    void writePackage(const char *filename, char outType, const char *comment);

    /*
     * Return the input data type letter (l, b, or e).
     */
    char getInType();

    // find the item in items[], return the non-negative index if found, else the binary-not of the insertion point
    int32_t findItem(const char *name, int32_t length=-1) const;

    /*
     * Set internal state for following calls to findNextItem() which will return
     * indexes for items whose names match the pattern.
     */
    void findItems(const char *pattern);
    int32_t findNextItem();
    /*
     * Set the match mode for findItems() & findNextItem().
     * @param mode 0=default
     *             MATCH_NOSLASH * does not match a '/'
     */
    void setMatchMode(uint32_t mode);

    enum {
        MATCH_NOSLASH=1
    };

    void addItem(const char *name);
    void addItem(const char *name, uint8_t *data, int32_t length, UBool isDataOwned, char type);
    void addFile(const char *filesPath, const char *name);
    void addItems(const Package &listPkg);

    void removeItem(int32_t itemIndex);
    void removeItems(const char *pattern);
    void removeItems(const Package &listPkg);

    /* The extractItem() functions accept outputType=0 to mean "don't swap the item". */
    void extractItem(const char *filesPath, int32_t itemIndex, char outType);
    void extractItems(const char *filesPath, const char *pattern, char outType);
    void extractItems(const char *filesPath, const Package &listPkg, char outType);

    /* This variant extracts an item to a specific filename. */
    void extractItem(const char *filesPath, const char *outName, int32_t itemIndex, char outType);

    int32_t getItemCount() const;
    const Item *getItem(int32_t idx) const;

    /*
     * Check dependencies and return true if all dependencies are fulfilled.
     */
    UBool checkDependencies();

    /*
     * Enumerate all the dependencies and give the results to context and call CheckDependency callback
     * @param context user context (will be passed to check function)
     * @param check will be called with context and any missing items
     */
    void enumDependencies(void *context, CheckDependency check);

private:
    void enumDependencies(Item *pItem, void *context, CheckDependency check);

    /**
     * Default CheckDependency function used by checkDependencies()
     */
    static void checkDependency(void *context, const char *itemName, const char *targetName);

    /*
     * Allocate a string in inStrings or outStrings.
     * The length does not include the terminating NUL.
     */
    char *allocString(UBool in, int32_t length);

    void sortItems();

    // data fields
    char inPkgName[MAX_PKG_NAME_LENGTH];
    char pkgPrefix[MAX_PKG_NAME_LENGTH];

    uint8_t *inData;
    uint8_t header[1024];
    int32_t inLength, headerLength;
    uint8_t inCharset;
    UBool inIsBigEndian;
    UBool doAutoPrefix;
    UBool prefixEndsWithType;

    int32_t itemCount;
    int32_t itemMax;
    Item   *items;

    int32_t inStringTop, outStringTop;
    char inStrings[STRING_STORE_SIZE], outStrings[STRING_STORE_SIZE];

    // match mode for findItems(pattern) and findNextItem()
    uint32_t matchMode;

    // state for findItems(pattern) and findNextItem()
    const char *findPrefix, *findSuffix;
    int32_t findPrefixLength, findSuffixLength;
    int32_t findNextIndex;

    // state for checkDependencies()
    UBool isMissingItems;

    /**
     * Grow itemMax to new value
     */
    void setItemCapacity(int32_t max);

    /**
     * Grow itemMax to at least itemCount+1
     */
    void ensureItemCapacity();
};

U_NAMESPACE_END

#endif