Buffer Sınıfı

CorsaiR

Emektar
27 Ara 2005
1,228
18
Çekirdekten
Buffer Sınıfı
Byte düzeyinde değişik tipteki dizi değişkenler üzerinde işlem yaparken System Namespace’te yer alan Buffer sınıfı işinizi kolaylaştırabilir.
Bu işlemler yapılırken Buffer sınıfının BlockCopy() metodundan yararlanılmaktadır.

Buffer sınıfının işlevini anlatan veya metotlarının nasıl kullanıldığını gösteren örnek hazırlamadan önce Array sınıfının Copy() metodundan söz edeceğim. Bu amaçla int tipinde farklı sayıda elemanlara sahip 2 dizi değişken tanımladım ve ilk dizinin 3 elemanını Copy() metodu ile ikinciye aktardım.

private **** Form1_Click(object sender, EventArgs e)
{
int[] Dizi_1 = {1,2,3,4};
int[] Dizi_2 = {0,0,0,0,0};
Array.Copy(Dizi_1, 0, Dizi_2, 0, 3);
}

Hatırlayacağınız gibi Array sınıfının Copy() metodu 1. parametre olarak verilen dizi değişkenin istenilen elemanından itibaren istenilen sayıda elemanı 3. parametrede işaret edilen hedef diziye kopyalamaktadır.

Bu kod işletildiğinde Copy() metodu ilk dizinin ilk 3 elemanının içeriğini ikinci dizinin aynı elemanlarına aktarır ve Dizi_2'nin elemanları sıra ile "1, 2, 3, 0, 0" değerlerini içerir. Aynı kopyalama işlemini Buffer sınıfının BlockCopy() metodu ile yapabilirsiniz. Bu metodun nasıl kullanıldığını aşağıda görebilirsiniz.

private **** Form1_Click(object sender, EventArgs e)
{
int[] Dizi_1 = {1,2,3,4};
int[] Dizi_2 = {0,0,0,0};
System.Buffer.BlockCopy(Dizi_1, 0, Dizi_2, 0, 3);
textBox1.Text = Dizi_2[0].ToString();
textBox2.Text = Dizi_2[1].ToString();
textBox3.Text = Dizi_2[2].ToString();
textBox4.Text = Dizi_2[3].ToString();
}

Buffer sınıfının BlockCopy() metodu bu şekilde kullanıldığında beklenenin aksine ilk TextBox'a 1, diğer TextBox'lara ise 0 aktarılır. Aşağıda verilen ekran görüntüsünü bu kodu işlettikten sonra aldım.

5738_image001.png


Çünkü BlockCopy() metodunu bu şekilde kullanmakla aslında şöyle bir talepte bulunmuş oluyoruz: İlk dizinin ilk byte’ından başlamak üzere ikinci diziye 3 byte bilgi kopyala. Belki bu cümle karışık oldu. Şimdi buna açıklık getirmeye çalışacağım. Madem int değiş¬kenler bellekte 4 byte yer kaplamaktadır int tipindeki ilk dizi değişkenin bellekteki yerleşimi aşağıdaki gibi resmedilebilir.

İlk elemanın bellekteki temsili yerleşimi

5738_1Eleman.gif


2. elemanın bellekteki temsili yerleşimi

5738_2Eleman.gif


3. elemanın bellekteki temsili yerleşimi

5738_3Eleman.gif


4. elemanın bellekteki temsili yerleşimi

5738_4Eleman.gif


int değişkene aktardığım değerler küçük olduğu için en sağdaki byte’lar yeterli olmaktadır. Bu 4 adet 32 bit bellekte arka arkaya dururlar. BlockCopy() metodunu aşağıdaki gibi kullanmakla gerçekte ne demiş oluyoruz?

System.Buffer.BlockCopy(Dizi_1, 0, Dizi_2, 0, 3);

Bu 4*4=16 byte’ın veya 4*4*8= 128 bitin ilk 3 byte’nı veya 8*3=24 bitini kopyala demiş oluyoruz. Bizim örnekte ilk byte 1, 2. ve 3. byte’larda ise 0 bilgisi olduğu için yukarıda verilen sonuç alınır. BlockCopy() metodu aşağıdaki gibi kullanılsaydı, başka bir deyişle kaynak diziden hedef diziye 3 yerine 4 byte kopyalansaydı değişen bir şey olmazdı.

