/* * util.c * Miscellaneous support * * Copyright (C) 1997,1999 Martin von Löwis * Copyright (C) 1997 Régis Duchesne * * The utf8 routines are copied from Python wstrop module. */ #include "ntfstypes.h" #include "struct.h" #include "util.h" #include /* FreeBSD doesn't seem to have EILSEQ in errno.h */ #ifndef EILSEQ # define EILSEQ EINVAL #endif #include "support.h" /* Converts a single wide character to a sequence of utf8 bytes. * The character is represented in host byte order. * Returns the number of bytes, or 0 on error. */ static int to_utf8(ntfs_u16 c,unsigned char* buf) { if(c==0) return 0; /* No support for embedded 0 runes */ if(c<0x80){ if(buf)buf[0]=(unsigned char)c; return 1; } if(c<0x800){ if(buf){ buf[0] = 0xc0 | (c>>6); buf[1] = 0x80 | (c & 0x3f); } return 2; } if(c<0x10000){ if(buf){ buf[0] = 0xe0 | (c>>12); buf[1] = 0x80 | ((c>>6) & 0x3f); buf[2] = 0x80 | (c & 0x3f); } return 3; } /* We don't support characters above 0xFFFF in NTFS */ return 0; } /* Decodes a sequence of utf8 bytes into a single wide character. * The character is returned in host byte order. * Returns the number of bytes consumed, or 0 on error. */ static int from_utf8(const unsigned char* str,ntfs_u16 *c) { int l=0,i; if(*str<0x80){ *c = *str; return 1; } if(*str<0xc0) /* lead byte must not be 10xxxxxx */ return 0; /* is c0 a possible lead byte? */ if(*str<0xe0){ /* 110xxxxx */ *c = *str & 0x1f; l=2; }else if(*str<0xf0){ /* 1110xxxx */ *c = *str & 0xf; l=3; }else if(*str<0xf8){ /* 11110xxx */ *c = *str & 7; l=4; }else /* We don't support characters above 0xFFFF in NTFS */ return 0; for(i=1;i=256) return EILSEQ; *out=result=ntfs_malloc(in_len+1); if(!result) return ENOMEM; result[in_len]='\0'; *out_len=in_len; for(i=0;inct & nct_utf8) return ntfs_dupuni2utf8(in,in_len,out,out_len); else if(vol->nct & nct_iso8859_1) return ntfs_dupuni288591(in,in_len,out,out_len); else if(vol->nct & (nct_map|nct_uni_xlate)) /* uni_xlate is handled inside map */ return ntfs_dupuni2map(vol,in,in_len,out,out_len); else return EINVAL; /* unknown encoding */ } int ntfs_decodeuni(ntfs_volume *vol,char *in, int in_len, ntfs_u16 **out, int *out_len) { if(vol->nct & nct_utf8) return ntfs_duputf82uni(in,in_len,out,out_len); else if(vol->nct & nct_iso8859_1) return ntfs_dup885912uni(in,in_len,out,out_len); else if(vol->nct & (nct_map | nct_uni_xlate)) return ntfs_dupmap2uni(vol,in,in_len,out,out_len); else return EINVAL; } /* Same address space copies */ void ntfs_put(ntfs_io *dest,void *src,ntfs_size_t n) { ntfs_memcpy(dest->param,src,n); ((char*)dest->param)+=n; } void ntfs_get(void* dest,ntfs_io *src,ntfs_size_t n) { ntfs_memcpy(dest,src->param,n); ((char*)src->param)+=n; } void *ntfs_calloc(int size) { void *result=ntfs_malloc(size); if(result) ntfs_bzero(result,size); return result; } #if 0 /* copy len unicode characters from from to to :) */ void ntfs_uni2ascii(char *to,char *from,int len) { int i; for(i=0;i> 32); unsigned int L = (unsigned int)ntutc; unsigned int numerator2; unsigned int lowseconds; unsigned int result; /* It is best to subtract 0x019db1ded53e8000 first. */ /* Then the 1601-based date becomes a 1970-based date. */ if(L < (unsigned)0xd53e8000) H--; L -= (unsigned)0xd53e8000; H -= (unsigned)0x019db1de; /* * Now divide 64-bit numbers on a 32-bit machine :-) * With the subtraction already done, the result fits in 32 bits. * The numerator fits in 56 bits and the denominator fits * in 24 bits, so we can shift by 8 bits to make this work. */ numerator2 = (H<<8) | (L>>24); result = (numerator2 / D); /* shifted 24 right!! */ lowseconds = result << 24; numerator2 = ((numerator2-result*D)<<8) | ((L>>16)&0xff); result = (numerator2 / D); /* shifted 16 right!! */ lowseconds |= result << 16; numerator2 = ((numerator2-result*D)<<8) | ((L>>8)&0xff); result = (numerator2 / D); /* shifted 8 right!! */ lowseconds |= result << 8; numerator2 = ((numerator2-result*D)<<8) | (L&0xff); result = (numerator2 / D); /* not shifted */ lowseconds |= result; return lowseconds; } /* Convert the Unix UTC into NT UTC */ ntfs_time64_t ntfs_unixutc2ntutc(ntfs_time_t t) { return ((t + (ntfs_time64_t)(369*365+89)*24*3600) * 10000000); } /* Fill index name. */ void ntfs_indexname(char *buf, int type) { char hex[]="0123456789ABCDEF"; int index; *buf++='$'; *buf++='I'; for (index=24; index>0; index-=4) if((0xF << index) & type) break; while(index>=0) { *buf++ = hex[(type >> index) & 0xF]; index-=4; } *buf='\0'; } /* * Local variables: * c-file-style: "linux" * End: */