Hello -

I am trying to store binary in a string by using an
ExternalAsciiStringResource. There is a problem with values over 127.
It seems this might be solved a some cast somewhere inside of V8? Or
is it more complicated than that? The problem is shown with the
attached C++ program.

It seems arbitrary binary data inside a string is possible as
demonstrated by this program:

 for (var i = 0; i < 256; i++) {
  var s = "'\\" + i.toString(8) + "'";
  S = eval(s);
  print(s + " " + JSON.stringify(S) + " " + S.charCodeAt(0));
  if(S.charCodeAt(0) != i) throw "mismatch";
 }

It would be nice to be able to use ExternalAsciiStringResource in this way.

--~--~---------~--~----~------------~-------~--~----~
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
-~----------~----~----~----~------~----~------~--~---

// compile with
//   g++ -o test_v8 test.cc libv8.a -Iinclude -pthread
#include <assert.h>
#include <stdlib.h>
#include <string.h>

#include <v8.h>

using namespace v8;

// Helper function that compiles and runs the source.
static Local<Value> CompileRun(const char* source) {
  return Script::Compile(String::New(source))->Run();
}

class MyExternal : public String::ExternalAsciiStringResource {
 public:
  MyExternal (char *d, size_t length) 
    : ExternalAsciiStringResource()
  {
    data_ = static_cast<char*>(malloc(length));
    memcpy(data_, d, length);
    length_ = length;
  }

  virtual ~MyExternal ()
  {
    free(data_);
  }

  virtual const char * data () const 
  {
    return data_;
  }

  virtual size_t length () const
  {
    return length_;
  }

 private:
  char *data_;
  size_t length_;
};

int main () 
{
  V8::Initialize();
  HandleScope handle_scope;
  Persistent<Context> context = Context::New(NULL);
  Context::Scope context_scope(context);

  char output[256];
  for (int i = 0; i < 256; i++) {
    output[i] = i;
  }
  MyExternal *m = new MyExternal(output, 256);
  Local<String> e = String::NewExternal(m);
  context->Global()->Set(String::New("binary"), e);

  Local<Value> result = CompileRun(
    "if (binary.length != 256) throw 'length error.';\n"
    "var charCodes = [];\n"
    "for (var i = 0; i < binary.length; i++) {\n"
    "  charCodes.push(binary.charCodeAt(i));\n" 
    "}\n"
    "charCodes;");
  assert(result->IsArray());

  Local<Array> charCodes = Local<Array>::Cast(result);

  for (int i = 0; i < 256; i++) {
    Local<Value> code_val = charCodes->Get(Integer::New(i));
    assert(code_val->IsInt32());
    int code = code_val->IntegerValue();
    printf("%d == %d\n", code, i);
    assert(code == i);
  }

  return 0;
}

Reply via email to