컴퓨터를 좀 안다고 생각했던 저도 rss 라는 것을 어제 알았습니다. 한마디로 각종 블로그나 기사를 골라읽기 위한 통신 규약이라고 생각하시면 됩니다. 비슷한 것으로 "atom" 이라는 것이 있습니다.

예를 들면 아고라의 "미네르바", 다음블로그의 "상승미소", 네이버블로그의 "드루킹" 님의 글을 읽는다고 합시다. 보통은 3개의 site 를 모두 즐겨찾기를 해놓고 한군데씩 들어가서 봅니다.

하지만 rss 를 이용하면 3 저자의 글을 한 화면에서 볼 수 있습니다 !!! 글도 시간 순서대로 정렬되어 있습니다.

rss 를 읽으려면 rss reader 라는 것이 있어야 하는데 쉽게 사용할 수 있는 rss reader 로는 google reader 가 있습니다. 이외에도 hanrss 등이 있습니다. rss 로 검색하면 나와요.

1) 일단 google.com 에 가입하시고.
2) http://reader.google.com 으로 들어갑니다.



왼쪽 위에 보면 구독 추가라고 되어 있습니다. 여기에 구독하고 싶은 rss 주소를 적어주면 됩니다.

3) rss 주소는 어디서 얻을까요 ?? "미네르바" 님의 rss 를 찾아보겠습니다. 아고라의 미네르바 님의 아이디를 클릭하면 아래처럼 나옵니다.

토론 2 옆에 보면 아까 보여드린  이 있습니다. 이걸 클릭하면 주소가 나옵니다.

이렇게 얻는 미네르바님의 rss 주소는
http://agora.media.daum.net/profile/rss.xml?key=yzcyxX5kuoE0&group_id=1

입니다. 이 주소를 2) 번에서 보여드린 google reader 의 구독 추가란에 적어주시면 됩니다.

현재 거의 모든 블로그 및 뉴스 기사 등이 rss 를 지원합니다. 잘 찾아보면 마크를 찾을 수 있습니다.

4) 결과입니다. 글이 잘 정렬되어 있습니다.




rss 로 많은 site 를 등록해서 본다면 시간도 절약하고 아고라의 알밥들도 피해갈 수 있으리라 생각됩니다. 몇몇 까페에서는 사람들이 죽어라 퍼나르고 있는데 이런 수고를 할 필요가 없습니다.

사실 저도 rss 를 모르고 열심히 비슷한 기능이 있는 홈페이지를 만드느라 고생 좀 했습니다. 진작 알았으면 이런 수고를 덜었겠죠. 그래도 많은 글들이 많이 있는 편리한 site 입니다. 많이 놀러와주세요.
http://sshan.net
,


해외 여행이란
그 나라를 느끼고 즐기고 체험하고 경험하고...

이번 싱가폴 여행에서는 또다른 경험들을...
많이 체험하고 왔다.

일반적으로 여행을 가서 경험 할 수 없는 색다른 경험~

 

이곳은 오차드 로드에 위치한 영화관이다.
영어를 특별히 잘 하지도 않으면서
1달 이상 장기 여행을 할때는 영화관을 들리곤 한다.

특히 싱가폴은 할수 있는게 너무 한정되어 있기때문에

더더욱 영화 관람이 즐겁게 느껴졌다.

내가 이날 본 영화는 "데쟈뷰" 날이 너무 많은 영화라서 거의 못 알아듣고 영상만 보고 나왔다는...

위에 있는 사진이 영화 티켓이다~
가로 5cm, 세로 7cm 정도의 아주 작은 싸이즈!


영화 상영시간을 기다리면서 옆에 있는 오락실에 갔다.
세계 어느나라나 영화관 옆에는 오락실이 있나봐~ㅎㅎ

이건 오락을 할수 있는 코인~
돈을 내고 코인으로 바꿔서 오락을 한다.

오락을 너무 못하는 나와 사촌동생은 3분도 안되서 게임 끝~!


이곳은 운전면허 시험을 접수하고
시험을 치르는 장소다.

현지에 살지 않으면 절대 방문 할 일이 없을것 같다.
사실 현지에 살아도 굳이 운전 면허를 딸 필요가 없는데
우리 이모부와 이모께서는 누군가 면허를 땄다는 말에 승부욕 발동...ㅋㅋㅋ
과연 딸수 있었을까???

결과는 시험 치르는 날 한국에 나와있었다는~^^


내가 세계 어느 나라를 여행가던 가장 좋아하는 장소이다.
사람들이 붐비고
여러가지 구경할게 많은 시장!

맛있는 과일을 싸게 많이 살 수 있는 이곳에서
나의 식탐은 또 발동되어
이모에게 이것도 먹어보고 싶고 저것도 먹어보고싶고~!!!
몽땅 졸라서 다 샀다


'즐거운 이야기~ > 떳다떳다 해외여행!' 카테고리의 다른 글

오사카  (1) 2009.01.17
싱가폴의 이곳저곳  (0) 2009.01.17
싱가폴 먹거리-3  (0) 2009.01.12
싱가폴 먹거리-2  (0) 2009.01.12
싱가폴 먹거리-1  (0) 2009.01.12
,


