1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************* 3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Copyright (C) 2000-2003, International Business Machines 5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Corporation and others. All Rights Reserved. 6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************* 8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* File writejava.c 10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Modification History: 12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Date Name Description 14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 01/11/02 Ram Creation. 15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************* 16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "rle.h" 18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The ESCAPE character is used during run-length encoding. It signals 20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * a run of identical chars. 21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const uint16_t ESCAPE = 0xA5A5; 23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The ESCAPE_BYTE character is used during run-length encoding. It signals 26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * a run of identical bytes. 27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const uint8_t ESCAPE_BYTE = (uint8_t)0xA5; 29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Append a byte to the given StringBuffer, packing two bytes into each 32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * character. The state parameter maintains intermediary data between 33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * calls. 34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param state A two-element array, with state[0] == 0 if this is the 35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * first byte of a pair, or state[0] != 0 if this is the second byte 36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * of a pair, in which case state[1] is the first byte. 37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint16_t* 39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)appendEncodedByte(uint16_t* buffer, uint16_t* buffLimit, uint8_t value, uint8_t state[],UErrorCode* status) { 40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!status || U_FAILURE(*status)){ 41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (state[0] != 0) { 44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t c = (uint16_t) ((state[1] << 8) | (((int32_t) value) & 0xFF)); 45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(buffer < buffLimit){ 46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *buffer++ = c; 47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_BUFFER_OVERFLOW_ERROR; 49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) state[0] = 0; 51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return buffer; 52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) state[0] = 1; 55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) state[1] = value; 56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return buffer; 57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Encode a run, possibly a degenerate run (of < 4 values). 61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param length The length of the run; must be > 0 && <= 0xFF. 62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint16_t* 64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)encodeRunByte(uint16_t* buffer,uint16_t* bufLimit, uint8_t value, int32_t length, uint8_t state[], UErrorCode* status) { 65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!status || U_FAILURE(*status)){ 66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (length < 4) { 69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t j=0; 70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (; j<length; ++j) { 71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (value == ESCAPE_BYTE) { 72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer = appendEncodedByte(buffer,bufLimit, ESCAPE_BYTE, state,status); 73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer = appendEncodedByte(buffer,bufLimit, value, state, status); 75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (length == ESCAPE_BYTE) { 79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (value == ESCAPE_BYTE){ 80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer = appendEncodedByte(buffer, bufLimit,ESCAPE_BYTE, state,status); 81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer = appendEncodedByte(buffer,bufLimit, value, state, status); 83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) --length; 84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer = appendEncodedByte(buffer,bufLimit, ESCAPE_BYTE, state,status); 86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer = appendEncodedByte(buffer,bufLimit, (char)length, state, status); 87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer = appendEncodedByte(buffer,bufLimit, value, state, status); /* Don't need to escape this value*/ 88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return buffer; 90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define APPEND( buffer, bufLimit, value, num, status){ \ 93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(buffer<bufLimit){ \ 94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *buffer++=(value); \ 95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ \ 96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_BUFFER_OVERFLOW_ERROR; \ 97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } \ 98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) num++; \ 99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Encode a run, possibly a degenerate run (of < 4 values). 103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param length The length of the run; must be > 0 && <= 0xFFFF. 104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint16_t* 106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)encodeRunShort(uint16_t* buffer,uint16_t* bufLimit, uint16_t value, int32_t length,UErrorCode* status) { 107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t num=0; 108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (length < 4) { 109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int j=0; 110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (; j<length; ++j) { 111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (value == (int32_t) ESCAPE){ 112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) APPEND(buffer,bufLimit,ESCAPE, num, status); 113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) APPEND(buffer,bufLimit,value,num, status); 116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (length == (int32_t) ESCAPE) { 120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (value == (int32_t) ESCAPE){ 121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) APPEND(buffer,bufLimit,ESCAPE,num,status); 122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) APPEND(buffer,bufLimit,value,num,status); 125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) --length; 126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) APPEND(buffer,bufLimit,ESCAPE,num,status); 128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) APPEND(buffer,bufLimit,(uint16_t) length, num,status); 129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) APPEND(buffer,bufLimit,(uint16_t)value, num, status); /* Don't need to escape this value */ 130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return buffer; 132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Construct a string representing a char array. Use run-length encoding. 136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * A character represents itself, unless it is the ESCAPE character. Then 137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * the following notations are possible: 138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * ESCAPE ESCAPE ESCAPE literal 139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * ESCAPE n c n instances of character c 140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Since an encoded run occupies 3 characters, we only encode runs of 4 or 141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * more characters. Thus we have n > 0 and n != ESCAPE and n <= 0xFFFF. 142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * If we encounter a run where n == ESCAPE, we represent this as: 143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * c ESCAPE n-1 c 144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The ESCAPE value is chosen so as not to collide with commonly 145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * seen values. 146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t 148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)usArrayToRLEString(const uint16_t* src,int32_t srcLen,uint16_t* buffer, int32_t bufLen,UErrorCode* status) { 149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t* bufLimit = buffer+bufLen; 150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t* saveBuffer = buffer; 151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(buffer < bufLimit){ 152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *buffer++ = (uint16_t)(srcLen>>16); 153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(buffer<bufLimit){ 154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t runValue = src[0]; 155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t runLength = 1; 156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int i=1; 157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *buffer++ = (uint16_t) srcLen; 158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (; i<srcLen; ++i) { 160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t s = src[i]; 161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (s == runValue && runLength < 0xFFFF){ 162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++runLength; 163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else { 164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer = encodeRunShort(buffer,bufLimit, (uint16_t)runValue, runLength,status); 165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) runValue = s; 166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) runLength = 1; 167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer= encodeRunShort(buffer,bufLimit,(uint16_t)runValue, runLength,status); 170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_BUFFER_OVERFLOW_ERROR; 172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_BUFFER_OVERFLOW_ERROR; 175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (int32_t)(buffer - saveBuffer); 177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Construct a string representing a byte array. Use run-length encoding. 181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Two bytes are packed into a single char, with a single extra zero byte at 182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * the end if needed. A byte represents itself, unless it is the 183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * ESCAPE_BYTE. Then the following notations are possible: 184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * ESCAPE_BYTE ESCAPE_BYTE ESCAPE_BYTE literal 185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * ESCAPE_BYTE n b n instances of byte b 186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Since an encoded run occupies 3 bytes, we only encode runs of 4 or 187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * more bytes. Thus we have n > 0 and n != ESCAPE_BYTE and n <= 0xFF. 188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * If we encounter a run where n == ESCAPE_BYTE, we represent this as: 189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * b ESCAPE_BYTE n-1 b 190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The ESCAPE_BYTE value is chosen so as not to collide with commonly 191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * seen values. 192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t 194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)byteArrayToRLEString(const uint8_t* src,int32_t srcLen, uint16_t* buffer,int32_t bufLen, UErrorCode* status) { 195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const uint16_t* saveBuf = buffer; 196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t* bufLimit = buffer+bufLen; 197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(buffer < bufLimit){ 198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *buffer++ = ((uint16_t) (srcLen >> 16)); 199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(buffer<bufLimit){ 201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint8_t runValue = src[0]; 202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int runLength = 1; 203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint8_t state[2]= {0}; 204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int i=1; 205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *buffer++=((uint16_t) srcLen); 206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (; i<srcLen; ++i) { 207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint8_t b = src[i]; 208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (b == runValue && runLength < 0xFF){ 209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++runLength; 210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer = encodeRunByte(buffer, bufLimit,runValue, runLength, state,status); 213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) runValue = b; 214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) runLength = 1; 215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer = encodeRunByte(buffer,bufLimit, runValue, runLength, state, status); 218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* We must save the final byte, if there is one, by padding 220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * an extra zero. 221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (state[0] != 0) { 223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) buffer = appendEncodedByte(buffer,bufLimit, 0, state ,status); 224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_BUFFER_OVERFLOW_ERROR; 227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_BUFFER_OVERFLOW_ERROR; 230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (int32_t) (buffer - saveBuf); 232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Construct an array of shorts from a run-length encoded string. 237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t 239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)rleStringToUCharArray(uint16_t* src, int32_t srcLen, uint16_t* target, int32_t tgtLen, UErrorCode* status) { 240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t length = 0; 241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t ai = 0; 242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int i=2; 243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!status || U_FAILURE(*status)){ 245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* the source is null terminated */ 248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcLen == -1){ 249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcLen = u_strlen(src); 250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcLen <= 2){ 252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 2; 253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length = (((int32_t) src[0]) << 16) | ((int32_t) src[1]); 255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(target == NULL){ 257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return length; 258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(tgtLen < length){ 260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_BUFFER_OVERFLOW_ERROR; 261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return length; 262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (; i<srcLen; ++i) { 265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t c = src[i]; 266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (c == ESCAPE) { 267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c = src[++i]; 268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (c == ESCAPE) { 269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) target[ai++] = c; 270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t runLength = (int32_t) c; 272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t runValue = src[++i]; 273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int j=0; 274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (; j<runLength; ++j) { 275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) target[ai++] = runValue; 276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) target[ai++] = c; 281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (ai != length){ 285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_INTERNAL_PROGRAM_ERROR; 286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return length; 289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Construct an array of bytes from a run-length encoded string. 293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t 295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)rleStringToByteArray(uint16_t* src, int32_t srcLen, uint8_t* target, int32_t tgtLen, UErrorCode* status) { 296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t length = 0; 298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool nextChar = TRUE; 299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t c = 0; 300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t node = 0; 301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t runLength = 0; 302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i = 2; 303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t ai=0; 304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!status || U_FAILURE(*status)){ 306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* the source is null terminated */ 309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcLen == -1){ 310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcLen = u_strlen(src); 311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcLen <= 2){ 313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 2; 314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length = (((int32_t) src[0]) << 16) | ((int32_t) src[1]); 316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(target == NULL){ 318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return length; 319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(tgtLen < length){ 321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_BUFFER_OVERFLOW_ERROR; 322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return length; 323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (; ai<tgtLen; ) { 326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* This part of the loop places the next byte into the local 327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * variable 'b' each time through the loop. It keeps the 328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * current character in 'c' and uses the boolean 'nextChar' 329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * to see if we've taken both bytes out of 'c' yet. 330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint8_t b; 332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (nextChar) { 333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c = src[i++]; 334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b = (uint8_t) (c >> 8); 335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) nextChar = FALSE; 336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b = (uint8_t) (c & 0xFF); 339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) nextChar = TRUE; 340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* This part of the loop is a tiny state machine which handles 343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * the parsing of the run-length encoding. This would be simpler 344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * if we could look ahead, but we can't, so we use 'node' to 345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * move between three nodes in the state machine. 346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch (node) { 348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 0: 349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Normal idle node */ 350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (b == ESCAPE_BYTE) { 351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) node = 1; 352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) target[ai++] = b; 355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 1: 358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* We have seen one ESCAPE_BYTE; we expect either a second 359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * one, or a run length and value. 360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (b == ESCAPE_BYTE) { 362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) target[ai++] = ESCAPE_BYTE; 363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) node = 0; 364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) runLength = b; 367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) node = 2; 368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 2: 371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int j=0; 373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* We have seen an ESCAPE_BYTE and length byte. We interpret 374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * the next byte as the value to be repeated. 375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (; j<runLength; ++j){ 377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(ai<tgtLen){ 378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) target[ai++] = b; 379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_BUFFER_OVERFLOW_ERROR; 381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ai; 382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) node = 0; 385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (node != 0){ 391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_INTERNAL_PROGRAM_ERROR; 392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /*("Bad run-length encoded byte array")*/ 393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (i != srcLen){ 398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /*("Excess data in RLE byte array string");*/ 399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_INTERNAL_PROGRAM_ERROR; 400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ai; 401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ai; 404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 406