// © 2016 and later: Unicode, Inc. and others. // License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * * Copyright (C) 2000-2003, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* * * File writejava.c * * Modification History: * * Date Name Description * 01/11/02 Ram Creation. ******************************************************************************* */ #include #include "rle.h" /** * The ESCAPE character is used during run-length encoding. It signals * a run of identical chars. */ static const uint16_t ESCAPE = 0xA5A5; /** * The ESCAPE_BYTE character is used during run-length encoding. It signals * a run of identical bytes. */ static const uint8_t ESCAPE_BYTE = (uint8_t)0xA5; /** * Append a byte to the given StringBuffer, packing two bytes into each * character. The state parameter maintains intermediary data between * calls. * @param state A two-element array, with state[0] == 0 if this is the * first byte of a pair, or state[0] != 0 if this is the second byte * of a pair, in which case state[1] is the first byte. */ static uint16_t* appendEncodedByte(uint16_t* buffer, uint16_t* buffLimit, uint8_t value, uint8_t state[],UErrorCode* status) { if(!status || U_FAILURE(*status)){ return NULL; } if (state[0] != 0) { uint16_t c = (uint16_t) ((state[1] << 8) | (((int32_t) value) & 0xFF)); if(buffer < buffLimit){ *buffer++ = c; }else{ *status = U_BUFFER_OVERFLOW_ERROR; } state[0] = 0; return buffer; } else { state[0] = 1; state[1] = value; return buffer; } } /** * Encode a run, possibly a degenerate run (of < 4 values). * @param length The length of the run; must be > 0 && <= 0xFF. */ static uint16_t* encodeRunByte(uint16_t* buffer,uint16_t* bufLimit, uint8_t value, int32_t length, uint8_t state[], UErrorCode* status) { if(!status || U_FAILURE(*status)){ return NULL; } if (length < 4) { int32_t j=0; for (; j 0 && <= 0xFFFF. */ static uint16_t* encodeRunShort(uint16_t* buffer,uint16_t* bufLimit, uint16_t value, int32_t length,UErrorCode* status) { int32_t num=0; if (length < 4) { int j=0; for (; j 0 and n != ESCAPE and n <= 0xFFFF. * If we encounter a run where n == ESCAPE, we represent this as: * c ESCAPE n-1 c * The ESCAPE value is chosen so as not to collide with commonly * seen values. */ int32_t usArrayToRLEString(const uint16_t* src,int32_t srcLen,uint16_t* buffer, int32_t bufLen,UErrorCode* status) { uint16_t* bufLimit = buffer+bufLen; uint16_t* saveBuffer = buffer; if(buffer < bufLimit){ *buffer++ = (uint16_t)(srcLen>>16); if(buffer 0 and n != ESCAPE_BYTE and n <= 0xFF. * If we encounter a run where n == ESCAPE_BYTE, we represent this as: * b ESCAPE_BYTE n-1 b * The ESCAPE_BYTE value is chosen so as not to collide with commonly * seen values. */ int32_t byteArrayToRLEString(const uint8_t* src,int32_t srcLen, uint16_t* buffer,int32_t bufLen, UErrorCode* status) { const uint16_t* saveBuf = buffer; uint16_t* bufLimit = buffer+bufLen; if(buffer < bufLimit){ *buffer++ = ((uint16_t) (srcLen >> 16)); if(buffer> 8); nextChar = false; } else { b = (uint8_t) (c & 0xFF); nextChar = true; } /* This part of the loop is a tiny state machine which handles * the parsing of the run-length encoding. This would be simpler * if we could look ahead, but we can't, so we use 'node' to * move between three nodes in the state machine. */ switch (node) { case 0: /* Normal idle node */ if (b == ESCAPE_BYTE) { node = 1; } else { target[ai++] = b; } break; case 1: /* We have seen one ESCAPE_BYTE; we expect either a second * one, or a run length and value. */ if (b == ESCAPE_BYTE) { target[ai++] = ESCAPE_BYTE; node = 0; } else { runLength = b; node = 2; } break; case 2: { int j=0; /* We have seen an ESCAPE_BYTE and length byte. We interpret * the next byte as the value to be repeated. */ for (; j