- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
void __fastcall ReverseStream(TMemoryStream* Stream)
{
TMemoryStream* buf = new TMemoryStream;
buf->LoadFromStream(Stream);
__int64 size = Stream->Size;
Stream->Clear();
for (__int64 i=size-1; i >= 0; i--) {
buf->Position = i;
Stream->CopyFrom(buf, 1);
}
}
Если вы уверены, что это - говнокод, то давайте в студию и интерфейс данного класса, чтобы мы все увидели, что данную функциональность можно действительно реализовать эффективнее.
а в том, что у TMemoryStream говноинтерфейс сомнений быть не может:
1) копирующего конструктора нет
2) по крайней мере одно поле (Position) доступно напрямую
говноинтерфейсы плодят говнокод
а в том, что у TMemoryStream говноинтерфейс сомнений быть не может:
1) по крайней мере два поля (Size, Position) доступны напрямую
2) копирующий конструктор не используется (почему?)
3) метод CopyFrom() логичнее переделать в CopyFrom(откуда, с какого, сколько)
4) возникает ощущение что создатель говноинтерфейса любитель указателей. и возникает вопрос почему нет конструктора TMemoryStream(TMemoryStream *)?
2) Еще раз: не видя интерфейса класса `TMemoryStream` невозможно судить о том, есть ли там копирующий конструктор или нет. (И это, кстати, отдельный вопрос, должен ли он там быть для класса типа "stream").
3) Кто вам сказал, что вы можете там что-то "переделать"? Это может быть интерфейсом из "не вашей" библиотеки.
4) Аналогично №2 + №3.
Вы, похоже, наивно полагаете, что автор этого кода является и автором класса `TMemoryStream`. Где это сказано?
Копирующего конструктора там нет.
RTL см. http://docwiki.embarcadero.com/VCL/en/Classes.TMemoryStream
№1 тоже мимо, там геттеры
жалко память 2*N, а чпу здесь впустую не тратится (видимо побайтное копирование в лоб будет быстрее чем обмен байт из головы и хвоста массива)
вполне достаточно было написать что-то вроде
char *buf = new char[Stream->Size];
Stream->Position = 0;
__int64 size = Stream->Size;
for (__int64 i=size-1; i >= 0; i--) {
Stream->ReadBuffer(&(buf[i]), 1);
}
Stream->Clear();
Stream->WriteBuffer(buf, size);
delete[] buf;
уж лучше так....
Возмите, к примеру, класс `str::vector` из стандартной билиотеки. Вы можете добавлять в него элементы по одному N раз, но количество перевыделений памяти при этом в традиционной реализации будет log N, а не N. Так получается потому, что перевыделение памяти обычно делается с запасом, путем мультипликативного роста рамера вектора (например, каждый раз - растем в два раза).
В данном случае может иметь место точно такая же стратегия перевыделения памяти, т.е. утверждать, что количество перевыделений будет равно именно `size` не видя реализации нельзя. Или вы откуда-то знаете, что метод `CopyFrom` реализован именно так?
там есть виртуальный метод Realloc, который переопределен в TMemoryStream
выделяемый размер выравнивается по 8192 байт - нормальный запас...
это TMemoryStream из VCL, а там std нету... ибо дельфи.
может уж тогда все на std делать?
если это используется не для работы с другими компонентами BCB, а логика системы.
stl - не панацея от быдлокода.
Где?
> использование char, а не unsigned char
Какая разница в данном контексте?
>v[0] без проверки размера
И что?
> stl - не панацея от быдлокода.
Советую подучить мат.часть.
std::reverse (static_cast<char*>(stream->Memory), static_cast<char*>(stream->Memory) + stream->Size);
?