|
|
|
Парсер урлов для ГЕТ и переменных для ПОСТ на Ц
|
|||
|---|---|---|---|
|
#18+
Пишу на Ц парсер для переменных окружения и стандартного ввода - аналог функций GET и POST на PHP. Ощущение, что обработка строк на Ц почти аналогична ходьбе на руках - в принципе возможно, но крайне неудобно. Или приём пищи хоккейными клюшками. Причём на вытянутых руках. Предстваляю какая чехарда начинается при вызове библиотечной функции - поиск и подгрузка с диска нужного *.so, поиск точки входа и тп. На Асме такого бардака стараться больно долго. Оптимизирующим компиляторам и не снилось какой красивый код руками можно написать. В общем пишу прогу разбирающую урлу на переменные со значениями. Наверняка кто-то где-то такое уже делал, но я не нашел. Если кто знает где искать - подскажите. Меньше мучаться буду. А тут ещё совсем неестетсвенная проблема - написать конвертер - из байта делать байт. Причём не какие-то там кодировки или шифрование. Всё тривиально. Нужно байт интерпретируемый (ой блин, компилируемый) как целое бесзнаковое число считать символом - просто MOV. В терминах Ц (если он вдруг числа хранит как строки) функция ITOA. Но такой во всяких инклюдах с либами на FreeBSD 5.1 на нашёл. Обратная функция есть, и вообще, и в коде. И писать её приходится только потому, что когда ненадо Ц мешает обрабатывать данные, типо заботится о целостности. А когда надо бы проверять хотябы границы массива, плюёт с высокой колокольни. А ведь наверняка рядом с переменной есть структура, в которой хранится и тип и размер. Надо только поменять тип. Да... на лирику потянуло. Спать надо больше. Итак заготовка: // gcc -L/usr/local/lib/mysql -lmysqlclient -lz -lcrypt -lm -L/usr/lib -lssl -lcrypto -o get_vars get_vars.c #include </usr/include/stdarg.h> #include </usr/include/stdio.h> #include </usr/include/stdlib.h> #include </usr/include/string.h> char Query[100], *String, *Mail_user, *Mail_old_password, *Mail_new_password, *Mail_new_password1, *ErrorMessage; int Pay, Result; //mysql_real_query(); unsigned long i; unsigned long String_Length; char *Variable, *Value, *Write_Symbol, Symbol[1]; //Read_Symbol unsigned int Character, Read_Symbol; //unsigned int ITOA (unsigned int iNteger) {unsigned int cHaracter; unsigned int hUndreds, tEns, oNes; char ITOA (unsigned int iNteger) { char cHaracter; unsigned int hUndreds, tEns, oNes; hUndreds%=iNteger/100; iNteger=iNteger-hUndreds*100; tEns%=iNteger/10; oNes=iNteger-tEns*10; // cHaracter=hUndreds*100+tEns*10+oNes; cHaracter=(hUndreds-'0')*100+(tEns-'0')*10+(oNes-'0'); return(cHaracter); } int main (int argc, char **argv) { setvbuf (stdout, NULL, _IONBF, 0); String = getenv ("CONTENT_LENGTH"); String = getenv ("SHLVL"); i=atoi(String); //printf("String=%s\n",String); printf("i=%d\n",i); //Read_Symbol=205; Character=ITOA(Read_Symbol); printf("rs=%d\n",Character); //Read_Symbol=205; Write_Symbol=ITOA(Read_Symbol); printf("rs=%d\n",Write_Symbol); Read_Symbol=205; Symbol[0]=ITOA(Read_Symbol); printf("rs=%d\n",Symbol[0]); String = getenv ("CLIENT_IP"); String = getenv ("QUERY_STRING"); String = getenv ("PATH"); String_Length=strlen(String); for (i=0; i<String_Length; i++) { Variable=""; Value=""; Read_Symbol=String ; //putchar(Read_Symbol); //Write_Symbol=Read_Symbol; /* if (Read_Symbol>32 && Read_Symbol<50) {printf("F*ck\n");} Character=atoi(&Read_Symbol); Symbol[0]=Read_Symbol; Write_Symbol="64"; Character=atoi(Write_Symbol); Character=atoi("Z"); //Symbol[0]); //Write_Symbol=Character; //Write_Symbol="1"; if (Read_Symbol=="+") {Write_Symbol=" ";} printf ("%d",Character); //printf ("%s",Character); Segmentation fault (core dumped) printf ("%s",Write_Symbol); putchar(Write_Symbol); Symbol[0]=Read_Symbol; printf (&Symbol[0]); //Write_Symbol=Symbol; trash output Character=atoi(Symbol); Write_Symbol="1"; //Write_Symbol=itoa(Character); itoa==unknown function sprintf ( Symbol, "%s", &Read_Symbol ); //printf (Symbol); each symbol appends "`" strcpy (Write_Symbol, **Read_Symbol); char* strcat(char* dest, const char* source); sprintf(Query,"select password from %s where login='%s'\n",Table,User); strcat(Query, Table); printf("String=%s\n",String); String=strchr (String,':'); if ((String=strchr (String,':'))) { String++;} //skip element printf("String=%s\n",String); i=666; printf("i=%d\n",i); sprintf (Query,"%d", i); printf("Query=%s\n",Query); i=atoi(Query); printf("i=%d\n",i); */ } exit(0); } Как бы написать парсер вообще и конвертер в частности. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.01.2005, 03:57 |
|
||
|
Парсер урлов для ГЕТ и переменных для ПОСТ на Ц
|
|||
|---|---|---|---|
|
#18+
первый на... автору риспехт, пеши ищо... ps авторОщущение, что обработка строк на Ц почти аналогична ходьбе на руках - в принципе возможно, но крайне неудобно юзай с++ std::string pps такое ощущение, что откуда то вытащили древнего asm кодера и поручили ему сделать сайт :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.01.2005, 05:10 |
|
||
|
Парсер урлов для ГЕТ и переменных для ПОСТ на Ц
|
|||
|---|---|---|---|
|
#18+
я не знаю что там у тебя за проблема как написали до меня string.h полностю подходить ;) у тебя же каждый раз разделитель не меняется ? вот и раздели по этому разделителю и потом по знаку = каждую часть ;) думаю просто Вам практике не хватает ;) а на счет исходников - помочь не смогу .. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.01.2005, 08:59 |
|
||
|
Парсер урлов для ГЕТ и переменных для ПОСТ на Ц
|
|||
|---|---|---|---|
|
#18+
а) никто не мешает делать ассемблерные вставки б) про вызовы - ладно уж, никто на ядро не жалуется, никто на apache не жалуется в) про строки - можно написать свои быстрые, юзат библиотечные, юзать классы std, всё что хочется г) Про массивы. Сам по себе ни асм ни С не проверяют границы массивов, и это нормально разработчик думать должен, а не на кнопочки в среде разработки жать) Про структуры: никаких структур рядом с переменной нет. Про тип переменной в C известно компилятору на стадии компиляции. Потом - в памяти вы не различите ваш char или это что-то еще. Кстати char ничем от числа не отличается, можете смело приравнивать. Главное, не забывать, что во первых unsigned int это как минимум 2 байта и что значение числа размером в байт далеко не всегда представляется 1 символом. Я допустим понятия не имею, как представить байт 0xFF в виде char, ведь это 255 Для этого можно банально использовать sprintf() с одним параметром. А если хотите сказать, что php это делает проще и не надо ничего думать, так вот, php написан на С, и уж точно на эту универсальность убивается намного больше времени, чем вызов sprintf ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.01.2005, 11:35 |
|
||
|
Парсер урлов для ГЕТ и переменных для ПОСТ на Ц
|
|||
|---|---|---|---|
|
#18+
Мысль о СТРИНГ не нова - в первом посте можно (при желании) заметить "#include </usr/include/string.h>","sprintf","strcpy","strlen". Вопрос не в том, что разделители - константы. А в том, как на Ц написать выражение вида X=Y; ? Причем компилер не должен ругаться на несоответствия типов (выбрать правильную фунцию) X=func(Y); Исходник.Ц должен компилиться, а также во время выполнения приложение не должно завершаться корами дампов и сегментированных сбоев. Более того, приложение должно правильно работать - т.е. если к примеру Y="J"; X=Y; то X=="J" . К сожалению, написать приложение на Асме на 100% не получится по многим причинам, главная - жёсткий лимит времени. Асмовые вставки пробовал, но ввиду 0% документированности GCC пробы не увенчались успехом. А тут необходимо точно знать как от компилера получить адреса переменных, чтобы сделать нечто подобное: do_you_really_paranoid_worry_about_datatypes_mismatch: mov esi, offset[where_is_placed_source_byte] ;unsigned integer mov al, ds:[esi] mov edi, offset[where_is_placed_target_byte] ;unsigned character mov es:[edi], al ret И рад бы число чару приравнять, да компилер не даёт. Более того, тема такая поднялась только потому, что для соблюдения соответствия типов приходится искать окольные пути. sprintf(с_одним_параметром); не получается - GCC не велит. Много времени приходится убивать на пляски с типами данных. Я и не спорю, что PHP выглядит надстройкой над C, избавляющий от необходимости отвлекаться от сути приложения. Если с типами и лажанулся, всё исправляется на лету. Я переписываю приложение с PHP на Ц и заметил разницу во времени разработки. Более того, знаю о BinaryPHP, но он настолько сырой, что пользоваться им практически нереально. Компилятор (не интерпретатор) PHP стоит 1500 президентов. Приходится учить GCC. Изучать ++ и классы может и неплохо, но нет столько времени на "ускорение". Проблема записать исполнимым способом выражение: Write_Symbol=Read_Symbol; Чтобы затем сравнивать и присваивать Write_Symbol нужные значения без ограничений. Новая заготовка с комментариями: // gcc -L/usr/local/lib/mysql -lmysqlclient -lz -lcrypt -lm -L/usr/lib -lssl -lcrypto -o get_vars get_vars.c #include </usr/include/stdarg.h> #include </usr/include/stdio.h> #include </usr/include/stdlib.h> #include </usr/include/string.h> char Query[100], *String, *Mail_user, *Mail_old_password, *Mail_new_password, *Mail_new_password1, *ErrorMessage; int Pay, Result; //mysql_real_query(); unsigned long i; unsigned long String_Length; unsigned char *Variable, *Value, *Write_Symbol, Symbol[1]; //Read_Symbol unsigned int Character, Read_Symbol; int main (int argc, char **argv) { setvbuf (stdout, NULL, _IONBF, 0); String = getenv ("CONTENT_LENGTH"); String = getenv ("SHLVL"); i=atoi(String); //printf("String=%s\n",String); printf("i=%d\n",i); //Read_Symbol=205; Character=ITOA(Read_Symbol); printf("rs=%d\n",Character); //Read_Symbol=205; Write_Symbol=ITOA(Read_Symbol); printf("rs=%d\n",Write_Symbol); //Read_Symbol=205; Symbol[0]=ITOA(Read_Symbol); printf("rs=%d\n",Symbol[0]); String = getenv ("CLIENT_IP"); String = getenv ("QUERY_STRING"); String = getenv ("PATH"); String_Length=strlen(String); for (i=0; i<String_Length; i++) { Variable=""; Value=""; Read_Symbol=String ; //putchar(Read_Symbol); //Write_Symbol=Read_Symbol; //if (Read_Symbol=="+") {Write_Symbol=" ";} //warning: comparison between pointer and integer } exit(0); } /* strncpy(Variable,Value,1); //Bus error (core dumped) Write_Symbol="Z"; sprintf (Query,"%s",Write_Symbol); printf("%s",Query); sprintf (Query,"%s",Read_Symbol); //printf("%s",Query); //Segmentation fault (core dumped) Write_Symbol=itoa(Read_Symbol); printf(Write_Symbol); //trash sprintf(Write_Symbol, &**? Read_Symbol); sprintf(Write_Symbol,String); argument 2 type mismatch Write_Symbol=sprintf(Read_Symbol); //too few arguments to function `sprintf' Write_Symbol=&String; printf("%s\n",Write_Symbol); //copy to Write_Symbol left truncated string strncpy(Write_Symbol,&String,1); //Segmentation fault (core dumped) strncpy(Write_Symbol,*Read_Symbol,1); //invalid type argument of `unary *' Symbol[0]=Read_Symbol; strncpy (Write_Symbol, Symbol,1); //Segmentation fault (core dumped) Write_Symbol=iToa(Read_Symbol); //warning: assignment makes pointer from integer without a cast if (Read_Symbol>32 && Read_Symbol<50) {printf("Fuck\n");} Character=atoi(&Read_Symbol); Symbol[0]=Read_Symbol; Write_Symbol="64"; Character=atoi(Write_Symbol); Character=atoi("Z"); //Symbol[0]); //Write_Symbol=Character; //Write_Symbol="1"; printf ("%d",Character); //printf ("%s",Character); Segmentation fault (core dumped) printf ("%s",Write_Symbol); putchar(Write_Symbol); Symbol[0]=Read_Symbol; printf (&Symbol[0]); //Write_Symbol=Symbol; trash output Character=atoi(Symbol); Write_Symbol="1"; //Write_Symbol=itoa(Character); itoa==unknown function sprintf ( Symbol, "%s", &Read_Symbol ); //printf (Symbol); each symbol appends "`" strcpy (Write_Symbol, **Read_Symbol); char* strcat(char* dest, const char* source); sprintf(Query,"select password from %s where login='%s'\n",Table,User); strcat(Query, Table); printf("String=%s\n",String); String=strchr (String,':'); if ((String=strchr (String,':'))) { String++;} //skip element printf("String=%s\n",String); i=666; printf("i=%d\n",i); sprintf (Query,"%d", i); printf("Query=%s\n",Query); i=atoi(Query); printf("i=%d\n",i); char *itoa(val) register int val; { register char *ptr; static char buffer[16]; // result is built here 16 is sufficient since the largest number we will ever convert will be 2^32-1, which is 10 digits. ptr = buffer + sizeof(buffer); *--ptr = '\0'; if (val == 0) {*--ptr = '0';} else while (val != 0) {*--ptr=(val%10)+'0'; val /= 10;} return(ptr); } //unsigned int ITOA (unsigned int iNteger) {unsigned int cHaracter; unsigned int hUndreds, tEns, oNes; unsigned char ITOA (unsigned int iNteger) { unsigned char cHaracter; unsigned int hUndreds, tEns, oNes; hUndreds%=iNteger/100; iNteger=iNteger-hUndreds*100; tEns%=iNteger/10; oNes=iNteger-tEns*10; // cHaracter=hUndreds*100+tEns*10+oNes; cHaracter=(hUndreds-'0')*100+(tEns-'0')*10+(oNes-'0'); return(cHaracter); } unsigned char iToa (unsigned int inTeger) {unsigned char chAracter; chAracter=inTeger; return(chAracter); } char *itoa (int i) {static char buf[12]; char *pos=buf+sizeof(buf)-1; unsigned int u; int negative = 0; if (i < 0) {negative=1; u = ((unsigned int)(-(1+i))) + 1; } else { u = i; } *pos = 0; do { *--pos = '0' + (u % 10); u /= 10; } while (u); if (negative) { *--pos = '-'; } return pos; } unsigned char int2char (unsigned int inteGer) { unsigned int intergeR; // asm mov intergeR, inteGer //syntax error before "mov" // asm push eax //syntax error before "push" return integeR; } */ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.01.2005, 19:44 |
|
||
|
Парсер урлов для ГЕТ и переменных для ПОСТ на Ц
|
|||
|---|---|---|---|
|
#18+
Всем спасибо. Взаимокорректные конструкции на Ц подобраны. Ядро парсера написано. Осталось два вопроса: на будущее - как в GCC использовать асемблерные вставки (по каким смещениям в стеке искать адреса переменных и почему GCC игнорирует ключевое слово asm) и для настоящего: структура (кодирование) данных (переменных и значений) при методе ПОСТ (через стдин) аналогично методу ГЕТ (через окружение) или какой свой формат? Тоже собственно про куки и апложенные файлы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2005, 03:25 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=32854069&tid=2033894]: |
0ms |
get settings: |
7ms |
get forum list: |
13ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
20ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
35ms |
get tp. blocked users: |
1ms |
| others: | 214ms |
| total: | 304ms |

| 0 / 0 |
