1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru***************************************************************************
327f654740f2a26ad62a5c155af9199af9e69b889claireho*   Copyright (C) 1999-2010 International Business Machines Corporation   *
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   and others. All rights reserved.                                      *
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru***************************************************************************
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h"
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_BREAK_ITERATION
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h"
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "rbbidata.h"
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "rbbirb.h"
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "utrie.h"
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "udatamem.h"
17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h"
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cstring.h"
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "umutex.h"
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uassert.h"
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-----------------------------------------------------------------------------------
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//   Trie access folding function.  Copied as-is from properties code in uchar.c
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-----------------------------------------------------------------------------------
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CDECL_BEGIN
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t U_CALLCONV
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerugetFoldingOffset(uint32_t data) {
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* if bit 15 is set, then the folding offset is in bits 14..0 of the 16-bit trie result */
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(data&0x8000) {
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return (int32_t)(data&0x7fff);
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } else {
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 0;
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CDECL_END
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-----------------------------------------------------------------------------
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//    Constructors.
46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-----------------------------------------------------------------------------
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRBBIDataWrapper::RBBIDataWrapper(const RBBIDataHeader *data, UErrorCode &status) {
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    init(data, status);
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
5285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoRBBIDataWrapper::RBBIDataWrapper(const RBBIDataHeader *data, enum EDontAdopt, UErrorCode &status) {
5385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    init(data, status);
5485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fDontFreeData = TRUE;
5585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
5685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRBBIDataWrapper::RBBIDataWrapper(UDataMemory* udm, UErrorCode &status) {
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const RBBIDataHeader *d = (const RBBIDataHeader *)
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // ((char *)&(udm->pHeader->info) + udm->pHeader->info.size);
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // taking into consideration the padding added in by udata_write
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ((char *)(udm->pHeader) + udm->pHeader->dataHeader.headerSize);
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    init(d, status);
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fUDataMem = udm;
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-----------------------------------------------------------------------------
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//    init().   Does most of the work of construction, shared between the
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//              constructors.
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-----------------------------------------------------------------------------
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid RBBIDataWrapper::init(const RBBIDataHeader *data, UErrorCode &status) {
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) {
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fHeader = data;
7727f654740f2a26ad62a5c155af9199af9e69b889claireho    if (fHeader->fMagic != 0xb1a0 || fHeader->fFormatVersion[0] != 3)
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = U_INVALID_FORMAT_ERROR;
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
8227f654740f2a26ad62a5c155af9199af9e69b889claireho    // Note: in ICU version 3.2 and earlier, there was a formatVersion 1
8327f654740f2a26ad62a5c155af9199af9e69b889claireho    //       that is no longer supported.  At that time fFormatVersion was
8427f654740f2a26ad62a5c155af9199af9e69b889claireho    //       an int32_t field, rather than an array of 4 bytes.
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
8685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fDontFreeData = FALSE;
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fUDataMem     = NULL;
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fReverseTable = NULL;
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSafeFwdTable = NULL;
90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSafeRevTable = NULL;
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (data->fFTableLen != 0) {
92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fForwardTable = (RBBIStateTable *)((char *)data + fHeader->fFTable);
93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (data->fRTableLen != 0) {
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fReverseTable = (RBBIStateTable *)((char *)data + fHeader->fRTable);
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (data->fSFTableLen != 0) {
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fSafeFwdTable = (RBBIStateTable *)((char *)data + fHeader->fSFTable);
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (data->fSRTableLen != 0) {
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fSafeRevTable = (RBBIStateTable *)((char *)data + fHeader->fSRTable);
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    utrie_unserialize(&fTrie,
106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       (uint8_t *)data + fHeader->fTrie,
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       fHeader->fTrieLen,
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       &status);
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) {
110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fTrie.getFoldingOffset=getFoldingOffset;
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fRuleSource   = (UChar *)((char *)data + fHeader->fRuleSource);
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fRuleString.setTo(TRUE, fRuleSource, -1);
117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    U_ASSERT(data->fRuleSourceLen > 0);
118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fRuleStatusTable = (int32_t *)((char *)data + fHeader->fStatusTable);
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fStatusMaxIdx    = data->fStatusTableLen / sizeof(int32_t);
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fRefCount = 1;
123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifdef RBBI_DEBUG
125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char *debugEnv = getenv("U_RBBIDEBUG");
126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (debugEnv && uprv_strstr(debugEnv, "data")) {this->printData();}
127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-----------------------------------------------------------------------------
132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//    Destructor.     Don't call this - use removeReference() instead.
134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-----------------------------------------------------------------------------
136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRBBIDataWrapper::~RBBIDataWrapper() {
137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    U_ASSERT(fRefCount == 0);
138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (fUDataMem) {
139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        udata_close(fUDataMem);
14085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else if (!fDontFreeData) {
141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        uprv_free((void *)fHeader);
142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-----------------------------------------------------------------------------
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//   Operator ==    Consider two RBBIDataWrappers to be equal if they
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                  refer to the same underlying data.  Although
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                  the data wrappers are normally shared between
152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                  iterator instances, it's possible to independently
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                  open the same data twice, and get two instances, which
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                  should still be ==.
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-----------------------------------------------------------------------------
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool RBBIDataWrapper::operator ==(const RBBIDataWrapper &other) const {
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (fHeader == other.fHeader) {
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return TRUE;
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (fHeader->fLength != other.fHeader->fLength) {
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return FALSE;
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (uprv_memcmp(fHeader, other.fHeader, fHeader->fLength) == 0) {
165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return TRUE;
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return FALSE;
168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t  RBBIDataWrapper::hashCode() {
171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return fHeader->fFTableLen;
172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-----------------------------------------------------------------------------
177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//    Reference Counting.   A single RBBIDataWrapper object is shared among
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                          however many RulesBasedBreakIterator instances are
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//                          referencing the same data.
181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-----------------------------------------------------------------------------
183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid RBBIDataWrapper::removeReference() {
184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (umtx_atomic_dec(&fRefCount) == 0) {
185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete this;
186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRBBIDataWrapper *RBBIDataWrapper::addReference() {
191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru   umtx_atomic_inc(&fRefCount);
192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru   return this;
193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-----------------------------------------------------------------------------
198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//  getRuleSourceString
200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-----------------------------------------------------------------------------
202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UnicodeString &RBBIDataWrapper::getRuleSourceString() const {
203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return fRuleString;
204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-----------------------------------------------------------------------------
208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//  print   -  debugging function to dump the runtime data tables.
210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-----------------------------------------------------------------------------
212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifdef RBBI_DEBUG
213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid  RBBIDataWrapper::printTable(const char *heading, const RBBIStateTable *table) {
214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t   c;
215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint32_t   s;
216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBIDebugPrintf("   %s\n", heading);
218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBIDebugPrintf("State |  Acc  LA TagIx");
220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (c=0; c<fHeader->fCatCount; c++) {RBBIDebugPrintf("%3d ", c);}
221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBIDebugPrintf("\n------|---------------"); for (c=0;c<fHeader->fCatCount; c++) {
222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        RBBIDebugPrintf("----");
223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBIDebugPrintf("\n");
225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (table == NULL) {
227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        RBBIDebugPrintf("         N U L L   T A B L E\n\n");
228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (s=0; s<table->fNumStates; s++) {
231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        RBBIStateTableRow *row = (RBBIStateTableRow *)
232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                  (table->fTableData + (table->fRowLen * s));
233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        RBBIDebugPrintf("%4d  |  %3d %3d %3d ", s, row->fAccepting, row->fLookAhead, row->fTagIdx);
234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        for (c=0; c<fHeader->fCatCount; c++)  {
235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            RBBIDebugPrintf("%3d ", row->fNextState[c]);
236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        RBBIDebugPrintf("\n");
238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBIDebugPrintf("\n");
240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifdef RBBI_DEBUG
245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid  RBBIDataWrapper::printData() {
246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBIDebugPrintf("RBBI Data at %p\n", (void *)fHeader);
247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBIDebugPrintf("   Version = {%d %d %d %d}\n", fHeader->fFormatVersion[0], fHeader->fFormatVersion[1],
248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                                    fHeader->fFormatVersion[2], fHeader->fFormatVersion[3]);
249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBIDebugPrintf("   total length of data  = %d\n", fHeader->fLength);
250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBIDebugPrintf("   number of character categories = %d\n\n", fHeader->fCatCount);
251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    printTable("Forward State Transition Table", fForwardTable);
253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    printTable("Reverse State Transition Table", fReverseTable);
254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    printTable("Safe Forward State Transition Table", fSafeFwdTable);
255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    printTable("Safe Reverse State Transition Table", fSafeRevTable);
256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBIDebugPrintf("\nOrignal Rules source:\n");
258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (int32_t c=0; fRuleSource[c] != 0; c++) {
259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        RBBIDebugPrintf("%c", fRuleSource[c]);
260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBIDebugPrintf("\n\n");
262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END
267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_USE
268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-----------------------------------------------------------------------------
270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//  ubrk_swap   -  byte swap and char encoding swap of RBBI data
272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//
273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-----------------------------------------------------------------------------
274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2
276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruubrk_swap(const UDataSwapper *ds, const void *inData, int32_t length, void *outData,
277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru           UErrorCode *status) {
278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (status == NULL || U_FAILURE(*status)) {
280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 0;
281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(ds==NULL || inData==NULL || length<-1 || (length>0 && outData==NULL)) {
283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *status=U_ILLEGAL_ARGUMENT_ERROR;
284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 0;
285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //  Check that the data header is for for break data.
289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //    (Header contents are defined in genbrk.cpp)
290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UDataInfo *pInfo = (const UDataInfo *)((const char *)inData+4);
292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(!(  pInfo->dataFormat[0]==0x42 &&   /* dataFormat="Brk " */
293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru           pInfo->dataFormat[1]==0x72 &&
294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru           pInfo->dataFormat[2]==0x6b &&
295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru           pInfo->dataFormat[3]==0x20 &&
296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru           pInfo->formatVersion[0]==3  )) {
297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        udata_printError(ds, "ubrk_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized\n",
298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                         pInfo->dataFormat[0], pInfo->dataFormat[1],
299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                         pInfo->dataFormat[2], pInfo->dataFormat[3],
300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                         pInfo->formatVersion[0]);
301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *status=U_UNSUPPORTED_ERROR;
302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 0;
303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Swap the data header.  (This is the generic ICU Data Header, not the RBBI Specific
307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //                         RBBIDataHeader).  This swap also conveniently gets us
308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //                         the size of the ICU d.h., which lets us locate the start
309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //                         of the RBBI specific data.
310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t headerSize=udata_swapDataHeader(ds, inData, length, outData, status);
312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Get the RRBI Data Header, and check that it appears to be OK.
316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //    Note:  ICU 3.2 and earlier, RBBIDataHeader::fDataFormat was actually
318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //           an int32_t with a value of 1.  Starting with ICU 3.4,
319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //           RBBI's fDataFormat matches the dataFormat field from the
320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //           UDataInfo header, four int8_t bytes.  The value is {3,1,0,0}
321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const uint8_t  *inBytes =(const uint8_t *)inData+headerSize;
323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBIDataHeader *rbbiDH = (RBBIDataHeader *)inBytes;
32427f654740f2a26ad62a5c155af9199af9e69b889claireho    if (ds->readUInt32(rbbiDH->fMagic) != 0xb1a0 ||
32527f654740f2a26ad62a5c155af9199af9e69b889claireho        rbbiDH->fFormatVersion[0] != 3 ||
326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ds->readUInt32(rbbiDH->fLength)  <  sizeof(RBBIDataHeader))
327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        udata_printError(ds, "ubrk_swap(): RBBI Data header is invalid.\n");
329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *status=U_UNSUPPORTED_ERROR;
330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 0;
331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Prefight operation?  Just return the size
335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t breakDataLength = ds->readUInt32(rbbiDH->fLength);
337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t totalSize = headerSize + breakDataLength;
338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (length < 0) {
339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return totalSize;
340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Check that length passed in is consistent with length from RBBI data header.
344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (length < totalSize) {
346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        udata_printError(ds, "ubrk_swap(): too few bytes (%d after ICU Data header) for break data.\n",
347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            breakDataLength);
348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *status=U_INDEX_OUTOFBOUNDS_ERROR;
349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 0;
350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Swap the Data.  Do the data itself first, then the RBBI Data Header, because
355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //                 we need to reference the header to locate the data, and an
356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //                 inplace swap of the header leaves it unusable.
357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint8_t         *outBytes = (uint8_t *)outData + headerSize;
359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    RBBIDataHeader  *outputDH = (RBBIDataHeader *)outBytes;
360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t   tableStartOffset;
362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t   tableLength;
363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // If not swapping in place, zero out the output buffer before starting.
366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //    Individual tables and other data items within are aligned to 8 byte boundaries
367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //    when originally created.  Any unused space between items needs to be zero.
368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (inBytes != outBytes) {
370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        uprv_memset(outBytes, 0, breakDataLength);
371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Each state table begins with several 32 bit fields.  Calculate the size
375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //   in bytes of these.
376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t         topSize = offsetof(RBBIStateTable, fTableData);
378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Forward state table.
380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    tableStartOffset = ds->readUInt32(rbbiDH->fFTable);
381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    tableLength      = ds->readUInt32(rbbiDH->fFTableLen);
382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (tableLength > 0) {
384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ds->swapArray32(ds, inBytes+tableStartOffset, topSize,
385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            outBytes+tableStartOffset, status);
386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ds->swapArray16(ds, inBytes+tableStartOffset+topSize, tableLength-topSize,
387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            outBytes+tableStartOffset+topSize, status);
388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Reverse state table.  Same layout as forward table, above.
391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    tableStartOffset = ds->readUInt32(rbbiDH->fRTable);
392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    tableLength      = ds->readUInt32(rbbiDH->fRTableLen);
393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (tableLength > 0) {
395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ds->swapArray32(ds, inBytes+tableStartOffset, topSize,
396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            outBytes+tableStartOffset, status);
397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ds->swapArray16(ds, inBytes+tableStartOffset+topSize, tableLength-topSize,
398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            outBytes+tableStartOffset+topSize, status);
399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Safe Forward state table.  Same layout as forward table, above.
402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    tableStartOffset = ds->readUInt32(rbbiDH->fSFTable);
403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    tableLength      = ds->readUInt32(rbbiDH->fSFTableLen);
404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (tableLength > 0) {
406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ds->swapArray32(ds, inBytes+tableStartOffset, topSize,
407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            outBytes+tableStartOffset, status);
408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ds->swapArray16(ds, inBytes+tableStartOffset+topSize, tableLength-topSize,
409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            outBytes+tableStartOffset+topSize, status);
410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Safe Reverse state table.  Same layout as forward table, above.
413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    tableStartOffset = ds->readUInt32(rbbiDH->fSRTable);
414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    tableLength      = ds->readUInt32(rbbiDH->fSRTableLen);
415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (tableLength > 0) {
417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ds->swapArray32(ds, inBytes+tableStartOffset, topSize,
418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            outBytes+tableStartOffset, status);
419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ds->swapArray16(ds, inBytes+tableStartOffset+topSize, tableLength-topSize,
420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            outBytes+tableStartOffset+topSize, status);
421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Trie table for character categories
424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    utrie_swap(ds, inBytes+ds->readUInt32(rbbiDH->fTrie), ds->readUInt32(rbbiDH->fTrieLen),
425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            outBytes+ds->readUInt32(rbbiDH->fTrie), status);
426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Source Rules Text.  It's UChar data
428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ds->swapArray16(ds, inBytes+ds->readUInt32(rbbiDH->fRuleSource), ds->readUInt32(rbbiDH->fRuleSourceLen),
429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        outBytes+ds->readUInt32(rbbiDH->fRuleSource), status);
430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Table of rule status values.  It's all int_32 values
432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ds->swapArray32(ds, inBytes+ds->readUInt32(rbbiDH->fStatusTable), ds->readUInt32(rbbiDH->fStatusTableLen),
433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        outBytes+ds->readUInt32(rbbiDH->fStatusTable), status);
434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // And, last, the header.
43627f654740f2a26ad62a5c155af9199af9e69b889claireho    //   It is all int32_t values except for fFormataVersion, which is an array of four bytes.
43727f654740f2a26ad62a5c155af9199af9e69b889claireho    //   Swap the whole thing as int32_t, then re-swap the one field.
438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //
439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ds->swapArray32(ds, inBytes, sizeof(RBBIDataHeader), outBytes, status);
44027f654740f2a26ad62a5c155af9199af9e69b889claireho    ds->swapArray32(ds, outputDH->fFormatVersion, 4, outputDH->fFormatVersion, status);
441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return totalSize;
443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
447