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