Analytics 로 결과를 보면 검색엔진이 전부 "search" 로 나온다.
이는 네이버 / 다음 과 같은 검색 site 가 등록이 안되어 있어서 발생하는 문제이다.
검색엔진을 등록하면 해결할 수 있다.

google 의 help 를 보면

pageTracker._addOrganic("name_of_searchengine","q_var");

로 등록하라고 한다. name_of_searchengine 은 검색 엔진의 고유한 주소이고 q_var 는 검색 키워드가 저장되는 변수명이다.


예를 들면 엠파스의 경우 "keyword" 로 검색버튼을 누르면 주소창에

http://search.empas.com/search/all.html?z=A&q=keyword&x=0&y=0&qn=&s=&f=&bd=&bw=&tq=

라고 뜨는 것을 볼 수 있다. search.empas.com 이 검색 엔진 주소이고 &q=keyword 에서 q 가 검색값인 "keyword" 가 저장되는 장소이다. 따라서

pageTracker._addOrganic("empas","q");

를 추가하면 된다.

한가지 문제가 더 있는데 구글은 search 가 들어가는 주소를 "search"라는 검색엔진으로 등록하고 있다. 이것을 무시하게 만들어야 한다.

pageTracker._clearOrganic();

를 앞에 추가하자.

cf) 원래는
pageTracker._addIgnoredOrganic("search"); 만 해도 search 가 삭제되야 하는데 버그가 있는 것 같다. pageTracker._clearOrganic(); 을 추가해서 모든 검색엔진 정보를 지웠다. 이경우에는 search 엔진을 전부 등록해 주어야한다. 우리나라에서 쓰는 엔진 위주로 올렸다.


아래는 내가 쓰는 analytics 코드이다. "UA-XXXXXX-X" 부분을 자신의 것으로 바꾸어 쓰면 된다. 아래 코드를 모두 </body> tag 전에 삽입하면 인식이 된다.

ps) 아래에 UA-@@@@@@-@ 는 자신의 것으로 바꾸어야 한다.



<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-@@@@@@-@");
pageTracker._clearOrganic();
pageTracker._addOrganic("naver.com","query");
pageTracker._addOrganic("daum.net","q");
pageTracker._addOrganic("nate.com","q");
pageTracker._addOrganic("empas.com","q");
pageTracker._addOrganic("google.com","q");
pageTracker._addOrganic("paran.com","Query");
pageTracker._addOrganic("yahoo.com","p");
pageTracker._trackPageview();
} catch(err) {}</script>



http://www.antezeta.com/blog/google-analytics-search-engines

http://www.google.com/support/googleanalytics/bin/answer.py?answer=57046

http://www.google.com/support/googleanalytics/bin/answer.py?answer=55479
,


http://mldonkey.sourceforge.net/

donkey(당나귀)는 p2p 프로그램의 대명사입니다. 많이 쓰이는 overnet 도 donkey 에서 힌트를 얻어 나왔지요. overnet 과 donkey 의 차이는 donkey 는 중앙 서버가 필요한 반면에 overnet 의 경우에는 중앙 서버가 필요없는 완벽한 p2p 라고 할 수 있겠습니다.

하여튼 donkey 는 이미 소스가 공개 되어서 emule, aMule, xMule, 푸루나 등의 clone 이 만들어졌습니다. 안의 구조는 같지만 사용하기 편하게 조금씩 바꾼 프로그램들이지요.

그 중에서 가장 특징이 있는 donkey 를 꼽는다면 주저없이 mldonkey 를 꼽겠습니다. mldonkey 는 두가지 중요한 특징이 있습니다.

1) explore 로 원격 제어가 가능하다.

다른 donkey 와 다르게 mldonkey 는 인터넷 explore 를 통해 접근이 가능합니다. 아래는 explore 에서 본 mldonkey 의 제어창입니다.



2) 사용자 계정 설정이 가능하다.

 mldonkey 내에서는 사용자 설정을 할 수 있습니다. 저희 집 같은 경우 신발장에 donkey 서버가 있습니다. 물론 mldonkey 도 설치되어 있지요. mldonkey 안에 3명의 계정이 있답니다. 각각의 사람이 접속해서 자료를 다운을 걸어 놓으면 자신의 계정 폴더에 다운로드됩니다.


 donkey 의 가장 큰 문제는 느린 다운 속도였습니다. 이 때문에 donkey 프로그램을 하루종일 켜놓는 경우가 많죠. 하지만 donkey 하나 쓸려고 컴퓨터를 하루종일 켜 놓는 것은 낭비입니다. mldonkey 가 없다면 형이랑 동생이랑 둘다 donkey 를 사용한다면 컴퓨터를 2대 켜놓아야 합니다. 하지만 mldonkey 를 쓰면 mldonkey 가 설치된 컴퓨터 한대가 계속 일을 하게 됩니다. 형/동생 계정으로 다운로드를 제어하면 되지요.

 저희 집 같은 경우 신발장에 자료 저장용 linux 컴퓨터가 있는에 이 녀석이 mldonkey 서버 역할을 하고 있습니다. 우리집 식구는 모두 mldonkey 계정이 있습니다. 일단 자료만 걸어 놓으면 하루종일 받고 있습니다. 똘똘한 놈이지요.


 


