Monday, January 27, 2014

BinaryWriter로 String을 썼는데 앞에 쓰레기값이 붙음 어떻게 해야 함?

그거 문자열 길이임 ㅋㅋㅋ

System.IO.BinaryWriter(System.IO.Stream)
"제공된 스트림을 기반으로 UTF-8을 문자열의 인코딩으로 사용하여 BinaryWriter 클래스의 새 인스턴스를 초기화합니다."

void BinaryWriter.Write(string)
"BinaryWriter의 현재 인코딩으로 된 이 스트림에 문자열의 길이가 맨 앞에 나오는 문자열을 쓴 다음 사용된 인코딩과 스트림에 쓰여지는 특정 문자의 길이만큼 스트림의 현재 위치를 앞으로 이동합니다"

그럼 이렇게 쓴 문자열을 읽을 때는 어떻게 해야 할까?
일단 integer를 하나 읽고, 거기서... 그럴 리가 없고

그냥 읽으면 된다.
BinaryReader.ReadString()은 문자열의 길이가 맨 앞에 오는 문자열을 읽게 되어 있다.

VS2010의 이 함수 설명은 해석이 괴상한데, 사실 원문도 좀 이상하긴 하다.

현재 스트림에서 문자열을 읽습니다. 한 번에 7비트 정수로 인코딩된 문자열 길이는 해당 문자열 앞에 옵니다.

원문은 이거다:
Reads a string from the current stream. The string is prefixed with the length, encoded as an integer seven bits at a time.
String이 length로 prefixed되어 있다는 중요한 사실을 먼저 말하는 게 당연하다.

위 번역은 일단 쉼표(,)로 구분된 문장을 잘못 번역했다.
(그) 문자열은 (문자열) 길이가 (맨) 앞에 오며, 이것(문자열 길이를 나타내는 정수)은 한 번에 7비트 정수로 인코딩되어 있습니다.

한 번에 7비트 정수로 인코딩(encoded as an integer seven bits at a time)은 도대체 무슨 소리일까?
같은 궁금증을 가진 사람이 역시 있었다:
답변자는 BinaryReader의 소스코드까지 따라가 보았다. 존경한다.
요약하면, 문자열 길이는 int의 배열로 저장되는 게 아니라, 8비트(=1바이트) 중 최상위 1비트를 다음 바이트가 필요한 지 여부를 나타내는 데 씀으로써 정수 크기에 따라 필요한 바이트 수에 맞게 알아서 잘(...) 쓴다는 것이다.
예를 들어 127까지는 7비트 이내니까 그냥 쓰고, 그보다 큰 숫자는 앞에 표시해서(아마도 0이 아니라 1로 세팅하거나 그런 거겠지) 다음 바이트도 (문자열이 아니라 문자열 길이를 나타내는) 정수로 읽게 하는 것이다. - 대충 이해한 거라 틀릴 수도 있지만 대략의 내용은 맞을 것이다.

그냥 7bitEncoding을 이용해 인코딩되어 있다(encoded by 7bitEncoding)라고 했으면 7bitEncoding이라는 게 있나 보다 하고 넘어갔을 텐데 encoded as an integer seven bits at a time이라는 문장이 오해를 불렀다.
전문 용어를 전문 용어가 아닌 척하고 쓰는 건 나쁜 글쓰기 습관이다. 특히나 개념에 대한 검색을 어렵게 한다는 점에서 그렇다. Encode ... ~ bits at a time이 업계의 관용구인가 알아보려고 해도 알 수가 없잖아?

Friday, January 24, 2014

파워포인트PowerPoint 2007 Two-Page View 한 화면에 두 페이지 보기

진짜 되는 건 아니고 흉내낼 수는 있다.


새 창을 누르면 아무 것도 안 변한 것 같지만 PowerPoint 창 제목이 바뀌어 있다:


프레젠테이션1:2에서 :2 부분이 같은 파일을 연 창 여러 개 중 2번째라는 뜻이다('프레젠테이션1'이 파일 이름이다. 저장하기 전이라 그렇다. 저장한 파일 이름이 name.pptx면 name.pptx:2라고 나왔을 것이다).

작업표시줄을 보면 창이 두개 열린 것을 확인할 수 있다.
여기서 (작업표시줄 단추를 눌러) 다른 창을 고르면 역시 변한 게 없다. 어쩌란 말인가?
▶ 이건 PowerPoint 프로그램의 인스턴스를 두 개 이상 띄울 수 없게 해 놓았기 때문이다(정확히는 꼭 그런 건 아니지만 창의 관점에서 그렇다는 것이다.). 여기서 의문이 생긴다. 한 가지 파일을 여러 여러 뷰(view)에서 보고자 한다면 여러 창을 동시에 볼 수 있어야 할 게 아닌가? 도대체 새 창 버튼은 왜 만든 것인가?

