/* * Copyright (C)2005-2016 Haxe Foundation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include HL_PRIM vbyte *hl_alloc_bytes( int size ) { return (vbyte*)hl_gc_alloc_noptr(size); } HL_PRIM vbyte *hl_copy_bytes( const vbyte *ptr, int size ) { vbyte *b = hl_alloc_bytes(size); memcpy(b,ptr,size); return b; } HL_PRIM void hl_bytes_blit( char *dst, int dpos, char *src, int spos, int len ) { memmove(dst + dpos,src+spos,len); } HL_PRIM int hl_bytes_compare( vbyte *a, int apos, vbyte *b, int bpos, int len ) { return memcmp(a+apos,b+bpos,len); } HL_PRIM int hl_bytes_compare16( vbyte *a, vbyte *b, int len ) { unsigned short *s1 = (unsigned short *)a; unsigned short *s2 = (unsigned short *)b; int i; for(i=0;i= pattern_size) return ((void*)(match_base)); } } return NULL; } HL_PRIM int hl_bytes_find( vbyte *where, int pos, int len, vbyte *which, int wpos, int wlen ) { size_t searchbuf [256]; bool repeat_find = false; vbyte *found = (vbyte*)memfind_rb(where + pos,len,which+wpos,wlen,searchbuf,&repeat_find); if( found == NULL ) return -1; return (int)(size_t)(found - where); } HL_PRIM int hl_bytes_rfind( vbyte *where, int len, vbyte *which, int wlen ) { if( wlen > len ) return -1; if( wlen == 0 ) return len; // at end int pos = len - wlen; while( pos >= 0 ) { if( memcmp(where+pos,which,wlen) == 0 ) return pos; pos--; } return -1; } HL_PRIM void hl_bytes_fill( vbyte *bytes, int pos, int len, int value ) { memset(bytes+pos,value,len); } static int ms_gcd( int m, int n ) { while( n != 0 ) { int t = m % n; m=n; n=t; } return m; } #define TSORT int #define TID(t) t##_i32 #include "sort.h" #define TSORT double #define TID(t) t##_f64 #include "sort.h" HL_PRIM void hl_bsort_i32( vbyte *bytes, int pos, int len, vclosure *cmp ) { m_sort_i32 m; m.arr = (int*)(bytes + pos); m.c = cmp; merge_sort_rec_i32(&m,0,len); } HL_PRIM void hl_bsort_f64( vbyte *bytes, int pos, int len, vclosure *cmp ) { m_sort_f64 m; m.arr = (double*)(bytes + pos); m.c = cmp; merge_sort_rec_f64(&m,0,len); } static inline bool is_space_char(uchar c) { return c == 32 || (c > 8 && c < 14); } HL_PRIM double hl_parse_float( vbyte *bytes, int pos, int len ) { const uchar *str = (uchar*)(bytes+pos); uchar *end = NULL; while( is_space_char(*str) ) str++; double d = utod(str,&end); if( end == str ) return hl_nan(); return d; } static inline bool has_hex_prefix( const uchar *c, int len, bool is_signed ) { if (is_signed) return len >= 3 && c[1] == '0' && (c[2] == 'x' || c[2] == 'X'); return len >= 2 && c[0] == '0' && (c[1] == 'x' || c[1] == 'X'); } HL_PRIM vdynamic *hl_parse_int( vbyte *bytes, int pos, int len ) { const uchar *c = (uchar*)(bytes + pos); const uchar *start = c; int h; while( is_space_char(*c) ) c++; uchar sign = c[0]; bool is_signed = sign == '-' || sign == '+'; if( has_hex_prefix(c,(int)(len+start-c),is_signed) ) { h = 0; c += is_signed ? 3 : 2; while( *c ) { uchar k = *c++; if( k >= '0' && k <= '9' ) h = (h << 4) | (k - '0'); else if( k >= 'A' && k <= 'F' ) h = (h << 4) | ((k - 'A') + 10); else if( k >= 'a' && k <= 'f' ) h = (h << 4) | ((k - 'a') + 10); else break; } if( sign == '-' ) h = -h; } else { uchar *end = NULL; h = utoi(c,&end); if( c == end ) return NULL; } return hl_make_dyn(&h,&hlt_i32); } // pointer manipulation HL_PRIM vbyte *hl_bytes_offset( vbyte *src, int offset ) { return src + offset; } HL_PRIM int hl_bytes_subtract( vbyte *a, vbyte *b ) { return (int)(a - b); } HL_PRIM int hl_bytes_address( vbyte *a, int *high ) { # ifdef HL_64 *high = (int)(((uint64)a)>>32); # else *high = 0; # endif return (int)(int_val)a; } HL_PRIM vbyte *hl_bytes_from_address( int low, int high ) { # ifdef HL_64 // MSVC does overflow on <<32 even on uint64... struct { int low; int high; } i64; i64.low = low; i64.high = high; return *(vbyte**)&i64; # else return (vbyte*)low; # endif } HL_PRIM int hl_string_compare( vbyte *a, vbyte *b, int len ) { return memcmp(a,b,len * sizeof(uchar)); } DEFINE_PRIM(_BYTES,alloc_bytes,_I32); DEFINE_PRIM(_VOID,bytes_blit,_BYTES _I32 _BYTES _I32 _I32); DEFINE_PRIM(_I32,bytes_compare,_BYTES _I32 _BYTES _I32 _I32); DEFINE_PRIM(_I32,bytes_compare16,_BYTES _BYTES _I32); DEFINE_PRIM(_I32,string_compare,_BYTES _BYTES _I32); DEFINE_PRIM(_I32,bytes_find,_BYTES _I32 _I32 _BYTES _I32 _I32); DEFINE_PRIM(_I32,bytes_rfind,_BYTES _I32 _BYTES _I32); DEFINE_PRIM(_VOID,bytes_fill,_BYTES _I32 _I32 _I32); DEFINE_PRIM(_F64, parse_float,_BYTES _I32 _I32); DEFINE_PRIM(_NULL(_I32), parse_int, _BYTES _I32 _I32); DEFINE_PRIM(_VOID,bsort_i32,_BYTES _I32 _I32 _FUN(_I32,_I32 _I32)); DEFINE_PRIM(_VOID,bsort_f64,_BYTES _I32 _I32 _FUN(_I32,_F64 _F64)); DEFINE_PRIM(_BYTES,bytes_offset, _BYTES _I32); DEFINE_PRIM(_I32,bytes_subtract, _BYTES _BYTES); DEFINE_PRIM(_I32,bytes_address, _BYTES _REF(_I32)); DEFINE_PRIM(_BYTES,bytes_from_address, _I32 _I32);