,


제가 아는 인터넷 앨범 프로그램에 가장 많이 쓰이는 것은 2가지 있습니다.

1) Gallery (http://gallery.menalto.com)
Gallery - YOUR PHOTOS ON YOUR WEBSITE
2) album.pl (http://perl.bobbitt.ca/album)



입니다. 두개 중에 우열을 가린다면 Gallery 가 압승입니다. album.pl 은 perl 로 만들어져 있는데 아무래도 php 로 만들어진 gallery 보다 느립니다. 서버에 부하도 많이 줍니다.

제가 사용하는 gallery 는 ubuntu linux 에서 자동 업데이트 되는 버젼으로 사용합니다. 아무래도 apt-get(우분투 프로그램 업데이터) 으로 업데이트 하는 것이 편하니까요.

제 홈페이지(http://whria.net) 와 보시면 photography 부분이 있습니다. 이것은 gallery 로 만들어져 있습니다. 매우 짜임새있고 좋습니다. 단점이라면 댓글 다는 부분이 조금 부족합니다.
,

맛있는 세계 각국의 음식이 너무 많은 나라...
싱가폴...
내가 느낀 싱가폴은 깨끗한 도시와 맛있는 음식이 인상적인 나라였다.
세계 어느 나라를 가도 음식에 대한 큰 거부감이 없는 나라서 그런가?^^


여러 민족이 사는 나라...
 그만큼 각국의 다양한 음식이 모여있는 나라...


언젠가 다시 싱가폴을 방문하게 되면
이제 이모네 식구가 이곳에 살지 않는다고 해도
먹을것 고민과 선택은 걱정 하지 않아도 될것같다~



보타닉 가든에서 브런치를 싸고 맛있게 즐길 수 있는곳~
보타닉 가든에 몇군데의 식당이 있는데 그중 제일 맛있다~
제일 앞에 있는 하얀거는 우리나라에도 있는 순두부~ㅎㅎ





빠꾸떼~
우리나라 여행 책자에도 소개되어있다.
싱가폴에 가면 꼭 먹어봐야 할 음식~!
이모부랑 이모는 주말 아침이면 빠꾸떼를 자주 먹는다고 하였다.
이모는 나에게 "아가씨들은 이런거 못먹어~"라고말했고~
난 이모에게 "꼭~~~먹어보고 싶어~~~"라고 말했다.ㅎㅎ
우리나라 갈비탕이랑 비슷한데 돼지고기로 끓인다는...
사실 먹기전에 냄새나서 못 먹으면 어떡하지?이모한테 구박 들을텐데...혼자 내심 걱정했지만
괜한 걱정이었다~
너무 맛있어~~~ㅎㅎㅎ
이모가 가끔가는 깔끔하고 맛있는 호커센터에서...





내가 또 너무 좋아하는 크랩~
칠리크랩과 페퍼크랩~
완전 맛있어~맛있어~~~
밑에 있는건 맛조개 위에 마늘이 잔뜩 뿌려져 있는건데...이것 또한 완전 맛나~^^





피쉬해드커리~
생긴건 딱 징그럽게 생겼지만 맛은 기가 막히다.
조금만 먹기로 이모랑 약속하고 먹엇는데 둘이서 3인분 먹어버렸다는~ㅎㅎ





싱가폴은 음식값이 참 싸다.
맛있고 질 좋은 요리를 우리나라 절반 가격이면 맛 볼수 있다.
이곳은 새침떼기 사촌 동생과 같이간곳~
"언니가 쏜다~!"라는 말에 부담을 느꼈는지 못시키고 쭈뼛쭈뼛~
그래서~내가 먹고싶은거 다 시키기?ㅎㅎ
디저트를 좋아하는 사촌동생을 위해서 2개~^^





실가폴에서 제일 유명한 칵테일~
싱가폴실링~
두말 할 필요가 없다~!!!



※ 혹 위치를 알고 싶으신 분이 계시면 댓글이나 방명록에 남겨주세요~
기억이 허락하는한 설명 해 드릴께요~^^


'즐거운 이야기~ > 떳다떳다 해외여행!' 카테고리의 다른 글

싱가폴의 이곳저곳  (0) 2009.01.17
현지생활 즐기기~!  (0) 2009.01.14
싱가폴 먹거리-2  (0) 2009.01.12
싱가폴 먹거리-1  (0) 2009.01.12
싱가폴  (0) 2009.01.12
,

아침에 일어나면...
이모부 출근하실때 상냥하게 인사하고
사촌동생 학교 갈때 열심히 손 흔들어주고~

일하는 아줌마가 가져다준 과일쥬스 마시면서
이모와 난 매일 똑같은 고민을 반복했다...

"어딜가서 뭘 먹으면 잘 먹었다고 소문 날까?" 라는...

이럴땐 정말 손발이 잘 맞고
식성이 비슷한 이모가 있다는게 참 좋다~^^



싱가폴에서 제일 유명한 길거리 음식
빵 사이에 아이스크림을 넣어서 먹는 음식인데
불량식품 맛이 느껴지긴 하나 그나라의 문화의 일 부분이니 꼭 맛봐야지~^^




더운 나라라서 라임쥬스를 많이 먹는다고 책에서 읽고갔다.
먹는걸 무지 좋아하는 나는 우리나라에는 없으니까 꼭 먹어야지 다짐을 하고~
길에 있는 과일쥬스 가게에서 당당하게 주문을하고~
사진 찍어줄 사람이 없어서 가게 부스 안에 있는 사람한테 나와서 나좀 찍어달라고 했다~ㅎㅎ
(이모는 이날 약속이 있는 관계로 나 혼자 똘똘하게 돌아다닌 하루...)




우리나라에선 어색해서 좀처럼 할 수 없는행동...
혼자서 밥 먹기~!
외국에선 나 아는 사람 마주칠 걱정 없이니...당당하게...!
허나...어디가 맛있는 집인지 알 길이 없어 그나마 제일 깨끗해 보이는 곳에 들어가서 먹은 음식.
아무리 아는 사람이 없다고 해도 너무 어색해서 음식의 이름이 뭔지...맛이 어땠는지 기억이 나지 않는다ㅜ.ㅜ





가장 화려하고 맛있었던 뷔페
해산물이 풍부한 나라라 그런지 우리나라 뷔페에서 볼 수 없는 튼실한 랍스터와 새우들...
나오는 순간까지도 입에 오물오물 음식을 가득 담고 나왔던^^


※ 혹 위치를 알고 싶으신 분이 계시면 댓글이나 방명록에 남겨주세요~
기억이 허락하는한 설명 해 드릴께요~^^

'즐거운 이야기~ > 떳다떳다 해외여행!' 카테고리의 다른 글

현지생활 즐기기~!  (0) 2009.01.14
싱가폴 먹거리-3  (0) 2009.01.12
싱가폴 먹거리-1  (0) 2009.01.12
싱가폴  (0) 2009.01.12
롯본기!!!  (0) 2009.01.11
,

이번 싱가폴 여행은
무얼 먹을까?에 대한 고민이 전혀 필요 없는 여행이었다.

맛있는 음싱이 많은 나라...

갔다 온지 얼마 안돼도
다시 가고 싶다는 생각이 드는 이유는

10시까지 영업을 하는 백화점과
싸고 맛있는 음식이 많다는게 가장 큰 이유이다.

자~
이번 여행에서 과연 난 어떤것들을 먹었을까??? 


백화점 문 열기 전에 시간이 방방 뜰때 이모가 들른다는곳...
우리는 집에서 아침을 먹고 나온 상태였지만 그래도 맛있게 스프와 빵과 커피를~



싱가폴에서 꼭 맛봐야하는 야쿤카야 토스트
우리나라에도 몇군데 들어와 있긴 하지만 현지와는 맛이달라~
커피를 take-out할때 들고가기 편하게 비닐을 끼워준다.
신기하고 귀여워서 몇개 집에 가지고 왔는데 어디있지?




싱가폴은 다민족이 모여사는 국가라서 그런지 다양한 음식들이 많다.
태국을 대표하는 요리 수끼~
COCA라는 음식점에서...




사테라고 불리우는 소고기를 꼬치에 끼운
음식 땅콩소스에 곁들여 먹는 음식인데 계속계속 손이 가게 만든다.
그리고 밑에 음식은 소똥이라고 불린다~ㅋㅋ
오징어로 만든 우리나라 오징어 볶음과 비슷한 음식


여행은 맛있는 음식이 동반되어야 한다.
특히 현지에 살고 있는 이모덕분에 싸고 질 좋은 음식을 많이 맛 볼 수 있었다.
우리나라 여행책에 나와있는 음식점들과 겹치는 곳들도 몇곳 있긴 하지만
역시...달라~달라~~~

※ 혹 위치를 알고 싶으신 분이 계시면 댓글이나 방명록에 남겨주세요~
기억이 허락하는한 설명 해 드릴께요~^^

'즐거운 이야기~ > 떳다떳다 해외여행!' 카테고리의 다른 글

싱가폴 먹거리-3  (0) 2009.01.12
싱가폴 먹거리-2  (0) 2009.01.12
싱가폴  (0) 2009.01.12
롯본기!!!  (0) 2009.01.11
긴자에 있는 맛있는 스시집~^^  (0) 2009.01.11
,


유니 코드 (UTF-8 or UTF-16LE) 를 local (아스키 또는 각자의 codepage) 로 변환시키는 문제는 유니코드 지원 프로그래밍을 위해서는 매우 복잡한 문제이다.

먼저 보통 말하는 local codepage 랑 아스키랑 같은 것이라는 것을 알자. 나는 처음에 이게 차이가 있을 까봐 정말 머리가 아팠다.

결국...

UTF8 <-> UTF16LE
UTF16LE <-> UTF8
UTF8 <-> local
UTF16LE <-> local

이렇게 4 가지 조합만 바꿀 수 있으면 unicode 를 완벽하게 지원하는 프로그램을 짤 수 있다.

c++ 에서 사용할 수 있는 locale 을 바꿔 주는 library 가 몇가지 있는데...

1) iconv
2) boost
3) qt 의 qstring
4) 그리고 피부미인의 codechanger ㅋㅋㅋ

