/* * This file was generated automatically by ExtUtils::ParseXS version 2.18 from the * contents of Map.xs. Do not edit this file, edit Map.xs instead. * * ANY CHANGES MADE HERE WILL BE LOST! * */ #line 1 "Map.xs" /* * $Id: Map.xs,v 1.28 1998/03/23 23:57:46 schwartz Exp $ * * ALPHA version * * Unicode::Map - C extensions * * Interface documentation at Map.pm * * Copyright (C) 1998, 1999, 2000 Martin Schwartz. All rights reserved. * This program is free software; you can redistribute it and/or * modify it under the same terms as Perl itself. * * Contact: Martin Schwartz */ #ifdef __cplusplus extern "C" { #endif #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #ifdef __cplusplus } #endif /* * It seems that dowarn isn't defined on some systems, PL_dowarn not on * others. Gisle Aas deals with it this way: */ #include "patchlevel.h" #if PATCHLEVEL <= 4 && !defined(PL_dowarn) #define PL_dowarn dowarn #endif /* * * "Map.h" * */ #define M_MAGIC 0xb827 /* magic word */ #define MAP8_BINFILE_MAGIC_HI 0xfffe /* magic word for Gisle's file format */ #define MAP8_BINFILE_MAGIC_LO 0x0001 /* */ #define M_END 0 /* end */ #define M_INF 1 /* infinite subsequent entries (default) */ #define M_BYTE 2 /* 1..255 subsequent entries */ #define M_VER 4 /* (Internal) file format revision. */ #define M_AKV 6 /* key1, val1, key2, val2, ... (default) */ #define M_AKAV 7 /* key1, key2, ..., val1, val2, ... */ #define M_PKV 8 /* partial key value mappings */ #define M_CKn 10 /* compress keys not */ #define M_CK 11 /* compress keys (default) */ #define M_CVn 13 /* compress values not */ #define M_CV 14 /* compress values (default) */ #define I_NAME 20 /* Info: (wstring) Character Set Name */ #define I_ALIAS 21 /* Info: (wstring) Charset alias (several entries ok) */ #define I_VER 22 /* Info: (wstring) Mapfile revision */ #define I_AUTH 23 /* Info: (wstring) Mapfile authRess */ #define I_INFO 24 /* Info: (wstring) Some userEss definable string */ #define T_BAD 0 /* Type: unknown */ #define T_MAP8 1 /* Type: Map8 style */ #define T_MAP 2 /* Type: Map style */ #define num1_DEFAULT M_INF; #define method1_DEFAULT M_AKV; #define keys1_DEFAULT M_CK; #define values1_DEFAULT M_CV; /* No function prototypes (as very old C-Compilers don't like them) */ /* * * "Map.c" * */ U8 _byte(char** buf) { U8* tmp = (U8*) *buf; *buf+=1; return tmp[0]; } U16 _word(char** buf) { U16 tmp; memcpy ((char*) &tmp, *buf, 2); *buf+=2; return ntohs(tmp); } U32 _long(char** buf) { U32 tmp; memcpy ((char*) &tmp, *buf, 4); *buf+=4; return ntohl(tmp); } AV* __system_test (void) { /* * If this test suit gets passed ok, the C methods will probably work. */ char* check = "\x01\x04\xfe\x83\x73\xf8\x04\x59\x19"; char* buf; AV* list = newAV(); U32 i, k; /* * Have the Unn the bytesize I assume? */ if (sizeof(U8)!=1) { av_push (list, newSVpv("1a", 1)); } if (sizeof(U16)!=2) { av_push (list, newSVpv("1b", 1)); } if (sizeof(U32)!=4) { av_push (list, newSVpv("1c", 1)); } /* * Does _byte work? */ buf = check; if (_byte(&buf) != 0x01) { av_push(list, newSVpv("2a", 2)); } if (_byte(&buf) != 0x04) { av_push(list, newSVpv("2b", 2)); } if (_byte(&buf) != 0xfe) { av_push(list, newSVpv("2c", 2)); } if (_byte(&buf) != 0x83) { av_push(list, newSVpv("2d", 2)); } /* * Are _word and _long really reading Network order? */ if (_word(&buf) != 0x73f8) { av_push(list, newSVpv("3a", 2)); } if (_word(&buf) != 0x0459) { av_push(list, newSVpv("3b", 2)); } buf = check + 1; if (_byte(&buf) != 0x04) { av_push(list, newSVpv("4a", 2)); } if (_long(&buf) != 0xfe8373f8) { av_push(list, newSVpv("4b", 2)); } /* * Is U32 really not an I32? */ buf = check + 2; i = _long(&buf); i ++; if (i != 0xfe8373f9) { av_push(list, newSVpv("5", 1)); } k = htonl(0x12345678); if (memcmp((char*)&k+(4-1), "\x78", 1)) { av_push(list, newSVpv("6a", 2)); } if (memcmp((char*)&k+(4-2), "\x56\x78", 2)) { av_push(list, newSVpv("6b", 2)); } if (memcmp((char*)&k+(4-4), "\x12\x34\x56\x78", 4)) { av_push(list, newSVpv("6c", 2)); } return (list); } int __limit_ol (SV* string, SV* o, SV* l, char** ro, U32* rl, U16 cs) { /* * Checks, if offset and length are valid. If offset is negative, it is * treated like a negative offset in perl. * * When successful, sets ro (real offset) and rl (real length). */ STRLEN slen; char* address; I32 offset; U32 length; *ro = 0; *rl = 0; if (!SvOK(string)) { if (PL_dowarn) { warn ("String undefined!"); } return (0); } address = SvPV (string, slen); offset = SvOK(o) ? SvIV(o) : 0; length = SvOK(l) ? SvIV(l) : slen; if (offset < 0) { offset += slen; } if (offset < 0) { offset = 0; length = slen; if (PL_dowarn) { warn ("Bad negative string offset!"); } } if (offset > slen) { offset = slen; length = 0; if (PL_dowarn) { warn ("String offset to big!"); } } if (offset + length > slen) { length = slen - offset; if (PL_dowarn) { warn ("Bad string length!"); } } if (length % cs != 0) { if (length>cs) { length -= (length % cs); } else { length = 0; } if (PL_dowarn) { warn("Bad string size!"); } } *ro = address + offset; *rl = length; return (1); } int __get_mode (char** buf, U8* num, U8* method, U8* keys, U8* values) { U8 type, size; type = _byte(buf); size = _byte(buf); *buf += size; switch (type) { case M_INF: case M_BYTE: *num = type; break; case M_AKV: case M_AKAV: case M_PKV: *method = type; break; case M_CKn: case M_CK: *keys = type; break; case M_CVn: case M_CV: *values = type; break; } return (type); } /* * void = __read_binary_mapping (bufS, oS, UR, CR) * * Table of mode combinations: * * Mode | n1 n2 | INF BYTE | CK CKn | CV CVn * --------------------------------------------------------- * AKV | | | | * AKAV | | | | * PKV ok | ==1 ==1 | ok | ok | ok */ int __read_binary_mapping (SV* bufS, SV* oS, SV* UR, SV* CR) { char* buf; U32 o; HV* U; SV* uR; HV* u; HV* C; SV* cR; HV* c; int buflen; char* bufmax; U8 cs1, cs1b, cs2, cs2b; U32 n1, n2; U16 check; U16 type=T_BAD; U8 num1, method1, keys1, values1; I16 kn, vn; U32 kbegin, vbegin; SV* Ustr; SV* Cstr; SV** tmp_spp; buf = SvPVX (bufS); o = SvIV (oS); U = (HV *) SvRV (UR); C = (HV *) SvRV (CR); buflen = SvCUR(bufS); if (buflen < 2) { /* * Too short file. (No place for magic) */ if ( PL_dowarn ) { warn ( "Bad map file: too short!" ); } return (0); } bufmax = buf + buflen; buf += o; check = _word(&buf); if (check == M_MAGIC) { type = T_MAP; } else if ( ( check == MAP8_BINFILE_MAGIC_HI ) && ( _word(&buf) == MAP8_BINFILE_MAGIC_LO ) ) { type = T_MAP8; } if (type == T_BAD) { if ( PL_dowarn ) { warn ( "Unknown map file format!" ); } return (0); } num1 = num1_DEFAULT; method1 = method1_DEFAULT; keys1 = keys1_DEFAULT; values1 = values1_DEFAULT; while (buf All (key, value) pairs */ SV* tmpk; SV* tmpv; while (buf bufmax) { break; } hv_store_ent(u, tmpk, tmpv, 0); hv_store_ent(c, tmpv, tmpk, 0); } } else if (method1==M_AKV) { /* * Map mode */ U32 ksize = n1*cs1b; SV* tmpk; U32 vsize = n2*cs2b; SV* tmpv; if ( num1==M_INF ) { /* * All (key, value) pairs */ while (bufbufmax ) { buf += ( ksize+vsize ); break; } tmpk = newSVpv(buf, ksize); buf += ksize; tmpv = newSVpv(buf, vsize); buf += vsize; hv_store_ent(c, tmpv, tmpk, 0); hv_store_ent(u, tmpk, tmpv, 0); } } else if ( num1==M_BYTE ) { while ( buf0 ) { if ( buf+ksize+vsize>bufmax ) { buf += ( ksize+vsize ); break; } tmpk = newSVpv(buf, ksize); buf += ksize; tmpv = newSVpv(buf, vsize); buf += vsize; hv_store_ent(c, tmpv, tmpk, 0); hv_store_ent(u, tmpk, tmpv, 0); kn--; } } } } else if (method1==M_AKAV) { /* * First all keys, then all values */ if ( PL_dowarn ) { warn ( "M_AKAV not supported!" ); } return (0); } else if (method1==M_PKV) { /* * Partial */ if (num1==M_INF) { /* no infinite mode */ if ( PL_dowarn ) { warn ( "M_INF not supported for M_PKV!" ); } return (0); } while(buf0) { if (values3==M_CV) { /* * Partial, keys compressed, values compressed */ SV* tmpk; U32 k; SV* tmpv; U32 v; U32 max; vn = _byte(&buf); if (!vn) { if(__get_mode(&buf,&num3,&method3,&keys3,&values3)==M_END){ break; } continue; } if ((n1 != 1) || (n2 != 1)) { /* * n (n>1) characters cannot be mapped to one integer */ if ( PL_dowarn ) { warn("Bad map file: count mismatch!"); } return (0); } switch (cs2b) { case 1: vbegin = _byte(&buf); break; case 2: vbegin = _word(&buf); break; case 4: vbegin = _long(&buf); break; default: if ( PL_dowarn ) { warn ( "Unknown element size!" ); } return (0); } max = kbegin + vn; for (; kbegin=2; len-=2 ) { char tmp = *src++; *dest++ = *src++; *dest++ = tmp; } #line 605 "Map.c" PUTBACK; return; } } XS(XS_Unicode__Map__map_hash); /* prototype to pass -Wmissing-prototypes */ XS(XS_Unicode__Map__map_hash) { #ifdef dVAR dVAR; dXSARGS; #else dXSARGS; #endif if (items != 6) Perl_croak(aTHX_ "Usage: %s(%s)", "Unicode::Map::_map_hash", "Map, string, mappingR, bytesize, o, l"); PERL_UNUSED_VAR(cv); /* -W */ { SV* Map = ST(0); SV* string = ST(1); SV* mappingR = ST(2); SV* bytesize = ST(3); SV* o = ST(4); SV* l = ST(5); #line 601 "Map.xs" char* offset; U32 length; U16 bs; char* smax; HV* mapping; SV** tmp; #line 636 "Map.c" SV * RETVAL; #line 607 "Map.xs" bs = SvIV(bytesize); __limit_ol (string, o, l, &offset, &length, bs); smax = offset + length; RETVAL = newSV((length/bs+1)*2); mapping = (HV *) SvRV(mappingR); for (; offset