Çünkü temsili resimden görebileceğiniz gibi int tipindeki kaynak dizinin ilk elemanın son byte’ının bütün bitleri 0 ile doludur. Peki BlockCopy() metodu aşağıdaki gibi kullanılmış olsaydı hedef dizi değişkenin elemanlarının içeriği ne olurdu?

System.Buffer.BlockCopy(Dizi_1, 0, Dizi_2, 0, 5);

4. parametre olarak 5 kullanıldığı için toplam 4 elemanı olan int tipindeki kaynak dizi değiş¬kenin toplam 16 byte’ın ilk 5 byte veya ilk 40 biti hedef diziye kopyalanır. Kaynak dizi değiş¬kenin 2. elemanı 2 değerini içeriği için sorunsuz bir şekilde 2. elemanın içeriği hedef dizideki 2. elemana kopyalanır ve aşağıdaki gibi bir sonuç alınır.

5738_image002.png


Şimdi şeytanın avukatlığını yapıp kaynak dizi değişkenin başlangıçta 2 olan içeriğini 256 yapacağım. Bu şartlarda BlockCopy() metodu ile kaynak dizinin ilk 5 byte’ı okunup hedef diziye aktarılırsa ne olur?

int[] Dizi_1 = {1,256,3,4};
int[] Dizi_2 = {0,0,0,0};
System.Buffer.BlockCopy(Dizi_1, 0, Dizi_2, 0, 5);

Bu şartlarda int tipindeki kaynak dizi değişkenin 2. elamanın veya ikinci 32 bitinin bellek¬teki temsili yerleşimi aşağıdaki gibi olur. Eleman 256 bilgisini içerdiği için 9. bit hariç bütün bitler 0 değerini içerir.

2. elemanın bellekteki temsili yerleşimi

5738_5Eleman.gif


Bu durumda int tipindeki kaynak dizi değişkenden 5 byte veya 5*8=40 bit bilgi okunursa hedef dizinin 2. elemanı 0 olarak kalmaya devam eder. Çünkü 0 olmayan ilk bit 41. bitte bulunmaktadır. Bu şartlarda yukarıda verilen kod işletilirse aşağıdaki gibi bir sonuç alınır.

5738_image001.png


BlockCopy() metodu ile kaynak diziden 5*8=40 byte yerine 6*8=48 byte okunsaydı hedef dizi değişkenin 2. elemanı 256 olurdu. Kaynak dizinin 2. elemanı 256 yerine 500 sayısını içeriyor olsaydı ve BlockCopy() metodu ile kaynak diziden 5*8=40 byte okunup hedef diziye aktarılmış olsaydı hedef dizinin 2. elamın içeriği ne olurdu?

Bu sorunun cevabını yukarıda verdiğim ve BlockCopy() metodunun kullanıldığı kodu işlet¬meden bulmak istiyorsanız Windows ile birlikte verilen Hesap Makinesi programını çalıştırıp 10 tabanlı 500 sayısının 2 tabanlı karşılığını öğrenerek bulabilirsiniz. 500 sayısını 2 tabanlı olarak ifade etmek için 9 bit yeterli olmaktadır(1 1 1 1 1 0 1 0 0).

Kaynak dizi değişkenin 2. elemanı 500 sayısını içeriyorken BlockCopy() metodu ile 40 byte okursanız hedef dizi değişkene, kaynak dizi değişkenin aynı sıradaki elemanın ilk 8 byte’ı kopyalanır ve içeriği 224 olur. Çünkü 2 tabanlı “1 1 1 1 0 1 0 0” sayısının 10 tabanlı karşılığı 224’tür.

int[] Dizi_1 = {1,500,3,4};
int[] Dizi_2 = {0,0,0,0};
System.Buffer.BlockCopy(Dizi_1, 0, Dizi_2, 0, 5);

