U_CAPI UBiDi * U_EXPORT2 ubidi_openSized(int32_t maxLength, int32_t maxRunCount, UErrorCode *pErrorCode) { UBiDi *pBiDi; /* check the argument values */ if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { return NULL; } else if(maxLength<0 || maxRunCount<0) { *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; return NULL; /* invalid arguments */ } /* allocate memory for the object */ pBiDi=(UBiDi *)icu_malloc(sizeof(UBiDi)); if(pBiDi==NULL) { *pErrorCode=U_MEMORY_ALLOCATION_ERROR; return NULL; } /* reset the object, all pointers NULL, all flags FALSE, all sizes 0 */ icu_memset(pBiDi, 0, sizeof(UBiDi)); /* allocate memory for arrays as requested */ if(maxLength>0) { if( !getInitialDirPropsMemory(pBiDi, maxLength) || !getInitialLevelsMemory(pBiDi, maxLength) ) { *pErrorCode=U_MEMORY_ALLOCATION_ERROR; } } else { pBiDi->mayAllocateText=TRUE; } if(maxRunCount>0) { if(maxRunCount==1) { /* use simpleRuns[] */ pBiDi->runsSize=sizeof(Run); } else if(!getInitialRunsMemory(pBiDi, maxRunCount)) { *pErrorCode=U_MEMORY_ALLOCATION_ERROR; } } else { pBiDi->mayAllocateRuns=TRUE; } if(U_SUCCESS(*pErrorCode)) { return pBiDi; } else { ubidi_close(pBiDi); return NULL; } }
U_CAPI const UBiDiLevel * U_EXPORT2 ubidi_getLevels(UBiDi *pBiDi, UErrorCode *pErrorCode) { int32_t start, length; if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { return NULL; } else if(pBiDi==NULL || (length=pBiDi->length)<=0) { *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; return NULL; } if((start=pBiDi->trailingWSStart)==length) { /* the current levels array reflects the WS run */ return pBiDi->levels; } /* * After the previous if(), we know that the levels array * has an implicit trailing WS run and therefore does not fully * reflect itself all the levels. * This must be a UBiDi object for a line, and * we need to create a new levels array. */ if(getLevelsMemory(pBiDi, length)) { UBiDiLevel *levels=pBiDi->levelsMemory; if(start>0 && levels!=pBiDi->levels) { icu_memcpy(levels, pBiDi->levels, start); } icu_memset(levels+start, pBiDi->paraLevel, length-start); /* this new levels array is set for the line and reflects the WS run */ pBiDi->trailingWSStart=length; return pBiDi->levels=levels; } else { /* out of memory */ *pErrorCode=U_MEMORY_ALLOCATION_ERROR; return NULL; } }