Нужна помощь!

 

Приветствую, други!

Собственно в рамках одного немаленького проекта пришлось использовать доступ к файлам через WinAPI. Досовые функции (_lcreat и иже с ними) не покатили -- слишком много траблов, уж лучше нормальные функции юзать.

Вот и решил написать библиотечку для работы с файлами. Любыми файлами. Средствами WinAPI. Причем так, чтобы пользоваться ей было максимально просто и удобно.

Часть библиотеки для чтения файлов уже готова (имплементация ConstFile).


Теперь собственно о помощи. Помощь нужна в тестировании, в архиве лежит либка (все уже разнесено по папкам) и пример ее использования с простейшим тест-кейсом в скрипте FileUnlimitedTest.mq5 .

Либку вполне можно использовать вместо стандартных функций (с некоторыми оговорками).


Оттестированная, либка в свободном виде выйдет в народ.

Большая просьба всем заинтересованным -- пожалуйста, максимально используйте либку.


Любые замечания, багрепорты, пожелания, критика и т.п. приветствуются.

Заранее спасибо!


ЗЫ: Пишушая часть и набор функций для работы будут доступны позднее и тоже будут нуждаться в тестировании.

Файлы:
MQL5.ZIP  9 kb
 

А тем временем либка написана и пылится на полке, правда очень поверхностно оттестированная :)

Если все будет ок, выложу вечером.

 

А может попросить MQ сделать нормальный доступ к файлам вне песочницы когда включено разрешение на импорт dll?

Переименовать пункт "разрешить DLL" в "разрешить пакостить" :)

 

Ну что, пробуйте. Возможно местами будет удобнее, чем обычными функциями.

Есть сомнения касательно адекватности реализации разделения, так что если будут предложения, высказывайтесь.

Тестовый скрипт, в прицепе он тоже есть:

#include <TheXpert/DebugTools/ASSERT.mqh>
#include <TheXpert/DebugTools/Trace/Trace.mqh>

#include <TheXpert/FileUnlimited/FileUnlimited.mqh>

void OnStart()
{__TRACE
   string name = "TheXpert\\Test.txt";
   string path = TerminalInfoString(TERMINAL_DATA_PATH) + "\\MQL5\\Files\\" + name;
   
   bool b1 = false, b2 = true;
   int i1 = -14, i2 = 243978;
   double d1 = -4.345, d2 = 248.234234;
   color c1 = clrBlueViolet, c2 = clrBlack;
   datetime t1 = TimeCurrent(), t2 = D'1990.10.5';
   string s1 = "1", s2 = "2348962349876";

   {
      File* file = OpenFile(path, CD_CREATE_ALWAYS, DA_READ_WRITE);
      if (CheckPointer(file) != POINTER_INVALID)
      {
         ASSERT(file.Write(b1));
         ASSERT(file.Write(long(i1)));
         ASSERT(file.Write(d1));
         ASSERT(file.Write(c1));
         ASSERT(file.Write(t1));
         ASSERT(file.Write(s1));
         ASSERT(file.Write(b2));
         ASSERT(file.Write(long(i2)));
         ASSERT(file.Write(d2));
         ASSERT(file.Write(c2));
         ASSERT(file.Write(t2));
         ASSERT(file.Write(s2));
         
         delete file;
      }
      else
      {
         Print("OpenFile failed with error #", GetLastErrorWin());
         ASSERT(false);
      }
   }

   bool b1_ = true, b2_ = false;
   int i1_ = 0, i2_ = 0;
   double d1_ = 0, d2_ = 0;
   color c1_ = clrBlack, c2_ = clrBlack;
   datetime t1_ = 0, t2_ = 0;
   string s1_ = "", s2_ = "";
   
   {
      ConstFile* file = OpenConstFile(path);
      if (CheckPointer(file) != POINTER_INVALID)
      {
         ASSERT(file.Read(b1_));
         ASSERT(file.Read(i1_));
         ASSERT(file.Read(d1_));
         ASSERT(file.Read(c1_));
         ASSERT(file.Read(t1_, ";\t\n\r"));
         ASSERT(file.Read(s1_));
         ASSERT(file.Read(b2_));
         ASSERT(file.Read(i2_));
         ASSERT(file.Read(d2_));
         ASSERT(file.Read(c2_));
         ASSERT(file.Read(t2_, ";\t\n\r"));
         ASSERT(file.Read(s2_));
         
         delete file;
      }
      else ASSERT(false);
   }
   
   ASSERT(b1 == b1_);
   ASSERT(i1 == i1_);
   ASSERT(d1 == d1_);
   ASSERT(c1 == c1_);
   ASSERT(t1 == t1_);
   ASSERT(s1 == s1_);
   ASSERT(b2 == b2_);
   ASSERT(i2 == i2_);
   ASSERT(d2 == d2_);
   ASSERT(c2 == c2_);
   ASSERT(t2 == t2_);
   ASSERT(s2 == s2_);
}

Заодно пример инкапсуляции в либах :) реализация запрятана полностью.

Файлы:
MQL5.ZIP  22 kb
 
bool   FileTimeToSystemTime(const uint& lpFileTime[], MqlDateTime& lpSystemTime[]);
из ConstFileUnlimitedWide.mq5 не должна правильно работать - по крайней мере на WIN32 там все разное - и форматы и размеры. WORD != int_mql5
 
A100:
из ConstFileUnlimitedWide.mq5 не должна правильно работать - по крайней мере на WIN32 там все разное - и форматы и размеры. WORD != int_mql5
Проверили или опять теоретизируете?
 
TheXpert:
Проверили или опять теоретизируете?

Конкретно FileTimeToSystemTime(...) не проверял, но ранее опытным путем для WIN32 установлено

WORD эквивалентно 16-bit unsigned integer 

int_mql5 эквивалентно 32-bit signed integer 

а если MqlDateTime фактически не иcпользуется - то зачем её объявлять? тем более, что её описание не соответствует SYSTEMTIME

 
A100:
Все будет работать ок. Хотя памяти и вправду в 2 раза больше выделяется чем надо. Взял себе на заметку.
 
TheXpert:
Все будет работать ок.

Ok будет только для какой-нибудь простенькой даты - типа 01.01.1980

поля разные  MqlDateTime != SYSTEMTIME

 
A100:

Ok будет только для какой-нибудь простенькой даты - типа 01.01.1980

Во-первых этот массив используется только в качестве буфера, я сам его НЕ ковыряю, поэтому это не может работать неправильно.

поля разные  MqlDateTime != SYSTEMTIME

Уверен?
 
struct MqlDateTime
  {
   int year;           // год
   int mon;            // месяц 
   int day;            // день
   int hour;           // час
   int min;            // минуты
   int sec;            // секунды
   int day_of_week;    // день недели (0-воскресенье, 1-понедельник, ... ,6-суббота)
   int day_of_year;    // порядковый номер в году (1 января имеет номер 0)
  };

typedef struct _SYSTEMTIME {
  WORD wYear;
  WORD wMonth; // 1-12
  WORD wDayOfWeek; // день недели
  WORD wDay;
  WORD wHour;
  WORD wMinute;
  WORD wSecond;
  WORD wMilliseconds; // миллисекунды
} SYSTEMTIME, *PSYSTEMTIME;