コード例 #1
0
ファイル: backldif.c プロジェクト: Romppanen/gammu
static gboolean ReadLDIFText(const char *Buffer, const char *Start, char *Value)
{
	unsigned char 	Buffer2[1000],buff[200];
	int 		i;

	Value[0] = 0x00;

	strcpy(buff,Start);
	strcat(buff,":: ");
	if (!strncmp(Buffer,buff,strlen(buff))) {
		i = DecodeBASE64(Buffer+strlen(Start)+3, Buffer2, strlen(Buffer)-(strlen(Start)+3));
		dbgprintf(NULL, "Text after DecodeBASE64 is \"%s\"\n",Buffer2);
		DecodeUTF8(Value, Buffer2, i);
		dbgprintf(NULL, "Text after DecodeUTF8 is \"%s\"\n",DecodeUnicodeString(Value));
		return TRUE;
	}
	strcpy(buff,Start);
	strcat(buff,": ");
	if (!strncmp(Buffer,buff,strlen(buff))) {
		EncodeUnicode(Value,Buffer+strlen(Start)+2,strlen(Buffer)-(strlen(Start)+2));
		dbgprintf(NULL, "Text after EncodeUnicode is \"%s\"\n",DecodeUnicodeString(Value));
		return TRUE;
	}
	return FALSE;
}
コード例 #2
0
ファイル: Str.cpp プロジェクト: BlueMagnificent/Urho3D
unsigned String::NextUTF8Char(unsigned& byteOffset) const
{
    if (!buffer_)
        return 0;

    const char* src = buffer_ + byteOffset;
    unsigned ret = DecodeUTF8(src);
    byteOffset = (unsigned)(src - buffer_);

    return ret;
}
コード例 #3
0
ファイル: String.cpp プロジェクト: joewan/turso3d
unsigned String::NextUTF8Char(size_t& byteOffset) const
{
    if (!buffer)
        return 0;
    
    const char* src = Buffer() + byteOffset;
    unsigned ret = DecodeUTF8(src);
    byteOffset = src - Buffer();
    
    return ret;
}
コード例 #4
0
ファイル: UTF8String.cpp プロジェクト: dreamsxin/nsg-library
    //
    // Copyright (c) 2008-2014 the Urho3D project.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a copy
    // of this software and associated documentation files (the "Software"), to deal
    // in the Software without restriction, including without limitation the rights
    // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    // copies of the Software, and to permit persons to whom the Software is
    // furnished to do so, subject to the following conditions:
    //
    // The above copyright notice and this permission notice shall be included in
    // all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    unsigned UTF8String::NextUTF8Char(unsigned& byteOffset) const
    {
        const char* buffer = c_str();
        if (!buffer)
            return 0;
        
        const char* src = buffer + byteOffset;
        unsigned ret = DecodeUTF8(src);
		auto bytesDiff = src - buffer;
		CHECK_ASSERT(bytesDiff < std::numeric_limits<unsigned>::max());
        byteOffset = (unsigned)(src - buffer);
        
        return ret;
    }
コード例 #5
0
ファイル: Str.cpp プロジェクト: BlueMagnificent/Urho3D
unsigned String::LengthUTF8() const
{
    unsigned ret = 0;

    const char* src = buffer_;
    if (!src)
        return ret;
    const char* end = buffer_ + length_;

    while (src < end)
    {
        DecodeUTF8(src);
        ++ret;
    }

    return ret;
}
コード例 #6
0
ファイル: String.cpp プロジェクト: joewan/turso3d
size_t String::LengthUTF8() const
{
    size_t ret = 0;
    
    const char* src = Buffer();
    if (!src)
        return ret;
    const char* end = Buffer() + Length();
    
    while (src < end)
    {
        DecodeUTF8(src);
        ++ret;
    }
    
    return ret;
}
コード例 #7
0
	//----------------------------------------------------------------------------
	int GetTextChar(const char *text, int pos, int *nextPos=0)
	{
		int ch;
		unsigned int len;
		if (mEncoding == UTF8)
		{
			ch = DecodeUTF8((const unsigned char *)&text[pos], &len);
			if (ch == -1) len = 1;
		}
		else if (mEncoding == UTF16)
		{
			ch = DecodeUTF16((const unsigned char *)&text[pos], &len);
			if (ch == -1) len = 2;
		}
		else
		{
			len = 1;
			ch = (unsigned char)text[pos];
		}

		if (nextPos) *nextPos = pos + len;
		return ch;
	}
