Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> работа со спроецированным файлом 
V
    Опции темы
wallstreet
Дата 28.4.2012, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



Всем дообрый день.
Передо мной стоит задача посчитать символы и слова в тектовом файле, предварительно спроецированным в память.
Как пишут учебники, функция MapViewOfFile() проецирует файл на зарезервированное пространство и возвращает указатель
на начало области памяти "проекции файла" с которым можно работать как с обычным одномерным массивом.
Соответственно сразу рождается идея обычным циклом пробежаться по всем символам и понаходить пробелы + 1. Так
мы найдем кол-во слов.  А вот кол-во символов посчитать мне, поидее, должна помочь функция
GetFileSize(), однако она возвращает DWORD.

Соственно вопросы:
1) Немного непонятно что является началом области памяти "проекция файла", первый символ спроецированного файла?
2) Как конвертировать DWORD в int или какой функцией можно из значения переменной DWORD сделать строку?
 
PM MAIL   Вверх
feodorv
Дата 29.4.2012, 01:46 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Цитата(wallstreet @  28.4.2012,  18:16 Найти цитируемый пост)
однако она возвращает DWORD

Неужели этот так страшно? DWORD - сокращение от "double word" - "двойное слово" (4-х байтовая переменная). 

А можно и заглянуть в windef.h и увидеть такое:
Код

typedef unsigned long       DWORD;

То есть это, действительно, тип для 4-х байтовой беззнаковой переменной. Для win32 и win64 совпадает с "unsigned int". Поэтому вопрос
Цитата(wallstreet @  28.4.2012,  18:16 Найти цитируемый пост)
Как конвертировать DWORD в int

отпадает сам собой. 


Цитата(wallstreet @  28.4.2012,  18:16 Найти цитируемый пост)
GetFileSize(), однако она возвращает DWORD.

Внимательный осмотр вызова GetFileSize() показывает, что "она" возвращает не одно значение DWORD, а целых два smile 


Цитата(wallstreet @  28.4.2012,  18:16 Найти цитируемый пост)
Немного непонятно что является началом области памяти "проекция файла", первый символ спроецированного файла?

Гм. 
Цитата

LPVOID MapViewOfFile(
  HANDLE hFileMappingObject,   // handle to file-mapping object
  DWORD dwDesiredAccess,       // access mode
  DWORD dwFileOffsetHigh,      // high-order DWORD of offset
  DWORD dwFileOffsetLow,       // low-order DWORD of offset
  SIZE_T dwNumberOfBytesToMap  // number of bytes to map
);

LPVOID:
Код

typedef void far            *LPVOID;

То есть фактически LPVIOD есть "void *", указатель на память с проекцией файла. Работать с void * побайтово не очень удобно, но никто нам не мешает сделать так:
Код

unsigned char *mem = (unsigned char *) MapViewOfFile( ... );

И работайте себе (относительно) спокойно с mem как массивом байт...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Dem_max
Дата 30.4.2012, 10:11 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 16
Всего: 39



или так
Код

int *mem = (int *) MapViewOfFile( ... );
int i = mem[10];

short *mem = (short *) MapViewOfFile( ... );
int i = short[10];

BYTE *mem = (BYTE *) MapViewOfFile( ... );
mem+=10;
BYTE b = *mem;



--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
wallstreet
Дата 8.5.2012, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



Цитата(feodorv @  29.4.2012,  01:46 Найти цитируемый пост)
То есть это, действительно, тип для 4-х байтовой беззнаковой переменной. Для win32 и win64 совпадает с "unsigned int".


при инициализации переменной x типа unsigned int значением переменной y типа DWORD результат получается раскодированый какой-то. Число 12 превращается в 3435973836, это в каком формате то?

Вобщем опишу более детально на чем застопорился. Создал функцию которая считает слова в тексте, а кол-фо символов, включая пробелы буду определять функцией GetFileSize().
Проецирую файл:
Код

static HANDLE hFile, hFileMap;
static DWORD fSize;
TCHAR *p;
static RECT rt;
int *wCount, i, *q;
TCHAR *str;
case WM_CREATE:
        hFile = CreateFile(_T("My.txt"), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if(hFile != INVALID_HANDLE_VALUE)
        {
            fSize = GetFileSize(hFile, NULL);
            hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, fSize, NULL);
            if(hFileMap)
                p = (TCHAR*)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
            break;
        }


вот так формирую строку и вывожу данные в WM_PAINT:
Код

_stprintf(str, _T("Word count = %I64d\n Simbols count = %I64d\n"), WordCount(p, fSize), SimbolsCount(fSize));
TextOut(hdc, 0, 0, str, fSize);


функция считающая слова и символы:
Код