1 번은 가장 많이 쓰는데 static 으로 compile 할라면 머리아프다. 나는 DLL 을 정말 싫어한다.
2 번은 사람들이 잘 모르는데 boost 안에 일부 function 이 unicode 프로그래밍의 중요한 clue 를 제공한다. 여기서 개발된 것이 4 번의 피부미인의 codechanger 이다.
3 번 qt 는 일단 install 할라면 너무 머리아프다. build 하다가 다른 library 랑 부딛치면 돌아버린다.

4 번 피부미인의 codechanger 는 내가 medicalphoto 라는 프로젝트를 하면서 정말정말 어렵게 만든겁니다.  여기에만 특별히 공개하겠습니다. ^^g 이걸 쓰려면 boost library 를 설치해야합니다. 아니면 utf8-codecvt_facet.hpp 에 있는 boost/config.hpp 나 boost/detail/workaround.hpp 등만 copy 해서 사용해도 됩니다.


사용법은 아래와 같다.

MCodeChanger::_CCL("unicode letters") = "local code letters"
MCodeChanger::_CCU("local code letters") = "unicode letters"



1. codechanger.h

////////////////////////////////////////////////////////////////////////////////
// Copyright : Han Seung Seog
// It was so damn hard to make this library
// http://prettygom.com
// http://sshan.net
// 2008. 8. 1
////////////////////////////////////////////////////////////////////////////////

