1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************* 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 4fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius* Copyright (C) 2003-2014, International Business Machines 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************* 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* file name: udataswp.c 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* encoding: US-ASCII 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* tab size: 8 (not used) 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* indentation:4 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* created on: 2003jun05 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* created by: Markus W. Scherer 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Definitions for ICU data transformations for different platforms, 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* changing between big- and little-endian data and/or between 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* charset families (ASCII<->EBCDIC). 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdarg.h> 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h" 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/udata.h" /* UDataInfo */ 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ucmndata.h" /* DataHeader */ 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h" 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "udataswp.h" 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* swapping primitives ------------------------------------------------------ */ 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t U_CALLCONV 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuprv_swapArray16(const UDataSwapper *ds, 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const void *inData, int32_t length, void *outData, 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const uint16_t *p; 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t *q; 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t count; 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t x; 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ds==NULL || inData==NULL || length<0 || (length&1)!=0 || outData==NULL) { 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* setup and swapping */ 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru p=(const uint16_t *)inData; 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru q=(uint16_t *)outData; 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count=length/2; 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(count>0) { 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru x=*p++; 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *q++=(uint16_t)((x<<8)|(x>>8)); 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru --count; 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return length; 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t U_CALLCONV 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuprv_copyArray16(const UDataSwapper *ds, 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const void *inData, int32_t length, void *outData, 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ds==NULL || inData==NULL || length<0 || (length&1)!=0 || outData==NULL) { 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length>0 && inData!=outData) { 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(outData, inData, length); 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return length; 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t U_CALLCONV 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuprv_swapArray32(const UDataSwapper *ds, 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const void *inData, int32_t length, void *outData, 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const uint32_t *p; 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t *q; 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t count; 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t x; 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ds==NULL || inData==NULL || length<0 || (length&3)!=0 || outData==NULL) { 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* setup and swapping */ 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru p=(const uint32_t *)inData; 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru q=(uint32_t *)outData; 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count=length/4; 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(count>0) { 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru x=*p++; 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *q++=(uint32_t)((x<<24)|((x<<8)&0xff0000)|((x>>8)&0xff00)|(x>>24)); 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru --count; 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return length; 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t U_CALLCONV 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuprv_copyArray32(const UDataSwapper *ds, 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const void *inData, int32_t length, void *outData, 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ds==NULL || inData==NULL || length<0 || (length&3)!=0 || outData==NULL) { 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length>0 && inData!=outData) { 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(outData, inData, length); 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return length; 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 126fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic int32_t U_CALLCONV 127fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusuprv_swapArray64(const UDataSwapper *ds, 128fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const void *inData, int32_t length, void *outData, 129fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode *pErrorCode) { 130fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const uint64_t *p; 131fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius uint64_t *q; 132fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t count; 133fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 134fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 135fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return 0; 136fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 137fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(ds==NULL || inData==NULL || length<0 || (length&7)!=0 || outData==NULL) { 138fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 139fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return 0; 140fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 141fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 142fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius /* setup and swapping */ 143fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius p=(const uint64_t *)inData; 144fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius q=(uint64_t *)outData; 145fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius count=length/8; 146fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius while(count>0) { 147fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius uint64_t x=*p++; 148fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius x=(x<<56)|((x&0xff00)<<40)|((x&0xff0000)<<24)|((x&0xff000000)<<8)| 149fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ((x>>8)&0xff000000)|((x>>24)&0xff0000)|((x>>40)&0xff00)|(x>>56); 150fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *q++=x; 151fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius --count; 152fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 153fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 154fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return length; 155fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 156fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 157fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic int32_t U_CALLCONV 158fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusuprv_copyArray64(const UDataSwapper *ds, 159fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const void *inData, int32_t length, void *outData, 160fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode *pErrorCode) { 161fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 162fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return 0; 163fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 164fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(ds==NULL || inData==NULL || length<0 || (length&7)!=0 || outData==NULL) { 165fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 166fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return 0; 167fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 168fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 169fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(length>0 && inData!=outData) { 170fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius uprv_memcpy(outData, inData, length); 171fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 172fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return length; 173fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 174fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic uint16_t U_CALLCONV 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuprv_readSwapUInt16(uint16_t x) { 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (uint16_t)((x<<8)|(x>>8)); 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic uint16_t U_CALLCONV 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuprv_readDirectUInt16(uint16_t x) { 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return x; 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic uint32_t U_CALLCONV 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuprv_readSwapUInt32(uint32_t x) { 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (uint32_t)((x<<24)|((x<<8)&0xff0000)|((x>>8)&0xff00)|(x>>24)); 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic uint32_t U_CALLCONV 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuprv_readDirectUInt32(uint32_t x) { 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return x; 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void U_CALLCONV 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuprv_writeSwapUInt16(uint16_t *p, uint16_t x) { 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *p=(uint16_t)((x<<8)|(x>>8)); 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void U_CALLCONV 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuprv_writeDirectUInt16(uint16_t *p, uint16_t x) { 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *p=x; 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void U_CALLCONV 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuprv_writeSwapUInt32(uint32_t *p, uint32_t x) { 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *p=(uint32_t)((x<<24)|((x<<8)&0xff0000)|((x>>8)&0xff00)|(x>>24)); 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void U_CALLCONV 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruuprv_writeDirectUInt32(uint32_t *p, uint32_t x) { 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *p=x; 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int16_t U_EXPORT2 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruudata_readInt16(const UDataSwapper *ds, int16_t x) { 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (int16_t)ds->readUInt16((uint16_t)x); 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruudata_readInt32(const UDataSwapper *ds, int32_t x) { 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (int32_t)ds->readUInt32((uint32_t)x); 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Swap a block of invariant, NUL-terminated strings, but not padding 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * bytes after the last string. 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @internal 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruudata_swapInvStringBlock(const UDataSwapper *ds, 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const void *inData, int32_t length, void *outData, 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *inChars; 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t stringsLength; 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ds==NULL || inData==NULL || length<0 || (length>0 && outData==NULL)) { 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* reduce the strings length to not include bytes after the last NUL */ 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inChars=(const char *)inData; 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru stringsLength=length; 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(stringsLength>0 && inChars[stringsLength-1]!=0) { 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru --stringsLength; 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap up to the last NUL */ 253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapInvChars(ds, inData, stringsLength, outData, pErrorCode); 254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy the bytes after the last NUL */ 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(inData!=outData && length>stringsLength) { 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy((char *)outData+stringsLength, inChars+stringsLength, length-stringsLength); 258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* return the length including padding bytes */ 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_SUCCESS(*pErrorCode)) { 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return length; 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruudata_printError(const UDataSwapper *ds, 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *fmt, 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ...) { 272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru va_list args; 273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ds->printError!=NULL) { 275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru va_start(args, fmt); 276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->printError(ds->printErrorContext, fmt, args); 277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru va_end(args); 278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* swap a data header ------------------------------------------------------- */ 282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruudata_swapDataHeader(const UDataSwapper *ds, 285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const void *inData, int32_t length, void *outData, 286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const DataHeader *pHeader; 288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t headerSize, infoSize; 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* argument checking */ 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(ds==NULL || inData==NULL || length<-1 || (length>0 && outData==NULL)) { 295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* check minimum length and magic bytes */ 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pHeader=(const DataHeader *)inData; 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( (length>=0 && length<sizeof(DataHeader)) || 302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pHeader->dataHeader.magic1!=0xda || 303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pHeader->dataHeader.magic2!=0x27 || 304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pHeader->info.sizeofUChar!=2 305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "udata_swapDataHeader(): initial bytes do not look like ICU data\n"); 307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru headerSize=ds->readUInt16(pHeader->dataHeader.headerSize); 312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru infoSize=ds->readUInt16(pHeader->info.size); 313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( headerSize<sizeof(DataHeader) || 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru infoSize<sizeof(UDataInfo) || 316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru headerSize<(sizeof(pHeader->dataHeader)+infoSize) || 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (length>=0 && length<headerSize) 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru udata_printError(ds, "udata_swapDataHeader(): header size mismatch - headerSize %d infoSize %d length %d\n", 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru headerSize, infoSize, length); 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(length>0) { 326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DataHeader *outHeader; 327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *s; 328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t maxLength; 329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Most of the fields are just bytes and need no swapping. */ 331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(inData!=outData) { 332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(outData, inData, headerSize); 333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outHeader=(DataHeader *)outData; 335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outHeader->info.isBigEndian = ds->outIsBigEndian; 337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outHeader->info.charsetFamily = ds->outCharset; 338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap headerSize */ 340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, &pHeader->dataHeader.headerSize, 2, &outHeader->dataHeader.headerSize, pErrorCode); 341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap UDataInfo size and reservedWord */ 343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapArray16(ds, &pHeader->info.size, 4, &outHeader->info.size, pErrorCode); 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap copyright statement after the UDataInfo */ 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru infoSize+=sizeof(pHeader->dataHeader); 347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru s=(const char *)inData+infoSize; 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru maxLength=headerSize-infoSize; 349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* get the length of the string */ 350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(length=0; length<maxLength && s[length]!=0; ++length) {} 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* swap the string contents */ 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ds->swapInvChars(ds, s, length, (char *)outData+infoSize, pErrorCode); 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return headerSize; 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* API functions ------------------------------------------------------------ */ 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI UDataSwapper * U_EXPORT2 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruudata_openSwapper(UBool inIsBigEndian, uint8_t inCharset, 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool outIsBigEndian, uint8_t outCharset, 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UDataSwapper *swapper; 365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(inCharset>U_EBCDIC_FAMILY || outCharset>U_EBCDIC_FAMILY) { 370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* allocate the swapper */ 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru swapper=uprv_malloc(sizeof(UDataSwapper)); 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(swapper==NULL) { 377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(swapper, 0, sizeof(UDataSwapper)); 381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set values and functions pointers according to in/out parameters */ 383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru swapper->inIsBigEndian=inIsBigEndian; 384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru swapper->inCharset=inCharset; 385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru swapper->outIsBigEndian=outIsBigEndian; 386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru swapper->outCharset=outCharset; 387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru swapper->readUInt16= inIsBigEndian==U_IS_BIG_ENDIAN ? uprv_readDirectUInt16 : uprv_readSwapUInt16; 389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru swapper->readUInt32= inIsBigEndian==U_IS_BIG_ENDIAN ? uprv_readDirectUInt32 : uprv_readSwapUInt32; 390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru swapper->writeUInt16= outIsBigEndian==U_IS_BIG_ENDIAN ? uprv_writeDirectUInt16 : uprv_writeSwapUInt16; 392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru swapper->writeUInt32= outIsBigEndian==U_IS_BIG_ENDIAN ? uprv_writeDirectUInt32 : uprv_writeSwapUInt32; 393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru swapper->compareInvChars= outCharset==U_ASCII_FAMILY ? uprv_compareInvAscii : uprv_compareInvEbcdic; 395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 396fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(inIsBigEndian==outIsBigEndian) { 397fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius swapper->swapArray16=uprv_copyArray16; 398fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius swapper->swapArray32=uprv_copyArray32; 399fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius swapper->swapArray64=uprv_copyArray64; 400fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 401fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius swapper->swapArray16=uprv_swapArray16; 402fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius swapper->swapArray32=uprv_swapArray32; 403fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius swapper->swapArray64=uprv_swapArray64; 404fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(inCharset==U_ASCII_FAMILY) { 407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru swapper->swapInvChars= outCharset==U_ASCII_FAMILY ? uprv_copyAscii : uprv_ebcdicFromAscii; 408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else /* U_EBCDIC_FAMILY */ { 409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru swapper->swapInvChars= outCharset==U_EBCDIC_FAMILY ? uprv_copyEbcdic : uprv_asciiFromEbcdic; 410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return swapper; 413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI UDataSwapper * U_EXPORT2 416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruudata_openSwapperForInputData(const void *data, int32_t length, 417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool outIsBigEndian, uint8_t outCharset, 418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode *pErrorCode) { 419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const DataHeader *pHeader; 420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint16_t headerSize, infoSize; 421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool inIsBigEndian; 422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int8_t inCharset; 423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( data==NULL || 428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (length>=0 && length<sizeof(DataHeader)) || 429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru outCharset>U_EBCDIC_FAMILY 430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pHeader=(const DataHeader *)data; 436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( (length>=0 && length<sizeof(DataHeader)) || 437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pHeader->dataHeader.magic1!=0xda || 438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pHeader->dataHeader.magic2!=0x27 || 439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pHeader->info.sizeofUChar!=2 440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inIsBigEndian=(UBool)pHeader->info.isBigEndian; 446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inCharset=pHeader->info.charsetFamily; 447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(inIsBigEndian==U_IS_BIG_ENDIAN) { 449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru headerSize=pHeader->dataHeader.headerSize; 450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru infoSize=pHeader->info.size; 451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru headerSize=uprv_readSwapUInt16(pHeader->dataHeader.headerSize); 453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru infoSize=uprv_readSwapUInt16(pHeader->info.size); 454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( headerSize<sizeof(DataHeader) || 457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru infoSize<sizeof(UDataInfo) || 458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru headerSize<(sizeof(pHeader->dataHeader)+infoSize) || 459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (length>=0 && length<headerSize) 460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return udata_openSwapper(inIsBigEndian, inCharset, outIsBigEndian, outCharset, pErrorCode); 466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruudata_closeSwapper(UDataSwapper *ds) { 470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(ds); 471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 472