ICU-5858 Add constructors for RuleBasedBreakIterator and RBBIDataWrapper

that take RBBIDataHeader* but do not adopt it.

X-SVN-Rev: 24641
This commit is contained in:
Peter Edberg 2008-09-25 05:48:27 +00:00
parent 5b3a479e50
commit d08940016b
6 changed files with 130 additions and 5 deletions

View File

@ -70,6 +70,20 @@ RuleBasedBreakIterator::RuleBasedBreakIterator(RBBIDataHeader* data, UErrorCode
}
}
/**
* Same as above but does not adopt memory
*/
RuleBasedBreakIterator::RuleBasedBreakIterator(const RBBIDataHeader* data, enum EDontAdopt, UErrorCode &status)
{
init();
fData = new RBBIDataWrapper(data, RBBIDataWrapper::kDontAdopt, status); // status checked in constructor
if (U_FAILURE(status)) {return;}
if(fData == 0) {
status = U_MEMORY_ALLOCATION_ERROR;
return;
}
}
//-------------------------------------------------------------------------------
//
// Constructor from a UDataMemory handle to precompiled break rules

View File

@ -1,6 +1,6 @@
/*
***************************************************************************
* Copyright (C) 1999-2007 International Business Machines Corporation *
* Copyright (C) 1999-2008 International Business Machines Corporation *
* and others. All rights reserved. *
***************************************************************************
*/
@ -49,6 +49,11 @@ RBBIDataWrapper::RBBIDataWrapper(const RBBIDataHeader *data, UErrorCode &status)
init(data, status);
}
RBBIDataWrapper::RBBIDataWrapper(const RBBIDataHeader *data, enum EDontAdopt, UErrorCode &status) {
init(data, status);
fDontFreeData = TRUE;
}
RBBIDataWrapper::RBBIDataWrapper(UDataMemory* udm, UErrorCode &status) {
const RBBIDataHeader *d = (const RBBIDataHeader *)
// ((char *)&(udm->pHeader->info) + udm->pHeader->info.size);
@ -77,6 +82,7 @@ void RBBIDataWrapper::init(const RBBIDataHeader *data, UErrorCode &status) {
return;
}
fDontFreeData = FALSE;
fUDataMem = NULL;
fReverseTable = NULL;
fSafeFwdTable = NULL;
@ -130,7 +136,7 @@ RBBIDataWrapper::~RBBIDataWrapper() {
U_ASSERT(fRefCount == 0);
if (fUDataMem) {
udata_close(fUDataMem);
} else {
} else if (!fDontFreeData) {
uprv_free((void *)fHeader);
}
}

View File

@ -1,7 +1,7 @@
/*
*******************************************************************************
*
* Copyright (C) 1999-2005, International Business Machines
* Copyright (C) 1999-2005,2008 International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
@ -141,7 +141,11 @@ typedef enum {
/* */
class RBBIDataWrapper : public UMemory {
public:
enum EDontAdopt {
kDontAdopt
};
RBBIDataWrapper(const RBBIDataHeader *data, UErrorCode &status);
RBBIDataWrapper(const RBBIDataHeader *data, enum EDontAdopt dontAdopt, UErrorCode &status);
RBBIDataWrapper(UDataMemory* udm, UErrorCode &status);
~RBBIDataWrapper();
@ -179,6 +183,7 @@ private:
int32_t fRefCount;
UDataMemory *fUDataMem;
UnicodeString fRuleString;
UBool fDontFreeData;
RBBIDataWrapper(const RBBIDataWrapper &other); /* forbid copying of this class */
RBBIDataWrapper &operator=(const RBBIDataWrapper &other); /* forbid copying of this class */

View File

@ -1,6 +1,6 @@
/*
***************************************************************************
* Copyright (C) 1999-2007 International Business Machines Corporation *
* Copyright (C) 1999-2008 International Business Machines Corporation *
* and others. All rights reserved. *
***************************************************************************
@ -170,6 +170,18 @@ protected:
// constructors
//=======================================================================
/**
* Constant to be used in the constructor
* RuleBasedBreakIterator(RBBIDataHeader*, EDontAdopt, UErrorCode &);
* which does not adopt the memory indicated by the RBBIDataHeader*
* parameter.
*
* @internal
*/
enum EDontAdopt {
kDontAdopt
};
/**
* Constructor from a flattened set of RBBI data in malloced memory.
* RulesBasedBreakIterators built from a custom set of rules
@ -182,6 +194,16 @@ protected:
*/
RuleBasedBreakIterator(RBBIDataHeader* data, UErrorCode &status);
/**
* Constructor from a flattened set of RBBI data in memory which need not
* be malloced (e.g. it may be a memory-mapped file, etc.).
*
* This version does not adopt the memory, and does not
* free it when done.
* @internal
*/
RuleBasedBreakIterator(const RBBIDataHeader* data, enum EDontAdopt dontAdopt, UErrorCode &status);
friend class RBBIRuleBuilder;
/** @internal */

View File

@ -21,6 +21,7 @@
#include "ubrkimpl.h"
#include "unicode/ustring.h"
#include "unicode/utext.h"
#include "cmemory.h"
/**
* API Test the RuleBasedBreakIterator class
@ -1047,6 +1048,50 @@ void RBBIAPITest::TestRoundtripRules() {
}
}
// Try out the RuleBasedBreakIterator constructors that take RBBIDataHeader*
// (these are protected so we access them via a local class RBBIWithProtectedFunctions).
// This is just a sanity check, not a thorough test (e.g. we don't check that the
// first delete actually frees rulesCopy).
void RBBIAPITest::TestCreateFromRBBIData() {
// Get some handy RBBIData
const char *brkName = "word"; // or "sent", "line", "char", etc.
UErrorCode status = U_ZERO_ERROR;
UDataMemory * data = udata_open(U_ICUDATA_BRKITR, "brk", brkName, &status);
if ( U_SUCCESS(status) ) {
const RBBIDataHeader * builtRules = (const RBBIDataHeader *)udata_getMemory(data);
uint32_t length = builtRules->fLength;
RBBIWithProtectedFunctions * brkItr;
// Try the memory-adopting constructor, need to copy the data first
RBBIDataHeader * rulesCopy = (RBBIDataHeader *) uprv_malloc(length);
if ( rulesCopy ) {
uprv_memcpy( rulesCopy, builtRules, length );
brkItr = new RBBIWithProtectedFunctions(rulesCopy, status);
if ( U_SUCCESS(status) ) {
delete brkItr; // this should free rulesCopy
} else {
errln("create RuleBasedBreakIterator from RBBIData (adopted): ICU Error \"%s\"\n", u_errorName(status) );
status = U_ZERO_ERROR;// reset for the next test
uprv_free( rulesCopy );
}
}
// Now try the non-adopting constructor
brkItr = new RBBIWithProtectedFunctions(builtRules, RBBIWithProtectedFunctions::kDontAdopt, status);
if ( U_SUCCESS(status) ) {
delete brkItr; // this should NOT attempt to free builtRules
if (builtRules->fLength != length) { // sanity check
errln("create RuleBasedBreakIterator from RBBIData (non-adopted): delete affects data\n" );
}
} else {
errln("create RuleBasedBreakIterator from RBBIData (non-adopted): ICU Error \"%s\"\n", u_errorName(status) );
}
udata_close(data);
}
}
//---------------------------------------------
// runIndexedTest
//---------------------------------------------
@ -1069,6 +1114,7 @@ void RBBIAPITest::runIndexedTest( int32_t index, UBool exec, const char* &name,
case 10: name = "TestRegistration"; if (exec) TestRegistration(); break;
case 11: name = "TestBoilerPlate"; if (exec) TestBoilerPlate(); break;
case 12: name = "TestRoundtripRules"; if (exec) TestRoundtripRules(); break;
case 13: name = "TestCreateFromRBBIData"; if (exec) TestCreateFromRBBIData(); break;
default: name = ""; break; // needed to end loop
}
@ -1115,4 +1161,18 @@ void RBBIAPITest::doTest(UnicodeString& testString, int32_t start, int32_t gotof
logln(prettify("****selected \"" + selected + "\""));
}
//---------------------------------------------
//RBBIWithProtectedFunctions class functions
//---------------------------------------------
RBBIWithProtectedFunctions::RBBIWithProtectedFunctions(RBBIDataHeader* data, UErrorCode &status)
: RuleBasedBreakIterator(data, status)
{
}
RBBIWithProtectedFunctions::RBBIWithProtectedFunctions(const RBBIDataHeader* data, enum EDontAdopt, UErrorCode &status)
: RuleBasedBreakIterator(data, RuleBasedBreakIterator::kDontAdopt, status)
{
}
#endif /* #if !UCONFIG_NO_BREAK_ITERATION */

View File

@ -1,6 +1,6 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 1999-2004, International Business Machines Corporation and
* Copyright (c) 1999-2004,2008 International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
/************************************************************************
@ -63,6 +63,12 @@ public:
void RoundtripRule(const char *dataFile);
/**
* Test creating RuleBasedBreakIterator from RBBIData.
**/
void TestCreateFromRBBIData(void);
/**
* Tests grouping effect of 'single quotes' in rules.
**/
@ -92,6 +98,18 @@ public:
};
/**
* Special class to enable testing of protected functions in RuleBasedBreakIterator
*/
class RBBIWithProtectedFunctions: public RuleBasedBreakIterator {
public:
enum EDontAdopt {
kDontAdopt
};
RBBIWithProtectedFunctions(RBBIDataHeader* data, UErrorCode &status);
RBBIWithProtectedFunctions(const RBBIDataHeader* data, enum EDontAdopt dontAdopt, UErrorCode &status);
};
#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
#endif