#pragma once

#include "../boost.h"
#include <string>
#include <boost/format.hpp>
#include "tchar.h"
#include "utf8_codecvt_facet.hpp"
#include "unicode.h"

#ifdef _UNICODE
    #define _CCL U_W
    #define _CCU W_U
    #define _CCW mbs_to_wcs
    #define _CCN wcs_to_mbs
#else
    #define _CCL U_L
    #define _CCU L_U
    #define _CCW LocaltoLocal
    #define _CCN LocaltoLocal
#endif // _UNICODE

class MCodeChanger
{
public:
    static tstring LocaltoLocal(const tstring& str)
    {
        return str;
    }

    static std::string L_U(const std::string& str)
    {
        std::locale local(std::locale(""),new utf8_codecvt_facet);
        return wcs_to_mbs(mbs_to_wcs(str),local);
    }
    static std::string U_L(const std::string& str)
    {
        std::locale local(std::locale(""),new utf8_codecvt_facet);
        return wcs_to_mbs(mbs_to_wcs(str,local));
    }
    static std::string W_U(const std::wstring& str)
    {
        std::locale local(std::locale(""),new utf8_codecvt_facet);
        return wcs_to_mbs(str,local);
    }
    static std::wstring U_W(const std::string& str)
    {
        std::locale local(std::locale(""),new utf8_codecvt_facet);
        return mbs_to_wcs(str,local);
    }

static std::wstring
mbs_to_wcs(std::string const& str, std::locale const& loc = std::locale(""))
{
    typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_t;
    codecvt_t const& codecvt = std::use_facet<codecvt_t>(loc);
    std::mbstate_t state = 0;
    std::vector<wchar_t> buf(str.size() + 1);
    char const* in_next = str.c_str();
    wchar_t* out_next = &buf[0];
    codecvt_t::result r = codecvt.in(state,
        str.c_str(), str.c_str() + str.size(), in_next,
        &buf[0], &buf[0] + buf.size(), out_next);
    return std::wstring(&buf[0]);
}
 
static std::string
wcs_to_mbs(std::wstring const& str, std::locale const& loc = std::locale(""))
{
    typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_t;
    codecvt_t const& codecvt = std::use_facet<codecvt_t>(loc);
    std::mbstate_t state = 0;
    std::vector<char> buf((str.size() + 1) * codecvt.max_length());
    wchar_t const* in_next = str.c_str();
    char* out_next = &buf[0];
    codecvt_t::result r = codecvt.out(state,
        str.c_str(), str.c_str() + str.size(), in_next,
        &buf[0], &buf[0] + buf.size(), out_next);
    return std::string(&buf[0]);
}
};

2. [ utf8_codesvt_facet.hpp ]

// Copyright ?2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu)
// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu).
// Distributed under the Boost Software License, Version 1.0. (See accompany-
// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#pragma once

// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// utf8_codecvt_facet.hpp

