/**
 * разбираем группу для подбора арматуры
 * Документ 28
 //    2   int     кол-во байт в названии группы
 //    x   string  название группы
 //    80  string  C255, остальные нулевые
 //    8   double  сопротивление стали
 //    8   -       нулевые байты
 //    8   double  gamma_C
 //    8   double  FC
 //    1   -       1-группа, 0-конструктивный элемент
 //    2   -       нулевые байты
 //    8   double  коэффициент расчетной длины XoZ
 //    8   double  коэффициент расчетной длины XoY
 //    64  -       нулевые байты
 //    4   int     кол-во элементов
 //    x   int     номера элементов друг за другом по 4 байта    
 *
 * @param String $s
 * @return Array
 */
 function get_from_spr($s)
 {
     $pos = 0;
     //кол-во байт в названии группы
     $group_name_byte_count = unpackInt_2(substr($s, $pos, 2));
     $pos += 2;
     //название группы
     $this->name = (string) substr($s, $pos, $group_name_byte_count);
     $pos += $group_name_byte_count;
     //класс стали, используем только 10 символов из 80
     $this->steel = (string) substr($s, $pos, 10);
     $pos += 80;
     //сопротивление стали
     $this->Ry = unpackDouble(substr($s, $pos, 8));
     $pos += 8;
     //пропускаем пустые 8 байт
     $pos += 8;
     //gamma_C
     $this->gamma_c = unpackDouble(substr($s, $pos, 8));
     $pos += 8;
     //гибкость
     $this->FC = unpackDouble(substr($s, $pos, 8));
     $pos += 8;
     //тип группы, пропуск 2-х пустых
     $this->group_type = unpackInt_1(substr($s, $pos, 1));
     $pos += 3;
     //коэффициенты расчетной длины
     $this->mu_XZ = unpackDouble(substr($s, $pos, 8));
     $pos += 8;
     $this->mu_XY = unpackDouble(substr($s, $pos, 8));
     $pos += 8;
     //пропускаем пустые 64 байта
     $pos += 64;
     //кол-во элементов
     $member_count = unpackInt_4(substr($s, $pos, 4));
     $pos += 4;
     //номера элементов
     $this->list = array();
     for ($i = 1; $i <= $member_count; $i++) {
         $this->list[] = unpackInt_4(substr($s, $pos, 4));
         $pos += 4;
     }
 }
 function get_from_scad_spr($s)
 {
     mysql_query("TRUNCATE TABLE " . member_group_for_steel);
     $group = new MemberGroupSteel11();
     //начинаем чтение с кол-ва групп
     $pos = 80 + 4 * 8 + 1;
     $group_count = unpackInt_4(substr($s, $pos, 4));
     $pos += 4;
     //перебор строк
     for ($i = 1; $i <= $group_count; $i++) {
         //кол-во байт в названии группы
         $group_name_byte_count = unpackInt_2(substr($s, $pos, 2));
         //кол-во элементов
         $member_count = unpackInt_4(substr($s, $pos + 2 + $group_name_byte_count + 80 + 4 * 8 + 1 + 2 + 2 * 8 + 64, 4));
         //получаем часть данных, описание текущей группы
         $gap = 2 + $group_name_byte_count + 80 + 4 * 8 + 1 + 2 + 2 * 8 + 64 + 4 + $member_count * 4;
         $group->get_from_spr(substr($s, $pos, $gap));
         $pos += $gap;
         //запись в базу данных
         mysql_query("INSERT IGNORE INTO " . member_group_for_steel . " SET\n                      steel = '{$group->steel}',\n                      Ry = '{$group->Ry}',\n                      gamma_c = '{$group->gamma_c}',\n                      FC = '{$group->FC}',\n                      group_type = '{$group->group_type}',\n                      mu_XZ = '{$group->mu_XZ}',\n                      mu_XY = '{$group->mu_XY}',\n                      name = '" . iconv('Windows-1251', 'UTF-8', $group->name) . "',\n                      list = '" . implode(' ', $group->list) . "'");
     }
 }
 function get_from_scad_spr($data)
 {
     mysql_query("TRUNCATE TABLE " . member_group_for_steel);
     // кол-во групп
     $groupCount = unpackInt_4(substr($data, 1, 4));
     // Количество байт описания групп (имена + списки элементов) за вычетом байтов на имена
     $listBytes = unpackInt_4(substr($data, 5, 4));
     // Получаем блоки КО и описания КО
     $groupData = substr($data, 9, 329 * $groupCount);
     $listData = substr($data, 9 + 329 * $groupCount);
     // Позиция имени первого КО
     $listOffset = 0;
     // КО или группы КО блоками по 329 байт
     for ($i = 0; $i < $groupCount; $i++) {
         $group = new MemberGroupSteel21();
         // Разбираем КО
         $group->get_from_spr(substr($groupData, $i * 329, 329));
         //кол-во байт в названии группы (ищем первое вхождение нулевого байта)
         $groupNameByteCount = strpos($listData, "", $listOffset) - $listOffset;
         // Читаем имя КО
         $group->name = substr($listData, $listOffset, $groupNameByteCount);
         $listOffset += $groupNameByteCount + 1;
         $listBytes -= $groupNameByteCount + 1;
         //кол-во элементов
         $member_count = unpackInt_4(substr($listData, $listOffset, 4));
         $listOffset += 4;
         // Читаем список элементов
         for ($k = 0; $k < $member_count; $k++) {
             $group->list[] = unpackInt_4(substr($listData, $listOffset, 4));
             $listOffset += 4;
             $listBytes -= 4;
         }
         //запись в базу данных
         mysql_query("INSERT IGNORE INTO " . member_group_for_steel . " SET\n                      steel = '{$group->steel_type}',\n                      Ry = '{$group->steel_Ry}',\n                          \n                      group_type = '{$group->group_type}',\n                      member_type = '{$group->member_type}',\n                          \n                      isMuReg = '{$group->isMuSameWithRegulation}',\n                      isMuUsed = '{$group->isMuUsed}',\n                      onlyElastic = '{$group->isOnlyElastic}',\n                      addGroup = '{$group->isGroupAdditional}',\n                      check_DAL = '{$group->deflectionFromAllLoadsToBeChecked}',\n                      check_DTL = '{$group->deflectionFromTemporaryLoadsToBeChecked}',\n                          \n                      limit_RDAL = '{$group->limitRelativeDisplacementFromAllLoads}',\n                      limit_RDTL = '{$group->limitRelativeDisplacementFromTemporaryLoads}',\n                      limit_ADAL = '{$group->limitAbsoluteDisplacementFromAllLoads}',\n                      limit_ADTL = '{$group->limitAbsoluteDisplacementFromTemporaryLoads}',\n                          \n                      gamma_n = '{$group->gamma_n}',                        \n                      gamma_c = '{$group->gamma_c}',\n                          \n                      FC = '{$group->flexCompressed}',\n                      FT = '{$group->flexTensed}',\n                      BD = '{$group->bucklingDistance}',    \n\n                      mu_XZ = '{$group->mu_XZ}',\n                      mu_XY = '{$group->mu_XY}',\n                      length_XZ = '{$group->length_XZ}',\n                      length_XY = '{$group->length_XY}',\n                          \n                      name = '" . iconv('Windows-1251', 'UTF-8', $group->name) . "',\n                      list = '" . implode(' ', $group->list) . "'");
     }
     if ($listBytes != 0) {
         echo "ERROR in DOC28 <br/>";
     }
 }
 // Минимальный offset
 $minDocOffset = $docDescriptionOffset;
 // Читаем массив адресов документов в конце файла
 // Переходим на первый документ
 fseek($f, $docDescriptionOffset);
 $document = array();
 // Добавляем пустой элемент для документа No.0
 $document[0] = 0;
 $isFinalDoc = FALSE;
 while ($isFinalDoc === FALSE) {
     // читаем номер документа
     $number = unpackInt_2(fread($f, 2));
     // если номер положителен, читаем offset и count
     if ($number > 0) {
         $offset = unpackInt_4(fread($f, 4));
         $count = unpackInt_4(fread($f, 4));
         $doc = new TDoc($number, $offset, $count);
         $document[$number] = $doc;
         //            echo "$doc->number - $doc->byte_offset - $doc->byte_count<br/>";
         if ($doc->byte_offset < $minDocOffset) {
             $minDocOffset = $doc->byte_offset;
         }
     } else {
         $isFinalDoc = TRUE;
     }
 }
 // Добавляем документ No.0
 // Байты между указателем на адрес описания документов и первым записанным документом
 $document[0] = new TDoc(0, START_OFFSET + 4, $minDocOffset - START_OFFSET - 4);
 // Читаем документы в массив
 foreach ($document as &$object) {