Yukarıda belirtildiği gibi int tipindeki kaynak dizi değişkenimiz 4 elemana sahiptir ve bellekte toplam 4*4=16 byte yer kapmaktadır. Eğer bu örnekte BlockCopy() metoduna 16’dan büyük bir değeri 5. parametre olarak verirseniz hata meydana gelir.

Yukarıda verdiğim örnekte kaynak ve hedef dizi değişkenler aynı tipteydi. BlockCopy() metodu farklı tipteki dizi değişkenleri parametre olarak alıp kopyalama yapabilmektedir. Bu konuda bilgi vermek için birisi 2 byte’lık Short diğeri 1 Byte’lık byte tipinde 2 dizi değişken tanımladım.

short[] Kaynak_Dizi = {1000,2000};
byte[] Hedef_Dizi = new byte[10];

Bu şekilde tanımlanıp 2 elemanlı olması sağlanan short dizi değişken bellekte 2*2=4 byte veya 2*2*8=32 bit yer kaplar. Bu dizi değişkenin bellekteki yerleşimi aşağıdaki gibi olur.

5738_6Eleman.gif


Şimdi bu kaynak dizinin ilk 3 byte’nı veya 24 bitini BlockCopy()metodu ile okuyup Byte tipindeki hedef diziye aktaracağım. Başka bir deyişle kaynak dizinin ilk elamanın bütün bitlerini, 2. elemanın ise ilk 8 bitini okuyacağım.

short[] Kaynak_Dizi = {1000,2000,3000};
byte[] Hedef_Dizi = new byte[10];
System.Buffer.BlockCopy(Kaynak_Dizi, 0, Hedef_Dizi, 0, 3);

BlockCopy() metodu bu şekilde kullanıldığında toplam 6 byte bilgi okunduğu için byte tipindeki hedef dizi değişkenin ilk 6 elemanı doldurulur. Bu elemanların içeriklerini size göstermek için forma TextBox’lar yerleştirdim ve aşağıda verdiğim kodu hazırladım.

private **** Form1_Click(object sender, EventArgs e)
{
short[] Kaynak_Dizi = {1000,2000,3000};
byte[] Hedef_Dizi = new byte[10];
System.Buffer.BlockCopy(Kaynak_Dizi, 0, Hedef_Dizi, 0, 3);
textBox1.Text = Hedef_Dizi[0].ToString();
textBox2.Text = Hedef_Dizi[1].ToString();
textBox3.Text = Hedef_Dizi[2].ToString();
textBox4.Text = Hedef_Dizi[3].ToString();
}

Bu kod işletildiğinde 2 bitlik kaynak dizinin ilk elemanın yarısı byte tipindeki hedef dizinin ilk elemana, diğer yarısı ise 2. elemana aktarılır. Kaynak dizinin 2. elemanın ilk byte’ı veya yarısı ise hedef dizideki 3. elemana aktarılır. Bu kod işletildiğinde aşağıda verilen sonuç alınır.

5738_image003.png


Yukarıda verilen örneklerde kaynak dizinin eleman sayısını her elemanın bellekte kapladığı byte miktarını kendim çarpıp hedef dizide gereken eleman sayısını buldum. Ancak bu hesapların kod yazılarak yapılması gerekir. Buffer sınıfının ByteLength() metodu parametre olarak aldığı dizi değişkenin bellekte kaç byte yer kapladığını bulmaktadır. ByteLength() metodu aşağıdaki gibi kullanıldığında geriye 4*10=40 sayısını gönderir.

private **** Form1_Click(object sender, EventArgs e)
{
int[] Dizi = new int[10];
int sayi = System.Buffer.ByteLength(Dizi);
textBox1.Text = sayi.ToString();
}

Buffer sınıfının yukarıda sözü edilen BlockCopy() ve ByteLength() metotlarından başka ayrıca GetByte() adında bir metodu bulunmaktadır. Bu metot istenen tipteki dizi değişke¬nin istenen byte’nın içeriğini okumaya yaramaktadır. GetByte() metodunun nasıl kullanıldığını aşağıda görebilirsiniz.