// This header defines class utf8_codecvt_facet, derived fro
// std::codecvt<wchar_t, char>, which can be used to convert utf8 data in
// files into wchar_t strings in the application.
//
// The header is NOT STANDALONE, and is not to be included by the USER.
// There are at least two libraries which want to use this functionality, and
// we want to avoid code duplication. It would be possible to create utf8
// library, but:
// - this requires review process first
// - in the case, when linking the a library which uses utf8
//   (say 'program_options'), user should also link to the utf8 library.
//   This seems inconvenient, and asking a user to link to an unrevieved
//   library is strange.
// Until the above points are fixed, a library which wants to use utf8 must:
// - include this header from one of it's headers or sources
// - include the corresponding .cpp file from one of the sources
// - before including either file, the library must define
//   - BOOST_UTF8_BEGIN_NAMESPACE to the namespace declaration that must be used
//   - BOOST_UTF8_END_NAMESPACE to the code to close the previous namespace
//   - declaration.
//   -  -- to the code which must be used for all 'exportable'
//     symbols.
//
// For example, program_options library might contain:
//    #define BOOST_UTF8_BEGIN_NAMESPACE <backslash character>
//             namespace boost { namespace program_options {
//    #define BOOST_UTF8_END_NAMESPACE }}
//    #define  BOOST_PROGRAM_OPTIONS_DECL
//    #include "../../detail/utf8/utf8_codecvt.cpp"
//
// Essentially, each library will have its own copy of utf8 code, in
// different namespaces.

// Note:(Robert Ramey).  I have made the following alterations in the original
// code.
// a) Rendered utf8_codecvt<wchar_t, char>  with using templates
// b) Move longer functions outside class definition to prevent inlining
// and make code smaller
// c) added on a derived class to permit translation to/from current
// locale to utf8

//  See http://www.boost.org for updates, documentation, and revision history.

// archives stored as text - note these ar templated on the basic
// stream templates to accommodate wide (and other?) kind of characters
//
// note the fact that on libraries without wide characters, ostream is
// is not a specialization of basic_ostream which in fact is not defined
// in such cases.   So we can't use basic_ostream<OStream::char_type> but rather
// use two template parameters
//
// utf8_codecvt_facet
//   This is an implementation of a std::codecvt facet for translating
//   from UTF-8 externally to UCS-4.  Note that this is not tied to
//   any specific types in order to allow customization on platforms
//   where wchar_t is not big enough.
//
// NOTES:  The current implementation jumps through some unpleasant hoops in
// order to deal with signed character types.  As a std::codecvt_base::result,
// it is necessary  for the ExternType to be convertible to unsigned  char.
// I chose not to tie the extern_type explicitly to char. But if any combination
// of types other than <wchar_t,char_t> is used, then std::codecvt must be
// specialized on those types for this to work.

#include <locale>
// for mbstate_t
#include <wchar.h>
// for std::size_t
#include <cstddef>

#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>

namespace std {
    #if defined(__LIBCOMO__)
        using ::mbstate_t;
    #elif defined(BOOST_DINKUMWARE_STDLIB) && !defined(__BORLANDC__)
        using ::mbstate_t;
    #elif defined(__SGI_STL_PORT)
    #elif defined(BOOST_NO_STDC_NAMESPACE)
        using ::mbstate_t;
        using ::codecvt;
    #endif
} // namespace std

#if !defined(__MSL_CPP__) && !defined(__LIBCOMO__)
    #define BOOST_CODECVT_DO_LENGTH_CONST const
#else
    #define BOOST_CODECVT_DO_LENGTH_CONST
#endif

// maximum lenght of a multibyte string
#define MB_LENGTH_MAX 8

struct  utf8_codecvt_facet :
    public std::codecvt<wchar_t, char, std::mbstate_t> 
{
public:
    explicit utf8_codecvt_facet(std::size_t no_locale_manage=0)
        : std::codecvt<wchar_t, char, std::mbstate_t>(no_locale_manage)
    {}
protected:
    virtual std::codecvt_base::result do_in(
        std::mbstate_t& state,
        const char * from,
        const char * from_end,
        const char * & from_next,
        wchar_t * to,
        wchar_t * to_end,
        wchar_t*& to_next
    ) const;

    virtual std::codecvt_base::result do_out(
        std::mbstate_t & state, const wchar_t * from,
        const wchar_t * from_end, const wchar_t*  & from_next,
        char * to, char * to_end, char * & to_next
    ) const;

    bool invalid_continuing_octet(unsigned char octet_1) const {
        return (octet_1 < 0x80|| 0xbf< octet_1);
    }

    bool invalid_leading_octet(unsigned char octet_1)   const {
        return (0x7f < octet_1 && octet_1 < 0xc0) ||
            (octet_1 > 0xfd);
    }

    // continuing octets = octets except for the leading octet
    static unsigned int get_cont_octet_count(unsigned   char lead_octet) {
        return get_octet_count(lead_octet) - 1;
    }

    static unsigned int get_octet_count(unsigned char   lead_octet);

    // How many "continuing octets" will be needed for this word
    // ==   total octets - 1.
    int get_cont_octet_out_count(wchar_t word) const ;

    virtual bool do_always_noconv() const throw() { return false; }

    // UTF-8 isn't really stateful since we rewind on partial conversions
    virtual std::codecvt_base::result do_unshift(
        std::mbstate_t&,
        char * from,
        char * /*to*/,
        char * & next
    ) const
    {
        next = from;
        return ok;
    }

    virtual int do_encoding() const throw() {
        const int variable_byte_external_encoding=0;
        return variable_byte_external_encoding;
    }

    // How many char objects can I process to get <= max_limit
    // wchar_t objects?
    virtual int do_length(
        BOOST_CODECVT_DO_LENGTH_CONST std::mbstate_t &,
        const char * from,
        const char * from_end,
        std::size_t max_limit
#if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))
        ) const throw();
#else
        ) const;