int WordCount(TCHAR *pStr, unsigned int fSize){
int i, count;
for(i=1; i<fSize; i++)
{
    if(*pStr == ' ')
                    count++;
}
return count + 1;
}

int SimbolsCount(unsigned int fSize){

return fSize;
}


Мне кажется что я все делаю неправильно. Укажите с чего начинать исправлять ситуацию?
Кстати непонятно что значит плохой указатель (Bad Ptr):
user posted image
ссылка на проект Проект

Это сообщение отредактировал(а) wallstreet - 8.5.2012, 17:48
PM MAIL   Вверх
feodorv
Дата 9.5.2012, 01:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Цитата(wallstreet @  8.5.2012,  14:06 Найти цитируемый пост)
при инициализации переменной x типа unsigned int значением переменной y типа DWORD результат получается раскодированый какой-то. Число 12 превращается в 3435973836, это в каком формате то?

Ну, если печатать так:
Цитата(wallstreet @  8.5.2012,  14:06 Найти цитируемый пост)
"Word count = %I64d\n Simbols count = %I64d\n"

величины, которые объявлены как int, то, да, 12 может превратиться во что угодно. Намёк: 4 байта = 32 битам, никак не 64.


Цитата(wallstreet @  8.5.2012,  14:06 Найти цитируемый пост)
int SimbolsCount(unsigned int fSize){
return fSize;
}

Ну и? А где fSize / sizeof(TCHAR)?


Цитата(wallstreet @  8.5.2012,  14:06 Найти цитируемый пост)
WordCount(p, fSize)

И почему fSize, а не WordCount(p, SimbolsCount(fSize))?
И откуда Вы знаете, что исследуемый файл находится в UNICODE, а не в ASCII? Или наоборот?

По крайней мере, в WordCount отправляется число байт файла, а содержимое файла обрабатывается по-символьно:
Цитата(wallstreet @  8.5.2012,  14:06 Найти цитируемый пост)
int WordCount(TCHAR *pStr, unsigned int fSize)



Цитата(wallstreet @  8.5.2012,  14:06 Найти цитируемый пост)
    if(*pStr == ' ')
                    count++;

Здесь точно ' ', даже для UNICODE версии программы?
А если два пробела подряд? А если табуляция или, не дай Бог, перевод строки? smile 


Цитата(wallstreet @  8.5.2012,  14:06 Найти цитируемый пост)
Кстати непонятно что значит плохой указатель (Bad Ptr):

Это значит указатель, который указывает на регион памяти, не переданный данному процессу. Процессу принадлежат его 4 гига (или больше для 64-х битных ОС), но не вся эта память является действительной (зарезервированной процессом). Иначе говоря, p указывает непонятно куда. Почему 0xcccccccc? Потому что:
Цитата
0xCC, 0xCCCCCCCC — The /GX Microsoft Visual C++ compiler option initialises all local variables not explicitly initialised by the program. It fills all memory used by these variables with 0xCC, 0xCCCCCCCC.
.
 smile 


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Albor
Дата 11.5.2012, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 589
Регистрация: 28.2.2009

Репутация: нет
Всего: 9



Цитата(wallstreet @  8.5.2012,  12:06 Найти цитируемый пост)
функция считающая слова и символы:
код C++

int WordCount(TCHAR *pStr, unsigned int fSize){
int i, count;
for(i=1; i<fSize; i++)
{
    if(*pStr == ' ')
                    count++;
}
return count + 1;
}
int SimbolsCount(unsigned int fSize){
return fSize;
}

Ишь, как просто слова считать... smile А если в тексте пропущен пробел после запятой, например, (про несколько пробелов уже писали). Слово начинается с буквы и буквой заканчивается - вот определяющий фактор подсчёта, ну и определиться, считать ли за слова числа.

Это сообщение отредактировал(а) Albor - 11.5.2012, 11:17
PM MAIL ICQ   Вверх
wallstreet
Дата 14.5.2012, 18:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



Цитата(feodorv @  9.5.2012,  01:26 Найти цитируемый пост)
Намёк: 4 байта = 32 битам, никак не 64.

я понял, исправил на:
Код

_stprintf(str, _T("Word count = %i\n Simbols count = %i\n"), WordCount(p, SimbolsCount(fSize)), SimbolsCount(fSize));



Цитата(feodorv @  9.5.2012,  01:26 Найти цитируемый пост)
Ну и? А где fSize / sizeof(TCHAR)?

функция 
Код

fSize = GetFileSize(hFile, NULL);

может я в чем-то заблуждаюсь, но возвращает правильное кол-во символов в файле.
user posted image


Цитата(feodorv @  9.5.2012,  01:26 Найти цитируемый пост)
И откуда Вы знаете, что исследуемый файл находится в UNICODE, а не в ASCII? Или наоборот?

