Thrift Haxe Software Library

License
=======

Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.

Using Thrift with Haxe
========================

Haxe setup
---------------

Thrift requires Haxe 4.2.1. Installers for Windows and OSX
platforms are available at `http://haxe.org/download`. 

Depending on the desired targets, you may have to install the appropriate HaxeLibs 
after installing Haxe itself. For example, if you plan to target C++, enter the 
following command after installing Haxe:

    haxelib install hxcpp

For other targets, please consult the Haxe documentation whether or not any additional
target libraries need to be installed and how to achieve this.


Haxe on Linux 
---------------

For Linux platforms it is recommended to use the distro-specific package
manager, where possible. More detailed information can be found at the 
Haxe Linux download section: http://haxe.org/download/linux

If you run into the error message 

    Uncaught exception - load.c(237) : Failed to load library : /usr/lib/neko/regexp.ndll  
	(libpcre.so.3: cannot open shared object file: No such file or directory)

this can be solved depending on your OSes bitness by either

    sudo ln -sf /usr/lib/libpcre.so.1 /usr/lib/libpcre.so.3
    sudo ldconfig
	
or

    sudo ln -sf /usr/lib64/libpcre.so.1 /usr/lib64/libpcre.so.3
    sudo ldconfig

Thrift Haxe bindings
-------------------
	
Thrift Haxe bindings can be set up via the `haxelib` tool  as usual.
Alternatively, the "github" method can be used.

- To set up any **stable version**, choose the appropriate branch (e.g. `0.14.1`):

    - `haxelib git thrift https://github.com/apache/thrift.git 0.14.1 lib/haxe`

- To set up the current **development version**, use the `master` branch:
  
    - `haxelib git thrift https://github.com/apache/thrift.git master lib/haxe`

As usual, the installed library can be updated using `haxelib upgrade` 
or `haxelib update thrift`.

In order to work with Thrift, you will need to install the Thrift compiler 
or build from source, depending on your operating system. Appropriate 
downloads and more information can be found at http://thrift.apache.org
	
To get started, visit the /tutorial/haxe and /test/haxe dirs for examples. 
If you are using the HaxeDevelop IDE, you'll find appropriate project files 
in these folders.


Breaking changes
========================
This version requires Haxe 4 and cannot be used with earlier versions.

It is recommended to clear out all gen-haxe contents once before switching 
to the new version. Otherwise you may run into troubles with leftovers from 
previous versions.

The compiler option ```callbacks``` is now obsolete. The compiler will always 
generate a dual interface (i.e. with optional callback style) for use on the 
client side, plus a new ```_service``` interface to be used for server 
implementations. Consequentially, your client and server implementations will
need some manual intervention.


PHP HTTP Server notes
========================

- you have to import PHP files generated by haxe into PHP
```php
require_once  dirname(__FILE__) . '/bin/php-web-server/Main-debug.php';
```

- trace() by default outputs into stdout (http response), so you have to redirect it to stderr or you own logs, something like
```haxe
//remap trace to error log
haxe.Log.trace = function(v:Dynamic, ?infos:haxe.PosInfos) 
{ 
	//simulate normal trace https://github.com/HaxeFoundation/haxe/blob/development/std/haxe/Log.hx
	var newValue : Dynamic;
	if (infos != null && infos.customParams!=null) {
		var extra:String = "";
		for( v in infos.customParams )
			extra += "," + v;
		newValue = v + extra;
	}
	else {
		newValue = v;
	}
	var msg = infos != null ? infos.fileName + ':' + infos.lineNumber + ': ' : '';
	Sys.stderr().writeString('${msg}${newValue}\n');
}
```

- to allow thrift server to read/write HTTP request/response, it should be pointed out to php streams
```haxe
transport =	new TWrappingServerTransport(
				new TStreamTransport(
					new TFileStream("php://input", Read),
					new TFileStream("php://output", Append)
					)
				);
```

- TSimpleServer doesn't stop after first call, so processor.process() should be called instead, or use runOnce property 
```haxe
var server = new TSimpleServer( processor, transport, transfactory, protfactory);
server.runOnce = true;
```