#endif

    // Largest possible value do_length(state,from,from_end,1) could return.
    virtual int do_max_length() const throw () {
        return 6; // largest UTF-8 encoding of a UCS-4 character
    }
};


3. [utf8_codecvt_facet.cpp]

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// utf8_codecvt_facet.cpp

// Copyright ?2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu)
// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu).
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

// Please see the comments in <boost/detail/utf8_codecvt_facet.hpp> to
// learn how this file should be used.
#include "stdafx.h"
#include "utf8_codecvt_facet.hpp"

#include <cstdlib> // for multi-byte converson routines
#include <cassert>

#include <boost/limits.hpp>
#include <boost/config.hpp>

// If we don't have wstring, then Unicode support
// is not available anyway, so we don't need to even
// compiler this file. This also fixes the problem
// with mingw, which can compile this file, but will
// generate link error when building DLL.
#ifndef BOOST_NO_STD_WSTRING

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// implementation for wchar_t

// Translate incoming UTF-8 into UCS-4
std::codecvt_base::result utf8_codecvt_facet::do_in(
    std::mbstate_t& /*state*/,
    const char * from,
    const char * from_end,
    const char * & from_next,
    wchar_t * to,
    wchar_t * to_end,
    wchar_t * & to_next
) const {
    // Basic algorithm:  The first octet determines how many
    // octets total make up the UCS-4 character.  The remaining
    // "continuing octets" all begin with "10". To convert, subtract
    // the amount that specifies the number of octets from the first
    // octet.  Subtract 0x80 (1000 0000) from each continuing octet,
    // then mash the whole lot together.  Note that each continuing
    // octet only uses 6 bits as unique values, so only shift by
    // multiples of 6 to combine.
    while (from != from_end && to != to_end) {

        // Error checking   on the first octet
        if (invalid_leading_octet(*from)){
            from_next = from;
            to_next = to;
            return std::codecvt_base::error;
        }

        // The first octet is   adjusted by a value dependent upon
        // the number   of "continuing octets" encoding the character
        const   int cont_octet_count = get_cont_octet_count(*from);
        const   wchar_t octet1_modifier_table[] =   {
            0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc
        };

        // The unsigned char conversion is necessary in case char is
        // signed   (I learned this the hard way)
        wchar_t ucs_result =
            (unsigned char)(*from++) - octet1_modifier_table[cont_octet_count];

        // Invariants   :
        //   1) At the start of the loop,   'i' continuing characters have been
        //    processed
        //   2) *from   points to the next continuing character to be processed.
        int i   = 0;
        while(i != cont_octet_count && from != from_end) {

            // Error checking on continuing characters
            if (invalid_continuing_octet(*from)) {
                from_next   = from;
                to_next =   to;
                return std::codecvt_base::error;
            }

            ucs_result *= (1 << 6);

            // each continuing character has an extra (10xxxxxx)b attached to
            // it that must be removed.
            ucs_result += (unsigned char)(*from++) - 0x80;
            ++i;
        }

        // If   the buffer ends with an incomplete unicode character...
        if (from == from_end && i   != cont_octet_count) {
            // rewind "from" to before the current character translation
            from_next = from - (i+1);
            to_next = to;
            return std::codecvt_base::partial;
        }
        *to++   = ucs_result;
    }
    from_next = from;
    to_next = to;

    // Were we done converting or did we run out of destination space?
    if(from == from_end) return std::codecvt_base::ok;
    else return std::codecvt_base::partial;
}

std::codecvt_base::result utf8_codecvt_facet::do_out(
    std::mbstate_t& /*state*/,
    const wchar_t *   from,
    const wchar_t * from_end,
    const wchar_t * & from_next,
    char * to,
    char * to_end,
    char * & to_next
) const
{
    // RG - consider merging this table with the other one
    const wchar_t octet1_modifier_table[] = {
        0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc
    };

    wchar_t max_wchar = (std::numeric_limits<wchar_t>::max)();
    while (from != from_end && to != to_end) {

        // Check for invalid UCS-4 character
        if (*from  > max_wchar) {
            from_next = from;
            to_next = to;
            return std::codecvt_base::error;
        }

        int cont_octet_count = get_cont_octet_out_count(*from);

        // RG  - comment this formula better
        int shift_exponent = (cont_octet_count) *   6;

        // Process the first character
        *to++ = static_cast<char>(octet1_modifier_table[cont_octet_count] +
            (unsigned char)(*from / (1 << shift_exponent)));

        // Process the continuation characters
        // Invariants: At   the start of the loop:
        //   1) 'i' continuing octets   have been generated
        //   2) '*to'   points to the next location to place an octet
        //   3) shift_exponent is   6 more than needed for the next octet
        int i   = 0;
        while   (i != cont_octet_count && to != to_end) {
            shift_exponent -= 6;
            *to++ = static_cast<char>(0x80 + ((*from / (1 << shift_exponent)) % (1 << 6)));
            ++i;
        }
        // If   we filled up the out buffer before encoding the character
        if(to   == to_end && i != cont_octet_count) {
            from_next = from;
            to_next = to - (i+1);
            return std::codecvt_base::partial;
        }
        *from++;
    }
    from_next = from;
    to_next = to;
    // Were we done or did we run out of destination space
    if(from == from_end) return std::codecvt_base::ok;
    else return std::codecvt_base::partial;
}