コード例 #8
0
ファイル: bitmapfont.c プロジェクト: kycho0820/TaeanPwr
static int Font_GetTextChar ( const char *text, int pos, int *nextPos )
{
	int ch;
	unsigned int len;
	EFontTextEncoding encoding = cur_pFont->encoding;

	if ( encoding == UTF8 )
	{
		ch = DecodeUTF8 ( &text[pos], &len );

		if ( ch == -1 ) len = 1;
	}
	else if ( encoding == UTF16 )
	{
		ch = DecodeUTF16 ( &text[pos], &len );

		if ( ch == -1 ) len = 2;
	}
	else
	{
		len = 1;
		ch = ( unsigned char ) text[pos];

		if ( ch >= 0x80 ) //oem
		{
			U16 oemcode;
			int ch2 = ( unsigned char ) text[pos + 1];
			len = 2;
			oemcode = ( ( U16 ) ch << 8 ) + ch2;
			ch = oem_to_unicode ( oemcode ); //oem to unicode
		}
	}

	if ( nextPos ) *nextPos = pos + len;

	return ch;
}
コード例 #9
0
// tests the encoding and decoding capability of an wxMBConv object
//
// decodes the utf-8 bytes into wide characters
// encodes the wide characters to compare against input multiBuffer
// decodes the multiBuffer to compare against wide characters
// decodes the multiBuffer into wide characters
void MBConvTestCase::TestCoder(
    const char*    multiBuffer, // a multibyte encoded character sequence that can be decoded by "converter"
    size_t         multiBytes,  // the byte length of the multibyte character sequence that can be decoded by "converter"
    const char*    utf8Buffer,  // the same character sequence as multiBuffer, encoded as UTF-8
    size_t         utf8Bytes,   // the byte length of the UTF-8 encoded character sequence
    wxMBConv*      converter,   // the wxMBConv object thta can decode multiBuffer into a wide character sequence
    int            sizeofNull   // the number of bytes occupied by a terminating null in the converter's encoding
    )
{
    // wide character size and endian-ess varies from platform to platform
    // compiler support for wide character literals varies from compiler to compiler
    // so we should store the wide character version as UTF-8 and depend on
    // the UTF-8 converter's ability to decode it to platform specific wide characters
    // this test is invalid if the UTF-8 converter can't decode
    wxWCharBuffer wideBuffer((size_t)0);
    wideBuffer = DecodeUTF8( utf8Buffer, utf8Bytes );
    size_t wideChars = wxWcslen( wideBuffer.data() );

    TestDecoder
        ( 
        wideBuffer.data(), 
        wideChars,
        (const char*)multiBuffer, 
        multiBytes,
        converter,
        sizeofNull
        );
    TestEncoder
        ( 
        wideBuffer.data(), 
        wideChars,
        (const char*)multiBuffer, 
        multiBytes,
        converter,
        sizeofNull
        );
}
コード例 #10
0
ファイル: sql.c プロジェクト: joltcan/gammu
/* Find one multi SMS to sending and return it (or return ERR_EMPTY)
 * There is also set ID for SMS
 */