Честно признаться, я знаю в чем отличие между двумя этими кодировками но как определить кодировку в которой находится файл не имею понятия. Может по символам которые в 256 битную таблицу ASCII не влазят пробежаться циклом, или как? Вообще я думал что если я читаю текстовый файл и при этом использую расширенную кодировку в разных функциях работы с файлом, то все будет получаться, т.к. UNICODE содержит все символы и буквы кодировки ASCII.


Цитата(feodorv @  9.5.2012,  01:26 Найти цитируемый пост)
По крайней мере, в WordCount отправляется число байт файла, а содержимое файла обрабатывается по-символьно:Цитата(wallstreet @  8.5.2012,  14:06 )int WordCount(TCHAR *pStr, unsigned int fSize)

Хммм... в смысле число байт? т.е. в виде двоичной системы счисления? В таком случаем с помощью какой функции можно конвертировать данные в символы? Или каким методом?


Цитата(feodorv @  9.5.2012,  01:26 Найти цитируемый пост)
Это значит указатель, который указывает на регион памяти, не переданный данному процессу

в объявлении:
Код

TCHAR *p = new TCHAR;

помогло.


Цитата(Albor @  11.5.2012,  11:17 Найти цитируемый пост)
Слово начинается с буквы и буквой заканчивается - вот определяющий фактор подсчёта

Я понял, переделал на вот так:
Код

int WordCount(TCHAR *pStr, unsigned int fSize){
    int i, j, y, count = 0;
    TCHAR *abc[26] = {_T("a"), _T("b"), _T("c"), _T("d"), _T("e"), _T("f"), // массив букв
                      _T("g"), _T("h"), _T("i"), _T("j"), _T("k"), _T("l"), 
                      _T("m"), _T("n"), _T("o"), _T("p"), _T("q"), _T("r"), 
                      _T("s"), _T("t"), _T("u"), _T("v"), _T("w"), _T("x"), 
                      _T("y"), _T("z")};
    TCHAR *simb[7] = {_T("."), _T(","), _T(";"), _T(":"), _T("!"), _T("?"), // массив символов 
                      _T(" ")};
    for(i=0; i<fSize; i++)                                                  // бежим по символам текста
    { 
        for(j=0; j<26; j++)                                                 // бежим по буквам и пытаемся
            if(*pStr == *abc[j])                                            // узнать, неявляется ли символ началом слова, т.е. буквой
                for(; i<fSize; i++)                                         // если является, то идем дальше по символам текста
                { 
                    for(y=0; y<6; y++)                                      // пока после букв нам не встретится знак припинания или пробел
                        if(*pStr == *simb[y])
                            count++;                                        // если встретился увеличиваем счетчик.
                }
    }
    return count;
}

но по всей видимости у меня действительно кракозябры вместо символов текста с которыми я сравниваю буквы из моего массива, соответственно ни одного совпадения по буквам не происходит поэтому счетчик нулевой.
Данным примером я хочу показать принцип, с помощью которого, по моему мнению нужно решать задачу. Если я ошибаюсь прошу поправить.

всех участвующих благодарю за бесценный вклад в мои знания.
чуть не забыл ->ссылка на проект

Это сообщение отредактировал(а) wallstreet - 14.5.2012, 18:08
PM MAIL   Вверх
volatile
Дата 15.5.2012, 00:14 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 13
Всего: 85



