На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
> Распарсить байтовый массив , разбор byte[]
    Уважаемые знатоки С# , подскажите пожалуйста такой вопрос , имеется заполненный байтовый массив, (по сути это ответ на SQL-запрос, так сказать , результат, таблица записанная в одну линию), длина строки известна , ширина столбика - известна, сколько столбиков и сколько столбцов тоже известно, это приходит на шаг впереди ,
    так вот подскажите пожалуйста как разобрать byte[] и разложить соответствующие данные по ячейкам DataTable

    Скрытый текст

    ExpandedWrap disabled
       
      структура  которая прилетает перед результатом
       [StructLayout(LayoutKind.Sequential)]
               struct hcSqlDstInfoT          // Структура содержит внутреннюю информацию о колонке результата,
              {       // полученного при выполнении SQL-запроса. http://hytechdb.ru/index.php?s=docs&ru=V25/hscli/str_hcSqlDstInfoT.htm
                  public int      aliasno    ; // Порядковый номер алиаса,
                  public int fieldno    ; // Номер колонки в таблице
                  public int type       ; // Тип колонки
                  public uint len        ; // Длина поля в байтах  ( в Си unsigned )
                  public uint off        ; // Смещение поля относительно начала логической записи ( в Си unsigned )
                  public fixed byte coder[32]  ;
                  public fixed byte fname[32]  ; // Имя поля в таблице
                  public int func;
                  public fixed byte asname[32] ; // Переименование поля
                  public int key        ;
                  public int resno      ; // Сквозной номер поля в результате
              };
       
       
       
       
      byte[] bufOut = new byte[(int)wBufSize];   // буфер для результата
        
                  
      err = hcSqlReadResults(pOper, gStart, bufOut, wBufSize, out cntOut); // Чтение результатов
                  
                  
      for (long i = 0; i < pStr; i++)// идем по строкам
      {
                      
         for (int j = 0; j < pCol; ++j)// идем по колонкам
        {
          
            switch (infCol[j].type)// в зависимости от типа колонки преобразовываем в соответствующий тип
            {
              case 0: // 0 Массив символов длиной не более заданной
                ......
        вот тут что то дописать что бы бралась порция в зависимости от типа
      .....  
       
               break;
                              //case 1: // 1 Массив байтов заданной длины
                              //       textBox4.AppendText(e1.GetString(bufOut).ToString() + " ");
                              //       break;
                  //            case 2: // 2 Элемент - unsigned char (короткое целое)  short
                              //   //  std::cout << *reinterpret_cast < unsigned char*> (p) << "  ";
                              //   //                               break;
       
                              //           case 3: // 3 Элемент - signed short  
                              //   //      std::cout << *reinterpret_cast < signed short*> (p) << "  ";
                              //   //                                break;
       
                              //          //case 4: // 4 Элемент - unsigned short  
                              //   //        std::cout << *reinterpret_cast < unsigned short*> (p) << "  ";
                              //   //        break;
       
                              //          //case 5: // 5 Дата    - unsigned short  
                              //   //        std::cout << *reinterpret_cast < unsigned short*> (p) << "  ";
                              //   //        break;
       
                              //          //case 6: //6  Номер   - 3-х байтовое целое без знака  
                              //   //                                // std::cout << *reinterpret_cast<  *>(p);
                              //   //        break;
       
                              //          //case 7: //7 Элемент - long int
                              //   //        std::cout << *reinterpret_cast < long int*> (p) << "  ";
                              //   //        break;
       
                              //case 8: // 8 Элемент - unsigned long int  в БД это dword  
                              //    textBox4.AppendText(infCol[j].type + " ");
                              //    textBox4.AppendText(infCol[j].len + " ");
                              //     std::cout << *reinterpret_cast < unsigned long int*> (p) << "  ";
                              //    break;
       
                                  //          //case 9: //    9  Элемент - float
                                  //   //        std::cout << *reinterpret_cast<float*>(p) << "  ";
                                  //   //        break;
       
                                  //          //case 10: //   10 Деньги (double)  
                                  //   //        std::cout << *reinterpret_cast<double*>(p) << "  ";
                                  //   //        break;
       
                                  //          //case 1: // 11 Элемент - double  
                                  //   //        std::cout << *reinterpret_cast<double*>(p) << "  ";
                                  //   //        break;
       
                                  //          //case 12: //   12 Элемент - signed __int64
                                  //   //        std::cout << *reinterpret_cast < signed __int64 *> (p) << "  ";
                                  //   //        break;
                                  //          //case 13: //   13 Элемент - unsigned __int64
                                  //   //        std::cout << *reinterpret_cast < unsigned __int64 *> (p) << "  ";
                                  //   //        break;
                          }//////switch
       
            p += infCol[j].len; ----- так сделано в проге на С++  
       
                      }/////// идем по колонкам
                      
                  } //// идем по строкам

    Сообщение отредактировано: kms -
      ОК вопрос решен

      может кому понадобится
      ExpandedWrap disabled
         byte[] tempBuf;
         
                    for (int i = 0; i < pStr; i++)// перебираем как бы строки
                    {
                     dR = dT.NewRow();
                     for (int j = 0; j < pCol; j++)//перебираем как бы поля на каждой строке
                     {
                           switch (infCol[j].type)// в зависимости от типа колонки преобразовываем в соответствующий тип
                                    {
                                        case 0: // 0 Массив символов длиной не более заданной
                                            tempBuf = new byte[(int)infCol[j].len];
                                            reader.Read(tempBuf, 0, (int)infCol[j].len);
                                            dR[j] = Encoding.GetEncoding(866).GetString(tempBuf);
                                            break;
         
                                        case 1: // 1 Массив байтов заданной длины
                                            tempBuf = new byte[(int)infCol[j].len];
                                            reader.Read(tempBuf, 0, (int)infCol[j].len);
                                            dR[j] = BitConverter.ToString(tempBuf);// tempBuf.ToString() ;
                                            break;
                                          
                                         case 2: // 2 Элемент - unsigned char (короткое целое)  short
                                            dR[j] = reader.ReadByte() ;
                                            break;
                                        
                                         case 3: // 3 Элемент - signed short  
                                            dR[j] = reader.ReadInt16();
                                            break;
         
                                         case 4: // 4 Элемент - unsigned short  
                                            dR[j] = reader.ReadUInt16();
                                            break;
         
                                         case 5: // 5 Дата    - unsigned short  
                                             dR[j] = reader.ReadUInt16();
                                             break;
         
                                         case 6: //6  Номер   - 3-х байтовое целое без знака  
                                             //textBox4.AppendText(infCol[j].type + " ");
                                           break;
         
                                         case 7: //7 Элемент - long int
                                              dR[j] = reader.ReadInt32();
                                           break;
         
                                         case 8: // 8 Элемент - unsigned long int  в БД это dword
                                             dR[j] = reader.ReadInt32();
                                            break;
         
                                        case 9: //  9  Элемент - float
                                            dR[j] = reader.ReadSingle();
                                         break;
         
                                        case 10: // 10 Деньги (double)  
                                           dR[j] = reader.ReadDouble();
                                          break;
         
                                        case 11: // 11 Элемент - double  
                                             dR[j] = reader.ReadDouble();
                                          break;
         
                                        case 12: // 12 Элемент - signed __int64
                                             dR[j] = reader.ReadInt64();
                                           break;
                                        case 13: // 13 Элемент - unsigned __int64
                                            dR[j] = reader.ReadUInt64();
                                           break;
         
                            }// switch
                        }/////////////////
                        dT.Rows.Add(dR);
                    }//////////////////// перебираем как бы строки
        Чуть переделал и выложил для удобного просмотра, кому нужен используте
        https://github.com/vovakms/dbms-HyTech_edition_CSharp
          Вопрос то решен , и так можно сказать , но решен оптимально или нет неизвестно , тема такая не насытная , сейчас пытаюсь более производительней сделать и применить другие методы , поетому прошу в соседние ветки , так сказать детализация
            Эх, в Си можно было что-то вида:
            ExpandedWrap disabled
              func метод[] = {ReadByte,ReadInt32,ReadInt64};
              dR[j] = метод[infCol[j].type]();
            Можно ли в Си++/диезе нечто таковое:
            ExpandedWrap disabled
              func метод[] = {reader.ReadByte,reader.ReadInt32,reader.ReadInt64};
              dR[j] = метод[infCol[j].type]();
              // или так:
              dR[j] = reader.(метод[infCol[j].type])();
            не знаю. :blush:
              Цитата Славян @
              Эх, в Си можно было что-то вида:

              func метод[] = {ReadByte,ReadInt32,ReadInt64};
              dR[j] = метод[infCol[j].type]();
              Можно ли в Си++/диезе нечто таковое:

              func метод[] = {reader.ReadByte,reader.ReadInt32,reader.ReadInt64};
              dR[j] = метод[infCol[j].type]();
              // или так:
              dR[j] = reader.(метод[infCol[j].type])();
              не знаю.


              ух ты вот это я и искал , а на Си поможешь у меня то все проекты под рукой можешь глянуть https://github.com/vovakms
              и прям там редактировать , я щас переключусь на Си

              Добавлено
              Славян подскажи пожалуйста func это что ??
                Цитата kms @
                func это что ?
                Ну это тип такой, функциональный. a'la
                ExpandedWrap disabled
                  typedef int (__stdcall* func)(char*);


                Цитата kms @
                а на Си поможешь у меня то все проекты под рукой можешь глянуть ...
                Выкладывайте мелкие вопросы сюда - будем решать. ;)
                  Цитата Славян @
                  Выкладывайте мелкие вопросы сюда - будем решать.

                  ОК спасибо
                    делаю вот так
                    ExpandedWrap disabled
                       typedef int(__stdcall* func)(char*);
                       
                          for (int j = 0; j < pCol; j++)  
                          {
                               func metodT[] = { ReadByte,ReadInt32,ReadInt64 };
                               std::cout << "" << metodT[infCol[j].type]() << endl; ;
                          }

                    не видит ReadByte,ReadInt32,ReadInt64

                    Добавлено
                    Славян я открываю новую тему на С/С++, чтобы тут не путать плюсы с шарпами
                      Конечно не видит, т.к. их где-то надо написать. :)

                      Например так:
                      ExpandedWrap disabled
                        int ReadInt32(char *a) { return *(int*)a; }
                      Сообщение отредактировано: Славян -
                        Может тогда return atoi(a);?
                          Вряд ли. Там, в оригинале, автор работает с сырыми данными. Но, да, - могу и полностью ошибаться.
                            Цитата Славян @
                            Вряд ли. Там, в оригинале, автор работает с сырыми данными. Но, да, - могу и полностью ошибаться.

                            Славян, то что ты написал - UB, в переводе на русский "Не определенное поведение". А если ты хочешь char* сконвертировать в числовой тип int, то для этого есть функция atoi
                            А то что ты привел, работать не будет так, как ты себе представляешь, вообще не будет работать ни с сырыми, ни с жареными данными. :-?
                            Сообщение отредактировано: KILLER -
                              Странно. Я всегда так делаю. Не вижу ни одной проблемы. :'(
                                Цитата Славян @
                                Странно. Я всегда так делаю. Не вижу ни одной проблемы. :'(

                                Это уже само по себе странно. И что, когда у тебя есть нечто подобное, у тебя на экран выводится 1235, как в данном случае? :
                                ExpandedWrap disabled
                                  #include <iostream>
                                   
                                  int ReadInt32(const char *a) { return *(int*)a; }
                                   
                                  int main()
                                  {
                                     const char* ppp = "1235";
                                     std::cout << ReadInt32(ppp);
                                     return 0;
                                  }

                                Дааа, это блин, действительно странно. <_<

                                Добавлено
                                Может быть я сделал что то не так? :-?
                                Сообщение отредактировано: KILLER -
                                  Да не, как и положено выведится 892547633=0x35333231.
                                    Цитата Славян @
                                    Да не, как и положено выведится 892547633=0x35333231.

                                    Как и положено?
                                    А ничего что вопрос стоит вот так?
                                    Цитата kms @
                                    так вот подскажите пожалуйста как разобрать byte[] и разложить соответствующие данные по ячейкам DataTable

                                    ничего что в твоем примере ты разименовываешь указатель и преобразуешь все это в int? Я даже не представляю где такое может понадобится?
                                    Славян, прошу тебя, не тупи.

                                    Добавлено
                                    Ничего, что ожидается вывод 1235 ?

                                    Добавлено
                                    Да и вообще - ты всегда такое число получаешь? Или при каждом запуске по разному?

                                    Добавлено
                                    Вообще, я так подумал, можно в принципе и об этом поговорить, на самом деле даже интересно стало <_<
                                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                    0 пользователей:


                                    Рейтинг@Mail.ru
                                    [ Script execution time: 0,0500 ]   [ 17 queries used ]   [ Generated: 28.03.24, 22:09 GMT ]