static GSM_Error SMSDSQL_FindOutboxSMS(GSM_MultiSMSMessage * sms, GSM_SMSDConfig * Config, char *ID)
{
	SQL_result res;
	struct GSM_SMSDdbobj *db = Config->db;
	int i;
	time_t timestamp;
	const char *coding;
	const char *text;
	size_t text_len;
	const char *text_decoded;
	const char *destination;
	const char *udh;
	const char *q;
	size_t udh_len;
	SQL_Var vars[3];

	vars[0].type = SQL_TYPE_INT;
	vars[0].v.i = 1;
	vars[1].type = SQL_TYPE_NONE;

	while (TRUE) {
		if (SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[SQL_QUERY_FIND_OUTBOX_SMS_ID], NULL, vars, &res) != SQL_OK) {
			SMSD_Log(DEBUG_INFO, Config, "Error reading from database (%s)", __FUNCTION__);
			return ERR_UNKNOWN;
		}

		if (db->NextRow(Config, &res) != 1) {
			db->FreeResult(Config, &res);
			return ERR_EMPTY;
		}

		sprintf(ID, "%ld", (long)db->GetNumber(Config, &res, 0));
		timestamp = db->GetDate(Config, &res, 1);

		db->FreeResult(Config, &res);

		if (timestamp == -1) {
			SMSD_Log(DEBUG_INFO, Config, "Invalid date for InsertIntoDB.");
			return ERR_UNKNOWN;
		}

		SMSDSQL_Time2String(Config, timestamp, Config->DT, sizeof(Config->DT));
		if (SMSDSQL_RefreshSendStatus(Config, ID) == ERR_NONE) {
			break;
		}
	}

	sms->Number = 0;
	for (i = 0; i < GSM_MAX_MULTI_SMS; i++) {
		GSM_SetDefaultSMSData(&sms->SMS[i]);
		sms->SMS[i].SMSC.Number[0] = 0;
		sms->SMS[i].SMSC.Number[1] = 0;
	}

	for (i = 1; i < GSM_MAX_MULTI_SMS + 1; i++) {
		vars[0].type = SQL_TYPE_STRING;
		vars[0].v.s = ID;
		vars[1].type = SQL_TYPE_INT;
		vars[1].v.i = i;
		vars[2].type = SQL_TYPE_NONE;
		if (i == 1) {
			q = Config->SMSDSQL_queries[SQL_QUERY_FIND_OUTBOX_BODY];
		} else {
			q = Config->SMSDSQL_queries[SQL_QUERY_FIND_OUTBOX_MULTIPART];
		}
		if (SMSDSQL_NamedQuery(Config, q, NULL, vars, &res) != SQL_OK) {
			SMSD_Log(DEBUG_ERROR, Config, "Error reading from database (%s)", __FUNCTION__);
			return ERR_UNKNOWN;
		}

		if (db->NextRow(Config, &res) != 1) {
			db->FreeResult(Config, &res);
			return ERR_NONE;
		}

		coding = db->GetString(Config, &res, 1);
		text = db->GetString(Config, &res, 0);
		if (text == NULL) {
			text_len = 0;
		} else {
			text_len = strlen(text);
		}
		text_decoded = db->GetString(Config, &res, 4);
		udh = db->GetString(Config, &res, 2);
		if (udh == NULL) {
			udh_len = 0;
		} else {
			udh_len = strlen(udh);
		}

		sms->SMS[sms->Number].Coding = GSM_StringToSMSCoding(coding);
		if (sms->SMS[sms->Number].Coding == 0) {
			if (text == NULL || text_len == 0) {
				SMSD_Log(DEBUG_NOTICE, Config, "Assuming default coding for text message");
				sms->SMS[sms->Number].Coding = SMS_Coding_Default_No_Compression;
			} else {
				SMSD_Log(DEBUG_NOTICE, Config, "Assuming 8bit coding for binary message");
				sms->SMS[sms->Number].Coding = SMS_Coding_8bit;
			}
		}

		if (text == NULL || text_len == 0) {
			if (text_decoded == NULL) {
				SMSD_Log(DEBUG_ERROR, Config, "Message without text!");
				return ERR_UNKNOWN;
			} else {
				SMSD_Log(DEBUG_NOTICE, Config, "Message: %s", text_decoded);
				DecodeUTF8(sms->SMS[sms->Number].Text, text_decoded, strlen(text_decoded));
			}
		} else {
			switch (sms->SMS[sms->Number].Coding) {
				case SMS_Coding_Unicode_No_Compression:

				case SMS_Coding_Default_No_Compression:
					DecodeHexUnicode(sms->SMS[sms->Number].Text, text, text_len);
					break;

				case SMS_Coding_8bit:
					DecodeHexBin(sms->SMS[sms->Number].Text, text, text_len);
					sms->SMS[sms->Number].Length = text_len / 2;
					break;

				default:
					break;
			}
		}

		if (i == 1) {
			destination = db->GetString(Config, &res, 6);
			if (destination == NULL) {
				SMSD_Log(DEBUG_ERROR, Config, "Message without recipient!");
				return ERR_UNKNOWN;
			}
			DecodeUTF8(sms->SMS[sms->Number].Number, destination, strlen(destination));
		} else {
			CopyUnicodeString(sms->SMS[sms->Number].Number, sms->SMS[0].Number);
		}

		sms->SMS[sms->Number].UDH.Type = UDH_NoUDH;
		if (udh != NULL && udh_len != 0) {
			sms->SMS[sms->Number].UDH.Type = UDH_UserUDH;
			sms->SMS[sms->Number].UDH.Length = udh_len / 2;
			DecodeHexBin(sms->SMS[sms->Number].UDH.Text, udh, udh_len);
		}

		sms->SMS[sms->Number].Class = db->GetNumber(Config, &res, 3);
		sms->SMS[sms->Number].PDU = SMS_Submit;
		sms->Number++;

		if (i == 1) {
			strcpy(Config->CreatorID, db->GetString(Config, &res, 10));
			Config->relativevalidity = db->GetNumber(Config, &res, 8);

			Config->currdeliveryreport = db->GetBool(Config, &res, 9);

			/* Is this a multipart message? */
			if (!db->GetBool(Config, &res, 7)) {
				db->FreeResult(Config, &res);
				break;
			}

		}
		db->FreeResult(Config, &res);
	}

	return ERR_NONE;
}
コード例 #11
0
ファイル: gsmmisc.c プロジェクト: AndyLavr/gammu
/**
 * We separate matching text (Start) to tokens and then try to find all
 * tokens in Buffer. We also accept tokens like PREF, CHARSET or ENCODING.
 *
 * Also it parses TYPE=* tokens, matching it to text types passed in Start
 * parameter. For example Start "TEL;FAX;VOICE" matches "TEL;TYPE=FAX,VOICE"
 * or "TEL;FAX;TYPE=VOICE" or "TEL;TYPE=FAX;TYPE=VOICE" and of course
 * "TEL;FAX;VOICE".
 *
 * When all tokens are matched we found matching line.
 */