Цитата(wallstreet @  14.5.2012,  18:01 Найти цитируемый пост)
int WordCount(TCHAR *pStr, unsigned int fSize){
    int i, j, y, count = 0;
    TCHAR *abc[26] = {_T("a"), _T("b"), _T("c"), _T("d"), _T("e"), _T("f"), // массив букв
                      _T("g"), _T("h"), _T("i


боже мой, ... ...

Добавлено через 12 минут и 45 секунд
wallstreet, это был ацкий кот!

Я бы слова подсчитывал по следующему простому алгоритму.
Если текущий символ - есь буква, а предыдущий был не буква, это есть начало слова. Конец ведь нам не нужен  smile.
То что конец будет, (и причем всему, уже скоро) это аксиома. Даже если текст оборвется на середине слова, мы это слово обязаны засчитать.

Ну и алгоритм упрощается, 

Код

int WordCount (TCHAR *pStr, unsigned int fSize)
{
    unsigned count = 0;
    int prev_alpha = 0; // булева переменная, истина, если предыдущий символ был буквой.
    for (unsigned i = 0; i < fSize; ++i)
    {
       int now_alpha = _istalpha (pStr [i]); // Текущий символ есть буква?
       count += now_alpha && !prev_alpha;    // Если текущий символ буква, и предыдущий был НЕ буква, то прибавляем счетчик
       prev_alpha = now_alpha;               // Текущий символ становится прошлым.
    }
    return count;
}

Задолбался писать комментарии...
PM MAIL   Вверх
volatile
Дата 15.5.2012, 00:29 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 13
Всего: 85



Вообще хорошо бы точное определение, что считать словом.
Если например вы хотите набор цифр и букв идущих подряд считать одним словом, то
 _istalpha()  нужно заменить на _istalnum()


Это сообщение отредактировал(а) volatile - 15.5.2012, 00:59
PM MAIL   Вверх
wallstreet
Дата 16.5.2012, 11:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



Спасибо, то что надо!  smile 
Проект компилируется и отрисовывает правильный результат, но после этого выскакивают ошибки с которыми не могу справиться.
user posted image
Подскажите в связи с чем эти ошибки и как я могу их устранить?

ссылка на проект

Это сообщение отредактировал(а) wallstreet - 16.5.2012, 12:00
PM MAIL   Вверх
volatile
Дата 16.5.2012, 23:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 13
Всего: 85



Цитата(wallstreet @  16.5.2012,  11:54 Найти цитируемый пост)
выскакивают ошибки

Какие ошибки?

лучше бы лог ошибок запостили, чем ничего незначащие картинки, и неочищенный проект на 11 метров.
(у меня например нэт здесь очень медленный, и дорогой. и грузить своп вашего харда никакого желания нет.)
PM MAIL   Вверх
GremlinProg
Дата 17.5.2012, 06:41 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



судя по содержимому окна output, край которого все же видно, это повреждение кучи,
которое скорее всего говорит о том, что в каком-то месте программы произведена запись блока памяти за пределы, на которые он был распределен


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
wallstreet
Дата 17.5.2012, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 153
Регистрация: 11.8.2011

Репутация: нет
Всего: нет



Цитата(volatile @  16.5.2012,  23:37 Найти цитируемый пост)
лучше бы лог ошибок запостили



Цитата

Critical error detected c0000374
Windows has triggered a breakpoint in HomeWork6.9.exe.

This may be due to a corruption of the heap, which indicates a bug in HomeWork6.9.exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while HomeWork6.9.exe has focus.

The output window may have more diagnostic information.





Цитата(GremlinProg @  17.5.2012,  06:41 Найти цитируемый пост)
в каком-то месте программы произведена запись блока памяти за пределы, на которые он был распределен 

насколько я понимаю первая проблема в выделении памяти под объявление MSG, который объявлен, насколько я понимаю в winuser.h
Так вот, неужели я буду что-то менять в этом файле? Или как тогда расширить пределы памяти, которая отводится под переменные функций?
PM MAIL   Вверх
feodorv
Дата 17.5.2012, 20:15 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Глянул код в проекте.... Замечаний масса..... Вот некоторые....

Цитата(GremlinProg @  17.5.2012,  07:41 Найти цитируемый пост)
которое скорее всего говорит о том, что в каком-то месте программы произведена запись блока памяти за пределы, на которые он был распределен 

Да там особо не чему за пределы выходить))) 


Цитата

int SimbolsCount(unsigned int fSize){

    return fSize;
}

Что юникод, что нет, всё едино  smile 


Цитата

    switch (message)
    {
    case WM_CREATE:
                ...
  DestroyWindow(hWnd);
  break;

Невиданная жестокость  smile  smile  smile  


Цитата

    case WM_DESTROY:
  UnmapViewOfFile(p);
  CloseHandle(hFileMap);
  CloseHandle(hFile);
                ...

Тут бы проверить, а стоИт ли вообще это делать:
Код

if( p != NULL ) ...
if( hFileMap != NULL ) ...
if( hFile != INVALID_HANDLE_VALUE ) ...

Ну и, соответственно, всё это проинициализировать... И не так:
Цитата

        ...
    TCHAR *p = new TCHAR;
         ...
    if(hFileMap)
    p = (TCHAR*)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
         ...
  case IDM_EXIT:
    delete p;

         ...



--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
GremlinProg
Дата 18.5.2012, 07:25 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(feodorv @  17.5.2012,  22:15 Найти цитируемый пост)
Да там особо не чему за пределы выходить))) 

эта ошибка системная, очень распространенная, спорить тут не о чем, т.е. выход за пределы блока - точно есть

я только не понял, почему поднято именно это исключение, т.к. в данном случае - это выход за пределы массива при чтении: в WordCount передается указатель на 1 символ, а читается fSize,

я бы предположил возможность исключения типа Access violation, но не суть,

вообще, странная запись:
Цитата(wallstreet)

TCHAR *p = new TCHAR;

p - локальная переменная в WndProc, т.е. ты на каждое сообщение резервируешь символ и не удаляешь его,
я уже не говорю, что результат MapViewOfFile так же теряется при выходе из WndProc( ..., WM_CREATE, ... ), т.е. пытаться как-то использовать p после этого бессмысленно


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0686 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.