// How many char objects can I process to get <= max_limit
// wchar_t objects?
int utf8_codecvt_facet::do_length(
    BOOST_CODECVT_DO_LENGTH_CONST std::mbstate_t &,
    const char * from,
    const char * from_end,
    std::size_t max_limit
#if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))
) const throw()
#else
) const
#endif
{
    // RG - this code is confusing!  I need a better way to express it.
    // and test cases.

    // Invariants:
    // 1) last_octet_count has the size of the last measured character
    // 2) char_count holds the number of characters shown to fit
    // within the bounds so far (no greater than max_limit)
    // 3) from_next points to the octet 'last_octet_count' before the
    // last measured character. 
    int last_octet_count=0;
    std::size_t char_count = 0;
    const char* from_next = from;
    // Use "<" because the buffer may represent incomplete characters
    while (from_next+last_octet_count <= from_end && char_count <= max_limit) {
        from_next += last_octet_count;
        last_octet_count = (get_octet_count(*from_next));
        ++char_count;
    }
    return static_cast<int>(from_next-from_end);
}

unsigned int utf8_codecvt_facet::get_octet_count(
    unsigned char   lead_octet
){
    // if the 0-bit (MSB) is 0, then 1 character
    if (lead_octet <= 0x7f) return 1;

    // Otherwise the count number of consecutive 1 bits starting at MSB
//    assert(0xc0 <= lead_octet && lead_octet <= 0xfd);

    if (0xc0 <= lead_octet && lead_octet <= 0xdf) return 2;
    else if (0xe0 <= lead_octet && lead_octet <= 0xef) return 3;
    else if (0xf0 <= lead_octet && lead_octet <= 0xf7) return 4;
    else if (0xf8 <= lead_octet && lead_octet <= 0xfb) return 5;
    else return 6;
}

namespace {
template<std::size_t s>
int get_cont_octet_out_count_impl(wchar_t word){
    if (word < 0x80) {
        return 0;
    }
    if (word < 0x800) {
        return 1;
    }
    return 2;
}

// note the following code will generate on some platforms where
// wchar_t is defined as UCS2.  The warnings are superfluous as
// the specialization is never instantitiated with such compilers.
template<>
int get_cont_octet_out_count_impl<4>(wchar_t word){
    if (word < 0x80) {
        return 0;
    }
    if (word < 0x800) {
        return 1;
    }
    if (word < 0x10000) {
        return 2;
    }
    if (word < 0x200000) {
        return 3;
    }
    if (word < 0x4000000) {
        return 4;
    }
    return 5;
}

} // namespace anonymous

// How many "continuing octets" will be needed for this word
// ==   total octets - 1.
int utf8_codecvt_facet::get_cont_octet_out_count(
    wchar_t word
) const {
    return get_cont_octet_out_count_impl<sizeof(wchar_t)>(word);
}


#endif



,


싱가폴은 나에게 처음으로
크리스마스를 민소매 차림으로 경험하게 해주었다.
1년 내내 더운 나라 임에도 불구하고
그들 나름대로 계절이 있다고 한다.
12월에도 25˚C 이상인 그곳에서
멋쟁이들은 모직으로 된 옷을 입는다고 한다.




시내에서 약간 떨어져 있는 이스트 코스트 파크

내가 찾은 그날은 토요일 아침 이어서 인지
자전거 타는 사람도 많고, 개들 데리고 나와서 산책을 하거나 조깅을 하는 사람들로 붐볐다.



멀리 바다가 보이는 장소에 앉아서 따듯한 카푸치노 한잔을 마시며 아침 시작~!

낯선 곳에서 낯선 사람들을 만나는것이 여행의 묘미인듯 싶다.

교통이 약간 불편하긴 하지만
이스트 코스트 파크는 싱가폴 안에서 또다른 이국의 느낌을 즐기기에 충분한듯 하다.



(사진은 위에서부터 '홀랜드 빌리지' , '부기스 졍선' , '레플즈 호텔' , '비보씨티')

내가 싱가폴을 방문했던 시기가 크리스마스때라 그런지
거리는 온통 크리스마스 장식으로 화려하게 꾸며져 있었다.

싱가폴에 살고있는 이모 얘기로는
매년 다른 주제로 거리에 크리스마스 장식을 꾸며
가장 화려하고 아름답게 꾸민 지역에는
1년동안 전기세를 면제 시켜준다고 했던거 같다...@.@

그저 난 여름 나라에서 크리스 마스를 보낸다는게 신기할 따름이었다~


'즐거운 이야기~ > 떳다떳다 해외여행!' 카테고리의 다른 글

싱가폴 먹거리-3  (0) 2009.01.12
싱가폴 먹거리-2  (0) 2009.01.12
싱가폴 먹거리-1  (0) 2009.01.12
롯본기!!!  (0) 2009.01.11
긴자에 있는 맛있는 스시집~^^  (0) 2009.01.11
,