해결책은 모두 정렬 버튼에 있다.

모두 정렬을 누르면 다음과 같이 two-page view 짝퉁을 구현할 수 있다(물론 창을 더 열어 3-page view도 가능하다.).

그러니까, 처음 '새 창'을 만들었을 때까지는 non-MDI 모드로 계속 동작하고, 모두 정렬 또는 계단식 버튼을 누르면 그제서야 MDI 모드로 동작하는 것이다. 반면 Excel은 처음부터 MDI 모드이기 때문에 새 창을 만들면, 만든 창이 바로 보이므로 창이 어디 갔나 찾지 않는다.

참고로 최대화된 창의 제목표시줄을 잡아당겨 이전 창으로 복귀*하게 할 수 있는데, 이것이 Word, PowerPoint에서는 되지만 Excel에서는 안 된다. 이 또한 Microsoft의 멋짐이라. (끌어당겨서 최대화는 되는 것도 멋짐.)


------------------------
* 최대화되지 않은 창.

Thursday, January 23, 2014

오늘의 골때리는 js 현상: alert 창을 닫아도 클릭 이벤트가 계속 trigger되어 alert가 무한히 나옴

텍스트박스에서 엔터를 치면 자동으로 입력되게 하려고 keyup 이벤트 핸들러를 등록했다.
잘 동작하는 듯했는데  alert창을 닫아도 닫아도 계속 열리는 것이다.
크롬이어서 다행이지 IE였으면 무한히 열렸을 거야...스페이스바로 눌러보길 잘했지*

