转到正文

奋斗

生命在于折腾

存档

分类: code

boost中的asio是一个非常好用的网络库
不过可以参考的资料比较少
大部分都是靠阅读自带的几个example来理解
这里记录一下这两天的几个心得

boost::asio::async_read_until(socket_, response_, “\r\n\r\n”, boost::bind(&shoutcast::handle_read_headers, this, boost::asio::placeholders::error));

async_read_until, 一直读,直到读到指定的内容.但是了,并不是刚刚读到就停止,一般缓冲区里会有更多的内容,
所以我们需要读出我们需要的,剩下的留下就好
官方是这么说的”After a successful async_read_until operation, the streambuf may contain additional data beyond the delimiter. An application will typically leave that data in the streambuf for a subsequent async_read_until operation to examine.”

boost::asio::async_read(socket_, response_, boost::asio::transfer_at_least(512), boost::bind(&shoutcast::handle_read_content, this, boost::asio::placeholders::error));

async_read 可以选择使用transfer_at_least 这个CompletionCondition
async_read 读入的缓冲区可以这样
boost::array buffer_;
boost::asio::buffer(buffer_);来构造
也可以直接用字符数组来构造
char _buf[512] = {0};
boost::asio::buffer(_buf, 512);
也可以用流,更像tcp的方式
使用boost::asio::streambuf response_;
它继承自 std::streambuf
一般这样使用
std::istream _stream(&response_);
这里要注意的是 basic_istream::get
如果我们指定get的个数count,那么取出的个数是count-1
msdn是这样说的”The fourth function extracts up to _Count – 1 elements and stores them in the array beginning at _Str.”

其实一直对android很感兴趣
虽然没有用过它的真机…

上个星期看到了这篇文章
Android:Google 翻译前端
作者的代码写的简单明了
并且发布了源代码给大家学习
真是很不错

看了之后 决定动手增加点东西 学习一下android的开发
增加的内容主要是在查询过程中弹出一个等待的对话框
涉及到的内容包括 ProgressDialog, AsyncTask
效果如下
当用户点击Translate的时候,会出现一个”正在查询”的对话框
查询完毕后对话框消失

对话框很好做 showDialog(1) 后
系统会调用

@Override
protected Dialog onCreateDialog(int id) {
if(1 == id)
{
ProgressDialog dialog = new ProgressDialog(GTranslator.this);
dialog.setTitle(“正在查询”);
dialog.setMessage(“请稍候……”);
return dialog;
}
return null;
}

但是 查询是个阻塞的过程
我们必须得在另外一个线程里去做这个事情
比较简单的方法就是继承AsyncTask
网上有一篇转载比较多的关于AsyncTask的文章(Android线程模型(Painless Threading))
官方的说明在这里 http://developer.android.com/reference/android/os/AsyncTask.html
大概说一下 android 的ui线程不是线程安全的
我们不能在其他的线程里直接做关于ui的操作
这里有个简单的办法就是继承AsyncTask
然后实现它的doInBackground方法
在类的onPreExecute(),publishProgress(Progress…),onPostExecute(Result)方法里
做ui的操作
如果在doInBackground里操作ui
可能会弹出异常提示
“Only the original thread that created a view hierarchy can touch its views”
不是每次都弹…为什么了?

下面贴一下线程的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
	private class ProcessDialogThread extends AsyncTask<String, Void, String> {
		// @Override
		protected String doInBackground(String... str) {
 
			String toTranslateTextString = toTranslateEditText.getText()
					.toString();
			String tempString = toTranslateTextString.replace(" ", "%20");
			fromString = mCountries[fromSpinner.getSelectedItemPosition()];
			toString = mCountries[toSpinner.getSelectedItemPosition()];
			String queryString = tempString + "&langpair=" + fromString + "%7C"
					+ toString;
 
			return getRawData(queryString);
		}
 
		protected void onPreExecute() {
			showDialog(1);
			translatedTextView.setText("Connecting...");
		}
 
		protected void onPostExecute(String rawData) {
			dismissDialog(1);
			if (null != rawData) {
				String parsedDataString = getData(rawData);
				if (null == parsedDataString || "" == parsedDataString) {
					try {
						translatedTextView.setText("Not found");
					} catch (Exception e) {
						e.printStackTrace();
					}
				} else {
					translatedTextView.setText(parsedDataString);
					dbAdapter.insertItem(toTranslateEditText.getText()
							.toString(), parsedDataString);
 
					/*
					 * FileAccess.writeFile(this,
					 * toTranslateEditText.getText().toString() + ":" +
					 * parsedDataString);
					 */
				}
			} else {
				translatedTextView.setText("Translate failed!");
			}
		}
 
		public String getRawData(String string) {
			String dataString = null;
			// String queryString = "hello%20world&langpair=en%7Czh-CN";
			String queryString = string;
			try {
				URL url;
				if (bAtOffice) {
					url = new URL("http://10.85.40.153:8000/a.xml");
				} else {
					url = new URL(
							"http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q="
									+ queryString);
				}
 
				URLConnection conn = url.openConnection();
				conn.connect();
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(conn.getInputStream()));
 
				byte buffer[] = new byte[1024];
 
				// bis.r
				String readerString;
				while ((readerString = reader.readLine()) != null) {
					dataString += readerString;
				}
 
				reader.close();
				// is.close();
 
			} catch (IOException e) {
				System.out.print("Net work error");
			}
			return dataString;
		}
	}