gboolean ReadVCALText(char *Buffer, const char *Start, unsigned char *Value, const gboolean UTF8, GSM_EntryLocation *location)
{
	char *line = NULL;
	char **tokens = NULL;
	char *charset = NULL;
	char *begin, *pos, *end, *end2;
	gboolean quoted_printable = FALSE;
	size_t numtokens, token;
	size_t i, j, len;
	gboolean found;
	gboolean ret = FALSE;

	/* Initialize output */
	Value[0] = 0x00;
	Value[1] = 0x00;

	/* Count number of tokens */
	len = strlen(Start);
	numtokens = 1;
	for (i = 0; i < len; i++) {
		if (Start[i] == ';') {
			numtokens++;
		}
	}

	/* Allocate memory */
	line = strdup(Start);
	if (line == NULL) {
		dbgprintf(NULL, "Could not alloc!\n");
		goto fail;
	}
	tokens = (char **)malloc(sizeof(char *) * numtokens);
	if (tokens == NULL) {
		dbgprintf(NULL, "Could not alloc!\n");
		goto fail;
	}

	/* Parse Start to vCard tokens (separated by ;) */
	token = 0;
	begin = line;
	for (i = 0; i < len; i++) {
		if (line[i] == ';') {
			tokens[token++] = begin;
			begin = line + i + 1;
			line[i] = 0;
		}
	}
	/* Store last token */
	tokens[token] = begin;

	/* Compare first token, it must be in place */
	pos = Buffer;
	len = strlen(tokens[0]);
	if (strncasecmp(pos, tokens[0], len) != 0) {
		goto fail;
	}
	/* Advance position */
	pos += len;
	/* No need to check this token anymore */
	tokens[0][0] = 0;
	/* Initialize location */
	if (location != NULL) {
		*location = PBK_Location_Unknown;
	}

	/* Check remaining tokens */
	while (*pos != ':') {
		if (*pos == ';') {
			pos++;
		} else {
			dbgprintf(NULL, "Could not parse! (stopped at string: %s)\n", pos);
			goto fail;
		}
		found = FALSE;
		for (token = 0; token < numtokens; token++) {
			len = strlen(tokens[token]);
			/* Skip already matched tokens */
			if (len == 0) {
				continue;
			}
			if (strncasecmp(pos, tokens[token], len) == 0) {
				dbgprintf(NULL, "Found %s\n", tokens[token]);
				/* Advance position */
				pos += len;
				/* We need to check one token less */
				tokens[token][0] = 0;
				found = TRUE;
				break;
			}
		}
		if (!found) {
			if (strncasecmp(pos, "ENCODING=QUOTED-PRINTABLE", 25) == 0) {
				quoted_printable = TRUE;
				/* Advance position */
				pos += 25;
				found = TRUE;
			} else if (strncasecmp(pos, "CHARSET=", 8) == 0) {
				/* Advance position */
				pos += 8;
				/* Grab charset */
				end = strchr(pos, ':');
				end2 = strchr(pos, ';');
				if (end == NULL && end2 == NULL) {
					dbgprintf(NULL, "Could not read charset!\n");
					goto fail;
				} else if (end == NULL) {
					end = end2;
				} else if (end2 != NULL && end2 < end) {
					end = end2;
				}
				/* We basically want strndup, but it is not portable */
				charset = strdup(pos);
				if (charset == NULL) {
					dbgprintf(NULL, "Could not alloc!\n");
					goto fail;
				}
				charset[end - pos] = 0;

				pos = end;
				found = TRUE;
			} else if (strncasecmp(pos, "TZID=", 5) == 0) {
				/* @todo: We ignore time zone for now */
				/* Advance position */
				pos += 5;
				/* Go behind value */
				end = strchr(pos, ':');
				end2 = strchr(pos, ';');
				if (end == NULL && end2 == NULL) {
					dbgprintf(NULL, "Could not read timezone!\n");
					goto fail;
				} else if (end == NULL) {
					end = end2;
				} else if (end2 != NULL && end2 < end) {
					end = end2;
				}
				pos = end;
				found = TRUE;
			} else if (strncasecmp(pos, "TYPE=", 5) == 0) {
				/* We ignore TYPE= prefix */
				pos += 5;

				/* Now process types, which should be comma separated */
				while (*pos != ':' && *pos != ';') {
					found = FALSE;

					/* Go through tokens to match */
					for (token = 0; token < numtokens; token++) {
						len = strlen(tokens[token]);
						/* Skip already matched tokens */
						if (len == 0) {
							continue;
						}
						if (strncasecmp(pos, tokens[token], len) == 0) {
							dbgprintf(NULL, "Found %s\n", tokens[token]);
							/* Advance position */
							pos += len;
							/* We need to check one token less */
							tokens[token][0] = 0;
							found = TRUE;
							break;
						}
					}

					if (!found) {
						if (strncasecmp(pos, "PREF", 4) == 0) {
							/* We ignore pref token */
							pos += 4;
							found = TRUE;
						} else if (strncasecmp(pos, "WORK", 4) == 0) {
							/* We ignore work token */
							pos += 4;
							found = TRUE;
							if (location != NULL) {
								*location = PBK_Location_Work;
							}
						} else if (strncasecmp(pos, "HOME", 4) == 0) {
							/* We ignore home token */
							pos += 4;
							found = TRUE;
							if (location != NULL) {
								*location = PBK_Location_Home;
							}
						} else {
							dbgprintf(NULL, "%s not found! (%s)\n", Start, pos);
							goto fail;
						}
					}

					if (*pos == ';' || *pos == ':') {
						dbgprintf(NULL, "End of TYPE= string\n");
						break;
					} else if (*pos == ',') {
						/* Advance past separator */
						pos++;
					} else {
						dbgprintf(NULL, "Could not parse TYPE=! (stopped at string: %s)\n", pos);
						goto fail;
					}

				}
			} else if (strncasecmp(pos, "PREF", 4) == 0) {
				/* We ignore pref token */
				pos += 4;
				found = TRUE;
			} else if (location && strncasecmp(pos, "WORK", 4) == 0) {
				/* We ignore pref token */
				pos += 4;
				found = TRUE;
				*location = PBK_Location_Work;
			} else if (location && strncasecmp(pos, "HOME", 4) == 0) {
				/* We ignore pref token */
				pos += 4;
				found = TRUE;
				*location = PBK_Location_Home;
			}
			if (!found) {
				dbgprintf(NULL, "%s not found!\n", Start);
				goto fail;
			}
		}
	}
	/* Skip : */
	pos++;
	/* Length of rest */
	len = strlen(pos);

	/* Did we match all our tokens? */
	for (token = 0; token < numtokens; token++) {
		if (strlen(tokens[token]) > 0) {
			dbgprintf(NULL, "All tokens did not match!\n");
			goto fail;
		}
	}

	/* Decode the text */
	if (charset == NULL) {
		if (quoted_printable) {
			if (UTF8) {
				DecodeUTF8QuotedPrintable(Value, pos, len);
			} else {
				DecodeISO88591QuotedPrintable(Value, pos, len);
			}
		} else {
			if (UTF8) {
				DecodeUTF8(Value, pos, len);
			} else {
				DecodeISO88591(Value, pos, len);
			}
		}
	} else {
		if (strcasecmp(charset, "UTF-8") == 0||
				strcasecmp(charset, "\"UTF-8\"") == 0
				) {
			if (quoted_printable) {
				DecodeUTF8QuotedPrintable(Value, pos, len);
			} else {
				DecodeUTF8(Value, pos, len);
			}
		} else if (strcasecmp(charset, "UTF-7") == 0||
				strcasecmp(charset, "\"UTF-7\"") == 0
				) {
			if (quoted_printable) {
				dbgprintf(NULL, "Unsupported charset: %s\n", charset);
				goto fail;
			} else {
				DecodeUTF7(Value, pos, len);
			}
		} else {
			dbgprintf(NULL, "Unsupported charset: %s\n", charset);
			goto fail;
		}
	}

	/* Postprocess escaped chars */
	len = UnicodeLength(Value);
	for (i = 0; i < len; i++) {
		if (Value[(2 * i)] == 0 && Value[(2 * i) + 1] == '\\') {
			j = i + 1;
			if (Value[(2 * j)] == 0 && (
						Value[(2 * j) + 1] == 'n' ||
						Value[(2 * j) + 1] == 'N')
						) {
				Value[(2 * i) + 1] = '\n';
			} else if (Value[(2 * j)] == 0 && (
						Value[(2 * j) + 1] == 'r' ||
						Value[(2 * j) + 1] == 'R')
						) {
				Value[(2 * i) + 1] = '\r';
			} else if (Value[(2 * j)] == 0 && Value[(2 * j) + 1] == '\\') {
				Value[(2 * i) + 1] = '\\';
			} else if (Value[(2 * j)] == 0 && Value[(2 * j) + 1] == ';') {
				Value[(2 * i) + 1] = ';';
			} else if (Value[(2 * j)] == 0 && Value[(2 * j) + 1] == ',') {
				Value[(2 * i) + 1] = ',';
			} else {
				/* We ignore unknown for now */
				continue;
			}
			/* Shift the string */
			memmove(Value + (2 * j), Value + (2 * j) + 2, 2 * (len + 1 - j));
			len--;
		}
	}

	ret = TRUE;
	dbgprintf(NULL, "ReadVCalText(%s) is \"%s\"\n", Start, DecodeUnicodeConsole(Value));
fail:
	free(line);
	line=NULL;
	free(tokens);
	tokens=NULL;
	free(charset);
	charset=NULL;
	return ret;
}
コード例 #12
0
ファイル: Request.cpp プロジェクト: alex-tifrea/gecko-dev
already_AddRefed<Promise>
Request::ConsumeBody(ConsumeType aType, ErrorResult& aRv)
{
  nsRefPtr<Promise> promise = Promise::Create(mOwner, aRv);
  if (aRv.Failed()) {
    return nullptr;
  }

  if (BodyUsed()) {
    aRv.ThrowTypeError(MSG_REQUEST_BODY_CONSUMED_ERROR);
    return nullptr;
  }

  SetBodyUsed();

  // While the spec says to do this asynchronously, all the body constructors
  // right now only accept bodies whose streams are backed by an in-memory
  // buffer that can be read without blocking. So I think this is fine.
  nsCOMPtr<nsIInputStream> stream;
  mRequest->GetBody(getter_AddRefs(stream));

  if (!stream) {
    aRv = NS_NewByteInputStream(getter_AddRefs(stream), "", 0,
                                NS_ASSIGNMENT_COPY);
    if (aRv.Failed()) {
      return nullptr;
    }
  }

  AutoJSAPI api;
  api.Init(mOwner);
  JSContext* cx = api.cx();

  // We can make this assertion because for now we only support memory backed
  // structures for the body argument for a Request.
  MOZ_ASSERT(NS_InputStreamIsBuffered(stream));
  nsCString buffer;
  uint64_t len;
  aRv = stream->Available(&len);
  if (aRv.Failed()) {
    return nullptr;
  }

  aRv = NS_ReadInputStreamToString(stream, buffer, len);
  if (aRv.Failed()) {
    return nullptr;
  }

  buffer.SetLength(len);

  switch (aType) {
    case CONSUME_ARRAYBUFFER: {
      JS::Rooted<JSObject*> arrayBuffer(cx);
      arrayBuffer =
        ArrayBuffer::Create(cx, buffer.Length(),
                            reinterpret_cast<const uint8_t*>(buffer.get()));
      JS::Rooted<JS::Value> val(cx);
      val.setObjectOrNull(arrayBuffer);
      promise->MaybeResolve(cx, val);
      return promise.forget();
    }
    case CONSUME_BLOB: {
      // XXXnsm it is actually possible to avoid these duplicate allocations
      // for the Blob case by having the Blob adopt the stream's memory
      // directly, but I've not added a special case for now.
      //
      // This is similar to nsContentUtils::CreateBlobBuffer, but also deals
      // with worker wrapping.
      uint32_t blobLen = buffer.Length();
      void* blobData = moz_malloc(blobLen);
      nsRefPtr<File> blob;
      if (blobData) {
        memcpy(blobData, buffer.BeginReading(), blobLen);
        blob = File::CreateMemoryFile(GetParentObject(), blobData, blobLen,
                                      NS_ConvertUTF8toUTF16(mMimeType));
      } else {
        aRv = NS_ERROR_OUT_OF_MEMORY;
        return nullptr;
      }

      promise->MaybeResolve(blob);
      return promise.forget();
    }
    case CONSUME_JSON: {
      nsString decoded;
      aRv = DecodeUTF8(buffer, decoded);
      if (aRv.Failed()) {
        return nullptr;
      }

      JS::Rooted<JS::Value> json(cx);
      if (!JS_ParseJSON(cx, decoded.get(), decoded.Length(), &json)) {
        JS::Rooted<JS::Value> exn(cx);
        if (JS_GetPendingException(cx, &exn)) {
          JS_ClearPendingException(cx);
          promise->MaybeReject(cx, exn);
        }
      }
      promise->MaybeResolve(cx, json);
      return promise.forget();
    }
    case CONSUME_TEXT: {
      nsString decoded;
      aRv = DecodeUTF8(buffer, decoded);
      if (aRv.Failed()) {
        return nullptr;
      }

      promise->MaybeResolve(decoded);
      return promise.forget();
    }
  }

  NS_NOTREACHED("Unexpected consume body type");
  // Silence warnings.
  return nullptr;
}