$('<input/>', { type: "text", id: "myInput" })
.appendTo(myForm)
.keyup(function (event) {
if (event.keyCode == 13) {  // 13=ENTER
// $(this).blur();
$("#myButton").click();
});
$('<button/>', { type: "button", text: "입력", id: "myButton" })
                .appendTo(myForm)
                .click(myButton_Click);

function myButton_Click() {
   alert("이거 무한 반복됨");
}


해결책: 저 코드의 주석을 해제하여 $(this).blur()로 포커스를 강제 해제하면 된다. alert 창이 닫힌 후 focus가 돌아오지 않는다는 게 문제지만 그건 나중에 해결하고.

아무튼 javascript는 콜백함수에서 입력한 게 콜백함수를 호출한 쪽에도 영향을 미치는 병맛나는신박한 언어다. 아니, jQuery의 문제인가? 뭔가 event.preventDefault() 같은 게 있는 거 같은데 해도 안 되고 그건 나중에 알아보기로.


*사실은 ok 버튼을 엔터키로 누를 때만 그렇다. 마우스로 클릭하거나 스페이스바로 확인하면 그러지 않는다(이벤트가 발생하지 않으므로 당연하다). 

Tuesday, January 7, 2014

javascript의 for와 C#의 foreach를 구분하기

js의 for는 마치 foreach처럼 쓸 수 있지만 for 내에서 선언한 variable이(이걸 뭐라고 불러야 하는 거지? iteration 계의 this 같은 그 무언가...)이 key-value pair의 value가 아니라 key라는 점이 C#과 다르다. 즉,

in C#,
foreach (var item in container) {
   item.DoSomething();
}

in js,
for(var property in obj) {
   var item = obj[property];
   item.doSomething();
}

PHP가 출동하면 어떨까?

meanwhile in PHP,
foreach($container as $item) {
    $item.doSomething();
}

아오 이색휘는 왜 순서가 반대여...
하지만 여기에도 나름의 장점이 있으니...

foreach($container as $key=>$value) {
    echo $key . ': ' . $value.toString();
}

이런 무시무시한 문법이 가능하다.

그러면 이들 중에서 C#이 제일 나쁜가하면 그건 아니다. 취존이겠지만 C#이 가장 좋아 보인다.
일단 PHP 문법은 영어 어순에 안 맞는다. For each item in container라고 하지 For each container xxx라고는 안 한다. (For each item in container as (k, v)라고 할 수는 있으려나...)
다음으로 index가 필요한 경우에는 foreach가 아니라 그냥 for를 쓰면 된다. foreach를 그냥 유지하면서 index도 쓰고 싶으면 변수를 하나 선언하고 foreach 안에서 increment/decrement하면 된다. Scope 때문에 귀찮아질 수도 있지만.
마지막으로 dictionary인 경우에는 key 필요 여부에 따라 달리 쓰면 된다.
var output="";
foreach(var key in dic.Keys) {
   output+=key + ": ";  // key1: value1, ...
   output+=dic[keys];
}
foreach(var value in dic.Values) {
   output+=value;
}
C++와 비교해도, C#은 key set을 바로 얻을 수 있어서 좋다.

js의 for는 그것 나름으로는 괜찮은 것 같지만 C#을 먼저 배운 사람에게는 가장 헷갈리는 것 종류가 될 것 같다.
게다가 for loop을 돌리는 대상이 Array 또는 객체 모두가 되기 때문에 혼란이 가중된다. 즉 object인줄 알았는데 array인  경우 기대했던 값이 안 나오고 죄다 undefined가 뜬다든가...

Sunday, January 5, 2014

jsplumb을 쓸 때 주의할 점

공식 문서를 참조하지 말 것.

다른 유저의 블로그나, SO나 기타 사이트들을 이용할 것.






API가 바뀌어도 반영이 안 돼 있다.


(아오...)

Saturday, January 4, 2014

수학 식 입력판 Math Input Panel

Windows 7 보조프로그램 중에

'수식편집기'도 아니고 무려 이름이 '수학 식 입력판'인 녀석이 있다.

(띄어쓰기에서도 주의한다)

보조프로그램에 들어있었는데 어느날 쓰려고 검색해보니 안 나오는 것이다.
(보통 이런 프로그램은 보조프로그램까지 찾아가기 귀찮기 때문에 검색을 쓴다. '그림판'이라든가, '메모장'이라든가.)

이유는 며칠전에 SSD 용량 아낀다고 Tablet PC 구성요소를 지워버렸기 때문이었다.
(수학 식 입력판 말고도 Table PC 입력판이 있다)

그래도 '수식편집기' 같은 걸로 검색하면 안 나오니 띄어쓰기에는 여전히 주의해야 한다?

Tablet PC 구성요소는 설치하고 나면 무려 Windows를 재시작할 것을 요구하는데 무시해도 된다. 다만 한동안은 프로그램 목록에 Math Input Panel로 나오는 것 같다.

Thursday, January 2, 2014

jQuery 스타일로 getter, setter 만들기

A라는 클래스의 멤버함수(*)인 getter 및 setter를 jQuery 스타일로 만들어 보자.
즉, propertyName(value)면 propertyName이 value로 세팅되고,
propertyName() 하면 propertyName 값을 반환한다.

//ctor
function A() {
  this.element = $('<div/>').appendTo('body');
}

A.prototype.X = function(x) {  // #
    if(x!=undefined) { // setter
        this.element.attr("x", x);
    }
    else {
        return this.element.attr("x");
    }
}

Remarks
1. 함수 하나가 리턴 값을 가졌다 안 가졌다 하고, 입력 개수 체크도 안 하는 막장스러운 js의 성질 덕분에 이런 멋있는 일을 할 수 있다.
2. 그냥 this._x = x; 이런 식으로 쓸 수도 있는데 굳이 DOM에 attribute로 추가하려고 해 보았다.


* js에는 원래 클래스 개념이 없으므로 사실 멤버 함수 흉내를 낸 거지만.

# 먼 미래에 js를 까먹었을 때를 대비해서 써놓자면, prototype은 js의 키워드이다.

Wednesday, January 1, 2014

외부 DLL의 네임스페이스 (ft. JSON.NET)

C#에서도 JSON을 좀 써 보려고 JSON.NET을 받아서 참조 추가까지는 했는데,,,

예제 코드들이 하나같이 namespace를 뭘 해야 되는 지 안 써놓는 것이다.


아 좀 친절해지라고!



저기 이미 있어서 그렇다.

using Newtonsoft.Json;



어쨌든 '첫 번째 예제'라 할 만한 것을 굳이 튜토리얼 스타일로 쓰지 않는 것은 이해하기 어렵다.

VS 아이콘 편집


[리빙포인트] 색을 고르려면 마우스 오른쪽 버튼으로 여기를 누르고 색상 창 표시를 선택해야 한다.

도킹된 모습
툴바에는 '색상 창 표시' 버튼을 만들지 않은 이유가 뭔지...

Captcha Coin (2)

자동연쇄징수시스템:

저작권료 지불 대행 같은 것.



지난번 포스트에서 쓴다고 해 놓고 못 쓰고 있었는데 오늘도 못 쓰겠다. ㅋㅋㅋ
이말년의 인생의 무게 2 같은 것이지.

창 핸들을 만드는 동안 오류가 발생했습니다

System.ComponentModel.Win32Exception was unhandled   MyForm w = new MyForm IntPtr handle = wnd.Handle;   // Exception occurs here class MyFo...