/** socket_send_to : 'socket -> buf:string -> pos:int -> length:int -> addr:{host:'int32,port:int} -> int <doc> Send data from an unconnected UDP socket to the given address. </doc> **/ static value socket_send_to( value o, value dataBuf, value pos, value len, value vaddr ) { int p,l; value host, port; struct sockaddr_in addr; val_check_kind(o,k_socket); buffer buf = val_to_buffer(dataBuf); const char *cdata = buffer_data(buf); int dlen = buffer_size(buf); val_check(pos,int); val_check(len,int); val_check(vaddr,object); host = val_field(vaddr, f_host); port = val_field(vaddr, f_port); val_check(host,int); val_check(port,int); p = val_int(pos); l = val_int(len); memset(&addr,0,sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(val_int(port)); *(int*)&addr.sin_addr.s_addr = val_int(host); if( p < 0 || l < 0 || p > dlen || p + l > dlen ) neko_error(); SOCKET sock = val_sock(o); gc_enter_blocking(); POSIX_LABEL(send_again); dlen = sendto(sock, cdata + p , l, MSG_NOSIGNAL, (struct sockaddr*)&addr, sizeof(addr)); if( dlen == SOCKET_ERROR ) { HANDLE_EINTR(send_again); return block_error(); } gc_exit_blocking(); return alloc_int(dlen); }
DEFINE_FUNC_1(webp_decode_argb, data_buffer_value) { if (!val_is_buffer(data_buffer_value)) { val_throw(alloc_string("webp_decode_argb: Expected to be a buffer")); return alloc_null(); } buffer data_buffer = val_to_buffer(data_buffer_value); int data_len = buffer_size(data_buffer); char *data_ptr = buffer_data(data_buffer); int webp_width = -1, webp_height = -1; char *webp_data_ptr = (char *)WebPDecodeARGB((const unsigned char *)data_ptr, data_len, &webp_width, &webp_height); int webp_data_len = webp_width * webp_height * 4; if (webp_data_ptr == NULL) { val_throw(alloc_string("webp_decode_argb: Invalid webp data")); return alloc_null(); } buffer webp_buffer = alloc_buffer_len(0); buffer_append_sub(webp_buffer, webp_data_ptr, webp_data_len); buffer_set_size(webp_buffer, webp_data_len); value array = alloc_array(3); val_array_set_i(array, 0, alloc_int(webp_width)); val_array_set_i(array, 1, alloc_int(webp_height)); val_array_set_i(array, 2, buffer_val(webp_buffer)); if (webp_data_ptr != NULL) free(webp_data_ptr); return array; }
static value socket_recv_from( value o, value dataBuf, value pos, value len, value addr ) { int p,l,ret; int retry = 0; struct sockaddr_in saddr; SockLen slen = sizeof(saddr); val_check_kind(o,k_socket); val_check(dataBuf,buffer); buffer buf = val_to_buffer(dataBuf); char *data = buffer_data(buf); int dlen = buffer_size(buf); val_check(pos,int); val_check(len,int); val_check(addr,object); p = val_int(pos); l = val_int(len); if( p < 0 || l < 0 || p > dlen || p + l > dlen ) neko_error(); SOCKET sock = val_sock(o); gc_enter_blocking(); POSIX_LABEL(recv_from_again); if( retry++ > NRETRYS ) { ret = recv(sock,data+p,l,MSG_NOSIGNAL); } else ret = recvfrom(sock, data + p , l, MSG_NOSIGNAL, (struct sockaddr*)&saddr, &slen); if( ret == SOCKET_ERROR ) { HANDLE_EINTR(recv_from_again); return block_error(); } gc_exit_blocking(); alloc_field(addr,f_host,alloc_int32(*(int*)&saddr.sin_addr)); alloc_field(addr,f_port,alloc_int(ntohs(saddr.sin_port))); return alloc_int(ret); }
DEFINE_FUNC_1(webp_get_features, data_buffer_value) { if (!val_is_buffer(data_buffer_value)) { val_throw(alloc_string("webp_get_features: Expected to be a buffer")); return alloc_null(); } buffer data_buffer = val_to_buffer(data_buffer_value); int data_len = buffer_size(data_buffer); char *data_ptr = buffer_data(data_buffer); WebPBitstreamFeatures features = {0}; VP8StatusCode code = WebPGetFeatures((const unsigned char *)data_ptr, data_len, &features); if (code != VP8_STATUS_OK) { val_throw(alloc_string("webp_get_features: Error: (code != VP8_STATUS_OK)")); return alloc_null(); } value array = alloc_array(7); val_array_set_i(array, 0, alloc_int(features.width)); val_array_set_i(array, 1, alloc_int(features.height)); val_array_set_i(array, 2, alloc_int(features.has_alpha)); //val_array_set_i(array, 3, alloc_int(features.bitstream_version)); val_array_set_i(array, 3, alloc_int(0)); val_array_set_i(array, 4, alloc_int(features.no_incremental_decoding)); val_array_set_i(array, 5, alloc_int(features.rotate)); val_array_set_i(array, 6, alloc_int(features.uv_sampling)); return array; }
/** file_read : 'file -> s:string -> p:int -> l:int -> int <doc> Read up to [l] chars into the string [s] starting at position [p]. Returns the number of chars readed which is > 0 (or 0 if l == 0). </doc> **/ static value file_read( value o, value s, value pp, value n ) { fio *f; int p; int len; int buf_len; val_check_kind(o,k_file); val_check(s,buffer); buffer buf = val_to_buffer(s); buf_len = buffer_size(buf); val_check(pp,int); val_check(n,int); f = val_file(o); p = val_int(pp); len = val_int(n); if( p < 0 || len < 0 || p > buf_len || p + len > buf_len ) return alloc_null(); gc_enter_blocking(); while( len > 0 ) { int d; POSIX_LABEL(file_read_again); d = (int)fread(buffer_data(buf)+p,1,len,f->io); if( d <= 0 ) { int size = val_int(n) - len; HANDLE_FINTR(f->io,file_read_again); if( size == 0 ) file_error("file_read",f); return alloc_int(size); } p += d; len -= d; } gc_exit_blocking(); return n; }
//data is expected to be a bytearray starting at desired position //FIXME Extend this like drawElements value bufferSubData( value target, value offset, value size, value data ) { glBufferSubData( (GLenum)val_int( target ), (GLintptr)val_int( offset ), (GLsizeiptr)val_int( size ), (const GLvoid *)buffer_data( val_to_buffer ( data ) ) ); return alloc_null( ); }
//data is expected to be a bytearray //FIXME Extend this like drawElements value bufferData( value target, value size, value data, value usage ) { glBufferData( (GLenum)val_int( target ), (GLsizeiptr)val_int( size ), (const GLvoid *)buffer_data( val_to_buffer ( data ) ), (GLenum)val_int( usage ) ); return alloc_null( ); }
value snow_lzma_decode(value input_value) { buffer input_buffer = val_to_buffer(input_value); buffer output_buffer = alloc_buffer_len(0); native_toolkit_lzma::Lzma::Decode(input_buffer, output_buffer); return buffer_val(output_buffer); } DEFINE_PRIM(snow_lzma_decode,1);
void Bytes::Resize (int size) { if (size != _length) { if (!_value) { _value = alloc_empty_object (); } if (val_is_null (val_field (_value, id_b))) { value dataValue; if (useBuffer) { buffer b = alloc_buffer_len (size); dataValue = buffer_val (b); _data = (unsigned char*)buffer_data (b); } else { dataValue = alloc_raw_string (size); _data = (unsigned char*)val_string (dataValue); } alloc_field (_value, id_b, dataValue); } else { if (useBuffer) { buffer b = val_to_buffer (val_field (_value, id_b)); buffer_set_size (b, size); _data = (unsigned char*)buffer_data (b); } else { value s = alloc_raw_string (size); memcpy ((char *)val_string (s), val_string (val_field (_value, id_b)), size); alloc_field (_value, id_b, s); _data = (unsigned char*)val_string (s); } } alloc_field (_value, id_length, alloc_int (size)); } _length = size; }
/** inflate_buffer : 'istream -> src:string -> srcpos:int -> dst:string -> dstpos:int -> { done => bool, read => int, write => int } **/ static value inflate_buffer( value s, value src, value srcpos, value dst, value dstpos ) { z_stream *z; int err; value o; val_check_kind(s,k_stream_inf); val_check(srcpos,int); buffer src_buf = val_to_buffer(src); if (!src_buf) hx_failure("invalid source buffer"); buffer dst_buf = val_to_buffer(dst); if (!dst_buf) hx_failure("invalid destination buffer"); int slen = buffer_size(src_buf); int dlen = buffer_size(dst_buf); val_check(dstpos,int); z = val_stream(s); if( val_int(srcpos) < 0 || val_int(dstpos) < 0 ) return alloc_null(); slen -= val_int(srcpos); dlen -= val_int(dstpos); if( slen < 0 || dlen < 0 ) return alloc_null(); z->next_in = (Bytef*)buffer_data(src_buf) + val_int(srcpos); z->next_out = (Bytef*)buffer_data(dst_buf) + val_int(dstpos); z->avail_in = slen; z->avail_out = dlen; if( (err = inflate(z,val_flush(z))) < 0 ) zlib_error(z,err); z->next_in = NULL; z->next_out = NULL; o = alloc_empty_object(); alloc_field(o,id_done,alloc_bool(err == Z_STREAM_END)); alloc_field(o,id_read,alloc_int((int)(slen - z->avail_in))); alloc_field(o,id_write,alloc_int((int)(dlen - z->avail_out))); return o; }
const unsigned char *ByteArray::Bytes () const { value bytes = val_call1 (gByteArrayBytes->get (), mValue); if (val_is_string (bytes)) return (unsigned char *)val_string (bytes); buffer buf = val_to_buffer (bytes); if (buf == 0) { val_throw (alloc_string ("Bad ByteArray")); } return (unsigned char *)buffer_data (buf); }
value hx_zmq_setbytessockopt(value socket_handle_, value option_, value bytes_optval_) { val_check_kind(socket_handle_, k_zmq_socket_handle); if (!val_is_int(option_)) { printf("option_ is not int"); val_throw(alloc_int(EINVAL)); return alloc_null(); } size_t size = 0; uint8_t *data = 0; // If data from neko if (val_is_string(bytes_optval_)) { size = val_strlen(bytes_optval_); data = (uint8_t *)val_string(bytes_optval_); } // else from C++ else if (val_is_buffer(bytes_optval_)) { buffer buf = val_to_buffer(bytes_optval_); size = buffer_size(buf); data = (uint8_t *)buffer_data(buf); } else { printf("bytes_optval_ not string or buffer"); val_throw(alloc_int(EINVAL)); return alloc_null(); } int rc = 0; int err = 0; int option = val_int(option_); rc = zmq_setsockopt (val_data(socket_handle_), option, data, size); err = zmq_errno(); if (rc != 0) { printf("err:%d",err); val_throw(alloc_int(err)); return alloc_null(); } return alloc_int(rc); }
//FIXME indices and bytearrays do not particularly mix //Does val_to_buffer throw an error on null? value drawElements( value mode, value count, value type, value indices ) { char *ptr = NULL; if (val_is_buffer(indices)) { ptr = buffer_data( val_to_buffer ( indices ) ); } else if (val_is_int(indices)) { ptr = ((char *)NULL+val_int(indices)); } glDrawElements( (GLenum)val_int( mode ), (GLsizei)val_int( count ), (GLenum)val_int( type ), (const GLvoid *)ptr ); return alloc_null( ); }
//---------------------------------------------------- inline void ofImage::allocatePixels(ofPixels &pix, int width, int height, int bpp){ bool bNeedToAllocate = false; if (pix.bAllocated == true){ if ( (pix.width == width) && (pix.height == height) && (pix.bitsPerPixel == bpp)){ //ofLog(OF_LOG_NOTICE,"we are good, no reallocation needed"); bNeedToAllocate = false; } else { //delete[] pix.pixels; bNeedToAllocate = true; } } else { bNeedToAllocate = true; } int byteCount = bpp / 8; if (bNeedToAllocate == true){ pix.width = width; pix.height = height; pix.bitsPerPixel = bpp; pix.bytesPerPixel = bpp / 8; switch (pix.bitsPerPixel){ case 8: pix.glDataType = GL_LUMINANCE; pix.ofImageType = OF_IMAGE_GRAYSCALE; break; case 24: pix.glDataType = GL_RGB; pix.ofImageType = OF_IMAGE_COLOR; break; case 32: pix.glDataType = GL_RGBA; pix.ofImageType = OF_IMAGE_COLOR_ALPHA; break; } //pix.pixels = new unsigned char[pix.width*pix.height*byteCount]; pix.pixels = (unsigned char *) buffer_data(val_to_buffer(val_ocall1(handler, val_id("__newByteData"), alloc_int(pix.width*pix.height*byteCount)))); pix.bAllocated = true; } }
/** socket_send : 'socket -> buf:string -> pos:int -> len:int -> int <doc>Send up to [len] bytes from [buf] starting at [pos] over a connected socket. Return the number of bytes sent.</doc> **/ static value socket_send( value o, value data, value pos, value len ) { int p,l,dlen; SOCKET sock = val_sock(o); val_check(pos,int); val_check(len,int); buffer buf = val_to_buffer(data); if (!buf) hx_failure("not bytebuffer"); p = val_int(pos); l = val_int(len); dlen = buffer_size(buf); if( p < 0 || l < 0 || p > dlen || p + l > dlen ) return alloc_null(); gc_enter_blocking(); dlen = send(sock, buffer_data(buf) + p , l, MSG_NOSIGNAL); if( dlen == SOCKET_ERROR ) return block_error(); gc_exit_blocking(); return alloc_int(dlen); }
/** socket_write : 'socket -> string -> void <doc>Send the whole content of a string over a connected socket.</doc> **/ static value socket_write( value o, value data ) { const char *cdata; int datalen, slen; SOCKET sock = val_sock(o); val_check(data,buffer); buffer buf = val_to_buffer(data); cdata = buffer_data(buf); datalen = buffer_size(buf); gc_enter_blocking(); while( datalen > 0 ) { POSIX_LABEL(write_again); slen = send(sock,cdata,datalen,MSG_NOSIGNAL); if( slen == SOCKET_ERROR ) { HANDLE_EINTR(write_again); return block_error(); } cdata += slen; datalen -= slen; } gc_exit_blocking(); return alloc_bool(true); }
/** socket_recv : 'socket -> buf:string -> pos:int -> len:int -> int <doc>Read up to [len] bytes from [buf] starting at [pos] from a connected socket. Return the number of bytes readed.</doc> **/ static value socket_recv( value o, value data, value pos, value len ) { int p,l,dlen; SOCKET sock = val_sock(o); val_check(data,buffer); buffer buf = val_to_buffer(data); val_check(pos,int); val_check(len,int); p = val_int(pos); l = val_int(len); dlen = buffer_size(buf); if( p < 0 || l < 0 || p > dlen || p + l > dlen ) return alloc_null(); gc_enter_blocking(); POSIX_LABEL(recv_again); dlen = recv(sock, buffer_data(buf) + p, l, MSG_NOSIGNAL); if( dlen == SOCKET_ERROR ) { HANDLE_EINTR(recv_again); return block_error(); } gc_exit_blocking(); return alloc_int(dlen); }
void Bytes::Set (value bytes) { if (val_is_null (bytes)) { _length = 0; _data = 0; _value = 0; } else { _value = bytes; _length = val_int (val_field (bytes, id_length)); if (_length > 0) { value b = val_field (bytes, id_b); if (val_is_string (b)) { _data = (unsigned char*)val_string (b); } else { _data = (unsigned char*)buffer_data (val_to_buffer (b)); } } else { _data = 0; } } }
/** * Receive data from socket * Based on code in https://github.com/zeromq/jzmq/blob/master/src/Socket.cpp */ value hx_zmq_send(value socket_handle_, value msg_data, value flags) { val_check_kind(socket_handle_, k_zmq_socket_handle); if (!val_is_null(flags) && !val_is_int(flags)) { val_throw(alloc_int(EINVAL)); return alloc_null(); } size_t size = 0; uint8_t *data = 0; zmq_msg_t message; // Extract byte data from either Neko string or C++ buffer // see: http://waxe.googlecode.com/svn-history/r32/trunk/src/waxe/HaxeAPI.cpp "Val2ByteData" if (val_is_string(msg_data)) { // Neko size = val_strlen(msg_data); data = (uint8_t *)val_string(msg_data); } else if (val_is_buffer(msg_data)) { // CPP buffer buf = val_to_buffer(msg_data); size = buffer_size(buf); data = (uint8_t *)buffer_data(buf); } else { val_throw(alloc_int(EINVAL)); return alloc_null(); } // Set up send message buffer by referencing the provided bytes data //zero copy version: int rc = zmq_msg_init_data (&message, data, size,NULL,NULL); int rc = zmq_msg_init_size(&message, size); memcpy (zmq_msg_data(&message), data, size); int err = zmq_errno(); if (rc != 0) { val_throw(alloc_int(err)); return alloc_null(); } gc_enter_blocking(); // Send #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0) rc = zmq_sendmsg (val_data(socket_handle_), &message, val_int(flags)); #else rc = zmq_send (val_data(socket_handle_), &message, val_int(flags)); #endif err = zmq_errno(); gc_exit_blocking(); // If NOBLOCK, but cant send message now, close message first before quitting if (rc == -1 && err == EAGAIN) { rc = zmq_msg_close (&message); err = zmq_errno(); if (rc != 0) { val_throw(alloc_int(err)); return alloc_null(); } return alloc_null(); } if (rc == -1) { val_throw(alloc_int(err)); rc = zmq_msg_close (&message); err = zmq_errno(); if (rc != 0) { val_throw(alloc_int(err)); return alloc_null(); } return alloc_null(); } rc = zmq_msg_close (&message); err = zmq_errno(); if (rc != 0) { val_throw(alloc_int(err)); return alloc_null(); } return alloc_null(); }
bool val_is_buffer(value inVal) { return val_to_buffer((hx::Object *)inVal)!=0; }
DEFINE_FUNC_5(webp_encode_argb, data_buffer_value, width_value, height_value, lossless_value, quality_factor_value) { int width = 0; int height = 0; float quality_factor = 100; int lossless = 1; int stride = 0; uint8_t* abgr = NULL; uint8_t* rgba = NULL; uint8_t* output = NULL; int output_size = 0; int pixels_size; int bytes_size; buffer data_buffer; if (val_is_int(width_value)) width = val_int(width_value); if (val_is_int(height_value)) height = val_int(height_value); if (val_is_bool(lossless_value)) lossless = val_bool(lossless_value); if (val_is_float(quality_factor_value)) quality_factor = val_float(quality_factor_value); stride = width * 4; pixels_size = width * height; bytes_size = pixels_size * 4; if (!val_is_buffer(data_buffer_value)) { val_throw(alloc_string("webp_encode_argb: Expected to be a buffer")); return alloc_null(); } data_buffer = val_to_buffer(data_buffer_value); if (bytes_size != buffer_size(data_buffer)) { val_throw(alloc_string("webp_encode_argb: Invalid buffer size")); return alloc_null(); } //if () abgr = (uint8_t *)buffer_data(data_buffer); rgba = (uint8_t *)malloc(bytes_size); uint8_t* _abgr = abgr; uint8_t* _rgba = rgba; int _pixels_size = pixels_size; while (_pixels_size-- > 0) { //_rgba[0] = _abgr[3]; _rgba[0] = _abgr[1]; _rgba[1] = _abgr[2]; _rgba[2] = _abgr[3]; _rgba[3] = _abgr[0]; _abgr += 4; _rgba += 4; } if (lossless) { output_size = WebPEncodeLosslessRGBA( rgba, //abgr, width, height, stride, &output ); } else { output_size = WebPEncodeRGBA( rgba, //abgr, width, height, stride, quality_factor, &output ); } printf("output_size: (%d, %d, %d) : %d\n", width, height, stride, output_size); buffer output_buffer = alloc_buffer_len(0); buffer_append_sub(output_buffer, (char *)output, output_size); buffer_set_size(output_buffer, output_size); if (output != NULL) free(output); if (rgba != NULL) free(rgba); return buffer_val(output_buffer); }