GAP: GAppProxy是一个运行于Google App Engine上的
遵循GUN的代理解决方案
关于它的详细介绍请访问项目主页
code.google.com/p/gappproxy

它的一个劣势就是需要运行一个客户端
是个简单的python脚本
在windows下 作者已经写好并打包了一个GUI程序
但是在linux下没有

上周末抽空做了一个Ubuntu下的GUI界面

点击start 后会缩放到托盘
GNOME的托盘是在上面哦

如果需要使用自己的server
首先修改并save
然后在start就好了

程序的部分代码是直接复制GAP下的gui.py里的
把代码解压后放到localproxy文件夹里
和proxy.py等 放一起就好

在终端里输入python linux_gui.py 运行
但 既然要在终端里输入命令
那为什么还要GUI了 ……
哈哈 看起来很笨拙
实际上我是想打包做成安装包的
尝试了freeze.py 但是在编译的时候出错
等有时间再想想办法吧

在Linux上 我基本还是小白
这段脚本测试的环境是
Ubuntu9.04
python2.6
Qt4 和 pyqt

Download linux_gui_gap Version 1

Qt真是庞大
甚至连软件的插件开发
它都替你考虑了
不过说实话 实在是不好用
之前以为是我vs2008+qt4.5的环境编译出来的插件不兼容
之后我花了三个晚上下载vs2005
又花了一个晚上编译qt4.4
之后编译出来的插件还是不能用
甚至还搜到了有人遇到了更奇怪的问题
发布的qt程序拷贝到其它机器无法读取plugin

Qt作为一个商业软件
这些事情实在是很恼火

发现qt4.4编译时比qt4.5占用的硬盘少很多


今天发布了第一个twittery的release版本
周中花了一个晚上的时间用google doc做了一个简单的网页
http://twittery.sourceforge.net/

twittery 是Launchy 的插件
可以让你方便的通过Launchy发送twitter消息

使用很简单
首先要在插件的设置窗口里输入你的twitter的用户名和密码
然后在文本框里输入”twtter”, 找到twittery
然后点击tab键
再输入你想要说的话
最后就是回车 等待你的消息发送成功

因为我现在的编译环境是vs2008和qt4.5
所以我编译出来的插件
以前的程序加载不成功
所以我放出来的文件是包括了重新编译了的launchy的安装包
同理 这个版本也不支持以前版本的插件
这是个很郁闷的问题
现在只能期望有朋友有vs2005和qt4.4环境
能帮我重新编译一下 这样官方的版本也可以使用这个插件了

twittery中的twitter api是使用twitlib的实现
它也是基于qt的实现

twittery也是一个开源的项目,遵循GPL协议
twittery的主页
http://twittery.sourceforge.net/
请多点击右边的google广告支持 :)

关于launchy 请看这里
http://bborn.cn/blog/2008/11/launchy212/
很高兴这个小东东终于可以拿出来分享
之前也有一些其他项目的想法 做出了雏形
但进度很慢 很难继续下去
生活的琐碎事太多
用业余时间来维护一个凭兴趣做的项目很难
希望大家能喜欢

今天在屋里宅了一天
一天写了好几篇东西
佩服

在windows下使用Qt的时候
有些时候需要将一个图标句柄HICON转换成QPixmap
在这里有一个解决方案 不过比较老了
http://www.methylblue.com/blog/hicon-to-qpixmap/
没有测试过

实际上在Qt的源码中是有这样的代码的
在src/gui/image/qpixmap_win.cpp中
这个函数 convertHIconToPixmap()
貌似并没有导出 需要自己拷贝代码出来使用

这里有个问题
在Qt4.5中实现和以前貌似不一样
所以了
在新版本中编译以前的代码
取得的QPixmap是个黑色的色块
使用最新的实现就可以

这就是昨天折腾一晚上的发现