diff options
| author | jhurst <jhurst@cinecert.com> | 2006-11-21 23:58:00 +0000 |
|---|---|---|
| committer | jhurst <> | 2006-11-21 23:58:00 +0000 |
| commit | f0476a3789369459fb91076af4a29372d86d7622 (patch) | |
| tree | 6502d6fc94619371219d23c7522fd5ae7e6525bc /src | |
| parent | 9f903fec9d68fc58399a925b0311af3dc9a3faf2 (diff) | |
MPEG parser fixes: zero run-in patch, header buffer increase
Diffstat (limited to 'src')
| -rwxr-xr-x | src/AS_DCP.h | 2 | ||||
| -rwxr-xr-x | src/AS_DCP_MXF.cpp | 5 | ||||
| -rwxr-xr-x | src/KM_error.h | 8 | ||||
| -rwxr-xr-x | src/KM_prng.cpp | 3 | ||||
| -rwxr-xr-x | src/KM_util.h | 2 | ||||
| -rwxr-xr-x | src/MPEG.h | 2 | ||||
| -rwxr-xr-x | src/MPEG2_Parser.cpp | 33 | ||||
| -rwxr-xr-x | src/WavFileWriter.h | 120 | ||||
| -rwxr-xr-x | src/asdcp-test.cpp | 19 | ||||
| -rw-r--r-- | src/blackwave.cpp | 2 | ||||
| -rw-r--r-- | src/kmrandgen.cpp | 128 |
11 files changed, 239 insertions, 85 deletions
diff --git a/src/AS_DCP.h b/src/AS_DCP.h index 961dae3..5dc358c 100755 --- a/src/AS_DCP.h +++ b/src/AS_DCP.h @@ -144,7 +144,7 @@ namespace ASDCP { // 1.0.1. If changes were also required in AS_DCP.h, the new version would be 1.1.1. const ui32_t VERSION_MAJOR = 1; const ui32_t VERSION_APIMINOR = 1; - const ui32_t VERSION_IMPMINOR = 11; + const ui32_t VERSION_IMPMINOR = 12; const char* Version(); // UUIDs are passed around as strings of UUIDlen bytes diff --git a/src/AS_DCP_MXF.cpp b/src/AS_DCP_MXF.cpp index 9b86b55..68d9d6b 100755 --- a/src/AS_DCP_MXF.cpp +++ b/src/AS_DCP_MXF.cpp @@ -32,6 +32,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <KM_fileio.h> #include "AS_DCP_internal.h" #include "JP2K.h" +#include "MPEG.h" #include "Wav.h" @@ -189,8 +190,10 @@ ASDCP::RawEssenceType(const char* filename, EssenceType_t& type) if ( ASDCP_SUCCESS(result) ) { const byte_t* p = FB.RoData(); + ui32_t i = 0; + while ( p[i] == 0 ) i++; - if ( p[0] == 0 && p[1] == 0 && p[2] == 1 && (p[3] == 0xb3 || p[3] == 0) ) + if ( i > 1 && p[i] == 1 && (p[i+1] == ASDCP::MPEG2::SEQ_START || p[i+1] == ASDCP::MPEG2::PIC_START) ) type = ESS_MPEG2_VES; else if ( ASDCP_SUCCESS(WavHeader.ReadFromBuffer(p, read_count, &data_offset)) ) diff --git a/src/KM_error.h b/src/KM_error.h index ed171be..a91d416 100755 --- a/src/KM_error.h +++ b/src/KM_error.h @@ -55,13 +55,13 @@ namespace Kumu inline bool operator==(const Result_t& rhs) const { return value == rhs.value; } inline bool operator!=(const Result_t& rhs) const { return value != rhs.value; } - inline bool Success() { return ( value >= 0 ); } - inline bool Failure() { return ( value < 0 ); } + inline bool Success() const { return ( value >= 0 ); } + inline bool Failure() const { return ( value < 0 ); } - inline long Value() { return value; } + inline long Value() const { return value; } inline operator long() const { return value; } - inline const char* Label() { return label; } + inline const char* Label() const { return label; } inline operator const char*() const { return label; } }; diff --git a/src/KM_prng.cpp b/src/KM_prng.cpp index 094ee1b..e710d9a 100755 --- a/src/KM_prng.cpp +++ b/src/KM_prng.cpp @@ -135,8 +135,7 @@ public: { byte_t tmp[RNG_BLOCK_SIZE]; AES_encrypt(m_ctr_buf, tmp, &m_Context); - *(ui32_t*)(m_ctr_buf + 12) += 1; - memcpy(buf, tmp, len - gen_count); + memcpy(buf + gen_count, tmp, len - gen_count); } } }; diff --git a/src/KM_util.h b/src/KM_util.h index e01cd2b..f80f028 100755 --- a/src/KM_util.h +++ b/src/KM_util.h @@ -117,7 +117,7 @@ namespace Kumu i32_t hex2bin(const char* str, byte_t* buf, ui32_t buf_len, ui32_t* char_count); // Convert a binary string to NULL-terminated UTF-8 hexadecimal, returns the buffer - // if the binary buffer was large enough to hold the result. If the output buffer + // if the output buffer was large enough to hold the result. If the output buffer // is too small or any of the pointer arguments are NULL, the subroutine will // return 0. // @@ -83,7 +83,7 @@ namespace ASDCP // class VESParserDelegate; // the delegate is declared later - const ui32_t VESHeaderBufSize = 1024; // should be larger than any expected header + const ui32_t VESHeaderBufSize = 1024*16; // should be larger than any expected header // MPEG VES parser class - call Parse() as many times as you want with buffers // of any size. State is maintained between calls. When complete headers are diff --git a/src/MPEG2_Parser.cpp b/src/MPEG2_Parser.cpp index 791a889..7b0a57b 100755 --- a/src/MPEG2_Parser.cpp +++ b/src/MPEG2_Parser.cpp @@ -54,6 +54,23 @@ enum ParserState_t { ST_SLICE, }; +const char* +StringParserState(ParserState_t state) +{ + switch ( state ) + { + case ST_INIT: return "INIT"; + case ST_SEQ: return "SEQ"; + case ST_PIC: return "PIC"; + case ST_GOP: return "GOP"; + case ST_EXT: return "EXT"; + case ST_SLICE: return "SLICE"; + } + + return "*UNKNOWN*"; +} + + // class h__ParserState @@ -74,11 +91,12 @@ class h__ParserState switch ( m_State ) { case ST_INIT: + case ST_EXT: m_State = ST_SEQ; return RESULT_OK; } - DefaultLogSink().Error("SEQ follows 0x%02x\n", m_State); + DefaultLogSink().Error("SEQ follows %s\n", StringParserState(m_State)); return RESULT_STATE; } @@ -94,7 +112,7 @@ class h__ParserState return RESULT_OK; } - DefaultLogSink().Error("Slice follows 0x%02x\n", m_State); + DefaultLogSink().Error("Slice follows %s\n", StringParserState(m_State)); return RESULT_STATE; } @@ -112,7 +130,7 @@ class h__ParserState return RESULT_OK; } - DefaultLogSink().Error("PIC follows 0x%02x\n", m_State); + DefaultLogSink().Error("PIC follows %s\n", StringParserState(m_State)); return RESULT_STATE; } @@ -128,7 +146,7 @@ class h__ParserState return RESULT_OK; } - DefaultLogSink().Error("GOP follows 0x%02x\n", m_State); + DefaultLogSink().Error("GOP follows %s\n", StringParserState(m_State)); return RESULT_STATE; } @@ -145,7 +163,7 @@ class h__ParserState return RESULT_OK; } - DefaultLogSink().Error("EXT follows 0x%02x\n", m_State); + DefaultLogSink().Error("EXT follows %s\n", StringParserState(m_State)); return RESULT_STATE; } }; @@ -399,7 +417,10 @@ ASDCP::MPEG2::Parser::h__Parser::OpenRead(const char* filename) // Since no one complained and that's the easiest thing to implement, // I have left it that way. Let me know if you want to be able to // locate the first GOP in the stream. - if ( p[0] != 0 || p[1] != 0 || p[2] != 1 || ! ( p[3] == SEQ_START || p[3] == PIC_START ) ) + ui32_t i = 0; + while ( p[i] == 0 ) i++; + + if ( i < 2 || p[i] != 1 || ! ( p[i+1] == SEQ_START || p[i+1] == PIC_START ) ) { DefaultLogSink().Error("Frame buffer does not begin with a PIC or SEQ start code.\n"); return RESULT_RAW_FORMAT; diff --git a/src/WavFileWriter.h b/src/WavFileWriter.h index 048a7ec..74ffe6b 100755 --- a/src/WavFileWriter.h +++ b/src/WavFileWriter.h @@ -30,21 +30,61 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <KM_fileio.h> +#include <KM_log.h> #include <Wav.h> #include <list> #ifndef _WAVFILEWRITER_H_ #define _WAVFILEWRITER_H_ + +// +class WavFileElement : public Kumu::FileWriter +{ + ASDCP::PCM::FrameBuffer m_Buf; + byte_t* m_p; + + WavFileElement(); + KM_NO_COPY_CONSTRUCT(WavFileElement); + +public: + WavFileElement(ui32_t s) : m_Buf(s), m_p(0) + { + m_p = m_Buf.Data(); + } + + ~WavFileElement() {} + + void WriteSample(const byte_t* sample, ui32_t sample_size) + { + memcpy(m_p, sample, sample_size); + m_p += sample_size; + } + + ASDCP::Result_t Flush() + { + ui32_t write_count = 0; + + if ( m_p == m_Buf.Data() ) + return ASDCP::RESULT_EMPTY_FB; + + ui32_t write_size = m_p - m_Buf.Data(); + m_p = m_Buf.Data(); + return Write(m_Buf.RoData(), write_size, &write_count); + } +}; + + // class WavFileWriter { ASDCP::PCM::AudioDescriptor m_ADesc; - std::list<Kumu::FileWriter*> m_OutFile; + std::list<WavFileElement*> m_OutFile; + ui32_t m_ChannelCount; ASDCP_NO_COPY_CONSTRUCT(WavFileWriter); public: - WavFileWriter() {} + WavFileWriter() : m_ChannelCount(0) {} ~WavFileWriter() { while ( ! m_OutFile.empty() ) @@ -54,31 +94,60 @@ class WavFileWriter } } + // + enum SplitType_t { + ST_NONE, // write all channels to a single WAV file + ST_MONO, // write each channel a separate WAV file + ST_STEREO // write channel pairs to separate WAV files + }; + ASDCP::Result_t - OpenWrite(ASDCP::PCM::AudioDescriptor &ADesc, const char* file_root, bool split) + OpenWrite(ASDCP::PCM::AudioDescriptor &ADesc, const char* file_root, SplitType_t split = ST_NONE) { ASDCP_TEST_NULL_STR(file_root); - char filename[256]; - ui32_t file_count = 1; + char filename[Kumu::MaxFilePath]; + ui32_t file_count = 0; ASDCP::Result_t result = ASDCP::RESULT_OK; m_ADesc = ADesc; - if ( split ) + switch ( split ) { - assert ( m_ADesc.ChannelCount % 2 == 0 ); // no support yet for stuffing odd files + case ST_NONE: + file_count = 1; + m_ChannelCount = m_ADesc.ChannelCount; + break; + + case ST_MONO: + file_count = m_ADesc.ChannelCount; + m_ChannelCount = 1; + break; + + case ST_STEREO: + if ( m_ADesc.ChannelCount % 2 != 0 ) + { + Kumu::DefaultLogSink().Error("Unable to create 2-channel splits with odd number of input channels.\n"); + return ASDCP::RESULT_PARAM; + } + file_count = m_ADesc.ChannelCount / 2; - m_ADesc.ChannelCount = 2; + m_ChannelCount = 2; + break; } + assert(file_count && m_ChannelCount); + + ui32_t element_size = ASDCP::PCM::CalcFrameBufferSize(m_ADesc) / file_count; for ( ui32_t i = 0; i < file_count && ASDCP_SUCCESS(result); i++ ) { - snprintf(filename, 256, "%s_%u.wav", file_root, (i + 1)); - m_OutFile.push_back(new Kumu::FileWriter); + snprintf(filename, Kumu::MaxFilePath, "%s_%u.wav", file_root, (i + 1)); + m_OutFile.push_back(new WavFileElement(element_size)); result = m_OutFile.back()->OpenWrite(filename); if ( ASDCP_SUCCESS(result) ) { - ASDCP::Wav::SimpleWaveHeader Wav(m_ADesc); + ASDCP::PCM::AudioDescriptor tmpDesc = m_ADesc; + tmpDesc.ChannelCount = m_ChannelCount; + ASDCP::Wav::SimpleWaveHeader Wav(tmpDesc); result = Wav.WriteToFile(*(m_OutFile.back())); } } @@ -89,25 +158,34 @@ class WavFileWriter ASDCP::Result_t WriteFrame(ASDCP::PCM::FrameBuffer& FB) { - ui32_t write_count; - ASDCP::Result_t result = ASDCP::RESULT_OK; - std::list<Kumu::FileWriter*>::iterator fi; - assert(! m_OutFile.empty()); - - ui32_t sample_size = ASDCP::PCM::CalcSampleSize(m_ADesc); + if ( m_OutFile.empty() ) + return ASDCP::RESULT_STATE; + + if ( m_OutFile.size() == 1 ) // no de-interleave needed, just write out the frame + return m_OutFile.back()->Write(FB.RoData(), FB.Size(), 0); + + std::list<WavFileElement*>::iterator fi; + ui32_t sample_size = m_ADesc.QuantizationBits / 8; const byte_t* p = FB.RoData(); const byte_t* end_p = p + FB.Size(); while ( p < end_p ) { - for ( fi = m_OutFile.begin(); fi != m_OutFile.end() && ASDCP_SUCCESS(result); fi++ ) + for ( fi = m_OutFile.begin(); fi != m_OutFile.end(); fi++ ) { - result = (*fi)->Write(p, sample_size, &write_count); - assert(write_count == sample_size); - p += sample_size; + for ( ui32_t c = 0; c < m_ChannelCount; c++ ) + { + (*fi)->WriteSample(p, sample_size); + p += sample_size; + } } } + ASDCP::Result_t result = ASDCP::RESULT_OK; + + for ( fi = m_OutFile.begin(); fi != m_OutFile.end() && ASDCP_SUCCESS(result); fi++ ) + result = (*fi)->Flush(); + return result; } }; diff --git a/src/asdcp-test.cpp b/src/asdcp-test.cpp index cf7a91f..3d802e9 100755 --- a/src/asdcp-test.cpp +++ b/src/asdcp-test.cpp @@ -134,7 +134,7 @@ USAGE: %s -c <output-file> [-b <buffer-size>] [-d <duration>] [-e|-E]\n\ %s -t <input-file>\n\ \n\ %s -x <file-prefix> [-b <buffer-size>] [-d <duration>]\n\ - [-f <starting-frame>] [-m] [-p <frame-rate>] [-R] [-s <num>] [-S]\n\ + [-f <starting-frame>] [-m] [-p <frame-rate>] [-R] [-s <num>] [-S|-1]\n\ [-v] [-W] <input-file>\n\ \n", PACKAGE, PACKAGE, PACKAGE, PACKAGE, PACKAGE, PACKAGE, PACKAGE); @@ -174,6 +174,8 @@ Read/Write Options:\n\ essence only, requires -c, -d)\n\ -S - Split Wave essence to stereo WAV files during extract.\n\ Default is multichannel WAV\n\ + -1 - Split Wave essence to mono WAV files during extract.\n\ + Default is multichannel WAV\n\ -W - Read input file only, do not write source file\n\ \n"); @@ -223,6 +225,7 @@ public: bool write_hmac; // true if HMAC values are to be generated and written bool read_hmac; // true if HMAC values are to be validated bool split_wav; // true if PCM is to be extracted to stereo WAV files + bool mono_wav; // true if PCM is to be extracted to mono WAV files bool verbose_flag; // true if the verbose option was selected ui32_t fb_dump_size; // number of bytes of frame buffer to dump bool showindex_flag; // true if index is to be displayed @@ -263,7 +266,7 @@ public: // CommandOptions(int argc, const char** argv) : mode(MMT_NONE), error_flag(true), key_flag(false), key_id_flag(false), encrypt_header_flag(true), - write_hmac(true), read_hmac(false), split_wav(false), + write_hmac(true), read_hmac(false), split_wav(false), mono_wav(false), verbose_flag(false), fb_dump_size(0), showindex_flag(false), showheader_flag(false), no_write_flag(false), version_flag(false), help_flag(false), start_frame(0), duration(0xffffffff), duration_flag(false), do_repeat(false), use_smpte_labels(false), @@ -281,10 +284,14 @@ public: continue; } - if ( argv[i][0] == '-' && isalpha(argv[i][1]) && argv[i][2] == 0 ) + if ( argv[i][0] == '-' + && ( isalpha(argv[i][1]) || isdigit(argv[i][1]) ) + && argv[i][2] == 0 ) { switch ( argv[i][1] ) { + case '1': mono_wav = true; break; + case '2': split_wav = true; break; case 'i': mode = MMT_INFO; break; case 'G': mode = MMT_GOP_START; break; case 'W': no_write_flag = true; break; @@ -389,7 +396,7 @@ public: } else { - fprintf(stderr, "Unrecognized option: %s\n", argv[i]); + fprintf(stderr, "Unrecognized argument: %s\n", argv[i]); return; } @@ -1048,7 +1055,9 @@ read_PCM_file(CommandOptions& Options) } ADesc.ContainerDuration = last_frame - Options.start_frame; - OutWave.OpenWrite(ADesc, Options.file_root, Options.split_wav); + OutWave.OpenWrite(ADesc, Options.file_root, + ( Options.split_wav ? WavFileWriter::ST_STEREO : + ( Options.mono_wav ? WavFileWriter::ST_MONO : WavFileWriter::ST_NONE ) )); } if ( ASDCP_SUCCESS(result) && Options.key_flag ) diff --git a/src/blackwave.cpp b/src/blackwave.cpp index 311a0db..3c6fbc7 100644 --- a/src/blackwave.cpp +++ b/src/blackwave.cpp @@ -167,7 +167,7 @@ make_black_wav_file(CommandOptions& Options) memset(FrameBuffer.Data(), 0, FrameBuffer.Capacity()); FrameBuffer.Size(FrameBuffer.Capacity()); - if ( 1 ) // Options.verbose_flag ) + if ( Options.verbose_flag ) { fprintf(stderr, "48Khz PCM Audio, %s fps (%u spf)\n", "24", PCM::CalcSamplesPerFrame(ADesc)); diff --git a/src/kmrandgen.cpp b/src/kmrandgen.cpp index 615f2d1..7c80811 100644 --- a/src/kmrandgen.cpp +++ b/src/kmrandgen.cpp @@ -67,24 +67,32 @@ void usage(FILE* stream = stdout) { fprintf(stream, "\ -USAGE: %s [-b|-c] [-n] [-s <size>] [-v]\n\ +USAGE: %s [-b|-B|-c|-x] [-n] [-s <size>] [-v]\n\ \n\ %s [-h|-help] [-V]\n\ \n\ -b - Output a stream of binary data\n\ + -B - Output a Base64 string\n\ -c - Output a C-language struct containing the values\n\ -h | -help - Show help\n\ -n - Suppress newlines\n\ - -s <size> - Number of random bytes to generate (default 32, supplied value\n\ - is rounded up to nearest multiple of 16)\n\ + -s <size> - Number of random bytes to generate (default 32)\n\ -v - Verbose. Prints informative messages to stderr\n\ -V - Show version information\n\ + -x - Output hexadecimal (default)\n\ \n\ NOTES: o There is no option grouping, all options must be distinct arguments.\n\ o All option arguments must be separated from the option by whitespace.\n\ \n", PACKAGE, PACKAGE); } +enum OutputFormat_t { + OF_HEX, + OF_BINARY, + OF_BASE64, + OF_CSTRUCT +}; + // class CommandOptions { @@ -93,20 +101,17 @@ class CommandOptions public: bool error_flag; // true if the given options are in error or not complete bool no_newline_flag; // - bool c_array_flag; // - bool binary_flag; // bool verbose_flag; // true if the verbose option was selected bool version_flag; // true if the version display option was selected bool help_flag; // true if the help display option was selected + OutputFormat_t format; // ui32_t request_size; // CommandOptions(int argc, const char** argv) : - error_flag(true), no_newline_flag(false), c_array_flag(false), binary_flag(false), - verbose_flag(false), version_flag(false), help_flag(false), request_size(32) + error_flag(true), no_newline_flag(false), verbose_flag(false), + version_flag(false), help_flag(false), format(OF_HEX), request_size(RandBlockSize*2) { - ui32_t tmp_size = 0, diff = 0; - for ( int i = 1; i < argc; i++ ) { @@ -120,24 +125,20 @@ public: { switch ( argv[i][1] ) { - case 'b': binary_flag = true; break; - case 'c': c_array_flag = true; break; + case 'b': format = OF_BINARY; break; + case 'B': format = OF_BASE64; break; + case 'c': format = OF_CSTRUCT; break; case 'n': no_newline_flag = true; break; case 'h': help_flag = true; break; case 's': TEST_EXTRA_ARG(i, 's'); - tmp_size = atoi(argv[i]); - diff = tmp_size % RandBlockSize; - - if ( diff != 0 ) - tmp_size += RandBlockSize - diff; - - request_size = tmp_size; + request_size = abs(atoi(argv[i])); break; case 'v': verbose_flag = true; break; case 'V': version_flag = true; break; + case 'x': format = OF_HEX; break; default: fprintf(stderr, "Unrecognized option: %s\n", argv[i]); @@ -151,14 +152,14 @@ public: } } - if ( help_flag || version_flag ) - return; + if ( help_flag || version_flag ) + return; - if ( binary_flag && c_array_flag ) - { - fprintf(stderr, "Error, must use only one of -b and -c options.\n"); - return; - } + if ( request_size == 0 ) + { + fprintf(stderr, "Please use a non-zero request size\n"); + return; + } error_flag = false; } @@ -190,32 +191,41 @@ main(int argc, const char** argv) ByteString Buf(Kumu::Kilobyte); if ( Options.verbose_flag ) - fprintf(stderr, "Creating %d random values.\n", Options.request_size); + fprintf(stderr, "Generating %d random byte%s.\n", Options.request_size, (Options.request_size == 1 ? "" : "s")); - if ( Options.binary_flag ) + if ( Options.format == OF_BINARY ) { - for ( ui32_t i = 0; i < Options.request_size; i += Kumu::Kilobyte ) + if ( KM_FAILURE(Buf.Capacity(Options.request_size)) ) { - RandGen.FillRandom(Buf); - ui32_t write_size = ((i + Kumu::Kilobyte) > Options.request_size) ? Options.request_size - i : Kumu::Kilobyte; - fwrite((byte_t*)Buf.Data(), 1, write_size, stdout); + fprintf(stderr, "randbuf: %s\n", RESULT_ALLOC.Label()); + return 1; } + + RandGen.FillRandom(Buf.Data(), Options.request_size); + fwrite((byte_t*)Buf.Data(), 1, Options.request_size, stdout); } - else if ( Options.c_array_flag ) + else if ( Options.format == OF_CSTRUCT ) { + ui32_t line_count = 0; byte_t* p = Buf.Data(); printf("byte_t rand_buf[%u] = {\n", Options.request_size); + if ( Options.request_size > 128 ) + fputs(" // 0x00000000\n", stdout); + while ( Options.request_size > 0 ) { + if ( line_count > 0 && (line_count % (RandBlockSize*8)) == 0 ) + fprintf(stdout, " // 0x%08x\n", line_count); + RandGen.FillRandom(p, RandBlockSize); fputc(' ', stdout); - for ( ui32_t i = 0; i < RandBlockSize; i++ ) + for ( ui32_t i = 0; i < RandBlockSize && Options.request_size > 0; i++, Options.request_size-- ) printf(" 0x%02x,", p[i]); fputc('\n', stdout); - Options.request_size -= RandBlockSize; + line_count += RandBlockSize; } fputs("};", stdout); @@ -223,20 +233,54 @@ main(int argc, const char** argv) if ( ! Options.no_newline_flag ) fputc('\n', stdout); } - else + else if ( Options.format == OF_BASE64 ) + { + if ( KM_FAILURE(Buf.Capacity(Options.request_size)) ) + { + fprintf(stderr, "randbuf: %s\n", RESULT_ALLOC.Label()); + return 1; + } + + ByteString Strbuf; + ui32_t e_len = base64_encode_length(Options.request_size) + 1; + + if ( KM_FAILURE(Strbuf.Capacity(e_len)) ) + { + fprintf(stderr, "strbuf: %s\n", RESULT_ALLOC.Label()); + return 1; + } + + RandGen.FillRandom(Buf.Data(), Options.request_size); + + if ( base64encode(Buf.RoData(), Options.request_size, (char*)Strbuf.Data(), Strbuf.Capacity()) == 0 ) + { + fprintf(stderr, "encode error\n"); + return 2; + } + + fputs((const char*)Strbuf.RoData(), stdout); + + if ( ! Options.no_newline_flag ) + fputs("\n", stdout); + } + else // OF_HEX { - char hex_buf[64]; byte_t* p = Buf.Data(); + char hex_buf[64]; - for ( ui32_t i = 0; i < Options.request_size; i += RandBlockSize ) + while ( Options.request_size > 0 ) { + ui32_t x_len = xmin(Options.request_size, RandBlockSize); RandGen.FillRandom(p, RandBlockSize); - bin2hex(p, RandBlockSize, hex_buf, 64); - fputs(hex_buf, stdout); + bin2hex(p, x_len, hex_buf, 64); + fputs(hex_buf, stdout); + + if ( ! Options.no_newline_flag ) + fputc('\n', stdout); + + Options.request_size -= x_len; + } - if ( ! Options.no_newline_flag ) - fputc('\n', stdout); - } } return 0; |