private **** Form1_Click(object sender, EventArgs e)
{
short[] Dizi = {100, 1000, 10000};
int ilk_byte = Buffer.GetByte(Dizi, 0);
int ikinci_byte = Buffer.GetByte(Dizi, 1);
int ucuncu_byte = Buffer.GetByte(Dizi, 2);
int dorduncu_byte = Buffer.GetByte(Dizi, 3);
textBox1.Text = ilk_byte.ToString();
textBox2.Text = ikinci_byte.ToString();
textBox3.Text = ucuncu_byte.ToString();
textBox4.Text = dorduncu_byte.ToString();
}

Bu örnekte GetByte() metoduna parametre olarak 3 elemanlı short tipindeki dizi değişkeni verdim. Short tipindeki bu dizi değişkenin her elamanı bellekte 2 byte yer kaplamakta ve ilk elemana aktarılan sayı ilk byte’a sığdığı için ilk byte’ın içeriği eksiksiz okunup ilk TextBox’a aktarılır.

Dizi değişkenin 2. elemanın bir kısmı ilk byte’ta, diğer kısmı 2. byte’ta tutulacağı için bu kod işletildiğinde aşağıdaki gibi bir sonuç alınır. Bit düzeyinde 3. ve 4. byte birleştirildiğinde 10 tabanlı 1000 sayısı elde edilir.

5738_image004.png


Herhangi tipteki dizi değişkenin istediğiniz byte’ına istediğiniz değeri yazmak veya mevcut içeriği değiştirmek istiyorsanız Buffer sınıfının SetByte() metodunu kullanabilirsiniz. 3 parametreye sahip olan bu metot içeriğinde değişiklik yapılmak istenen dizi değişkeni ilk parametre olarak almaktadır.

Bu metodun nasıl kullanıldığını anlatmak için int tipinde ve 3 elemanlı bir dizi değişken tanımladım ve tanımlama satırında bütün elemanlara 0 aktardım. int tipindeki dizi değişken 3 elaman sahip olduğu için bellekte 3*4=12 byte yer kaplar.

int[] Dizi = {0, 0, 0};

Şimdi SetByte() metodu ile int tipindeki bu dizi değişkenin 2. elemanın 1. ve 2. byte’larına, bellekteki sıralamaya göre 5. ve 6. elemanlara 255 sayısını aktaracağım. Sizce bu kod işletil¬diğinde int tipindeki dizi değişkenin 2. elemanın içeriği ne olur?

private **** Form1_Click(object sender, EventArgs e)
{
int[] Dizi = {0, 0, 0};
byte Sayi = 255;
System.Buffer.SetByte(Dizi, 4, Sayi);
System.Buffer.SetByte(Dizi, 5, Sayi);
textBox1.Text = Dizi[1].ToString();
}

Bu kod ile int tipindeki dizi değişkenin 2. elemanın 1. ve 2. byte’larının bütün bitlerini 1 ile doldurduğum için 2 tabanlı sayı sisteminde 16 adet 1 bir araya getirildiği zaman 65535 sayısı elde edileceği için TextBox’a 65535 yazılır. Şimdi bu kodda değişiklik yapıp ayrıca dizi değişkenin 3. byte’ındaki bütün bitlere 1 ile dolduracağım.

private **** Form1_Click(object sender, EventArgs e)
{
int[] Dizi = {0, 0, 0};
byte Sayi = 255;
System.Buffer.SetByte(Dizi, 2, Sayi);
System.Buffer.SetByte(Dizi, 4, Sayi);
System.Buffer.SetByte(Dizi, 5, Sayi);
textBox1.Text = Dizi[0].ToString();
textBox2.Text = Dizi[1].ToString();
}

Bu kod işletildiğinde int tipindeki dizi değişkenin bellekteki temsili yerleşimi aşağıdaki gibi olur. 2 tabanlı “111111110000000000000000” sayısının 10 tabanlı karşılığı 16711680 olduğu için bu kod işletildiğinde ilk TextBox’a 16711680 ve 2. TextBox ise 65535 yazılır.

5738_image005.png

 

yuregini_isterim

Yeni üye
22 Ağu 2007
1
0
s.a arkadaşım bende vega programı var kurarken ilk parametreyi veriyor benden 2.yi istiyor onu nasıl çözerim yardımcı olurmusun
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.